diff options
Diffstat (limited to 'src')
251 files changed, 3395 insertions, 2579 deletions
diff --git a/src/devices/bus/a2bus/a2cffa.cpp b/src/devices/bus/a2bus/a2cffa.cpp index 3839b338ae1..6aa0a2c904a 100644 --- a/src/devices/bus/a2bus/a2cffa.cpp +++ b/src/devices/bus/a2bus/a2cffa.cpp @@ -297,14 +297,14 @@ void a2bus_cffa2_device::nvram_default() bool a2bus_cffa2_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_eeprom, 0x1000, actual) && actual == 0x1000; + auto const [err, actual] = read(file, m_eeprom, 0x1000); + return !err && (actual == 0x1000); } bool a2bus_cffa2_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_eeprom, 0x1000, actual) && actual == 0x1000; + auto const [err, actual] = write(file, m_eeprom, 0x1000); + return !err; } void a2bus_cffa2_6502_device::nvram_default() @@ -314,14 +314,14 @@ void a2bus_cffa2_6502_device::nvram_default() bool a2bus_cffa2_6502_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_eeprom, 0x1000, actual) && actual == 0x1000; + auto const [err, actual] = read(file, m_eeprom, 0x1000); + return !err && (actual == 0x1000); } bool a2bus_cffa2_6502_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_eeprom, 0x1000, actual) && actual == 0x1000; + auto const [err, actual] = write(file, m_eeprom, 0x1000); + return !err; } } // anonymous namespace diff --git a/src/devices/bus/a7800/a78_slot.cpp b/src/devices/bus/a7800/a78_slot.cpp index 481e60faf90..2f407adb374 100644 --- a/src/devices/bus/a7800/a78_slot.cpp +++ b/src/devices/bus/a7800/a78_slot.cpp @@ -512,8 +512,7 @@ std::string a78_cart_slot_device::get_default_card_software(get_default_card_sof // Load and check the header uint8_t head[128]; - std::size_t actual; - hook.image_file()->read(&head[0], 128, actual); // FIXME: check error return or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &head[0], 128); // FIXME: check error return or read returning short // let's try to auto-fix some common errors in the header int const mapper = validate_header(get_u16be(&head[53]), false); diff --git a/src/devices/bus/a800/a800_slot.cpp b/src/devices/bus/a800/a800_slot.cpp index c3581c38ef5..8045f0152d0 100644 --- a/src/devices/bus/a800/a800_slot.cpp +++ b/src/devices/bus/a800/a800_slot.cpp @@ -655,9 +655,8 @@ std::string a800_cart_slot_device::get_default_card_software(get_default_card_so // check whether there is an header, to identify the cart type if ((len % 0x1000) == 0x10) { - size_t actual; uint8_t head[0x10]; - hook.image_file()->read(&head[0], 0x10, actual); // FIXME: check error return or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &head[0], 0x10); // FIXME: check error return or read returning short type = identify_cart_type(&head[0]); } else // otherwise try to guess based on size @@ -701,9 +700,8 @@ std::string a5200_cart_slot_device::get_default_card_software(get_default_card_s int type = A5200_8K; if ((len % 0x1000) == 0x10) { - size_t actual; uint8_t head[0x10]; - hook.image_file()->read(&head[0], 0x10, actual); // FIXME: check error return or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &head[0], 0x10); // FIXME: check error return or read returning short type = identify_cart_type(&head[0]); } else diff --git a/src/devices/bus/abcbus/ssa.cpp b/src/devices/bus/abcbus/ssa.cpp index c17c2e2a826..5a190fc0fbb 100644 --- a/src/devices/bus/abcbus/ssa.cpp +++ b/src/devices/bus/abcbus/ssa.cpp @@ -161,6 +161,23 @@ void abc_super_smartaid_device::device_reset() } +void abc_super_smartaid_device::nvram_default() +{ +} + +bool abc_super_smartaid_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram, m_nvram.bytes()); + return !err && (actual == m_nvram.bytes()); +} + +bool abc_super_smartaid_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram, m_nvram.bytes()); + return !err; +} + + //************************************************************************** // ABC BUS INTERFACE diff --git a/src/devices/bus/abcbus/ssa.h b/src/devices/bus/abcbus/ssa.h index daf42cce48c..d19f0ce9100 100644 --- a/src/devices/bus/abcbus/ssa.h +++ b/src/devices/bus/abcbus/ssa.h @@ -39,9 +39,9 @@ protected: virtual void device_reset() override; // device_nvram_interface implementation - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram, m_nvram.bytes(), actual) && actual == m_nvram.bytes(); } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram, m_nvram.bytes(), actual) && actual == m_nvram.bytes(); } + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; // device_abcbus_interface implementation virtual void abcbus_cs(uint8_t data) override { m_bus->write_cs(data); } diff --git a/src/devices/bus/adam/exp.cpp b/src/devices/bus/adam/exp.cpp index 837da2b6e77..33b950a1776 100644 --- a/src/devices/bus/adam/exp.cpp +++ b/src/devices/bus/adam/exp.cpp @@ -9,6 +9,8 @@ #include "emu.h" #include "exp.h" +#include <tuple> + //************************************************************************** @@ -76,13 +78,18 @@ void adam_expansion_slot_device::device_start() std::pair<std::error_condition, std::string> adam_expansion_slot_device::call_load() { + std::error_condition err; + if (m_card) { if (!loaded_through_softlist()) { size_t const size = length(); - fread(m_card->m_rom, size); + std::size_t actual; + std::tie(err, m_card->m_rom, actual) = read(image_core_file(), size); + if (!err && (actual != size)) + err = std::errc::io_error; } else { @@ -90,7 +97,7 @@ std::pair<std::error_condition, std::string> adam_expansion_slot_device::call_lo } } - return std::make_pair(std::error_condition(), std::string()); + return std::make_pair(err, std::string()); } diff --git a/src/devices/bus/aquarius/slot.cpp b/src/devices/bus/aquarius/slot.cpp index 90ca85a38d1..aa3863963c6 100644 --- a/src/devices/bus/aquarius/slot.cpp +++ b/src/devices/bus/aquarius/slot.cpp @@ -118,9 +118,8 @@ std::string aquarius_cartridge_slot_device::get_default_card_software(get_defaul { uint8_t header[16]; - size_t actual; hook.image_file()->seek(len - 0x2000, SEEK_SET); // FIXME: check error return - hook.image_file()->read(&header[0], 16, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &header[0], 16); // FIXME: check error return or read returning short // detect SuperCart header if (!memcmp(&header[0], SC08_HEADER, 16) || !memcmp(&header[0], SC16_HEADER, 16)) diff --git a/src/devices/bus/ata/cr589.cpp b/src/devices/bus/ata/cr589.cpp index 5cc413f0d60..15309f6e41e 100644 --- a/src/devices/bus/ata/cr589.cpp +++ b/src/devices/bus/ata/cr589.cpp @@ -29,8 +29,8 @@ void matsushita_cr589_device::nvram_default() bool matsushita_cr589_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(buffer, sizeof(buffer), actual) && actual == sizeof(buffer); + auto const [err, actual] = read(file, buffer, sizeof(buffer)); + return !err && (actual == sizeof(buffer)); } @@ -42,8 +42,8 @@ bool matsushita_cr589_device::nvram_read(util::read_stream &file) bool matsushita_cr589_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(buffer, sizeof(buffer), actual) && actual == sizeof(buffer); + auto const [err, actual] = write(file, buffer, sizeof(buffer)); + return !err; } diff --git a/src/devices/bus/c64/dqbb.cpp b/src/devices/bus/c64/dqbb.cpp index e08bfbd05b5..e4d50057537 100644 --- a/src/devices/bus/c64/dqbb.cpp +++ b/src/devices/bus/c64/dqbb.cpp @@ -75,6 +75,25 @@ void c64_dqbb_cartridge_device::device_reset() } +void c64_dqbb_cartridge_device::nvram_default() +{ +} + + +bool c64_dqbb_cartridge_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram.get(), 0x4000); + return !err && (actual == 0x4000); +} + + +bool c64_dqbb_cartridge_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram.get(), 0x4000); + return !err; +} + + //------------------------------------------------- // c64_cd_r - cartridge data read //------------------------------------------------- diff --git a/src/devices/bus/c64/dqbb.h b/src/devices/bus/c64/dqbb.h index ae480dc5c31..35a18f7e344 100644 --- a/src/devices/bus/c64/dqbb.h +++ b/src/devices/bus/c64/dqbb.h @@ -36,9 +36,9 @@ protected: virtual void device_reset() override; // device_nvram_interface implementation - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram.get(), 0x4000, actual) && actual == 0x4000; } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram.get(), 0x4000, actual) && actual == 0x4000; } + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; // device_c64_expansion_card_interface implementation virtual uint8_t c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2) override; diff --git a/src/devices/bus/c64/exp.cpp b/src/devices/bus/c64/exp.cpp index ebaad5d1815..7a53fadbf14 100644 --- a/src/devices/bus/c64/exp.cpp +++ b/src/devices/bus/c64/exp.cpp @@ -11,6 +11,8 @@ #include "formats/cbm_crt.h" +#include <tuple> + //************************************************************************** @@ -110,11 +112,16 @@ std::pair<std::error_condition, std::string> c64_expansion_slot_device::call_loa if (!loaded_through_softlist()) { + util::core_file &file = image_core_file(); size = length(); if (is_filetype("80")) { - fread(m_card->m_roml, size); + std::size_t actual; + std::tie(err, m_card->m_roml, actual) = read(file, size); + if (!err && (actual != size)) + err = std::errc::io_error; + m_card->m_roml_size = size; m_card->m_exrom = 0; @@ -125,7 +132,11 @@ std::pair<std::error_condition, std::string> c64_expansion_slot_device::call_loa } else if (is_filetype("a0")) { - fread(m_card->m_romh, 0x2000); + std::size_t actual; + std::tie(err, m_card->m_roml, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + m_card->m_romh_size = 0x2000; m_card->m_exrom = 0; @@ -133,14 +144,18 @@ std::pair<std::error_condition, std::string> c64_expansion_slot_device::call_loa } else if (is_filetype("e0")) { - fread(m_card->m_romh, 0x2000); + std::size_t actual; + std::tie(err, m_card->m_roml, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + m_card->m_romh_size = 0x2000; m_card->m_game = 0; } else if (is_filetype("crt")) { - if (cbm_crt_read_header(image_core_file(), &m_card->m_roml_size, &m_card->m_romh_size, &m_card->m_exrom, &m_card->m_game)) + if (cbm_crt_read_header(file, &m_card->m_roml_size, &m_card->m_romh_size, &m_card->m_exrom, &m_card->m_game)) { uint8_t *roml = nullptr; uint8_t *romh = nullptr; @@ -151,7 +166,7 @@ std::pair<std::error_condition, std::string> c64_expansion_slot_device::call_loa if (m_card->m_roml_size) roml = m_card->m_roml.get(); if (m_card->m_romh_size) romh = m_card->m_romh.get(); - cbm_crt_read_data(image_core_file(), roml, romh); + cbm_crt_read_data(file, roml, romh); } } else diff --git a/src/devices/bus/c64/fcc.cpp b/src/devices/bus/c64/fcc.cpp index 07ff8840e3a..879f69899ba 100644 --- a/src/devices/bus/c64/fcc.cpp +++ b/src/devices/bus/c64/fcc.cpp @@ -123,6 +123,25 @@ void c64_final_chesscard_device::device_reset() } +void c64_final_chesscard_device::nvram_default() +{ +} + + +bool c64_final_chesscard_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram.get(), 0x2000); + return !err && (actual == 0x2000); +} + + +bool c64_final_chesscard_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram.get(), 0x2000); + return !err; +} + + //------------------------------------------------- // c64_cd_r - cartridge data read //------------------------------------------------- diff --git a/src/devices/bus/c64/fcc.h b/src/devices/bus/c64/fcc.h index 7eafd23a1e9..90d3ba5556a 100644 --- a/src/devices/bus/c64/fcc.h +++ b/src/devices/bus/c64/fcc.h @@ -39,9 +39,9 @@ protected: virtual void device_reset() override; // device_nvram_interface implementation - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram.get(), 0x2000, actual) && actual == 0x2000; } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram.get(), 0x2000, actual) && actual == 0x2000; } + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; // device_c64_expansion_card_interface implementation virtual uint8_t c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2) override; diff --git a/src/devices/bus/c64/neoram.cpp b/src/devices/bus/c64/neoram.cpp index c0f292da161..e10ccac39b5 100644 --- a/src/devices/bus/c64/neoram.cpp +++ b/src/devices/bus/c64/neoram.cpp @@ -76,6 +76,25 @@ uint8_t c64_neoram_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int s } +void c64_neoram_cartridge_device::nvram_default() +{ +} + + +bool c64_neoram_cartridge_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram.get(), 0x200000); + return !err && (actual == 0x200000); +} + + +bool c64_neoram_cartridge_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram.get(), 0x200000); + return !err; +} + + //------------------------------------------------- // c64_cd_w - cartridge data write //------------------------------------------------- diff --git a/src/devices/bus/c64/neoram.h b/src/devices/bus/c64/neoram.h index c9711d2aca7..1a374440c45 100644 --- a/src/devices/bus/c64/neoram.h +++ b/src/devices/bus/c64/neoram.h @@ -36,9 +36,9 @@ protected: virtual void device_reset() override; // device_nvram_interface implementation - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram.get(), 0x200000, actual) && actual == 0x200000; } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram.get(), 0x200000, actual) && actual == 0x200000; } + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; // device_c64_expansion_card_interface implementation virtual uint8_t c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2) override; diff --git a/src/devices/bus/cbm2/exp.cpp b/src/devices/bus/cbm2/exp.cpp index bbb0d364722..187c98ef5aa 100644 --- a/src/devices/bus/cbm2/exp.cpp +++ b/src/devices/bus/cbm2/exp.cpp @@ -9,6 +9,8 @@ #include "emu.h" #include "exp.h" +#include <tuple> + //************************************************************************** @@ -91,22 +93,29 @@ std::pair<std::error_condition, std::string> cbm2_expansion_slot_device::call_lo { if (!loaded_through_softlist()) { + util::core_file &file = image_core_file(); size_t const size = length(); if (is_filetype("20")) { - m_card->m_bank1 = std::make_unique<uint8_t[]>(size); - fread(m_card->m_bank1, size); + size_t actual; + std::tie(err, m_card->m_bank1, actual) = util::read(file, size); + if (!err && (actual != size)) + err = std::errc::io_error; } else if (is_filetype("40")) { - m_card->m_bank2 = std::make_unique<uint8_t[]>(size); - fread(m_card->m_bank2, size); + size_t actual; + std::tie(err, m_card->m_bank2, actual) = util::read(file, size); + if (!err && (actual != size)) + err = std::errc::io_error; } else if (is_filetype("60")) { - m_card->m_bank3 = std::make_unique<uint8_t[]>(size); - fread(m_card->m_bank3, size); + size_t actual; + std::tie(err, m_card->m_bank3, actual) = util::read(file, size); + if (!err && (actual != size)) + err = std::errc::io_error; } else { diff --git a/src/devices/bus/cpc/cpc_rom.cpp b/src/devices/bus/cpc/cpc_rom.cpp index e8d17b61623..fee8cf3fdca 100644 --- a/src/devices/bus/cpc/cpc_rom.cpp +++ b/src/devices/bus/cpc/cpc_rom.cpp @@ -9,6 +9,9 @@ #include "emu.h" #include "cpc_rom.h" +#include <tuple> + + DEFINE_DEVICE_TYPE(CPC_ROM, cpc_rom_device, "cpc_rom", "CPC ROM Box") void cpc_exp_cards(device_slot_interface &device); @@ -103,20 +106,16 @@ void cpc_rom_image_device::device_start() -------------------------------------------------*/ std::pair<std::error_condition, std::string> cpc_rom_image_device::call_load() { - uint64_t const size = length(); - - m_base = std::make_unique<uint8_t[]>(16384); - if(size <= 16384) - { - fread(m_base, size); - } - else - { - fseek(size - 16384, SEEK_SET); - fread(m_base, 16384); - } - - return std::make_pair(std::error_condition(), std::string()); + uint64_t const total = length(); + size_t const size = std::min<uint64_t>(total, 16384); + + std::error_condition err; + size_t actual; + std::tie(err, m_base, actual) = read_at(image_core_file(), total - size, size); + if (!err && (actual != size)) + err = std::errc::io_error; + + return std::make_pair(err, std::string()); } diff --git a/src/devices/bus/ekara/slot.cpp b/src/devices/bus/ekara/slot.cpp index 0d10882ef13..33f4e087fa4 100644 --- a/src/devices/bus/ekara/slot.cpp +++ b/src/devices/bus/ekara/slot.cpp @@ -185,8 +185,7 @@ std::string ekara_cart_slot_device::get_default_card_software(get_default_card_s hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = get_cart_type(&rom[0], len); char const *const slot_string = ekara_get_slot(type); diff --git a/src/devices/bus/gamate/slot.cpp b/src/devices/bus/gamate/slot.cpp index ef613629651..b627aee6d3e 100644 --- a/src/devices/bus/gamate/slot.cpp +++ b/src/devices/bus/gamate/slot.cpp @@ -201,8 +201,7 @@ std::string gamate_cart_slot_device::get_default_card_software(get_default_card_ hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = get_cart_type(&rom[0], len); char const *const slot_string = gamate_get_slot(type); diff --git a/src/devices/bus/gameboy/gbslot.cpp b/src/devices/bus/gameboy/gbslot.cpp index c61507dbd4f..0f183b66cb1 100644 --- a/src/devices/bus/gameboy/gbslot.cpp +++ b/src/devices/bus/gameboy/gbslot.cpp @@ -26,6 +26,7 @@ #include <optional> #include <sstream> #include <string_view> +#include <tuple> #include <utility> #include <vector> @@ -551,10 +552,8 @@ bool is_m161(std::string_view tag, util::random_read &file, u64 length, u64 offs // look for a valid header in the second page u8 header2[0x50]; - size_t actual; - if (file.read_at(offset + 0x8000 + 0x0100, header2, sizeof(header2), actual) || (sizeof(header2) != actual)) - return false; - if (!cartheader::verify_header_checksum(header2)) + auto const [err, actual] = read_at(file, offset + 0x8000 + 0x0100, header2, sizeof(header2)); + if (err || (sizeof(header2) != actual) || !cartheader::verify_header_checksum(header2)) return false; // make sure it fits with the cartridge RAM size declaration @@ -614,10 +613,8 @@ bool read_gbx_footer_trailer(util::random_read &file, u64 length, gbxfile::trail if (sizeof(trailer) >= length) return false; - size_t actual; - if (file.read_at(length - sizeof(trailer), &trailer, sizeof(trailer), actual)) - return false; - if (sizeof(trailer) != actual) + auto const [err, actual] = read_at(file, length - sizeof(trailer), &trailer, sizeof(trailer)); + if (err || (sizeof(trailer) != actual)) return false; trailer.swap(); @@ -635,9 +632,11 @@ std::optional<char const *> probe_gbx_footer(std::string_view tag, util::random_ return std::nullopt; // need to read the footer leader - gbxfile::leader_1_0 leader; + std::error_condition err; size_t actual; - if (file.read_at(length - trailer.size, &leader, sizeof(leader), actual) || (sizeof(leader) != actual)) + gbxfile::leader_1_0 leader; + std::tie(err, actual) = read_at(file, length - trailer.size, &leader, sizeof(leader)); + if (err || (sizeof(leader) != actual)) { osd_printf_warning( "[%s] Error reading GBX trailer leader - assuming file is not GBX format\n", @@ -709,7 +708,8 @@ std::optional<char const *> probe_gbx_footer(std::string_view tag, util::random_ // need to probe for EEPROM size // TODO: does the GBX footer declare the EEPROM size as cartridge RAM size? u8 header[0x50]; - if (!file.read_at(offset + 0x100, header, sizeof(header), actual) && (sizeof(header) == actual)) + std::tie(err, actual) = read_at(file, offset + 0x100, header, sizeof(header)); + if (!err && (sizeof(header) == actual)) { result = guess_mbc7_type(tag, file, length, offset, header); } @@ -816,8 +816,8 @@ bool detect_mmm01(std::string_view tag, util::random_read &file, u64 length, u64 // now check for a valid cartridge header u32 const lastpage(get_mmm01_initial_low_page(length)); u8 backheader[0x50]; - size_t actual; - if (file.read_at(lastpage + 0x100, backheader, sizeof(backheader), actual) || (sizeof(backheader) != actual)) + auto const [err, actual] = read_at(file, lastpage + 0x100, backheader, sizeof(backheader)); + if (err || (sizeof(backheader) != actual)) { osd_printf_warning( "[%s] Error reading last page of program ROM - assuming cartridge does not use MMM01 controller\n", @@ -1005,8 +1005,8 @@ std::string gb_cart_slot_device::get_default_card_software(get_default_card_soft return guess; u8 header[0x50]; - size_t actual; - if (hook.image_file()->read_at(offset + 0x0100, header, sizeof(header), actual) || (sizeof(header) != actual)) + auto const [err, actual] = read_at(*hook.image_file(), offset + 0x0100, header, sizeof(header)); + if (err || (sizeof(header) != actual)) { // reading header failed - guess based on size if (0x8000 >= len) @@ -1128,7 +1128,6 @@ std::pair<std::error_condition, std::string> gb_cart_slot_device::load_image_fil bool proberam = true; auto len = length(); u64 offset; - size_t actual; // probe for GBX format memory_region *gbxregion = nullptr; @@ -1139,7 +1138,7 @@ std::pair<std::error_condition, std::string> gb_cart_slot_device::load_image_fil std::unique_ptr<u8 []> const footer(new (std::nothrow) u8 [gbxtrailer.size]); if (!footer) return std::make_pair(std::errc::not_enough_memory, "Error allocating memory to read GBX file footer"); - std::error_condition const err = file.read_at(len - gbxtrailer.size, footer.get(), gbxtrailer.size, actual); + auto const [err, actual] = read_at(file, len - gbxtrailer.size, footer.get(), gbxtrailer.size); if (err || (gbxtrailer.size != actual)) return std::make_pair(err ? err : std::errc::io_error, "Error reading GBX file footer"); if (1 != gbxtrailer.ver_maj) @@ -1241,7 +1240,7 @@ std::pair<std::error_condition, std::string> gb_cart_slot_device::load_image_fil { LOG("Allocating %u byte cartridge ROM region\n", len); memory_region *const romregion = machine().memory().region_alloc(subtag("rom"), len, 1, ENDIANNESS_LITTLE); - std::error_condition const err = file.read_at(offset, romregion->base(), len, actual); + auto const [err, actual] = read_at(file, offset, romregion->base(), len); if (err || (len != actual)) return std::make_pair(err ? err : std::errc::io_error, "Error reading ROM data from cartridge file"); diff --git a/src/devices/bus/gameboy/huc3.cpp b/src/devices/bus/gameboy/huc3.cpp index 99c5950fe59..c9b13943225 100644 --- a/src/devices/bus/gameboy/huc3.cpp +++ b/src/devices/bus/gameboy/huc3.cpp @@ -115,6 +115,7 @@ #include <iterator> #include <limits> #include <string> +#include <tuple> #include <type_traits> //#define VERBOSE 1 @@ -483,16 +484,22 @@ bool huc3_device::nvram_read(util::read_stream &file) { if (m_has_battery) { - // read previous machine time (seconds since epoch), seconds counter, and register contents - u64 machinesecs; + std::error_condition err; std::size_t actual; - if (file.read(&machinesecs, sizeof(machinesecs), actual) || (sizeof(machinesecs) != actual)) + + // read previous machine time (seconds since epoch) + u64 machinesecs; + std::tie(err, actual) = read(file, &machinesecs, sizeof(machinesecs)); + if (err || (sizeof(machinesecs) != actual)) return false; m_machine_seconds = big_endianize_int64(machinesecs); - if (file.read(&m_seconds, sizeof(m_seconds), actual) || (sizeof(m_seconds) != actual)) + // read seconds counter and register contents + std::tie(err, actual) = read(file, &m_seconds, sizeof(m_seconds)); + if (err || (sizeof(m_seconds) != actual)) return false; - if (file.read(&m_registers[0], sizeof(m_registers), actual) || (sizeof(m_registers) != actual)) + std::tie(err, actual) = read(file, &m_registers[0], sizeof(m_registers)); + if (err || (sizeof(m_registers) != actual)) return false; } else @@ -509,12 +516,16 @@ bool huc3_device::nvram_write(util::write_stream &file) system_time current; machine().current_datetime(current); u64 const machinesecs(big_endianize_int64(s64(std::make_signed_t<decltype(current.time)>(current.time)))); + std::error_condition err; std::size_t written; - if (file.write(&machinesecs, sizeof(machinesecs), written) || (sizeof(machinesecs) != written)) + std::tie(err, written) = write(file, &machinesecs, sizeof(machinesecs)); + if (err) return false; - if (file.write(&m_seconds, sizeof(m_seconds), written) || (sizeof(m_seconds) != written)) + std::tie(err, written) = write(file, &m_seconds, sizeof(m_seconds)); + if (err) return false; - if (file.write(&m_registers[0], sizeof(m_registers), written) || (sizeof(m_registers) != written)) + std::tie(err, written) = write(file, &m_registers[0], sizeof(m_registers)); + if (err) return false; return true; } diff --git a/src/devices/bus/gameboy/mbc3.cpp b/src/devices/bus/gameboy/mbc3.cpp index 1b567138498..c850ba2e8c9 100644 --- a/src/devices/bus/gameboy/mbc3.cpp +++ b/src/devices/bus/gameboy/mbc3.cpp @@ -82,6 +82,7 @@ #include "corestr.h" #include <string> +#include <tuple> //#define VERBOSE 1 //#define LOG_OUTPUT_FUNC osd_printf_info @@ -512,13 +513,17 @@ bool mbc3_device_base::nvram_read(util::read_stream &file) if (m_has_battery) { // read previous machine time (seconds since epoch) and RTC registers - u64 seconds; + std::error_condition err; std::size_t actual; - if (file.read(&seconds, sizeof(seconds), actual) || (sizeof(seconds) != actual)) + + u64 seconds; + std::tie(err, actual) = read(file, &seconds, sizeof(seconds)); + if (err || (sizeof(seconds) != actual)) return false; m_machine_seconds = big_endianize_int64(seconds); - if (file.read(&m_rtc_regs[0][0], sizeof(m_rtc_regs[0]), actual) || (sizeof(m_rtc_regs[0]) != actual)) + std::tie(err, actual) = read(file, &m_rtc_regs[0][0], sizeof(m_rtc_regs[0])); + if (err || (sizeof(m_rtc_regs[0]) != actual)) return false; } else @@ -535,10 +540,13 @@ bool mbc3_device_base::nvram_write(util::write_stream &file) system_time current; machine().current_datetime(current); u64 const seconds(big_endianize_int64(s64(std::make_signed_t<decltype(current.time)>(current.time)))); + std::error_condition err; std::size_t written; - if (file.write(&seconds, sizeof(seconds), written) || (sizeof(seconds) != written)) + std::tie(err, written) = write(file, &seconds, sizeof(seconds)); + if (err) return false; - if (file.write(&m_rtc_regs[0][0], sizeof(m_rtc_regs[0]), written) || (sizeof(m_rtc_regs[0]) != written)) + std::tie(err, written) = write(file, &m_rtc_regs[0][0], sizeof(m_rtc_regs[0])); + if (err) return false; return true; } diff --git a/src/devices/bus/gameboy/mdslot.cpp b/src/devices/bus/gameboy/mdslot.cpp index 8ef534c9bef..7339d139c1b 100644 --- a/src/devices/bus/gameboy/mdslot.cpp +++ b/src/devices/bus/gameboy/mdslot.cpp @@ -119,13 +119,12 @@ std::string megaduck_cart_slot_device::get_default_card_software(get_default_car std::pair<std::error_condition, std::string> megaduck_cart_slot_device::load_image_file(util::random_read &file) { auto const len = length(); - size_t actual; if (len) { LOG("Allocating %u byte cartridge ROM region\n", len); memory_region *const romregion = machine().memory().region_alloc(subtag("rom"), len, 1, ENDIANNESS_LITTLE); - std::error_condition const err = file.read_at(0, romregion->base(), len, actual); + auto const [err, actual] = read_at(file, 0, romregion->base(), len); if (err || (len != actual)) std::make_pair(err ? err : std::errc::io_error, "Error reading cartridge file"); } diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp index 950f4087eb8..e36c7a2650d 100644 --- a/src/devices/bus/gba/gba_slot.cpp +++ b/src/devices/bus/gba/gba_slot.cpp @@ -881,8 +881,7 @@ std::string gba_cart_slot_device::get_default_card_software(get_default_card_sof hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = get_cart_type(&rom[0], len); char const *const slot_string = gba_get_slot(type); diff --git a/src/devices/bus/intv/slot.cpp b/src/devices/bus/intv/slot.cpp index fbef7a20457..2d905d273ae 100644 --- a/src/devices/bus/intv/slot.cpp +++ b/src/devices/bus/intv/slot.cpp @@ -444,8 +444,7 @@ std::string intv_cart_slot_device::get_default_card_software(get_default_card_so hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int type = INTV_STD; if (rom[0] == 0xa8 && (rom[1] == (rom[2] ^ 0xff))) diff --git a/src/devices/bus/jakks_gamekey/slot.cpp b/src/devices/bus/jakks_gamekey/slot.cpp index c1760874010..7da3904f32c 100644 --- a/src/devices/bus/jakks_gamekey/slot.cpp +++ b/src/devices/bus/jakks_gamekey/slot.cpp @@ -183,8 +183,7 @@ std::string jakks_gamekey_slot_device::get_default_card_software(get_default_car hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = get_cart_type(&rom[0], len); char const *const slot_string = jakks_gamekey_get_slot(type); diff --git a/src/devices/bus/megadrive/md_slot.cpp b/src/devices/bus/megadrive/md_slot.cpp index b21f6779398..a7b4d2a20ac 100644 --- a/src/devices/bus/megadrive/md_slot.cpp +++ b/src/devices/bus/megadrive/md_slot.cpp @@ -909,8 +909,7 @@ std::string base_md_cart_slot_device::get_default_card_software(get_default_card hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + util::read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short uint32_t const offset = genesis_is_SMD(&rom[0x200], len - 0x200) ? 0x200 : 0; @@ -920,7 +919,9 @@ std::string base_md_cart_slot_device::get_default_card_software(get_default_card return std::string(slot_string); } else + { return software_get_default_slot("rom"); + } } diff --git a/src/devices/bus/msx/cart/cartridge.cpp b/src/devices/bus/msx/cart/cartridge.cpp index ade11a98b84..7fc7e863349 100644 --- a/src/devices/bus/msx/cart/cartridge.cpp +++ b/src/devices/bus/msx/cart/cartridge.cpp @@ -166,9 +166,8 @@ std::string msx_slot_cartridge_device::get_default_card_software(get_default_car return std::string(slotoptions::NOMAPPER); } length = std::min<u64>(length, 4 * 1024 * 1024); - std::vector<u8> rom(length); - size_t actual; - if (hook.image_file()->read(&rom[0], length, actual)) + auto const [err, rom, actual] = read(*hook.image_file(), length); + if (err || (actual != length)) { osd_printf_warning("[%s] Error reading from file\n", tag()); return std::string(slotoptions::NOMAPPER); diff --git a/src/devices/bus/nabupc/adapter.cpp b/src/devices/bus/nabupc/adapter.cpp index 8afd3a51484..0c6ecef575f 100644 --- a/src/devices/bus/nabupc/adapter.cpp +++ b/src/devices/bus/nabupc/adapter.cpp @@ -12,6 +12,8 @@ #include "emuopts.h" #include "unzip.h" +#include <tuple> + #define VERBOSE 0 #include "logmacro.h" @@ -93,7 +95,7 @@ std::error_condition network_adapter::segment_file::parse_segment(char *data, si current.tier[3] = 0xff; current.mbytes[0] = 0x7f; current.mbytes[1] = 0x80; - err = fd->read_at(offset, current.data, 991, actual); + std::tie(err, actual) = read_at(*fd, offset, current.data, 991); do { crc = 0xffff; if (err) { @@ -119,7 +121,7 @@ std::error_condition network_adapter::segment_file::parse_segment(char *data, si pak_list.push_back(current); offset = (++npak * 991); memset(current.data, 0, 991); - err = fd->read_at(offset, current.data, 991, actual); + std::tie(err, actual) = read_at(*fd, offset, current.data, 991); } } while(actual > 0); diff --git a/src/devices/bus/nes/aladdin.cpp b/src/devices/bus/nes/aladdin.cpp index b24543e720b..add680fbfed 100644 --- a/src/devices/bus/nes/aladdin.cpp +++ b/src/devices/bus/nes/aladdin.cpp @@ -145,8 +145,7 @@ std::string nes_aladdin_slot_device::get_default_card_software(get_default_card_ hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + util::read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short uint8_t const mapper = ((rom[6] & 0xf0) >> 4) | (rom[7] & 0xf0); diff --git a/src/devices/bus/nes/nes_slot.cpp b/src/devices/bus/nes/nes_slot.cpp index 3d873e4902d..d7df07d7693 100644 --- a/src/devices/bus/nes/nes_slot.cpp +++ b/src/devices/bus/nes/nes_slot.cpp @@ -799,8 +799,7 @@ std::string nes_cart_slot_device::get_default_card_software(get_default_card_sof hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short const char *slot_string = "nrom"; if ((rom[0] == 'N') && (rom[1] == 'E') && (rom[2] == 'S')) diff --git a/src/devices/bus/odyssey2/slot.cpp b/src/devices/bus/odyssey2/slot.cpp index e3d0ae34168..dba3fa09ff3 100644 --- a/src/devices/bus/odyssey2/slot.cpp +++ b/src/devices/bus/odyssey2/slot.cpp @@ -10,6 +10,9 @@ #include "emu.h" #include "slot.h" +#include <tuple> + + //************************************************************************** // GLOBAL VARIABLES //************************************************************************** @@ -132,6 +135,8 @@ static const char *o2_get_slot(int type) std::pair<std::error_condition, std::string> o2_cart_slot_device::call_load() { + std::error_condition err; + if (m_cart) { if (loaded_through_softlist()) @@ -153,24 +158,33 @@ std::pair<std::error_condition, std::string> o2_cart_slot_device::call_load() else { u32 const size = length(); - fread(m_cart->m_rom, size); - - m_cart->m_rom_size = size; - m_cart->m_exrom_size = 0; - m_cart->m_voice_size = 0; - m_b = 0; - - m_type = (size == 0x4000) ? O2_RALLY : O2_STD; + size_t actual; + std::tie(err, m_cart->m_rom, actual) = read(image_core_file(), size); + if (!err && (actual != size)) + err = std::errc::io_error; + + if (!err) + { + m_cart->m_rom_size = size; + m_cart->m_exrom_size = 0; + m_cart->m_voice_size = 0; + m_b = 0; + + m_type = (size == 0x4000) ? O2_RALLY : O2_STD; + } } if (m_cart->get_rom_size() > 0) - { m_cart->cart_init(); - return std::make_pair(std::error_condition(), std::string()); - } + else if (!err) + err = image_error::UNSPECIFIED; + } + else + { + err = image_error::UNSPECIFIED; } - return std::make_pair(image_error::UNSPECIFIED, std::string()); + return std::make_pair(err, std::string()); } diff --git a/src/devices/bus/pasopia/rampac2.cpp b/src/devices/bus/pasopia/rampac2.cpp index 3c128a10266..21ec9c2baaa 100644 --- a/src/devices/bus/pasopia/rampac2.cpp +++ b/src/devices/bus/pasopia/rampac2.cpp @@ -88,8 +88,8 @@ void pasopia_rampac2_device::device_start() bool pasopia_rampac2_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_ram[0], m_ram_size, actual) && actual == m_ram_size; + auto const [err, actual] = read(file, &m_ram[0], m_ram_size); + return !err && (actual == m_ram_size); } @@ -99,8 +99,8 @@ bool pasopia_rampac2_device::nvram_read(util::read_stream &file) bool pasopia_rampac2_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_ram[0], m_ram_size, actual) && actual == m_ram_size; + auto const [err, actual] = write(file, &m_ram[0], m_ram_size); + return !err; } diff --git a/src/devices/bus/pce/pce_rom.cpp b/src/devices/bus/pce/pce_rom.cpp index 64d2e1e1e9f..374fedf595b 100644 --- a/src/devices/bus/pce/pce_rom.cpp +++ b/src/devices/bus/pce/pce_rom.cpp @@ -104,14 +104,14 @@ void pce_tennokoe_device::nvram_default() bool pce_tennokoe_device::nvram_read(util::read_stream &file) { - size_t actual_size; - return !file.read(m_bram, m_bram_size, actual_size) && actual_size == m_bram_size; + auto const [err, actual] = read(file, m_bram, m_bram_size); + return !err && (actual == m_bram_size); } bool pce_tennokoe_device::nvram_write(util::write_stream &file) { - size_t actual_size; - return !file.write(m_bram, m_bram_size, actual_size) && actual_size == m_bram_size; + auto const [err, actual] = write(file, m_bram, m_bram_size); + return !err; } /*------------------------------------------------- diff --git a/src/devices/bus/pce/pce_slot.cpp b/src/devices/bus/pce/pce_slot.cpp index 15c0062ea13..2a6d3dd3290 100644 --- a/src/devices/bus/pce/pce_slot.cpp +++ b/src/devices/bus/pce/pce_slot.cpp @@ -324,8 +324,7 @@ std::string pce_cart_slot_device::get_default_card_software(get_default_card_sof hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = get_cart_type(&rom[0], len); char const *const slot_string = pce_get_slot(type); diff --git a/src/devices/bus/pofo/ccm.cpp b/src/devices/bus/pofo/ccm.cpp index bd86c5eecfa..d2b60021f1d 100644 --- a/src/devices/bus/pofo/ccm.cpp +++ b/src/devices/bus/pofo/ccm.cpp @@ -11,6 +11,8 @@ #include "softlist_dev.h" +#include <tuple> + //************************************************************************** @@ -70,15 +72,25 @@ void portfolio_memory_card_slot_device::device_start() std::pair<std::error_condition, std::string> portfolio_memory_card_slot_device::call_load() { + std::error_condition err; + if (m_card) { if (!loaded_through_softlist()) - fread(m_card->m_rom, length()); + { + size_t const size = length(); + size_t actual; + std::tie(err, m_card->m_rom, actual) = read(image_core_file(), size); + if (!err && (actual != size)) + err = std::errc::io_error; + } else + { load_software_region("rom", m_card->m_rom); + } } - return std::make_pair(std::error_condition(), std::string()); + return std::make_pair(err, std::string()); } diff --git a/src/devices/bus/pofo/hpc104.cpp b/src/devices/bus/pofo/hpc104.cpp index 0d8953b20c6..01dd6beb7c2 100644 --- a/src/devices/bus/pofo/hpc104.cpp +++ b/src/devices/bus/pofo/hpc104.cpp @@ -141,6 +141,25 @@ void pofo_hpc104_device::device_reset() } +void pofo_hpc104_device::nvram_default() +{ +} + + +bool pofo_hpc104_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram, 0x40000); + return !err && (actual == 0x40000); +} + + +bool pofo_hpc104_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram, 0x40000); + return !err; +} + + //------------------------------------------------- // nrdi_r - read //------------------------------------------------- diff --git a/src/devices/bus/pofo/hpc104.h b/src/devices/bus/pofo/hpc104.h index 7c9148d59e1..d8802d869f1 100644 --- a/src/devices/bus/pofo/hpc104.h +++ b/src/devices/bus/pofo/hpc104.h @@ -33,20 +33,18 @@ public: protected: pofo_hpc104_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - - // optional information overrides + // device_t implementation virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; - // device_nvram_interface overrides - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram, 0x40000, actual) && actual == 0x40000; } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram, 0x40000, actual) && actual == 0x40000; } + // device_nvram_interface implementation + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; - // device_portfolio_expansion_slot_interface overrides + // device_portfolio_expansion_slot_interface implementation virtual bool nmd1() override { return m_ccm->cdet_r(); } virtual uint8_t nrdi_r(offs_t offset, uint8_t data, bool iom, bool bcom, bool ncc1) override; diff --git a/src/devices/bus/pofo/ram.cpp b/src/devices/bus/pofo/ram.cpp index 7f1298b8b95..253b30d228b 100644 --- a/src/devices/bus/pofo/ram.cpp +++ b/src/devices/bus/pofo/ram.cpp @@ -44,6 +44,25 @@ void portfolio_ram_card_device::device_start() } +void portfolio_ram_card_device::nvram_default() +{ +} + + +bool portfolio_ram_card_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram, m_nvram.bytes()); + return !err && (actual == m_nvram.bytes()); +} + + +bool portfolio_ram_card_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram, m_nvram.bytes()); + return !err; +} + + //------------------------------------------------- // nrdi_r - read //------------------------------------------------- diff --git a/src/devices/bus/pofo/ram.h b/src/devices/bus/pofo/ram.h index 7217299a989..0332d201fb9 100644 --- a/src/devices/bus/pofo/ram.h +++ b/src/devices/bus/pofo/ram.h @@ -30,15 +30,15 @@ public: portfolio_ram_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - // device-level overrides + // device_t implementation virtual void device_start() override; - // device_nvram_interface overrides - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram, m_nvram.bytes(), actual) && actual == m_nvram.bytes(); } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram, m_nvram.bytes(), actual) && actual == m_nvram.bytes(); } + // device_nvram_interface implementation + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; - // device_portfolio_memory_card_slot_interface overrides + // device_portfolio_memory_card_slot_interface implementation virtual bool cdet() override { return 0; } virtual uint8_t nrdi_r(offs_t offset) override; diff --git a/src/devices/bus/ql/rom.cpp b/src/devices/bus/ql/rom.cpp index 82af5a35a4a..ab0e3c1e765 100644 --- a/src/devices/bus/ql/rom.cpp +++ b/src/devices/bus/ql/rom.cpp @@ -9,6 +9,8 @@ #include "emu.h" #include "rom.h" +#include <tuple> + //************************************************************************** @@ -87,11 +89,17 @@ void ql_rom_cartridge_slot_device::device_start() std::pair<std::error_condition, std::string> ql_rom_cartridge_slot_device::call_load() { + std::error_condition err; + if (m_card) { if (!loaded_through_softlist()) { - fread(m_card->m_rom, length()); + size_t const size = length(); + size_t actual; + std::tie(err, m_card->m_rom, actual) = util::read(image_core_file(), size); + if (!err && (actual != size)) + err = std::errc::io_error; } else { @@ -99,7 +107,7 @@ std::pair<std::error_condition, std::string> ql_rom_cartridge_slot_device::call_ } } - return std::make_pair(std::error_condition(), std::string()); + return std::make_pair(err, std::string()); } diff --git a/src/devices/bus/s100/seals8k.cpp b/src/devices/bus/s100/seals8k.cpp index 58a040efad4..ae81cc50d01 100644 --- a/src/devices/bus/s100/seals8k.cpp +++ b/src/devices/bus/s100/seals8k.cpp @@ -164,8 +164,8 @@ void s100_8k_sc_device::device_start() bool s100_8k_sc_bb_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_ram.get(), 0x2000, actual) && actual == 0x2000; + auto const [err, actual] = read(file, m_ram.get(), 0x2000); + return !err && (actual == 0x2000); } @@ -175,8 +175,8 @@ bool s100_8k_sc_bb_device::nvram_read(util::read_stream &file) bool s100_8k_sc_bb_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_ram.get(), 0x2000, actual) && actual == 0x2000; + auto const [err, actual] = write(file, m_ram.get(), 0x2000); + return !err; } diff --git a/src/devices/bus/saturn/bram.cpp b/src/devices/bus/saturn/bram.cpp index 604948343ed..d8ee2764da0 100644 --- a/src/devices/bus/saturn/bram.cpp +++ b/src/devices/bus/saturn/bram.cpp @@ -65,14 +65,14 @@ void saturn_bram_device::device_reset() bool saturn_bram_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_ext_bram[0], m_ext_bram.size(), actual) && actual == m_ext_bram.size(); + auto const [err, actual] = read(file, &m_ext_bram[0], m_ext_bram.size()); + return !err && (actual == m_ext_bram.size()); } bool saturn_bram_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_ext_bram[0], m_ext_bram.size(), actual) && actual == m_ext_bram.size(); + auto const [err, actual] = write(file, &m_ext_bram[0], m_ext_bram.size()); + return !err; } void saturn_bram_device::nvram_default() diff --git a/src/devices/bus/scv/slot.cpp b/src/devices/bus/scv/slot.cpp index 897bb42065b..b6ef651cdf5 100644 --- a/src/devices/bus/scv/slot.cpp +++ b/src/devices/bus/scv/slot.cpp @@ -236,8 +236,7 @@ std::string scv_cart_slot_device::get_default_card_software(get_default_card_sof hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = get_cart_type(&rom[0], len); char const *const slot_string = scv_get_slot(type); diff --git a/src/devices/bus/sega8/sega8_slot.cpp b/src/devices/bus/sega8/sega8_slot.cpp index ccc33c1a29b..d30b5c4e869 100644 --- a/src/devices/bus/sega8/sega8_slot.cpp +++ b/src/devices/bus/sega8/sega8_slot.cpp @@ -669,8 +669,7 @@ std::string sega8_cart_slot_device::get_default_card_software(get_default_card_s hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short uint32_t const offset = ((len % 0x4000) == 512) ? 512 : 0; diff --git a/src/devices/bus/snes/snes_slot.cpp b/src/devices/bus/snes/snes_slot.cpp index b98be058777..d447c390bd2 100644 --- a/src/devices/bus/snes/snes_slot.cpp +++ b/src/devices/bus/snes/snes_slot.cpp @@ -1044,8 +1044,7 @@ std::string base_sns_cart_slot_device::get_default_card_software(get_default_car std::vector<uint8_t> rom(len); int type = 0, addon = 0; - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check for error result or read returning short + /*auto const [err, actual] =*/ read(*hook.image_file(), &rom[0], len); // FIXME: check for error result or read returning short offset = snes_skip_header(&rom[0], len); diff --git a/src/devices/bus/ti99/gromport/gkracker.cpp b/src/devices/bus/ti99/gromport/gkracker.cpp index 2228a84e25e..0a6055bcd53 100644 --- a/src/devices/bus/ti99/gromport/gkracker.cpp +++ b/src/devices/bus/ti99/gromport/gkracker.cpp @@ -149,7 +149,8 @@ void ti99_gkracker_device::romgq_line(int state) { m_romspace_selected = (state==ASSERT_LINE); // Propagate to the guest - if (m_cartridge != nullptr) m_cartridge->romgq_line(state); + if (m_cartridge != nullptr) + m_cartridge->romgq_line(state); } /* @@ -158,12 +159,14 @@ void ti99_gkracker_device::romgq_line(int state) void ti99_gkracker_device::set_gromlines(line_state mline, line_state moline, line_state gsq) { m_grom_selected = (gsq==ASSERT_LINE); - if (m_cartridge != nullptr) m_cartridge->set_gromlines(mline, moline, gsq); + if (m_cartridge != nullptr) + m_cartridge->set_gromlines(mline, moline, gsq); } void ti99_gkracker_device::gclock_in(int state) { - if (m_cartridge != nullptr) m_cartridge->gclock_in(state); + if (m_cartridge != nullptr) + m_cartridge->gclock_in(state); } /* @@ -171,7 +174,7 @@ void ti99_gkracker_device::gclock_in(int state) */ bool ti99_gkracker_device::is_grom_idle() { - return (m_cartridge != nullptr)? m_cartridge->is_grom_idle() : false; + return (m_cartridge != nullptr) ? m_cartridge->is_grom_idle() : false; } void ti99_gkracker_device::readz(offs_t offset, uint8_t *value) @@ -307,12 +310,14 @@ void ti99_gkracker_device::write(offs_t offset, uint8_t data) void ti99_gkracker_device::crureadz(offs_t offset, uint8_t *value) { - if (m_cartridge != nullptr) m_cartridge->crureadz(offset, value); + if (m_cartridge != nullptr) + m_cartridge->crureadz(offset, value); } void ti99_gkracker_device::cruwrite(offs_t offset, uint8_t data) { - if (m_cartridge != nullptr) m_cartridge->cruwrite(offset, data); + if (m_cartridge != nullptr) + m_cartridge->cruwrite(offset, data); } INPUT_CHANGED_MEMBER( ti99_gkracker_device::gk_changed ) @@ -378,8 +383,8 @@ void ti99_gkracker_device::nvram_default() bool ti99_gkracker_device::nvram_read(util::read_stream &file) { - size_t readsize; - if (file.read(m_ram_ptr, 81920, readsize)) + auto const [err, readsize] = util::read(file, m_ram_ptr, 81920); + if (err) return false; LOGMASKED(LOG_GKRACKER, "Reading NVRAM\n"); // If we increased the size, fill the remaining parts with 0 @@ -393,8 +398,8 @@ bool ti99_gkracker_device::nvram_read(util::read_stream &file) bool ti99_gkracker_device::nvram_write(util::write_stream &file) { LOGMASKED(LOG_GKRACKER, "Writing NVRAM\n"); - size_t writesize; - return !file.write(m_ram_ptr, 81920, writesize) && writesize == 81920; + auto const [err, writesize] = util::write(file, m_ram_ptr, 81920); + return !err; } void ti99_gkracker_device::device_start() diff --git a/src/devices/bus/ti99/internal/buffram.cpp b/src/devices/bus/ti99/internal/buffram.cpp index 2747db9dd92..00356eb7817 100644 --- a/src/devices/bus/ti99/internal/buffram.cpp +++ b/src/devices/bus/ti99/internal/buffram.cpp @@ -47,14 +47,14 @@ void buffered_ram_device::nvram_default() bool buffered_ram_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_mem.get(), m_size, actual) && actual == m_size; + auto const [err, actual] = util::read(file, m_mem.get(), m_size); + return !err && (actual == m_size); } bool buffered_ram_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_mem.get(), m_size, actual) && actual == m_size; + auto const [err, actua] = util::write(file, m_mem.get(), m_size); + return !err; } } // end namespace bus::ti99::internal diff --git a/src/devices/bus/ti99/peb/evpc.cpp b/src/devices/bus/ti99/peb/evpc.cpp index 2ab3b98cf8e..31fff7e1182 100644 --- a/src/devices/bus/ti99/peb/evpc.cpp +++ b/src/devices/bus/ti99/peb/evpc.cpp @@ -133,8 +133,8 @@ void snug_enhanced_video_device::nvram_default() bool snug_enhanced_video_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_novram.get(), NOVRAM_SIZE, actual) && actual == NOVRAM_SIZE; + auto const [err, actual] = util::read(file, m_novram.get(), NOVRAM_SIZE); + return !err && (actual == NOVRAM_SIZE); } //------------------------------------------------- @@ -144,8 +144,8 @@ bool snug_enhanced_video_device::nvram_read(util::read_stream &file) bool snug_enhanced_video_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_novram.get(), NOVRAM_SIZE, actual) && actual == NOVRAM_SIZE; + auto const [err, actual] = util::write(file, m_novram.get(), NOVRAM_SIZE); + return !err; } /* diff --git a/src/devices/bus/ti99/peb/horizon.cpp b/src/devices/bus/ti99/peb/horizon.cpp index 19720a09015..d594f445e5b 100644 --- a/src/devices/bus/ti99/peb/horizon.cpp +++ b/src/devices/bus/ti99/peb/horizon.cpp @@ -324,7 +324,6 @@ void horizon_ramdisk_device::read_write(offs_t offset, uint8_t *value, bool writ */ void horizon_ramdisk_device::crureadz(offs_t offset, uint8_t *value) { - return; } /* @@ -463,8 +462,8 @@ bool horizon_ramdisk_device::nvram_read(util::read_stream &file) // Read complete file, at most ramsize+dsrsize // Mind that the configuration may have changed - size_t filesize; - if (file.read(&buffer[0], ramsize + dsrsize, filesize)) + auto const [err, filesize] = util::read(file, &buffer[0], ramsize + dsrsize); + if (err) return false; int nvramsize = int(filesize) - dsrsize; @@ -493,8 +492,8 @@ bool horizon_ramdisk_device::nvram_write(util::write_stream &file) memcpy(&buffer[ramsize], m_dsrram->pointer(), dsrsize); // Store both parts in one file - size_t filesize; - return !file.write(buffer.get(), ramsize + dsrsize, filesize) && filesize == ramsize + dsrsize; + auto const [err, filesize] = util::write(file, buffer.get(), ramsize + dsrsize); + return !err; } bool horizon_ramdisk_device::nvram_can_write() const diff --git a/src/devices/bus/vcs/vcs_slot.cpp b/src/devices/bus/vcs/vcs_slot.cpp index b0fe466722a..344071724e9 100644 --- a/src/devices/bus/vcs/vcs_slot.cpp +++ b/src/devices/bus/vcs/vcs_slot.cpp @@ -774,8 +774,7 @@ std::string vcs_cart_slot_device::get_default_card_software(get_default_card_sof hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files std::vector<uint8_t> rom(len); - size_t actual; - hook.image_file()->read(&rom[0], len, actual); // FIXME: check error return or read returning short + read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short int const type = identify_cart_type(&rom[0], len); char const *const slot_string = vcs_get_slot(type); diff --git a/src/devices/bus/vectrex/slot.cpp b/src/devices/bus/vectrex/slot.cpp index 013a985ab70..2b5ebd481a1 100644 --- a/src/devices/bus/vectrex/slot.cpp +++ b/src/devices/bus/vectrex/slot.cpp @@ -194,8 +194,7 @@ std::string vectrex_cart_slot_device::get_default_card_software(get_default_card std::uint64_t size; hook.image_file()->length(size); std::vector<uint8_t> rom(size); - std::size_t actual; - hook.image_file()->read(&rom[0], size, actual); + read(*hook.image_file(), &rom[0], size); int type = VECTREX_STD; if (!memcmp(&rom[0x06], "SRAM", 4)) // FIXME: bounds check! diff --git a/src/devices/bus/vic10/exp.cpp b/src/devices/bus/vic10/exp.cpp index 08866c7aeb9..2e050b40cc3 100644 --- a/src/devices/bus/vic10/exp.cpp +++ b/src/devices/bus/vic10/exp.cpp @@ -11,6 +11,8 @@ #include "formats/cbm_crt.h" +#include <tuple> + //************************************************************************** // DEVICE DEFINITIONS @@ -88,20 +90,29 @@ std::pair<std::error_condition, std::string> vic10_expansion_slot_device::call_l { if (!loaded_through_softlist()) { + util::core_file &file = image_core_file(); size_t const size = length(); if (is_filetype("80")) { - fread(m_card->m_lorom, 0x2000); + size_t actual; + std::tie(err, m_card->m_lorom, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; - if (size == 0x4000) + if (!err && (size == 0x4000)) { - fread(m_card->m_uprom, 0x2000); + std::tie(err, m_card->m_uprom, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; } } else if (is_filetype("e0")) { - fread(m_card->m_uprom, size); + size_t actual; + std::tie(err, m_card->m_uprom, actual) = read(file, size); + if (!err && (actual != size)) + err = std::errc::io_error; } else if (is_filetype("crt")) { @@ -110,7 +121,7 @@ std::pair<std::error_condition, std::string> vic10_expansion_slot_device::call_l int exrom = 1; int game = 1; - if (cbm_crt_read_header(image_core_file(), &roml_size, &romh_size, &exrom, &game)) + if (cbm_crt_read_header(file, &roml_size, &romh_size, &exrom, &game)) { uint8_t *roml = nullptr; uint8_t *romh = nullptr; @@ -121,7 +132,7 @@ std::pair<std::error_condition, std::string> vic10_expansion_slot_device::call_l if (roml_size) roml = m_card->m_lorom.get(); if (romh_size) romh = m_card->m_lorom.get(); - cbm_crt_read_data(image_core_file(), roml, romh); + cbm_crt_read_data(file, roml, romh); } } else diff --git a/src/devices/bus/vic20/exp.cpp b/src/devices/bus/vic20/exp.cpp index 9174f983915..c635db5c35c 100644 --- a/src/devices/bus/vic20/exp.cpp +++ b/src/devices/bus/vic20/exp.cpp @@ -9,6 +9,10 @@ #include "emu.h" #include "exp.h" +#include "multibyte.h" + +#include <tuple> + //************************************************************************** @@ -89,34 +93,144 @@ void vic20_expansion_slot_device::device_reset() std::pair<std::error_condition, std::string> vic20_expansion_slot_device::call_load() { + std::error_condition err; + if (m_card) { if (!loaded_through_softlist()) { - if (is_filetype("20")) fread(m_card->m_blk1, 0x2000); - else if (is_filetype("40")) fread(m_card->m_blk2, 0x2000); - else if (is_filetype("60")) fread(m_card->m_blk3, 0x2000); - else if (is_filetype("70")) fread(m_card->m_blk3, 0x2000, 0x1000); - else if (is_filetype("a0")) fread(m_card->m_blk5, 0x2000); - else if (is_filetype("b0")) fread(m_card->m_blk5, 0x2000, 0x1000); + util::core_file &file = image_core_file(); + + if (is_filetype("20")) + { + size_t actual; + std::tie(err, m_card->m_blk1, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + } + else if (is_filetype("40")) + { + size_t actual; + std::tie(err, m_card->m_blk2, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + } + else if (is_filetype("60")) + { + size_t actual; + std::tie(err, m_card->m_blk3, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + } + else if (is_filetype("70")) + { + try + { + m_card->m_blk3 = make_unique_clear<uint8_t []>(0x2000); + size_t actual; + std::tie(err, actual) = read(file, &m_card->m_blk3[0x1000], 0x1000); + if (!err && (actual != 0x1000)) + err = std::errc::io_error; + } + catch (std::bad_alloc const &) + { + err = std::errc::not_enough_memory; + } + } + else if (is_filetype("a0")) + { + size_t actual; + std::tie(err, m_card->m_blk5, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + } + else if (is_filetype("b0")) + { + try + { + m_card->m_blk5 = make_unique_clear<uint8_t []>(0x2000); + size_t actual; + std::tie(err, actual) = read(file, &m_card->m_blk5[0x1000], 0x1000); + if (!err && (actual != 0x1000)) + err = std::errc::io_error; + } + catch (std::bad_alloc const &) + { + err = std::errc::not_enough_memory; + } + } else if (is_filetype("crt")) { + size_t actual; + // read the header uint8_t header[2]; - fread(&header, 2); - uint16_t const address = (header[1] << 8) | header[0]; + std::tie(err, actual) = read(file, &header, 2); + if (!err && (actual != 2)) + err = std::errc::io_error; - switch (address) + if (!err) { - case 0x2000: fread(m_card->m_blk1, 0x2000); break; - case 0x4000: fread(m_card->m_blk2, 0x2000); break; - case 0x6000: fread(m_card->m_blk3, 0x2000); break; - case 0x7000: fread(m_card->m_blk3, 0x2000, 0x1000); break; - case 0xa000: fread(m_card->m_blk5, 0x2000); break; - case 0xb000: fread(m_card->m_blk5, 0x2000, 0x1000); break; - default: return std::make_pair(image_error::INVALIDIMAGE, "Unsupported address in CRT file header"); + uint16_t const address = get_u16le(&header[0]); + switch (address) + { + case 0x2000: + std::tie(err, m_card->m_blk1, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + break; + case 0x4000: + std::tie(err, m_card->m_blk2, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + break; + case 0x6000: + std::tie(err, m_card->m_blk3, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + break; + case 0x7000: + try + { + m_card->m_blk3 = make_unique_clear<uint8_t []>(0x2000); + size_t actual; + std::tie(err, actual) = read(file, &m_card->m_blk3[0x1000], 0x1000); + if (!err && (actual != 0x1000)) + err = std::errc::io_error; + } + catch (std::bad_alloc const &) + { + err = std::errc::not_enough_memory; + } + break; + case 0xa000: + std::tie(err, m_card->m_blk5, actual) = read(file, 0x2000); + if (!err && (actual != 0x2000)) + err = std::errc::io_error; + break; + case 0xb000: + try + { + m_card->m_blk5 = make_unique_clear<uint8_t []>(0x2000); + size_t actual; + std::tie(err, actual) = read(file, &m_card->m_blk5[0x1000], 0x1000); + if (!err && (actual != 0x1000)) + err = std::errc::io_error; + } + catch (std::bad_alloc const &) + { + err = std::errc::not_enough_memory; + } + break; + default: + return std::make_pair(image_error::INVALIDIMAGE, "Unsupported address in CRT file header"); + } } } + else + { + err = image_error::INVALIDIMAGE; + } } else { @@ -127,7 +241,7 @@ std::pair<std::error_condition, std::string> vic20_expansion_slot_device::call_l } } - return std::make_pair(std::error_condition(), std::string()); + return std::make_pair(err, std::string()); } diff --git a/src/devices/bus/vic20/megacart.cpp b/src/devices/bus/vic20/megacart.cpp index 21171bf4343..74da56d5395 100644 --- a/src/devices/bus/vic20/megacart.cpp +++ b/src/devices/bus/vic20/megacart.cpp @@ -65,6 +65,25 @@ void vic20_megacart_device::device_reset() } +void vic20_megacart_device::nvram_default() +{ +} + + +bool vic20_megacart_device::nvram_read(util::read_stream &file) +{ + auto const [err, actual] = read(file, m_nvram, 0x2000); + return !err && (actual == 0x2000); +} + + +bool vic20_megacart_device::nvram_write(util::write_stream &file) +{ + auto const [err, actual] = write(file, m_nvram, 0x2000); + return !err; +} + + //------------------------------------------------- // vic20_cd_r - cartridge data read //------------------------------------------------- diff --git a/src/devices/bus/vic20/megacart.h b/src/devices/bus/vic20/megacart.h index e1c691a9a4b..f812e2b6f63 100644 --- a/src/devices/bus/vic20/megacart.h +++ b/src/devices/bus/vic20/megacart.h @@ -30,19 +30,17 @@ public: vic20_megacart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - // device-level overrides + // device_t implementation + virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; - // optional information overrides - virtual void device_add_mconfig(machine_config &config) override; - - // device_nvram_interface overrides - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read(m_nvram, 0x2000, actual) && actual == 0x2000; } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(m_nvram, 0x2000, actual) && actual == 0x2000; } + // device_nvram_interface implementation + virtual void nvram_default() override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; - // device_vic20_expansion_card_interface overrides + // device_vic20_expansion_card_interface implementation virtual uint8_t vic20_cd_r(offs_t offset, uint8_t data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3) override; virtual void vic20_cd_w(offs_t offset, uint8_t data, int ram1, int ram2, int ram3, int blk1, int blk2, int blk3, int blk5, int io2, int io3) override; diff --git a/src/devices/bus/wswan/slot.cpp b/src/devices/bus/wswan/slot.cpp index db10482e52a..31edbc6d971 100644 --- a/src/devices/bus/wswan/slot.cpp +++ b/src/devices/bus/wswan/slot.cpp @@ -290,8 +290,7 @@ std::string ws_cart_slot_device::get_default_card_software(get_default_card_soft int type; u32 nvram; - size_t actual; - hook.image_file()->read(&rom[0], size, actual); + /*[err, actual] =*/ read(*hook.image_file(), &rom[0], size); // nvram size is not really used here, but we set it up nevertheless type = get_cart_type(&rom[0], size, nvram); diff --git a/src/devices/bus/z88/ram.cpp b/src/devices/bus/z88/ram.cpp index 6ba311908f9..6199995b698 100644 --- a/src/devices/bus/z88/ram.cpp +++ b/src/devices/bus/z88/ram.cpp @@ -11,18 +11,97 @@ #include "emu.h" #include "ram.h" -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ + +namespace { //************************************************************************** -// GLOBAL VARIABLES +// TYPE DEFINITIONS //************************************************************************** -DEFINE_DEVICE_TYPE(Z88_32K_RAM, z88_32k_ram_device, "z88_32k_ram", "Z88 32KB RAM") -DEFINE_DEVICE_TYPE(Z88_128K_RAM, z88_128k_ram_device, "z88_128k_ram", "Z88 128KB RAM") -DEFINE_DEVICE_TYPE(Z88_512K_RAM, z88_512k_ram_device, "z88_512k_ram", "Z88 512KB RAM") -DEFINE_DEVICE_TYPE(Z88_1024K_RAM, z88_1024k_ram_device, "z88_1024k_ram", "Z88 1024KB RAM") +// ======================> z88_32k_ram_device + +class z88_32k_ram_device : public device_t, + public device_nvram_interface, + public device_z88cart_interface +{ +public: + // construction/destruction + z88_32k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + z88_32k_ram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device_t implementations + virtual void device_start() override; + + // device_nvram_interface implementation + virtual void nvram_default() override + { + } + virtual bool nvram_read(util::read_stream &file) override + { + auto const [err, actual] = util::read(file, get_cart_base(), get_cart_size()); + return !err && (actual == get_cart_size()); + } + virtual bool nvram_write(util::write_stream &file) override + { + auto const [err, actual] = util::write(file, get_cart_base(), get_cart_size()); + return !err; + } + + // z88cart_interface implementation + virtual uint8_t read(offs_t offset) override; + virtual void write(offs_t offset, uint8_t data) override; + virtual uint8_t* get_cart_base() override; + virtual uint32_t get_cart_size() override { return 0x8000; } + +protected: + // internal state + uint8_t * m_ram; +}; + +// ======================> z88_128k_ram_device + +class z88_128k_ram_device : public z88_32k_ram_device +{ +public: + // construction/destruction + z88_128k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // z88cart_interface implementation + virtual uint32_t get_cart_size() override { return 0x20000; } +}; + +// ======================> z88_512k_ram_device + +class z88_512k_ram_device : public z88_32k_ram_device +{ +public: + // construction/destruction + z88_512k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // z88cart_interface implementation + virtual uint32_t get_cart_size() override { return 0x80000; } +}; + +// ======================> z88_1024k_ram_device + +class z88_1024k_ram_device : public z88_32k_ram_device +{ +public: + // construction/destruction + z88_1024k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // z88cart_interface overrides + virtual uint32_t get_cart_size() override { return 0x100000; } +}; + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ //************************************************************************** // LIVE DEVICE @@ -109,3 +188,15 @@ void z88_32k_ram_device::write(offs_t offset, uint8_t data) { m_ram[offset & (get_cart_size() - 1)] = data; } + +} // anonymous namespace + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(Z88_32K_RAM, device_z88cart_interface, z88_32k_ram_device, "z88_32k_ram", "Z88 32KB RAM") +DEFINE_DEVICE_TYPE_PRIVATE(Z88_128K_RAM, device_z88cart_interface, z88_128k_ram_device, "z88_128k_ram", "Z88 128KB RAM") +DEFINE_DEVICE_TYPE_PRIVATE(Z88_512K_RAM, device_z88cart_interface, z88_512k_ram_device, "z88_512k_ram", "Z88 512KB RAM") +DEFINE_DEVICE_TYPE_PRIVATE(Z88_1024K_RAM, device_z88cart_interface, z88_1024k_ram_device, "z88_1024k_ram", "Z88 1024KB RAM") diff --git a/src/devices/bus/z88/ram.h b/src/devices/bus/z88/ram.h index 96aafd82e24..c99ab03676f 100644 --- a/src/devices/bus/z88/ram.h +++ b/src/devices/bus/z88/ram.h @@ -7,85 +7,10 @@ #include "z88.h" -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> z88_32k_ram_device - -class z88_32k_ram_device : public device_t, - public device_nvram_interface, - public device_z88cart_interface -{ -public: - // construction/destruction - z88_32k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - z88_32k_ram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - - // device-level overrides - virtual void device_start() override; - - // device_nvram_interface overrides - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read (get_cart_base(), get_cart_size(), actual) && actual == get_cart_size(); } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(get_cart_base(), get_cart_size(), actual) && actual == get_cart_size(); } - - // z88cart_interface overrides - virtual uint8_t read(offs_t offset) override; - virtual void write(offs_t offset, uint8_t data) override; - virtual uint8_t* get_cart_base() override; - virtual uint32_t get_cart_size() override { return 0x8000; } - -protected: - // internal state - uint8_t * m_ram; -}; - -// ======================> z88_128k_ram_device - -class z88_128k_ram_device : public z88_32k_ram_device -{ -public: - // construction/destruction - z88_128k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - // z88cart_interface overrides - virtual uint32_t get_cart_size() override { return 0x20000; } -}; - -// ======================> z88_512k_ram_device - -class z88_512k_ram_device : public z88_32k_ram_device -{ -public: - // construction/destruction - z88_512k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - // z88cart_interface overrides - virtual uint32_t get_cart_size() override { return 0x80000; } -}; - -// ======================> z88_1024k_ram_device - -class z88_1024k_ram_device : public z88_32k_ram_device -{ -public: - // construction/destruction - z88_1024k_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - // z88cart_interface overrides - virtual uint32_t get_cart_size() override { return 0x100000; } -}; - -// device type definition -DECLARE_DEVICE_TYPE(Z88_32K_RAM, z88_32k_ram_device) -DECLARE_DEVICE_TYPE(Z88_128K_RAM, z88_128k_ram_device) -DECLARE_DEVICE_TYPE(Z88_512K_RAM, z88_512k_ram_device) -DECLARE_DEVICE_TYPE(Z88_1024K_RAM, z88_1024k_ram_device) +// device type declarations +DECLARE_DEVICE_TYPE(Z88_32K_RAM, device_z88cart_interface) +DECLARE_DEVICE_TYPE(Z88_128K_RAM, device_z88cart_interface) +DECLARE_DEVICE_TYPE(Z88_512K_RAM, device_z88cart_interface) +DECLARE_DEVICE_TYPE(Z88_1024K_RAM, device_z88cart_interface) #endif // MAME_BUS_Z88_RAM_H diff --git a/src/devices/bus/z88/rom.cpp b/src/devices/bus/z88/rom.cpp index 3d28a0a38b8..3f3d406365e 100644 --- a/src/devices/bus/z88/rom.cpp +++ b/src/devices/bus/z88/rom.cpp @@ -11,17 +11,91 @@ #include "emu.h" #include "rom.h" -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ + +namespace { //************************************************************************** -// GLOBAL VARIABLES +// TYPE DEFINITIONS //************************************************************************** -DEFINE_DEVICE_TYPE(Z88_32K_ROM, z88_32k_rom_device, "z88_32k_rom", "Z88 32KB ROM") -DEFINE_DEVICE_TYPE(Z88_128K_ROM, z88_128k_rom_device, "z88_128k_rom", "Z88 128KB ROM") -DEFINE_DEVICE_TYPE(Z88_256K_ROM, z88_256k_rom_device, "z88_256k_rom", "Z88 256KB ROM") +// ======================> z88_32k_rom_device + +class z88_32k_rom_device : public device_t, + public device_nvram_interface, + public device_z88cart_interface +{ +public: + // construction/destruction + z88_32k_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + z88_32k_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device_t implementation + virtual void device_start() override; + + // device_nvram_interface implementation + virtual void nvram_default() override + { + } + virtual bool nvram_read(util::read_stream &file) override + { + auto const [err, actual] = util::read(file, get_cart_base(), get_cart_size()); + return !err && (actual == get_cart_size()); + } + virtual bool nvram_write(util::write_stream &file) override + { + auto const [err, actual] = util::write(file, get_cart_base(), get_cart_size()); + return !err; + } + virtual bool nvram_can_write() const override + { + return m_modified; // Save only if the EPROM has been programmed + } + + // z88cart_interface implementation + virtual uint8_t read(offs_t offset) override; + virtual void write(offs_t offset, uint8_t data) override; + virtual void vpp_w(int state) override { m_vpp_state = state; } + virtual uint8_t* get_cart_base() override; + virtual uint32_t get_cart_size() override { return 0x8000; } + +protected: + // internal state + uint8_t * m_rom; + int m_vpp_state; + bool m_modified; +}; + +// ======================> z88_128k_rom_device + +class z88_128k_rom_device : public z88_32k_rom_device +{ +public: + // construction/destruction + z88_128k_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // z88cart_interface implementation + virtual uint32_t get_cart_size() override { return 0x20000; } +}; + +// ======================> z88_256k_rom_device + +class z88_256k_rom_device : public z88_32k_rom_device +{ +public: + // construction/destruction + z88_256k_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // z88cart_interface implementation + virtual uint32_t get_cart_size() override { return 0x40000; } +}; + +/*************************************************************************** + IMPLEMENTATION +***************************************************************************/ //************************************************************************** // LIVE DEVICE @@ -111,3 +185,13 @@ void z88_32k_rom_device::write(offs_t offset, uint8_t data) } } +} // anonymous namespace + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(Z88_32K_ROM, device_z88cart_interface, z88_32k_rom_device, "z88_32k_rom", "Z88 32KB ROM") +DEFINE_DEVICE_TYPE_PRIVATE(Z88_128K_ROM, device_z88cart_interface, z88_128k_rom_device, "z88_128k_rom", "Z88 128KB ROM") +DEFINE_DEVICE_TYPE_PRIVATE(Z88_256K_ROM, device_z88cart_interface, z88_256k_rom_device, "z88_256k_rom", "Z88 256KB ROM") diff --git a/src/devices/bus/z88/rom.h b/src/devices/bus/z88/rom.h index 8bdd1a5ef92..05c33fd814d 100644 --- a/src/devices/bus/z88/rom.h +++ b/src/devices/bus/z88/rom.h @@ -7,75 +7,9 @@ #include "z88.h" -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> z88_32k_rom_device - -class z88_32k_rom_device : public device_t, - public device_nvram_interface, - public device_z88cart_interface -{ -public: - // construction/destruction - z88_32k_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - z88_32k_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - - // device-level overrides - virtual void device_start() override; - - // device_nvram_interface overrides - virtual void nvram_default() override { } - virtual bool nvram_read(util::read_stream &file) override { size_t actual; return !file.read (get_cart_base(), get_cart_size(), actual) && actual == get_cart_size(); } - virtual bool nvram_write(util::write_stream &file) override { size_t actual; return !file.write(get_cart_base(), get_cart_size(), actual) && actual == get_cart_size(); } - virtual bool nvram_can_write() const override { return m_modified; } // Save only if the EPROM has been programmed - - // z88cart_interface overrides - virtual uint8_t read(offs_t offset) override; - virtual void write(offs_t offset, uint8_t data) override; - virtual void vpp_w(int state) override { m_vpp_state = state; } - virtual uint8_t* get_cart_base() override; - virtual uint32_t get_cart_size() override { return 0x8000; } - -protected: - // internal state - uint8_t * m_rom; - int m_vpp_state; - bool m_modified; -}; - -// ======================> z88_128k_rom_device - -class z88_128k_rom_device : public z88_32k_rom_device -{ -public: - // construction/destruction - z88_128k_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - // z88cart_interface overrides - virtual uint32_t get_cart_size() override { return 0x20000; } -}; - -// ======================> z88_256k_rom_device - -class z88_256k_rom_device : public z88_32k_rom_device -{ -public: - // construction/destruction - z88_256k_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - // z88cart_interface overrides - virtual uint32_t get_cart_size() override { return 0x40000; } -}; - -// device type definition -DECLARE_DEVICE_TYPE(Z88_32K_ROM, z88_32k_rom_device) -DECLARE_DEVICE_TYPE(Z88_128K_ROM, z88_128k_rom_device) -DECLARE_DEVICE_TYPE(Z88_256K_ROM, z88_256k_rom_device) +// device type declarations +DECLARE_DEVICE_TYPE(Z88_32K_ROM, device_z88cart_interface) +DECLARE_DEVICE_TYPE(Z88_128K_ROM, device_z88cart_interface) +DECLARE_DEVICE_TYPE(Z88_256K_ROM, device_z88cart_interface) #endif // MAME_BUS_Z88_ROM_H diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 9f30efc8991..131f9aabf4c 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -215,11 +215,10 @@ bool h8_device::nvram_write(util::write_stream &file) if(!m_nvram_battery) return true; - size_t actual; - // internal RAM if(m_internal_ram) { - if(file.write(&m_internal_ram[0], m_internal_ram.bytes(), actual) || m_internal_ram.bytes() != actual) + auto const [err, actual] = write(file, &m_internal_ram[0], m_internal_ram.bytes()); + if(err) return false; } @@ -234,11 +233,10 @@ bool h8_device::nvram_write(util::write_stream &file) bool h8_device::nvram_read(util::read_stream &file) { - size_t actual; - // internal RAM if(m_internal_ram) { - if(file.read(&m_internal_ram[0], m_internal_ram.bytes(), actual) || m_internal_ram.bytes() != actual) + auto const [err, actual] = read(file, &m_internal_ram[0], m_internal_ram.bytes()); + if (err || (m_internal_ram.bytes() != actual)) return false; } diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp index a4ea9839c26..3ba9c56a494 100644 --- a/src/devices/cpu/h8/h8_port.cpp +++ b/src/devices/cpu/h8/h8_port.cpp @@ -117,26 +117,18 @@ void h8_port_device::device_reset() bool h8_port_device::nvram_write(util::write_stream &file) { - size_t actual; - u8 buf[4]; - - buf[0] = m_ddr; - buf[1] = m_dr; - buf[2] = m_pcr; - buf[3] = m_odr; + u8 const buf[4]{ m_ddr, m_dr, m_pcr, m_odr }; - if(file.write(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) - return false; - - return true; + auto const [err, actual] = write(file, buf, sizeof(buf)); + return !err; } bool h8_port_device::nvram_read(util::read_stream &file) { - size_t actual; u8 buf[4]; - if(file.read(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) + auto const [err, actual] = read(file, buf, sizeof(buf)); + if(err || (sizeof(buf) != actual)) return false; m_ddr = buf[0]; diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index c39920dc106..0ca791726fc 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -24,6 +24,8 @@ TODO: #include "m6801.h" #include "6800dasm.h" +#include <tuple> + #define LOG_TX (1U << 1) #define LOG_TXTICK (1U << 2) #define LOG_RX (1U << 3) @@ -1519,14 +1521,17 @@ bool m6801_cpu_device::nvram_write(util::write_stream &file) if (!m_nvram_battery) return true; + std::error_condition err; size_t actual; - if (file.write(&m_internal_ram[0], m_nvram_bytes, actual) || m_nvram_bytes != actual) + std::tie(err, actual) = write(file, &m_internal_ram[0], m_nvram_bytes); + if (err) return false; // upper bits of RAM control register u8 ram_ctrl = m_ram_ctrl & 0xc0; - if (file.write(&ram_ctrl, 1, actual) || actual != 1) + std::tie(err, actual) = write(file, &ram_ctrl, 1); + if (err) return false; return true; @@ -1534,14 +1539,17 @@ bool m6801_cpu_device::nvram_write(util::write_stream &file) bool m6801_cpu_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - if (file.read(&m_internal_ram[0], m_nvram_bytes, actual) || m_nvram_bytes != actual) + std::tie(err, actual) = read(file, &m_internal_ram[0], m_nvram_bytes); + if (err || (m_nvram_bytes != actual)) return false; // upper bits of RAM control register u8 ram_ctrl = 0; - if (file.read(&ram_ctrl, 1, actual) || actual != 1) + std::tie(err, actual) = read(file, &ram_ctrl, 1); + if (err || (1 != actual)) return false; m_ram_ctrl |= ram_ctrl & 0xc0; @@ -1581,7 +1589,6 @@ bool hd6301_cpu_device::nvram_write(util::write_stream &file) if (!m6801_cpu_device::nvram_write(file)) return false; - size_t actual; std::vector<u8> buf(7); // misc registers @@ -1596,10 +1603,8 @@ bool hd6301_cpu_device::nvram_write(util::write_stream &file) // port output latches buf.insert(buf.end(), m_port_data, m_port_data + sizeof(m_port_data)); - if (file.write(buf.data(), buf.size(), actual) || (buf.size() != actual)) - return false; - - return true; + auto const [err, actual] = write(file, buf.data(), buf.size()); + return !err; } bool hd6301x_cpu_device::nvram_write(util::write_stream &file) @@ -1611,16 +1616,13 @@ bool hd6301x_cpu_device::nvram_write(util::write_stream &file) if (!hd6301_cpu_device::nvram_write(file)) return false; - size_t actual; std::vector<u8> buf; // port output latches buf.insert(buf.begin(), m_portx_data, m_portx_data + sizeof(m_portx_data)); - if (file.write(buf.data(), buf.size(), actual) || (buf.size() != actual)) - return false; - - return true; + auto const [err, actual] = write(file, buf.data(), buf.size()); + return !err; } bool hd6301_cpu_device::nvram_read(util::read_stream &file) @@ -1628,11 +1630,13 @@ bool hd6301_cpu_device::nvram_read(util::read_stream &file) if (!m6801_cpu_device::nvram_read(file)) return false; + std::error_condition err; size_t actual; u8 buf[7]; // misc registers - if (file.read(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) + std::tie(err, actual) = read(file, &buf, sizeof(buf)); + if (err || (sizeof(buf) != actual)) return false; m_s.b.h = buf[0]; @@ -1644,7 +1648,8 @@ bool hd6301_cpu_device::nvram_read(util::read_stream &file) m_tdr = buf[6]; // port output latches - if (file.read(&m_port_data[0], sizeof(m_port_data), actual) || sizeof(m_port_data) != actual) + std::tie(err, actual) = read(file, &m_port_data[0], sizeof(m_port_data)); + if (err || (sizeof(m_port_data) != actual)) return false; return true; @@ -1655,13 +1660,9 @@ bool hd6301x_cpu_device::nvram_read(util::read_stream &file) if (!hd6301_cpu_device::nvram_read(file)) return false; - size_t actual; - // port output latches - if (file.read(&m_portx_data[0], sizeof(m_portx_data), actual) || sizeof(m_portx_data) != actual) - return false; - - return true; + auto const [err, actual] = read(file, &m_portx_data[0], sizeof(m_portx_data)); + return !err && (sizeof(m_portx_data) == actual); } diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp index 934447a0c5f..30f498980c6 100644 --- a/src/devices/cpu/m6805/m68705.cpp +++ b/src/devices/cpu/m6805/m68705.cpp @@ -552,14 +552,14 @@ void m68705_device::nvram_default() bool m68705_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_user_rom[0], m_user_rom.bytes(), actual) && actual == m_user_rom.bytes(); + auto const [err, actual] = read(file, &m_user_rom[0], m_user_rom.bytes()); + return !err && (actual == m_user_rom.bytes()); } bool m68705_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_user_rom[0], m_user_rom.bytes(), actual) && actual == m_user_rom.bytes(); + auto const [err, actual] = write(file, &m_user_rom[0], m_user_rom.bytes()); + return !err; } void m6805_hmos_device::interrupt() diff --git a/src/devices/cpu/mc68hc11/mc68hc11.cpp b/src/devices/cpu/mc68hc11/mc68hc11.cpp index 4469be598ca..7843b26dd75 100644 --- a/src/devices/cpu/mc68hc11/mc68hc11.cpp +++ b/src/devices/cpu/mc68hc11/mc68hc11.cpp @@ -16,6 +16,8 @@ TODO: #include "mc68hc11.h" #include "hc11dasm.h" +#include <tuple> + #define LOG_IRQ (1U << 1) #define VERBOSE (0) @@ -163,12 +165,15 @@ std::unique_ptr<util::disasm_interface> mc68hc11_cpu_device::create_disassembler bool mc68hc11_cpu_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - if (file.read(&m_eeprom_data[0], m_internal_eeprom_size, actual) || actual != m_internal_eeprom_size) + std::tie(err, actual) = read(file, &m_eeprom_data[0], m_internal_eeprom_size); + if (err || (actual != m_internal_eeprom_size)) return false; - if (file.read(&m_config, 1, actual) || actual != 1) + std::tie(err, actual) = read(file, &m_config, 1); + if (err || (actual != 1)) return false; return true; @@ -176,12 +181,15 @@ bool mc68hc11_cpu_device::nvram_read(util::read_stream &file) bool mc68hc11_cpu_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - if (file.write(&m_eeprom_data[0], m_internal_eeprom_size, actual) || actual != m_internal_eeprom_size) + std::tie(err, actual) = write(file, &m_eeprom_data[0], m_internal_eeprom_size); + if (err) return false; - if (file.write(&m_config, 1, actual) || actual != 1) + std::tie(err, actual) = write(file, &m_config, 1); + if (err) return false; return true; diff --git a/src/devices/cpu/mcs51/mcs51.cpp b/src/devices/cpu/mcs51/mcs51.cpp index f75c3cdda3b..218e4640aa0 100644 --- a/src/devices/cpu/mcs51/mcs51.cpp +++ b/src/devices/cpu/mcs51/mcs51.cpp @@ -134,6 +134,8 @@ #include "mcs51.h" #include "mcs51dasm.h" +#include <tuple> + #define LOG_RX (1U << 1) #define LOG_TX (1U << 2) @@ -2696,22 +2698,28 @@ void ds5002fp_device::nvram_default() } } -bool ds5002fp_device::nvram_read( util::read_stream &file ) +bool ds5002fp_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - if (file.read( m_scratchpad, 0x80, actual ) || actual != 0x80) + std::tie(err, actual) = read(file, m_scratchpad, 0x80); + if (err || (actual != 0x80)) return false; - if (file.read( m_sfr_ram, 0x80, actual ) || actual != 0x80) + std::tie(err, actual) = read(file, m_sfr_ram, 0x80); + if (err || (actual != 0x80)) return false; return true; } -bool ds5002fp_device::nvram_write( util::write_stream &file ) +bool ds5002fp_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - if (file.write( m_scratchpad, 0x80, actual ) || actual != 0x80) + std::tie(err, actual) = write(file, m_scratchpad, 0x80); + if (err || (actual != 0x80)) return false; - if (file.write( m_sfr_ram, 0x80, actual ) || actual != 0x80) + std::tie(err, actual) = write(file, m_sfr_ram, 0x80); + if (err || (actual != 0x80)) return false; return true; } diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp index bdeb0c2d0f0..3f822838894 100644 --- a/src/devices/imagedev/midiin.cpp +++ b/src/devices/imagedev/midiin.cpp @@ -346,8 +346,8 @@ u8 midiin_device::midi_parser::byte() check_bounds(1); u8 result = 0; - std::size_t actual = 0; - if (m_stream.read_at(m_offset, &result, 1, actual) || actual != 1) + auto const [err, actual] = read_at(m_stream, m_offset, &result, 1); + if (err || actual != 1) throw error("Error reading data"); m_offset++; return result; @@ -363,8 +363,8 @@ u16 midiin_device::midi_parser::word_be() check_bounds(2); u16 result = 0; - std::size_t actual = 0; - if (m_stream.read_at(m_offset, &result, 2, actual) || actual != 2) + auto const [err, actual] = read_at(m_stream, m_offset, &result, 2); + if (err || actual != 2) throw error("Error reading data"); m_offset += 2; return big_endianize_int16(result); @@ -380,8 +380,8 @@ u32 midiin_device::midi_parser::triple_be() check_bounds(3); u32 result = 0; - std::size_t actual = 0; - if (m_stream.read_at(m_offset, &result, 3, actual) || actual != 3) + auto const [err, actual] = read_at(m_stream, m_offset, &result, 3); + if (err || actual != 3) throw error("Error reading data"); m_offset += 3; return big_endianize_int32(result) >> 8; @@ -397,8 +397,8 @@ u32 midiin_device::midi_parser::dword_be() check_bounds(4); u32 result = 0; - std::size_t actual = 0; - if (m_stream.read_at(m_offset, &result, 4, actual) || actual != 4) + auto const [err, actual] = read_at(m_stream, m_offset, &result, 4); + if (err || actual != 4) throw error("Error reading data"); m_offset += 4; return big_endianize_int32(result); @@ -414,8 +414,8 @@ u32 midiin_device::midi_parser::dword_le() check_bounds(4); u32 result = 0; - std::size_t actual = 0; - if (m_stream.read_at(m_offset, &result, 4, actual) || actual != 4) + auto const [err, actual] = read_at(m_stream, m_offset, &result, 4); + if (err || actual != 4) throw error("Error reading data"); m_offset += 4; return little_endianize_int32(result); diff --git a/src/devices/machine/28fxxx.cpp b/src/devices/machine/28fxxx.cpp index 60351ee7565..1c424b44b01 100644 --- a/src/devices/machine/28fxxx.cpp +++ b/src/devices/machine/28fxxx.cpp @@ -105,14 +105,14 @@ void base_28fxxx_device::nvram_default() bool base_28fxxx_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_data.get(), m_size, actual) && actual == m_size; + auto const [err, actual] = util::read(file, m_data.get(), m_size); + return !err && (actual == m_size); } bool base_28fxxx_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_data.get(), m_size, actual) && actual == m_size; + auto const [err, actual] = util::write(file, m_data.get(), m_size); + return !err; } void base_28fxxx_device::erase() diff --git a/src/devices/machine/at28c16.cpp b/src/devices/machine/at28c16.cpp index 48676f534a8..d092d7f6d34 100644 --- a/src/devices/machine/at28c16.cpp +++ b/src/devices/machine/at28c16.cpp @@ -107,18 +107,16 @@ void at28c16_device::nvram_default() // .nv file //------------------------------------------------- -bool at28c16_device::nvram_read( util::read_stream &file ) +bool at28c16_device::nvram_read(util::read_stream &file) { - std::vector<uint8_t> buffer( AT28C16_TOTAL_BYTES ); - size_t actual; + std::vector<uint8_t> buffer(AT28C16_TOTAL_BYTES); - if (file.read( &buffer[0], AT28C16_TOTAL_BYTES, actual ) || actual != AT28C16_TOTAL_BYTES) + auto const [err, actual] = util::read(file, &buffer[0], AT28C16_TOTAL_BYTES); + if (err || (actual != AT28C16_TOTAL_BYTES)) return false; - for( offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++ ) - { - space(AS_PROGRAM).write_byte( offs, buffer[ offs ] ); - } + for (offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++) + space(AS_PROGRAM).write_byte(offs, buffer[offs]); return true; } @@ -130,15 +128,13 @@ bool at28c16_device::nvram_read( util::read_stream &file ) bool at28c16_device::nvram_write( util::write_stream &file ) { - std::vector<uint8_t> buffer ( AT28C16_TOTAL_BYTES ); - size_t actual; + std::vector<uint8_t> buffer(AT28C16_TOTAL_BYTES); - for( offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++ ) - { - buffer[ offs ] = space(AS_PROGRAM).read_byte( offs ); - } + for (offs_t offs = 0; offs < AT28C16_TOTAL_BYTES; offs++) + buffer[offs] = space(AS_PROGRAM).read_byte(offs); - return !file.write( &buffer[0], AT28C16_TOTAL_BYTES, actual ) && actual == AT28C16_TOTAL_BYTES; + auto const [err, actual] = util::write(file, &buffer[0], AT28C16_TOTAL_BYTES); + return !err; } diff --git a/src/devices/machine/at28c64b.cpp b/src/devices/machine/at28c64b.cpp index ebb794b38e8..85bf3cb52fb 100644 --- a/src/devices/machine/at28c64b.cpp +++ b/src/devices/machine/at28c64b.cpp @@ -89,16 +89,14 @@ void at28c64b_device::device_start() void at28c64b_device::nvram_default() { - uint16_t default_value = 0xff; - for( offs_t offs = 0; offs < AT28C64B_TOTAL_BYTES; offs++ ) - { - space(AS_PROGRAM).write_byte( offs, default_value ); - } + uint16_t const default_value = 0xff; + for (offs_t offs = 0; offs < AT28C64B_TOTAL_BYTES; offs++) + space(AS_PROGRAM).write_byte(offs, default_value); /* populate from a memory region if present */ if (m_default_data.found()) { - for( offs_t offs = 0; offs < AT28C64B_DATA_BYTES; offs++ ) + for (offs_t offs = 0; offs < AT28C64B_DATA_BYTES; offs++) space(AS_PROGRAM).write_byte(offs, m_default_data[offs]); } } @@ -109,18 +107,16 @@ void at28c64b_device::nvram_default() // .nv file //------------------------------------------------- -bool at28c64b_device::nvram_read( util::read_stream &file ) +bool at28c64b_device::nvram_read(util::read_stream &file) { - std::vector<uint8_t> buffer( AT28C64B_TOTAL_BYTES ); - size_t actual; + std::vector<uint8_t> buffer(AT28C64B_TOTAL_BYTES); - if (file.read( &buffer[0], AT28C64B_TOTAL_BYTES, actual ) || actual != AT28C64B_TOTAL_BYTES) + auto const [err, actual] = util::read(file, &buffer[0], AT28C64B_TOTAL_BYTES); + if (err || (actual != AT28C64B_TOTAL_BYTES)) return false; - for( offs_t offs = 0; offs < AT28C64B_TOTAL_BYTES; offs++ ) - { - space(AS_PROGRAM).write_byte( offs, buffer[ offs ] ); - } + for (offs_t offs = 0; offs < AT28C64B_TOTAL_BYTES; offs++) + space(AS_PROGRAM).write_byte(offs, buffer[offs]); return true; } @@ -130,17 +126,15 @@ bool at28c64b_device::nvram_read( util::read_stream &file ) // .nv file //------------------------------------------------- -bool at28c64b_device::nvram_write( util::write_stream &file ) +bool at28c64b_device::nvram_write(util::write_stream &file) { - std::vector<uint8_t> buffer ( AT28C64B_TOTAL_BYTES ); - size_t actual; + std::vector<uint8_t> buffer(AT28C64B_TOTAL_BYTES); - for( offs_t offs = 0; offs < AT28C64B_TOTAL_BYTES; offs++ ) - { - buffer[ offs ] = space(AS_PROGRAM).read_byte( offs ); - } + for (offs_t offs = 0; offs < AT28C64B_TOTAL_BYTES; offs++) + buffer[offs] = space(AS_PROGRAM).read_byte(offs); - return !file.write( &buffer[0], AT28C64B_TOTAL_BYTES, actual ) && actual == AT28C64B_TOTAL_BYTES; + auto const [err, actual] = util::write(file, &buffer[0], AT28C64B_TOTAL_BYTES); + return !err; } diff --git a/src/devices/machine/at29x.cpp b/src/devices/machine/at29x.cpp index a4c04cc7229..232828b62bd 100644 --- a/src/devices/machine/at29x.cpp +++ b/src/devices/machine/at29x.cpp @@ -111,8 +111,8 @@ void at29x_device::nvram_default() bool at29x_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_eememory.get(), m_memory_size+2, actual) && actual == m_memory_size+2; + auto const [err, actual] = util::read(file, m_eememory.get(), m_memory_size+2); + return !err && (actual == m_memory_size+2); } //------------------------------------------------- @@ -126,8 +126,8 @@ bool at29x_device::nvram_write(util::write_stream &file) LOGMASKED(LOG_PRG, "Write to NVRAM file\n"); m_eememory[0] = m_version; - size_t actual; - return !file.write(m_eememory.get(), m_memory_size+2, actual) && actual == m_memory_size+2; + auto const [err, actual] = util::write(file, m_eememory.get(), m_memory_size+2); + return !err; } /* diff --git a/src/devices/machine/at45dbxx.cpp b/src/devices/machine/at45dbxx.cpp index f81c3f746f5..1dffb79329e 100644 --- a/src/devices/machine/at45dbxx.cpp +++ b/src/devices/machine/at45dbxx.cpp @@ -162,8 +162,8 @@ void at45db041_device::nvram_default() bool at45db041_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_data[0], m_size, actual) && actual == m_size; + auto const [err, actual] = read(file, &m_data[0], m_size); + return !err && (actual == m_size); } //------------------------------------------------- @@ -173,8 +173,8 @@ bool at45db041_device::nvram_read(util::read_stream &file) bool at45db041_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_data[0], m_size, actual) && actual == m_size; + auto const [err, actual] = write(file, &m_data[0], m_size); + return !err; } uint8_t at45db041_device::read_byte() diff --git a/src/devices/machine/bq4847.cpp b/src/devices/machine/bq4847.cpp index af4cbf0c7a9..d2618f03f53 100644 --- a/src/devices/machine/bq4847.cpp +++ b/src/devices/machine/bq4847.cpp @@ -500,12 +500,12 @@ void bq4847_device::nvram_default() bool bq4847_device::nvram_read(util::read_stream& file) { - size_t actual; - return !file.read(m_register, std::size(m_register), actual) && actual == std::size(m_register); + auto const [err, actual] = util::read(file, m_register, std::size(m_register)); + return !err && (actual == std::size(m_register)); } bool bq4847_device::nvram_write(util::write_stream& file) { - size_t actual; - return !file.write(m_register, std::size(m_register), actual) && actual == std::size(m_register); + auto const [err, actual] = util::write(file, m_register, std::size(m_register)); + return !err; } diff --git a/src/devices/machine/bq48x2.cpp b/src/devices/machine/bq48x2.cpp index 745f1a28def..a4524367d3c 100644 --- a/src/devices/machine/bq48x2.cpp +++ b/src/devices/machine/bq48x2.cpp @@ -537,8 +537,8 @@ void bq48x2_device::nvram_default() bool bq48x2_device::nvram_read(util::read_stream &file) { - size_t actual; - if (file.read(m_sram.get(), m_memsize, actual) || actual != m_memsize) + auto const [err, actual] = util::read(file, m_sram.get(), m_memsize); + if (err || (actual != m_memsize)) return false; transfer_to_access(); // Transfer the system time into the readable registers @@ -553,6 +553,6 @@ bool bq48x2_device::nvram_write(util::write_stream &file) { transfer_to_access(); - size_t actual; - return !file.write(m_sram.get(), m_memsize, actual) && actual == m_memsize; + auto const [err, actual] = util::write(file, m_sram.get(), m_memsize); + return !err; } diff --git a/src/devices/machine/dp8573a.cpp b/src/devices/machine/dp8573a.cpp index a9670de84b7..e6c461fb688 100644 --- a/src/devices/machine/dp8573a.cpp +++ b/src/devices/machine/dp8573a.cpp @@ -456,8 +456,8 @@ void dp8573a_device::nvram_default() bool dp8573a_device::nvram_read(util::read_stream &file) { - size_t actual; - if (file.read(m_ram.get(), ram_size(), actual) || actual != ram_size()) + auto const [err, actual] = util::read(file, m_ram.get(), ram_size()); + if (err || (actual != ram_size())) return false; return true; @@ -465,8 +465,8 @@ bool dp8573a_device::nvram_read(util::read_stream &file) bool dp8573a_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_ram.get(), ram_size(), actual) && actual == ram_size(); + auto const [err, actual] = util::write(file, m_ram.get(), ram_size()); + return !err; } void dp8572a_device::write(offs_t offset, uint8_t data) diff --git a/src/devices/machine/ds1204.cpp b/src/devices/machine/ds1204.cpp index cb00558207d..df4600e82d1 100644 --- a/src/devices/machine/ds1204.cpp +++ b/src/devices/machine/ds1204.cpp @@ -12,6 +12,7 @@ #include <cstdarg> #include <cstdio> +#include <tuple> #define VERBOSE_LEVEL ( 0 ) @@ -21,7 +22,7 @@ inline void ATTR_PRINTF( 3, 4 ) ds1204_device::verboselog( int n_level, const ch if( VERBOSE_LEVEL >= n_level ) { va_list v; - char buf[ 32768 ]; + char buf[32768]; va_start( v, s_fmt ); vsprintf( buf, s_fmt, v ); va_end( v ); @@ -94,22 +95,44 @@ void ds1204_device::nvram_default() bool ds1204_device::nvram_read( util::read_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.read( m_unique_pattern, sizeof( m_unique_pattern ), actual ) && actual == sizeof( m_unique_pattern ); - result = result && !file.read( m_identification, sizeof( m_identification ), actual ) && actual == sizeof( m_identification ); - result = result && !file.read( m_security_match, sizeof( m_security_match ), actual ) && actual == sizeof( m_security_match ); - result = result && !file.read( m_secure_memory, sizeof( m_secure_memory ), actual ) && actual == sizeof( m_secure_memory ); - return result; + + std::tie( err, actual ) = read( file, m_unique_pattern, sizeof( m_unique_pattern ) ); + if( err || ( sizeof( m_unique_pattern ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_identification, sizeof( m_identification ) ); + if( err || ( sizeof( m_identification ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_security_match, sizeof( m_security_match ) ); + if( err || ( sizeof( m_security_match ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_secure_memory, sizeof( m_secure_memory ) ); + if( err || ( sizeof( m_secure_memory ) != actual ) ) + return false; + + return true; } bool ds1204_device::nvram_write( util::write_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.write( m_unique_pattern, sizeof( m_unique_pattern ), actual ) && actual == sizeof( m_unique_pattern ); - result = result && !file.write( m_identification, sizeof( m_identification ), actual ) && actual == sizeof( m_identification ); - result = result && !file.write( m_security_match, sizeof( m_security_match ), actual ) && actual == sizeof( m_security_match ); - result = result && !file.write( m_secure_memory, sizeof( m_secure_memory ), actual ) && actual == sizeof( m_secure_memory ); - return result; + + std::tie( err, actual ) = write( file, m_unique_pattern, sizeof( m_unique_pattern ) ); + if( err ) + return false; + std::tie( err, actual ) = write( file, m_identification, sizeof( m_identification ) ); + if( err ) + return false; + std::tie( err, actual ) = write( file, m_security_match, sizeof( m_security_match ) ); + if( err ) + return false; + std::tie( err, actual ) = write( file, m_secure_memory, sizeof( m_secure_memory ) ); + if( err ) + return false; + + return true; } void ds1204_device::new_state( int state ) @@ -127,11 +150,11 @@ void ds1204_device::writebit( uint8_t *buffer ) if( m_dqw ) { - buffer[ index ] |= mask; + buffer[index] |= mask; } else { - buffer[ index ] &= ~mask; + buffer[index] &= ~mask; } m_bit++; @@ -145,7 +168,7 @@ void ds1204_device::readbit( uint8_t *buffer ) int index = m_bit / 8; int mask = 1 << ( m_bit % 8 ); - if( buffer[ index ] & mask ) + if( buffer[index] & mask ) { m_dqr = 1; } @@ -212,17 +235,17 @@ void ds1204_device::write_clk(int state) if( m_bit == 24 ) { verboselog( 1, "-> command %02x %02x %02x (%02x %02x)\n", - m_command[ 0 ], m_command[ 1 ], m_command[ 2 ], m_unique_pattern[ 0 ], m_unique_pattern[ 1 ] ); + m_command[0], m_command[1], m_command[2], m_unique_pattern[0], m_unique_pattern[1] ); - if( m_command[ 0 ] == COMMAND_READ && m_command[ 1 ] == ( m_unique_pattern[ 0 ] | CYCLE_NORMAL ) && m_command[ 2 ] == m_unique_pattern[ 1 ] ) + if( m_command[0] == COMMAND_READ && m_command[1] == ( m_unique_pattern[0] | CYCLE_NORMAL ) && m_command[2] == m_unique_pattern[1] ) { new_state( STATE_READ_IDENTIFICATION ); } - else if( m_command[ 0 ] == COMMAND_WRITE && m_command[ 1 ] == ( m_unique_pattern[ 0 ] | CYCLE_NORMAL ) && m_command[ 2 ] == m_unique_pattern[ 1 ] ) + else if( m_command[0] == COMMAND_WRITE && m_command[1] == ( m_unique_pattern[0] | CYCLE_NORMAL ) && m_command[2] == m_unique_pattern[1] ) { new_state( STATE_READ_IDENTIFICATION ); } - else if( m_command[ 0 ] == COMMAND_WRITE && m_command[ 1 ] == ( m_unique_pattern[ 0 ] | CYCLE_PROGRAM ) && m_command[ 2 ] == m_unique_pattern[ 1 ] ) + else if( m_command[0] == COMMAND_WRITE && m_command[1] == ( m_unique_pattern[0] | CYCLE_PROGRAM ) && m_command[2] == m_unique_pattern[1] ) { new_state( STATE_WRITE_IDENTIFICATION ); } @@ -239,8 +262,8 @@ void ds1204_device::write_clk(int state) if( m_bit == 64 ) { verboselog( 1, "<- identification %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_identification[ 0 ], m_identification[ 1 ], m_identification[ 2 ], m_identification[ 3 ], - m_identification[ 4 ], m_identification[ 5 ], m_identification[ 6 ], m_identification[ 7 ] ); + m_identification[0], m_identification[1], m_identification[2], m_identification[3], + m_identification[4], m_identification[5], m_identification[6], m_identification[7] ); new_state( STATE_WRITE_COMPARE_REGISTER ); } @@ -252,14 +275,14 @@ void ds1204_device::write_clk(int state) if( m_bit == 64 ) { verboselog( 1, "-> compare register %02x %02x %02x %02x %02x %02x %02x %02x (%02x %02x %02x %02x %02x %02x %02x %02x)\n", - m_compare_register[ 0 ], m_compare_register[ 1 ], m_compare_register[ 2 ], m_compare_register[ 3 ], - m_compare_register[ 4 ], m_compare_register[ 5 ], m_compare_register[ 6 ], m_compare_register[ 7 ], - m_security_match[ 0 ], m_security_match[ 1 ], m_security_match[ 2 ], m_security_match[ 3 ], - m_security_match[ 4 ], m_security_match[ 5 ], m_security_match[ 6 ], m_security_match[ 7 ] ); + m_compare_register[0], m_compare_register[1], m_compare_register[2], m_compare_register[3], + m_compare_register[4], m_compare_register[5], m_compare_register[6], m_compare_register[7], + m_security_match[0], m_security_match[1], m_security_match[2], m_security_match[3], + m_security_match[4], m_security_match[5], m_security_match[6], m_security_match[7] ); if( memcmp( m_compare_register, m_security_match, sizeof( m_compare_register ) ) == 0 ) { - if( m_command[ 0 ] == COMMAND_READ ) + if( m_command[0] == COMMAND_READ ) { new_state( STATE_READ_SECURE_MEMORY ); } @@ -281,10 +304,10 @@ void ds1204_device::write_clk(int state) if( m_bit == 128 ) { verboselog( 1, "<- secure memory %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_secure_memory[ 0 ], m_secure_memory[ 1 ], m_secure_memory[ 2 ], m_secure_memory[ 3 ], - m_secure_memory[ 4 ], m_secure_memory[ 5 ], m_secure_memory[ 6 ], m_secure_memory[ 7 ], - m_secure_memory[ 8 ], m_secure_memory[ 9 ], m_secure_memory[ 10 ], m_secure_memory[ 11 ], - m_secure_memory[ 12 ], m_secure_memory[ 13 ], m_secure_memory[ 14 ], m_secure_memory[ 15 ] ); + m_secure_memory[0], m_secure_memory[1], m_secure_memory[2], m_secure_memory[3], + m_secure_memory[4], m_secure_memory[5], m_secure_memory[6], m_secure_memory[7], + m_secure_memory[8], m_secure_memory[9], m_secure_memory[10], m_secure_memory[11], + m_secure_memory[12], m_secure_memory[13], m_secure_memory[14], m_secure_memory[15] ); new_state( STATE_STOP ); } @@ -296,10 +319,10 @@ void ds1204_device::write_clk(int state) if( m_bit == 128 ) { verboselog( 1, "-> secure memory %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_secure_memory[ 0 ], m_secure_memory[ 1 ], m_secure_memory[ 2 ], m_secure_memory[ 3 ], - m_secure_memory[ 4 ], m_secure_memory[ 5 ], m_secure_memory[ 6 ], m_secure_memory[ 7 ], - m_secure_memory[ 8 ], m_secure_memory[ 9 ], m_secure_memory[ 10 ], m_secure_memory[ 11 ], - m_secure_memory[ 12 ], m_secure_memory[ 13 ], m_secure_memory[ 14 ], m_secure_memory[ 15 ] ); + m_secure_memory[0], m_secure_memory[1], m_secure_memory[2], m_secure_memory[3], + m_secure_memory[4], m_secure_memory[5], m_secure_memory[6], m_secure_memory[7], + m_secure_memory[8], m_secure_memory[9], m_secure_memory[10], m_secure_memory[11], + m_secure_memory[12], m_secure_memory[13], m_secure_memory[14], m_secure_memory[15] ); new_state( STATE_STOP ); } @@ -311,8 +334,8 @@ void ds1204_device::write_clk(int state) if( m_bit == 64 ) { verboselog( 1, "-> identification %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_identification[ 0 ], m_identification[ 1 ], m_identification[ 2 ], m_identification[ 3 ], - m_identification[ 4 ], m_identification[ 5 ], m_identification[ 6 ], m_identification[ 7 ] ); + m_identification[0], m_identification[1], m_identification[2], m_identification[3], + m_identification[4], m_identification[5], m_identification[6], m_identification[7] ); new_state( STATE_WRITE_SECURITY_MATCH ); } @@ -324,27 +347,27 @@ void ds1204_device::write_clk(int state) if( m_bit == 64 ) { verboselog( 1, ">- security match %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_security_match[ 0 ], m_security_match[ 1 ], m_security_match[ 2 ], m_security_match[ 3 ], - m_security_match[ 4 ], m_security_match[ 5 ], m_security_match[ 6 ], m_security_match[ 7 ] ); + m_security_match[0], m_security_match[1], m_security_match[2], m_security_match[3], + m_security_match[4], m_security_match[5], m_security_match[6], m_security_match[7] ); new_state( STATE_STOP ); } break; case STATE_OUTPUT_GARBLED_DATA: - if( !m_clk && m_command[ 0 ] == COMMAND_READ ) + if( !m_clk && m_command[0] == COMMAND_READ ) { m_dqr = machine().rand() & 1; m_bit++; } - else if( m_clk && m_command[ 0 ] == COMMAND_WRITE ) + else if( m_clk && m_command[0] == COMMAND_WRITE ) { m_bit++; } if( m_bit == 64 ) { - if( m_command[ 0 ] == COMMAND_READ ) + if( m_command[0] == COMMAND_READ ) { verboselog( 1, "<- random\n" ); } diff --git a/src/devices/machine/ds1205.cpp b/src/devices/machine/ds1205.cpp index e5d1335cf75..034b99719f5 100644 --- a/src/devices/machine/ds1205.cpp +++ b/src/devices/machine/ds1205.cpp @@ -12,6 +12,7 @@ #include <cstdarg> #include <cstdio> +#include <tuple> #define VERBOSE_LEVEL ( 0 ) @@ -21,7 +22,7 @@ inline void ATTR_PRINTF( 3, 4 ) ds1205_device::verboselog( int n_level, const ch if( VERBOSE_LEVEL >= n_level ) { va_list v; - char buf[ 32768 ]; + char buf[32768]; va_start( v, s_fmt ); vsprintf( buf, s_fmt, v ); va_end( v ); @@ -96,14 +97,19 @@ void ds1205_device::nvram_default() bool ds1205_device::nvram_read( util::read_stream &file ) { + std::error_condition err; + size_t actual; + for(int i = 0; i < 3; i++) { - size_t actual; - if( file.read( m_identification[i], sizeof( m_identification[i] ), actual ) || actual != sizeof( m_identification[i] ) ) + std::tie( err, actual ) = read( file, m_identification[i], sizeof( m_identification[i] ) ); + if( err || ( sizeof( m_identification[i] ) != actual ) ) return false; - if( file.read( m_security_match[i], sizeof( m_security_match[i] ), actual ) || actual != sizeof( m_security_match[i] ) ) + std::tie( err, actual ) = read( file, m_security_match[i], sizeof( m_security_match[i] ) ); + if( err || ( sizeof( m_security_match[i] ) != actual ) ) return false; - if( file.read( m_secure_memory[i], sizeof( m_secure_memory[i] ), actual ) || actual != sizeof( m_secure_memory[i] ) ) + std::tie( err, actual ) = read( file, m_secure_memory[i], sizeof( m_secure_memory[i] ) ); + if( err || ( sizeof( m_secure_memory[i] ) != actual ) ) return false; } @@ -112,14 +118,19 @@ bool ds1205_device::nvram_read( util::read_stream &file ) bool ds1205_device::nvram_write( util::write_stream &file ) { + std::error_condition err; + size_t actual; + for(int i = 0; i < 3; i++) { - size_t actual; - if( file.write( m_identification[i], sizeof( m_identification[i] ), actual ) || actual != sizeof( m_identification[i] ) ) + std::tie( err, actual ) = write( file, m_identification[i], sizeof( m_identification[i] ) ); + if( err ) return false; - if( file.write( m_security_match[i], sizeof( m_security_match[i] ), actual ) || actual != sizeof( m_security_match[i] ) ) + std::tie( err, actual ) = write( file, m_security_match[i], sizeof( m_security_match[i] ) ); + if( err ) return false; - if( file.write( m_secure_memory[i], sizeof( m_secure_memory[i] ), actual ) || actual != sizeof( m_secure_memory[i] ) ) + std::tie( err, actual ) = write( file, m_secure_memory[i], sizeof( m_secure_memory[i] ) ); + if( err ) return false; } @@ -141,11 +152,11 @@ void ds1205_device::writebit( u8 *buffer ) if( m_dqw ) { - buffer[ index ] |= mask; + buffer[index] |= mask; } else { - buffer[ index ] &= ~mask; + buffer[index] &= ~mask; } m_bit++; @@ -159,7 +170,7 @@ void ds1205_device::readbit( u8 *buffer ) int index = m_bit / 8; int mask = 1 << ( m_bit % 8 ); - if( buffer[ index ] & mask ) + if( buffer[index] & mask ) { m_dqr = 1; } @@ -226,17 +237,17 @@ void ds1205_device::write_clk(int state) if( m_bit == 24 ) { verboselog( 1, "-> command %02x %02x %02x\n", - m_command[ 0 ], m_command[ 1 ], m_command[ 2 ] ); + m_command[0], m_command[1], m_command[2] ); - if( m_command[ 0 ] == COMMAND_GET_SCRATCHPAD && (m_command[ 1 ] & 0xc0) == 0xc0 && m_command[ 1 ] == ( ~m_command[ 2 ] & 0xff ) ) + if( m_command[0] == COMMAND_GET_SCRATCHPAD && (m_command[1] & 0xc0) == 0xc0 && m_command[1] == ( ~m_command[2] & 0xff ) ) { new_state( STATE_READ_SCRATCH ); } - else if( m_command[ 0 ] == COMMAND_GET_DATA && (m_command[ 1 ] & 0xc0) != 0xc0 && (m_command[ 1 ] & 0x3f) >= 0x10 && m_command[ 1 ] == ( ~m_command[ 2 ] & 0xff ) ) + else if( m_command[0] == COMMAND_GET_DATA && (m_command[1] & 0xc0) != 0xc0 && (m_command[1] & 0x3f) >= 0x10 && m_command[1] == ( ~m_command[2] & 0xff ) ) { new_state( STATE_READ_IDENTIFICATION ); } - else if( m_command[ 0 ] == COMMAND_SET_SECURITY && (m_command[ 1 ] & 0xc0) != 0xc0 && !(m_command [ 1 ] & 0x3f) && m_command[ 1 ] == ( ~m_command[ 2 ] & 0xff ) ) + else if( m_command[0] == COMMAND_SET_SECURITY && (m_command[1] & 0xc0) != 0xc0 && !(m_command[1] & 0x3f) && m_command[1] == ( ~m_command[2] & 0xff ) ) { new_state( STATE_READ_IDENTIFICATION ); } @@ -248,14 +259,14 @@ void ds1205_device::write_clk(int state) break; case STATE_READ_IDENTIFICATION: - readbit( m_identification[ m_command[ 1 ] >> 6 ] ); + readbit( m_identification[m_command[1] >> 6] ); if( m_bit == 64 ) { - int page = m_command [ 1 ] >> 6; + int page = m_command [1] >> 6; verboselog( 1, "<- identification %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_identification[ page ][ 0 ], m_identification[ page ][ 1 ], m_identification[ page ][ 2 ], m_identification[ page ][ 3 ], - m_identification[ page ][ 4 ], m_identification[ page ][ 5 ], m_identification[ page ][ 6 ], m_identification[ page ][ 7 ] ); + m_identification[page][0], m_identification[page][1], m_identification[page][2], m_identification[page][3], + m_identification[page][4], m_identification[page][5], m_identification[page][6], m_identification[page][7] ); new_state( STATE_WRITE_COMPARE_REGISTER ); } @@ -266,24 +277,24 @@ void ds1205_device::write_clk(int state) if( m_bit == 64 ) { - int page = m_command[ 1 ] >> 6; + int page = m_command[1] >> 6; verboselog( 1, "-> compare register %02x %02x %02x %02x %02x %02x %02x %02x (%02x %02x %02x %02x %02x %02x %02x %02x)\n", - m_compare_register[ 0 ], m_compare_register[ 1 ], m_compare_register[ 2 ], m_compare_register[ 3 ], - m_compare_register[ 4 ], m_compare_register[ 5 ], m_compare_register[ 6 ], m_compare_register[ 7 ], - m_security_match[ page ][ 0 ], m_security_match[ page ][ 1 ], m_security_match[ page ][ 2 ], m_security_match[ page ][ 3 ], - m_security_match[ page ][ 4 ], m_security_match[ page ][ 5 ], m_security_match[ page ][ 6 ], m_security_match[ page ][ 7 ] ); + m_compare_register[0], m_compare_register[1], m_compare_register[2], m_compare_register[3], + m_compare_register[4], m_compare_register[5], m_compare_register[6], m_compare_register[7], + m_security_match[page][0], m_security_match[page][1], m_security_match[page][2], m_security_match[page][3], + m_security_match[page][4], m_security_match[page][5], m_security_match[page][6], m_security_match[page][7] ); - if( memcmp( m_compare_register, m_security_match[ page ], sizeof( m_compare_register ) ) == 0 ) + if( memcmp( m_compare_register, m_security_match[page], sizeof( m_compare_register ) ) == 0 ) { - if( m_command[ 0 ] == COMMAND_GET_DATA ) + if( m_command[0] == COMMAND_GET_DATA ) { new_state( STATE_READ_DATA ); } - else if( m_command[ 0 ] == COMMAND_GET_SCRATCHPAD) + else if( m_command[0] == COMMAND_GET_SCRATCHPAD) { new_state( STATE_READ_SCRATCH ); } - else if( m_command[ 0 ] == COMMAND_SET_SECURITY) + else if( m_command[0] == COMMAND_SET_SECURITY) { new_state( STATE_WRITE_IDENTIFICATION ); } @@ -296,16 +307,16 @@ void ds1205_device::write_clk(int state) break; case STATE_READ_DATA: - readbit( m_secure_memory[ m_command[ 1 ] >> 6 ] ); + readbit( m_secure_memory[m_command[1] >> 6] ); if( m_bit == 384 ) { - int page = m_command [ 1 ] >> 6; + int page = m_command[1] >> 6; verboselog( 1, "<- secure memory %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_secure_memory[ page ][ 0 ], m_secure_memory[ page ][ 1 ], m_secure_memory[ page ][ 2 ], m_secure_memory[ page ][ 3 ], - m_secure_memory[ page ][ 4 ], m_secure_memory[ page ][ 5 ], m_secure_memory[ page ][ 6 ], m_secure_memory[ page ][ 7 ], - m_secure_memory[ page ][ 8 ], m_secure_memory[ page ][ 9 ], m_secure_memory[ page ][ 10 ], m_secure_memory[ page ][ 11 ], - m_secure_memory[ page ][ 12 ], m_secure_memory[ page ][ 13 ], m_secure_memory[ page ][ 14 ], m_secure_memory[ page ][ 15 ] ); + m_secure_memory[page][0], m_secure_memory[page][1], m_secure_memory[page][2], m_secure_memory[page][3], + m_secure_memory[page][4], m_secure_memory[page][5], m_secure_memory[page][6], m_secure_memory[page][7], + m_secure_memory[page][8], m_secure_memory[page][9], m_secure_memory[page][10], m_secure_memory[page][11], + m_secure_memory[page][12], m_secure_memory[page][13], m_secure_memory[page][14], m_secure_memory[page][15] ); new_state( STATE_STOP ); } @@ -317,57 +328,57 @@ void ds1205_device::write_clk(int state) if( m_bit == 512 ) { verboselog( 1, "<- scratchpad %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_scratchpad[ 0 ], m_scratchpad[ 1 ], m_scratchpad[ 2 ], m_scratchpad[ 3 ], - m_scratchpad[ 4 ], m_scratchpad[ 5 ], m_scratchpad[ 6 ], m_scratchpad[ 7 ], - m_scratchpad[ 8 ], m_scratchpad[ 9 ], m_scratchpad[ 10 ], m_scratchpad[ 11 ], - m_scratchpad[ 12 ], m_scratchpad[ 13 ], m_scratchpad[ 14 ], m_scratchpad[ 15 ] ); + m_scratchpad[0], m_scratchpad[1], m_scratchpad[2], m_scratchpad[3], + m_scratchpad[4], m_scratchpad[5], m_scratchpad[6], m_scratchpad[7], + m_scratchpad[8], m_scratchpad[9], m_scratchpad[10], m_scratchpad[11], + m_scratchpad[12], m_scratchpad[13], m_scratchpad[14], m_scratchpad[15] ); new_state( STATE_STOP ); } break; case STATE_WRITE_IDENTIFICATION: - writebit( m_identification[ m_command[ 1 ] >> 6 ] ); + writebit( m_identification[m_command[1] >> 6] ); if( m_bit == 64 ) { - int page = m_command[ 1 ] >> 6; + int page = m_command[1] >> 6; verboselog( 1, "-> identification %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_identification[ page ][ 0 ], m_identification[ page ][ 1 ], m_identification[ page ][ 2 ], m_identification[ page ][ 3 ], - m_identification[ page ][ 4 ], m_identification[ page ][ 5 ], m_identification[ page ][ 6 ], m_identification[ page ][ 7 ] ); + m_identification[page][0], m_identification[page][1], m_identification[page][2], m_identification[page][3], + m_identification[page][4], m_identification[page][5], m_identification[page][6], m_identification[page][7] ); new_state( STATE_WRITE_SECURITY_MATCH ); } break; case STATE_WRITE_SECURITY_MATCH: - writebit( m_security_match[ m_command[ 1 ] >> 6 ] ); + writebit( m_security_match[m_command[1] >> 6] ); if( m_bit == 64 ) { - int page = m_command[ 1 ] >> 6; + int page = m_command[1] >> 6; verboselog( 1, ">- security match %02x %02x %02x %02x %02x %02x %02x %02x\n", - m_security_match[ page ][ 0 ], m_security_match[ page ][ 1 ], m_security_match[ page ][ 2 ], m_security_match[ page ][ 3 ], - m_security_match[ page ][ 4 ], m_security_match[ page ][ 5 ], m_security_match[ page ][ 6 ], m_security_match[ page ][ 7 ] ); + m_security_match[page][0], m_security_match[page][1], m_security_match[page][2], m_security_match[page][3], + m_security_match[page][4], m_security_match[page][5], m_security_match[page][6], m_security_match[page][7] ); new_state( STATE_STOP ); } break; case STATE_OUTPUT_GARBLED_DATA: - if( !m_clk && m_command[ 0 ] == COMMAND_GET_DATA ) + if( !m_clk && m_command[0] == COMMAND_GET_DATA ) { m_dqr = machine().rand() & 1; m_bit++; } - else if( m_clk && m_command[ 0 ] == COMMAND_SET_DATA ) + else if( m_clk && m_command[0] == COMMAND_SET_DATA ) { m_bit++; } if( m_bit == 64 ) { - if( m_command[ 0 ] == COMMAND_GET_DATA ) + if( m_command[0] == COMMAND_GET_DATA ) { verboselog( 1, "<- random\n" ); } diff --git a/src/devices/machine/ds1207.cpp b/src/devices/machine/ds1207.cpp index 1cc301b0741..805f15c730d 100644 --- a/src/devices/machine/ds1207.cpp +++ b/src/devices/machine/ds1207.cpp @@ -33,6 +33,8 @@ #include "emu.h" #include "ds1207.h" +#include <tuple> + #define LOG_LINES (1U << 1) #define LOG_STATE (1U << 2) #define LOG_DATA (1U << 3) @@ -138,28 +140,62 @@ void ds1207_device::nvram_default() bool ds1207_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - bool result = !file.read(m_unique_pattern, sizeof(m_unique_pattern), actual) && actual == sizeof(m_unique_pattern); - result = result && !file.read(m_identification, sizeof(m_identification), actual) && actual == sizeof(m_identification); - result = result && !file.read(m_security_match, sizeof(m_security_match), actual) && actual == sizeof(m_security_match); - result = result && !file.read(m_secure_memory, sizeof(m_secure_memory), actual) && actual == sizeof(m_secure_memory); - result = result && !file.read(m_days_left, sizeof(m_days_left), actual) && actual == sizeof(m_days_left); - result = result && !file.read(m_start_time, sizeof(m_start_time), actual) && actual == sizeof(m_start_time); - result = result && !file.read(&m_device_state, sizeof(m_device_state), actual) && actual == sizeof(m_device_state); - return result; + + std::tie(err, actual) = read(file, m_unique_pattern, sizeof(m_unique_pattern)); + if (err || (sizeof(m_unique_pattern) != actual)) + return false; + std::tie(err, actual) = read(file, m_identification, sizeof(m_identification)); + if (err || (sizeof(m_identification) != actual)) + return false; + std::tie(err, actual) = read(file, m_security_match, sizeof(m_security_match)); + if (err || (sizeof(m_security_match) != actual)) + return false; + std::tie(err, actual) = read(file, m_secure_memory, sizeof(m_secure_memory)); + if (err || (sizeof(m_secure_memory) != actual)) + return false; + std::tie(err, actual) = read(file, m_days_left, sizeof(m_days_left)); + if (err || (sizeof(m_days_left) != actual)) + return false; + std::tie(err, actual) = read(file, m_start_time, sizeof(m_start_time)); + if (err || (sizeof(m_start_time) != actual)) + return false; + std::tie(err, actual) = read(file, &m_device_state, sizeof(m_device_state)); + if (err || (sizeof(m_device_state) != actual)) + return false; + + return true; } bool ds1207_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - bool result = !file.write(m_unique_pattern, sizeof(m_unique_pattern), actual) && actual == sizeof(m_unique_pattern); - result = result && !file.write(m_identification, sizeof(m_identification), actual) && actual == sizeof(m_identification); - result = result && !file.write(m_security_match, sizeof(m_security_match), actual) && actual == sizeof(m_security_match); - result = result && !file.write(m_secure_memory, sizeof(m_secure_memory), actual) && actual == sizeof(m_secure_memory); - result = result && !file.write(m_days_left, sizeof(m_days_left), actual) && actual == sizeof(m_days_left); - result = result && !file.write(m_start_time, sizeof(m_start_time), actual) && actual == sizeof(m_start_time); - result = result && !file.write(&m_device_state, sizeof(m_device_state), actual) && actual == sizeof(m_device_state); - return result; + + std::tie(err, actual) = write(file, m_unique_pattern, sizeof(m_unique_pattern)); + if (err) + return false; + std::tie(err, actual) = write(file, m_identification, sizeof(m_identification)); + if (err) + return false; + std::tie(err, actual) = write(file, m_security_match, sizeof(m_security_match)); + if (err) + return false; + std::tie(err, actual) = write(file, m_secure_memory, sizeof(m_secure_memory)); + if (err) + return false; + std::tie(err, actual) = write(file, m_days_left, sizeof(m_days_left)); + if (err) + return false; + std::tie(err, actual) = write(file, m_start_time, sizeof(m_start_time)); + if (err) + return false; + std::tie(err, actual) = write(file, &m_device_state, sizeof(m_device_state)); + if (err) + return false; + + return true; } void ds1207_device::new_state(uint8_t state) diff --git a/src/devices/machine/ds1302.cpp b/src/devices/machine/ds1302.cpp index 154716aa346..5c2b90955cf 100644 --- a/src/devices/machine/ds1302.cpp +++ b/src/devices/machine/ds1302.cpp @@ -159,8 +159,8 @@ void ds1302_device::nvram_default() bool ds1302_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_ram[0], m_ram_size, actual) && actual == m_ram_size; + auto const [err, actual] = read(file, &m_ram[0], m_ram_size); + return !err && (actual == m_ram_size); } @@ -171,8 +171,8 @@ bool ds1302_device::nvram_read(util::read_stream &file) bool ds1302_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_ram[0], m_ram_size, actual) && actual == m_ram_size; + auto const [err, actual] = write(file, &m_ram[0], m_ram_size); + return !err; } diff --git a/src/devices/machine/ds1386.cpp b/src/devices/machine/ds1386.cpp index 01d7c6b5906..413d598c8b8 100644 --- a/src/devices/machine/ds1386.cpp +++ b/src/devices/machine/ds1386.cpp @@ -361,14 +361,14 @@ void ds1386_device::nvram_default() bool ds1386_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_ram[0], m_ram_size, actual) && actual == m_ram_size; + auto const [err, actual] = read(file, &m_ram[0], m_ram_size); + return !err && (actual == m_ram_size); } bool ds1386_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_ram[0], m_ram_size, actual) && actual == m_ram_size; + auto const [err, actual] = write(file, &m_ram[0], m_ram_size); + return !err; } void ds1386_device::data_w(offs_t offset, uint8_t data) diff --git a/src/devices/machine/ds1994.cpp b/src/devices/machine/ds1994.cpp index a64a36b5c26..ab041984348 100644 --- a/src/devices/machine/ds1994.cpp +++ b/src/devices/machine/ds1994.cpp @@ -9,12 +9,14 @@ * */ -// FIXME: convert to device_rtc_interface and remove time.h +// FIXME: convert to device_rtc_interface and remove <ctime> #include "emu.h" #include "machine/ds1994.h" #include <ctime> +#include <tuple> + #define LOG_ERRORS (1U << 1) #define LOG_1WIRE (1U << 2) @@ -750,13 +752,26 @@ void ds1994_device::nvram_default() bool ds1994_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - bool result = !file.read(m_rom, ROM_SIZE, actual) && actual == ROM_SIZE; - result = result && !file.read(m_ram, SPD_SIZE, actual) && actual == SPD_SIZE; - result = result && !file.read(m_sram, DATA_SIZE, actual) && actual == DATA_SIZE; - result = result && !file.read(m_rtc, RTC_SIZE, actual) && actual == RTC_SIZE; - result = result && !file.read(m_regs, REGS_SIZE, actual) && actual == REGS_SIZE; - return result; + + std::tie(err, actual) = util::read(file, m_rom, ROM_SIZE); + if (err || (ROM_SIZE != actual)) + return false; + std::tie(err, actual) = util::read(file, m_ram, SPD_SIZE); + if (err || (SPD_SIZE != actual)) + return false; + std::tie(err, actual) = util::read(file, m_sram, DATA_SIZE); + if (err || (DATA_SIZE != actual)) + return false; + std::tie(err, actual) = util::read(file, m_rtc, RTC_SIZE); + if (err || (RTC_SIZE != actual)) + return false; + std::tie(err, actual) = util::read(file, m_regs, REGS_SIZE); + if (err || (REGS_SIZE != actual)) + return false; + + return true; } //------------------------------------------------- @@ -766,11 +781,24 @@ bool ds1994_device::nvram_read(util::read_stream &file) bool ds1994_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - bool result = !file.write(m_rom, ROM_SIZE, actual) && actual == ROM_SIZE; - result = result && !file.write(m_ram, SPD_SIZE, actual) && actual == SPD_SIZE; - result = result && !file.write(m_sram, DATA_SIZE, actual) && actual == DATA_SIZE; - result = result && !file.write(m_rtc, RTC_SIZE, actual) && actual == RTC_SIZE; - result = result && !file.write(m_regs, REGS_SIZE, actual) && actual == REGS_SIZE; - return result; + + std::tie(err, actual) = util::write(file, m_rom, ROM_SIZE); + if (err) + return false; + std::tie(err, actual) = util::write(file, m_ram, SPD_SIZE); + if (err) + return false; + std::tie(err, actual) = util::write(file, m_sram, DATA_SIZE); + if (err) + return false; + std::tie(err, actual) = util::write(file, m_rtc, RTC_SIZE); + if (err) + return false; + std::tie(err, actual) = util::write(file, m_regs, REGS_SIZE); + if (err) + return false; + + return true; } diff --git a/src/devices/machine/ds2404.cpp b/src/devices/machine/ds2404.cpp index 68845d86dc3..680b4043e20 100644 --- a/src/devices/machine/ds2404.cpp +++ b/src/devices/machine/ds2404.cpp @@ -346,8 +346,8 @@ void ds2404_device::nvram_default() bool ds2404_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_sram, sizeof(m_sram), actual) && actual == sizeof(m_sram); + auto const [err, actual] = read(file, m_sram, sizeof(m_sram)); + return !err && (actual == sizeof(m_sram)); } @@ -358,6 +358,6 @@ bool ds2404_device::nvram_read(util::read_stream &file) bool ds2404_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_sram, sizeof(m_sram), actual) && actual == sizeof(m_sram); + auto const [err, actual] = write(file, m_sram, sizeof(m_sram)); + return !err; } diff --git a/src/devices/machine/ds2430a.cpp b/src/devices/machine/ds2430a.cpp index b788f2e061d..fca443e76a1 100644 --- a/src/devices/machine/ds2430a.cpp +++ b/src/devices/machine/ds2430a.cpp @@ -39,6 +39,7 @@ #include "ds2430a.h" #include <numeric> // std::accumulate +#include <tuple> // std::tie #define LOG_PULSE (1U << 1) #define LOG_BITS (1U << 2) @@ -458,10 +459,13 @@ void ds2430a_device::device_start() bool ds2430a_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - if (file.read(&m_eeprom[0], 0x20, actual) || actual != 0x20) + std::tie(err, actual) = read(file, &m_eeprom[0], 0x20); + if (err || (0x20 != actual)) return false; - if (file.read(&m_rom[0], 8, actual) || actual != 8) + std::tie(err, actual) = read(file, &m_rom[0], 8); + if (err || (8 != actual)) return false; if (m_rom[0] != 0x14) @@ -481,10 +485,13 @@ bool ds2430a_device::nvram_read(util::read_stream &file) bool ds2430a_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - if (file.write(&m_eeprom[0], 0x20, actual) || actual != 0x20) + std::tie(err, actual) = write(file, &m_eeprom[0], 0x20); + if (err) return false; - if (file.write(&m_rom[0], 8, actual) || actual != 8) + std::tie(err, actual) = write(file, &m_rom[0], 8); + if (err) return false; return true; diff --git a/src/devices/machine/eeprom.cpp b/src/devices/machine/eeprom.cpp index 0cdf04154a8..a15b8b8bcf3 100644 --- a/src/devices/machine/eeprom.cpp +++ b/src/devices/machine/eeprom.cpp @@ -255,9 +255,9 @@ bool eeprom_base_device::nvram_read(util::read_stream &file) { uint32_t const eeprom_length = 1 << m_address_bits; uint32_t const eeprom_bytes = eeprom_length * m_data_bits / 8; - size_t actual_bytes; - return !file.read(&m_data[0], eeprom_bytes, actual_bytes) && actual_bytes == eeprom_bytes; + auto const [err, actual_bytes] = util::read(file, &m_data[0], eeprom_bytes); + return !err && (actual_bytes == eeprom_bytes); } @@ -270,9 +270,9 @@ bool eeprom_base_device::nvram_write(util::write_stream &file) { uint32_t const eeprom_length = 1 << m_address_bits; uint32_t const eeprom_bytes = eeprom_length * m_data_bits / 8; - size_t actual_bytes; - return !file.write(&m_data[0], eeprom_bytes, actual_bytes) && actual_bytes == eeprom_bytes; + auto const [err, actual_bytes] = util::write(file, &m_data[0], eeprom_bytes); + return !err; } diff --git a/src/devices/machine/er1400.cpp b/src/devices/machine/er1400.cpp index ef589ba71d9..de4ae9c8d28 100644 --- a/src/devices/machine/er1400.cpp +++ b/src/devices/machine/er1400.cpp @@ -106,10 +106,10 @@ void er1400_device::nvram_default() bool er1400_device::nvram_read(util::read_stream &file) { - size_t size = 100 * sizeof(m_data_array[0]); - size_t actual; + size_t const size = 100 * sizeof(m_data_array[0]); - return !file.read(&m_data_array[0], size, actual) && actual == size; + auto const [err, actual] = read(file, &m_data_array[0], size); + return !err && (actual == size); } @@ -120,10 +120,10 @@ bool er1400_device::nvram_read(util::read_stream &file) bool er1400_device::nvram_write(util::write_stream &file) { - size_t size = 100 * sizeof(m_data_array[0]); - size_t actual; + size_t const size = 100 * sizeof(m_data_array[0]); - return !file.write(&m_data_array[0], size, actual) && actual == size; + auto const [err, actual] = write(file, &m_data_array[0], size); + return !err; } diff --git a/src/devices/machine/er2055.cpp b/src/devices/machine/er2055.cpp index 18bcf102593..aa80957b12d 100644 --- a/src/devices/machine/er2055.cpp +++ b/src/devices/machine/er2055.cpp @@ -85,8 +85,8 @@ void er2055_device::nvram_default() bool er2055_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_rom_data[0], SIZE_DATA, actual) && actual == SIZE_DATA; + auto const [err, actual] = read(file, &m_rom_data[0], SIZE_DATA); + return !err && (actual == SIZE_DATA); } @@ -97,8 +97,8 @@ bool er2055_device::nvram_read(util::read_stream &file) bool er2055_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_rom_data[0], SIZE_DATA, actual) && actual == SIZE_DATA; + auto const [err, actual] = write(file, &m_rom_data[0], SIZE_DATA); + return !err; } diff --git a/src/devices/machine/generic_spi_flash.cpp b/src/devices/machine/generic_spi_flash.cpp index 356be2cb8e1..7421004bf2e 100644 --- a/src/devices/machine/generic_spi_flash.cpp +++ b/src/devices/machine/generic_spi_flash.cpp @@ -187,13 +187,13 @@ bool generic_spi_flash_device::nvram_read(util::read_stream &file) return false; } - size_t actual; - return !file.read(m_spiptr, m_length, actual) && actual == m_length; + auto const [err, actual] = util::read(file, m_spiptr, m_length); + return !err && (actual == m_length); } bool generic_spi_flash_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_spiptr, m_length, actual) && actual == m_length; + auto const [err, actual] = util::write(file, m_spiptr, m_length); + return !err; } diff --git a/src/devices/machine/hd64610.cpp b/src/devices/machine/hd64610.cpp index b1a33bde023..41482acacfe 100644 --- a/src/devices/machine/hd64610.cpp +++ b/src/devices/machine/hd64610.cpp @@ -249,8 +249,8 @@ void hd64610_device::nvram_default() bool hd64610_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_regs, 0x10, actual) && actual == 0x10; + auto const [err, actual] = util::read(file, m_regs, 0x10); + return !err && (actual == 0x10); } @@ -261,8 +261,8 @@ bool hd64610_device::nvram_read(util::read_stream &file) bool hd64610_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_regs, 0x10, actual) && actual == 0x10; + auto const [err, actual] = util::write(file, m_regs, 0x10); + return !err; } diff --git a/src/devices/machine/i2cmem.cpp b/src/devices/machine/i2cmem.cpp index 74504eb43ce..c8c49dc5fb3 100644 --- a/src/devices/machine/i2cmem.cpp +++ b/src/devices/machine/i2cmem.cpp @@ -255,8 +255,8 @@ void i2cmem_device::nvram_default() bool i2cmem_device::nvram_read( util::read_stream &file ) { - size_t actual; - return !file.read( &m_data[0], m_data_size, actual ) && actual == m_data_size; + auto const [err, actual] = read( file, &m_data[0], m_data_size ); + return !err && ( actual == m_data_size ); } //------------------------------------------------- @@ -266,8 +266,8 @@ bool i2cmem_device::nvram_read( util::read_stream &file ) bool i2cmem_device::nvram_write( util::write_stream &file ) { - size_t actual; - return !file.write( &m_data[0], m_data_size, actual ) && actual == m_data_size; + auto const [err, actual] = write( file, &m_data[0], m_data_size ); + return !err; } diff --git a/src/devices/machine/icm7170.cpp b/src/devices/machine/icm7170.cpp index 1dbe8837446..97be23ee0d2 100644 --- a/src/devices/machine/icm7170.cpp +++ b/src/devices/machine/icm7170.cpp @@ -257,8 +257,8 @@ void icm7170_device::nvram_default() bool icm7170_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_regs, 0x20, actual) && actual == 0x20; + auto const [err, actual] = util::read(file, m_regs, 0x20); + return !err && (actual == 0x20); } @@ -269,8 +269,8 @@ bool icm7170_device::nvram_read(util::read_stream &file) bool icm7170_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_regs, 0x20, actual) && actual == 0x20; + auto const [err, actual] = util::write(file, m_regs, 0x20); + return !err; } // non-inherited device functions diff --git a/src/devices/machine/intelfsh.cpp b/src/devices/machine/intelfsh.cpp index f0376b80d71..93f558b3d3c 100644 --- a/src/devices/machine/intelfsh.cpp +++ b/src/devices/machine/intelfsh.cpp @@ -396,8 +396,8 @@ void intelfsh_device::nvram_default() bool intelfsh_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_data[0], m_size, actual) && actual == m_size; + auto const [err, actual] = read(file, &m_data[0], m_size); + return !err && (actual == m_size); } @@ -408,8 +408,8 @@ bool intelfsh_device::nvram_read(util::read_stream &file) bool intelfsh_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_data[0], m_size, actual) && actual == m_size; + auto const [err, actual] = write(file, &m_data[0], m_size); + return !err; } diff --git a/src/devices/machine/kr1601rr1.cpp b/src/devices/machine/kr1601rr1.cpp index 561d3f212db..b3ebb561675 100644 --- a/src/devices/machine/kr1601rr1.cpp +++ b/src/devices/machine/kr1601rr1.cpp @@ -120,8 +120,8 @@ void kr1601rr1_device::nvram_default() bool kr1601rr1_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_earom, EAROM_SIZE, actual) && actual == EAROM_SIZE; + auto const [err, actual] = util::read(file, m_earom, EAROM_SIZE); + return !err && (actual == EAROM_SIZE); } //------------------------------------------------- @@ -131,8 +131,8 @@ bool kr1601rr1_device::nvram_read(util::read_stream &file) bool kr1601rr1_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_earom, EAROM_SIZE, actual) && actual == EAROM_SIZE; + auto const [err, actual] = util::write(file, m_earom, EAROM_SIZE); + return !err; } //------------------------------------------------- diff --git a/src/devices/machine/m3002.cpp b/src/devices/machine/m3002.cpp index 28422b8f488..8c9fe20db05 100644 --- a/src/devices/machine/m3002.cpp +++ b/src/devices/machine/m3002.cpp @@ -100,8 +100,8 @@ void m3002_device::device_clock_changed() bool m3002_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_ram[0], 0x10, actual) && actual == 0x10; + auto const [err, actual] = util::read(file, &m_ram[0], 0x10); + return !err && (actual == 0x10); } @@ -111,8 +111,8 @@ bool m3002_device::nvram_read(util::read_stream &file) bool m3002_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_ram[0], 0x10, actual) && actual == 0x10; + auto const [err, actual] = util::write(file, &m_ram[0], 0x10); + return !err; } diff --git a/src/devices/machine/m6m80011ap.cpp b/src/devices/machine/m6m80011ap.cpp index 43638d11224..7fd3e3ce5c5 100644 --- a/src/devices/machine/m6m80011ap.cpp +++ b/src/devices/machine/m6m80011ap.cpp @@ -78,8 +78,8 @@ void m6m80011ap_device::nvram_default() bool m6m80011ap_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_eeprom_data, 0x100, actual) && actual == 0x100; + auto const [err, actual] = read(file, m_eeprom_data, 0x100); + return !err && (actual == 0x100); } @@ -90,8 +90,8 @@ bool m6m80011ap_device::nvram_read(util::read_stream &file) bool m6m80011ap_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_eeprom_data, 0x100, actual) && actual == 0x100; + auto const [err, actual] = write(file, m_eeprom_data, 0x100); + return !err; } //************************************************************************** diff --git a/src/devices/machine/mc146818.cpp b/src/devices/machine/mc146818.cpp index dd956657526..ffa14fa4b55 100644 --- a/src/devices/machine/mc146818.cpp +++ b/src/devices/machine/mc146818.cpp @@ -279,9 +279,9 @@ void mc146818_device::nvram_default() bool mc146818_device::nvram_read(util::read_stream &file) { - size_t size = data_size(); - size_t actual; - if (file.read(&m_data[0], size, actual) || actual != size) + size_t const size = data_size(); + auto const [err, actual] = read(file, &m_data[0], size); + if (err || (actual != size)) return false; update_timer(); @@ -298,9 +298,9 @@ bool mc146818_device::nvram_read(util::read_stream &file) bool mc146818_device::nvram_write(util::write_stream &file) { - size_t size = data_size(); - size_t actual; - return !file.write(&m_data[0], size, actual) && actual == size; + size_t const size = data_size(); + auto const [err, actual] = write(file, &m_data[0], size); + return !err; } diff --git a/src/devices/machine/mccs1850.cpp b/src/devices/machine/mccs1850.cpp index 4f390f05ac2..af9edbddecd 100644 --- a/src/devices/machine/mccs1850.cpp +++ b/src/devices/machine/mccs1850.cpp @@ -373,8 +373,8 @@ void mccs1850_device::nvram_default() bool mccs1850_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_ram, RAM_SIZE, actual) && actual == RAM_SIZE; + auto const [err, actual] = read(file, m_ram, RAM_SIZE); + return !err && (actual == RAM_SIZE); } @@ -385,8 +385,8 @@ bool mccs1850_device::nvram_read(util::read_stream &file) bool mccs1850_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_ram, RAM_SIZE, actual) && actual == RAM_SIZE; + auto const [err, actual] = write(file, m_ram, RAM_SIZE); + return !err; } diff --git a/src/devices/machine/msm5001n.cpp b/src/devices/machine/msm5001n.cpp index b1fdc1766ed..8a3ab9f9ef7 100644 --- a/src/devices/machine/msm5001n.cpp +++ b/src/devices/machine/msm5001n.cpp @@ -171,14 +171,14 @@ TIMER_CALLBACK_MEMBER(msm5001n_device::clock_tick) bool msm5001n_device::nvram_write(util::write_stream &file) { - size_t actual; u8 buf[5]; // current time for (int i = 0; i < 5; i++) buf[i] = get_clock_register(i); - if (file.write(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) + auto const [err, actual] = write(file, &buf, sizeof(buf)); + if (err) return false; return true; @@ -186,10 +186,9 @@ bool msm5001n_device::nvram_write(util::write_stream &file) bool msm5001n_device::nvram_read(util::read_stream &file) { - size_t actual; - u8 buf[5]; - if (file.read(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) + auto const [err, actual] = read(file, &buf, sizeof(buf)); + if (err || (sizeof(buf) != actual)) return false; // current time diff --git a/src/devices/machine/msm58321.cpp b/src/devices/machine/msm58321.cpp index ade436a7d11..aa0c30987f6 100644 --- a/src/devices/machine/msm58321.cpp +++ b/src/devices/machine/msm58321.cpp @@ -348,8 +348,8 @@ void msm58321_device::nvram_default() bool msm58321_device::nvram_read(util::read_stream &file) { - size_t actual; - if (file.read(m_reg.data(), m_reg.size(), actual) || actual != m_reg.size()) + auto const [err, actual] = read(file, m_reg.data(), m_reg.size()); + if (err || (actual != m_reg.size())) return false; clock_updated(); @@ -364,8 +364,8 @@ bool msm58321_device::nvram_read(util::read_stream &file) bool msm58321_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_reg.data(), m_reg.size(), actual) && actual == m_reg.size(); + auto const [err, actual] = write(file, m_reg.data(), m_reg.size()); + return !err; } //------------------------------------------------- diff --git a/src/devices/machine/nandflash.cpp b/src/devices/machine/nandflash.cpp index 6c0c43cfc3c..fa7060d01c2 100644 --- a/src/devices/machine/nandflash.cpp +++ b/src/devices/machine/nandflash.cpp @@ -231,16 +231,16 @@ void nand_device::nvram_default() bool nand_device::nvram_read(util::read_stream &file) { - size_t actual; - uint32_t size = m_page_total_size * m_num_pages; - return !file.read(&m_feeprom_data[0], size, actual) && actual == size; + uint32_t const size = m_page_total_size * m_num_pages; + auto const [err, actual] = read(file, &m_feeprom_data[0], size); + return !err && (actual == size); } bool nand_device::nvram_write(util::write_stream &file) { - size_t actual; - uint32_t size = m_page_total_size * m_num_pages; - return !file.write(&m_feeprom_data[0], size, actual) && actual == size; + uint32_t const size = m_page_total_size * m_num_pages; + auto const [err, actual] = write(file, &m_feeprom_data[0], size); + return !err; } int nand_device::is_present() diff --git a/src/devices/machine/nmc9306.cpp b/src/devices/machine/nmc9306.cpp index 5ed22ff3160..2001f58e78d 100644 --- a/src/devices/machine/nmc9306.cpp +++ b/src/devices/machine/nmc9306.cpp @@ -165,8 +165,8 @@ void nmc9306_device::nvram_default() bool nmc9306_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_register, RAM_SIZE, actual) && actual == RAM_SIZE; + auto const [err, actual] = util::read(file, m_register, RAM_SIZE); + return !err && (actual == RAM_SIZE); } @@ -177,8 +177,8 @@ bool nmc9306_device::nvram_read(util::read_stream &file) bool nmc9306_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_register, RAM_SIZE, actual) && actual == RAM_SIZE; + auto const [err, actual] = util::write(file, m_register, RAM_SIZE); + return !err; } diff --git a/src/devices/machine/nvram.cpp b/src/devices/machine/nvram.cpp index 3de2a5b1e59..039b0360db0 100644 --- a/src/devices/machine/nvram.cpp +++ b/src/devices/machine/nvram.cpp @@ -107,8 +107,9 @@ bool nvram_device::nvram_read(util::read_stream &file) // make sure we have a valid base pointer determine_final_base(); - size_t actual; - return !file.read(m_base, m_length, actual) && actual == m_length; + // FIXME: consider width/Endianness + auto const [err, actual] = read(file, m_base, m_length); + return !err && (actual == m_length); } @@ -119,8 +120,9 @@ bool nvram_device::nvram_read(util::read_stream &file) bool nvram_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_base, m_length, actual) && actual == m_length; + // FIXME: consider width/Endianness + auto const [err, actual] = write(file, m_base, m_length); + return !err; } diff --git a/src/devices/machine/nvram.h b/src/devices/machine/nvram.h index 58bde56bece..92bc81f64bb 100644 --- a/src/devices/machine/nvram.h +++ b/src/devices/machine/nvram.h @@ -62,13 +62,13 @@ protected: void determine_final_base(); // configuration state - optional_memory_region m_region; - default_value m_default_value; - init_delegate m_custom_handler; + optional_memory_region m_region; + default_value m_default_value; + init_delegate m_custom_handler; // runtime state - void * m_base; - size_t m_length; + void * m_base; + size_t m_length; }; DECLARE_DEVICE_TYPE(NVRAM, nvram_device) diff --git a/src/devices/machine/pcf8583.cpp b/src/devices/machine/pcf8583.cpp index 890ca586fba..40c9d201a88 100644 --- a/src/devices/machine/pcf8583.cpp +++ b/src/devices/machine/pcf8583.cpp @@ -181,8 +181,8 @@ void pcf8583_device::nvram_default() bool pcf8583_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_data, sizeof(m_data), actual) && actual == sizeof(m_data); + auto const [err, actual] = read(file, m_data, sizeof(m_data)); + return !err && (actual == sizeof(m_data)); } //------------------------------------------------- @@ -192,8 +192,8 @@ bool pcf8583_device::nvram_read(util::read_stream &file) bool pcf8583_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_data, sizeof(m_data), actual) && actual == sizeof(m_data); + auto const [err, actual] = write(file, m_data, sizeof(m_data)); + return !err; } diff --git a/src/devices/machine/pcf8593.cpp b/src/devices/machine/pcf8593.cpp index 5aa9807c05e..9c16476cfb5 100644 --- a/src/devices/machine/pcf8593.cpp +++ b/src/devices/machine/pcf8593.cpp @@ -134,8 +134,8 @@ void pcf8593_device::nvram_default() bool pcf8593_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_data, sizeof(m_data), actual) && actual == sizeof(m_data); + auto const [err, actual] = read(file, m_data, sizeof(m_data)); + return !err && (actual == sizeof(m_data)); } @@ -146,8 +146,8 @@ bool pcf8593_device::nvram_read(util::read_stream &file) bool pcf8593_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_data, sizeof(m_data), actual) && actual == sizeof(m_data); + auto const [err, actual] = write(file, m_data, sizeof(m_data)); + return !err; } diff --git a/src/devices/machine/psion_ssd.cpp b/src/devices/machine/psion_ssd.cpp index 3041ddacb70..74b223959cc 100644 --- a/src/devices/machine/psion_ssd.cpp +++ b/src/devices/machine/psion_ssd.cpp @@ -42,6 +42,8 @@ #include "softlist_dev.h" +#include <tuple> + DEFINE_DEVICE_TYPE(PSION_SSD, psion_ssd_device, "psion_ssd", "Psion Solid State Disk") @@ -163,8 +165,11 @@ std::pair<std::error_condition, std::string> psion_ssd_device::call_load() if (size < 0x10000 || size > 0x800000 || (size & (size - 1)) != 0) return std::make_pair(image_error::INVALIDLENGTH, "Invalid size, must be 64K, 128K, 256K, 512K, 1M, 2M, 4M, 8M"); - if (fread(m_ssd_data, size) != size) - return std::make_pair(std::errc::io_error, std::string()); + std::error_condition err; + size_t actual; + std::tie(err, m_ssd_data, actual) = read(image_core_file(), size); + if (err || (actual != size)) + return std::make_pair(err ? err : std::errc::io_error, std::string()); // check for Flash header if ((m_ssd_data[0] | (m_ssd_data[1] << 8)) == 0xf1a5) // Flash diff --git a/src/devices/machine/rp5c01.cpp b/src/devices/machine/rp5c01.cpp index 0babbedb8eb..a5d097995e2 100644 --- a/src/devices/machine/rp5c01.cpp +++ b/src/devices/machine/rp5c01.cpp @@ -290,8 +290,8 @@ void rp5c01_device::nvram_default() bool rp5c01_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_ram, RAM_SIZE, actual) && actual == RAM_SIZE; + auto const [err, actual] = util::read(file, m_ram, RAM_SIZE); + return !err && (actual == RAM_SIZE); } @@ -302,8 +302,8 @@ bool rp5c01_device::nvram_read(util::read_stream &file) bool rp5c01_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_ram, RAM_SIZE, actual) && actual == RAM_SIZE; + auto const [err, actual] = util::write(file, m_ram, RAM_SIZE); + return !err; } diff --git a/src/devices/machine/rtc65271.cpp b/src/devices/machine/rtc65271.cpp index 2c442335585..adea3cb29d6 100644 --- a/src/devices/machine/rtc65271.cpp +++ b/src/devices/machine/rtc65271.cpp @@ -21,6 +21,9 @@ #include "emu.h" #include "rtc65271.h" +#include <tuple> + + /* Delay between the beginning (UIP asserted) and the end (UIP cleared and update interrupt asserted) of the update cycle */ #define UPDATE_CYCLE_TIME attotime::from_usec(1984) @@ -184,36 +187,45 @@ void rtc65271_device::nvram_default() bool rtc65271_device::nvram_read(util::read_stream &file) { uint8_t buf; + std::error_condition err; size_t actual; /* version flag */ - if (file.read(&buf, 1, actual) || actual != 1) + std::tie(err, actual) = util::read(file, &buf, 1); + if (err || (actual != 1)) return false; if (buf != 0) return false; /* control registers */ - if (file.read(&buf, 1, actual) || actual != 1) + std::tie(err, actual) = util::read(file, &buf, 1); + if (err || (actual != 1)) return false; m_regs[reg_A] = buf & (reg_A_DV /*| reg_A_RS*/); - if (file.read(&buf, 1, actual) || actual != 1) + std::tie(err, actual) = util::read(file, &buf, 1); + if (err || (actual != 1)) return false; m_regs[reg_B] = buf & (reg_B_SET | reg_B_DM | reg_B_24h | reg_B_DSE); /* alarm registers */ - if (file.read(&m_regs[reg_alarm_second], 1, actual) || actual != 1) + std::tie(err, actual) = util::read(file, &m_regs[reg_alarm_second], 1); + if (err || (actual != 1)) return false; - if (file.read(&m_regs[reg_alarm_minute], 1, actual) || actual != 1) + std::tie(err, actual) = util::read(file, &m_regs[reg_alarm_minute], 1); + if (err || (actual != 1)) return false; - if (file.read(&m_regs[reg_alarm_hour], 1, actual) || actual != 1) + std::tie(err, actual) = util::read(file, &m_regs[reg_alarm_hour], 1); + if (err || (actual != 1)) return false; /* user RAM */ - if (file.read(m_regs+14, 50, actual) || actual != 50) + std::tie(err, actual) = util::read(file, m_regs+14, 50); + if (err || (actual != 50)) return false; /* extended RAM */ - if (file.read(m_xram, 4096, actual) || actual != 4096) + std::tie(err, actual) = util::read(file, m_xram, 4096); + if (err || (actual != 4096)) return false; m_regs[reg_D] |= reg_D_VRT; /* the data was backed up successfully */ @@ -273,35 +285,44 @@ void rtc65271_device::rtc_clock_updated(int year, int month, int day, int day_of bool rtc65271_device::nvram_write(util::write_stream &file) { uint8_t buf; + std::error_condition err; size_t actual; /* version flag */ buf = 0; - if (file.write(&buf, 1, actual) || actual != 1) + std::tie(err, actual) = util::write(file, &buf, 1); + if (err) return false; /* control registers */ buf = m_regs[reg_A] & (reg_A_DV | reg_A_RS); - if (file.write(&buf, 1, actual) || actual != 1) + std::tie(err, actual) = util::write(file, &buf, 1); + if (err) return false; buf = m_regs[reg_B] & (reg_B_SET | reg_B_DM | reg_B_24h | reg_B_DSE); - if (file.write(&buf, 1, actual) || actual != 1) + std::tie(err, actual) = util::write(file, &buf, 1); + if (err) return false; /* alarm registers */ - if (file.write(&m_regs[reg_alarm_second], 1, actual) || actual != 1) + std::tie(err, actual) = util::write(file, &m_regs[reg_alarm_second], 1); + if (err) return false; - if (file.write(&m_regs[reg_alarm_minute], 1, actual) || actual != 1) + std::tie(err, actual) = util::write(file, &m_regs[reg_alarm_minute], 1); + if (err) return false; - if (file.write(&m_regs[reg_alarm_hour], 1, actual) || actual != 1) + std::tie(err, actual) = util::write(file, &m_regs[reg_alarm_hour], 1); + if (err) return false; /* user RAM */ - if (file.write(m_regs+14, 50, actual) || actual != 50) + std::tie(err, actual) = util::write(file, m_regs+14, 50); + if (err) return false; /* extended RAM */ - if (file.write(m_xram, 4096, actual) || actual != 4096) + std::tie(err, actual) = util::write(file, m_xram, 4096); + if (err) return false; return true; diff --git a/src/devices/machine/rtc9701.cpp b/src/devices/machine/rtc9701.cpp index 93ea8226eb1..fd615ed898f 100644 --- a/src/devices/machine/rtc9701.cpp +++ b/src/devices/machine/rtc9701.cpp @@ -168,8 +168,8 @@ void rtc9701_device::nvram_default() bool rtc9701_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(rtc9701_data, 0x200, actual) && actual == 0x200; + auto const [err, actual] = read(file, rtc9701_data, 0x200); + return !err && (actual == 0x200); } @@ -180,8 +180,8 @@ bool rtc9701_device::nvram_read(util::read_stream &file) bool rtc9701_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(rtc9701_data, 0x200, actual) && actual == 0x200; + auto const [err, actual] = write(file, rtc9701_data, 0x200); + return !err; } //------------------------------------------------- diff --git a/src/devices/machine/s3520cf.cpp b/src/devices/machine/s3520cf.cpp index 8f256f24dfc..402dc909e12 100644 --- a/src/devices/machine/s3520cf.cpp +++ b/src/devices/machine/s3520cf.cpp @@ -164,8 +164,8 @@ void s3520cf_device::nvram_default() bool s3520cf_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_nvdata, 15, actual) && actual == 15; + auto const [err, actual] = read(file, m_nvdata, 15); + return !err && (actual == 15); } //------------------------------------------------- @@ -175,8 +175,8 @@ bool s3520cf_device::nvram_read(util::read_stream &file) bool s3520cf_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_nvdata, 15, actual) && actual == 15; + auto const [err, actual] = write(file, m_nvdata, 15); + return !err; } void s3520cf_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) diff --git a/src/devices/machine/sda2006.cpp b/src/devices/machine/sda2006.cpp index 8e48cd19689..3de3e276a7a 100644 --- a/src/devices/machine/sda2006.cpp +++ b/src/devices/machine/sda2006.cpp @@ -116,8 +116,8 @@ void sda2006_device::nvram_default() bool sda2006_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_eeprom_data, EEPROM_CAPACITY, actual) && actual == EEPROM_CAPACITY; + auto const [err, actual] = read(file, m_eeprom_data, EEPROM_CAPACITY); + return !err && (actual == EEPROM_CAPACITY); } //------------------------------------------------- @@ -127,8 +127,8 @@ bool sda2006_device::nvram_read(util::read_stream &file) bool sda2006_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_eeprom_data, EEPROM_CAPACITY, actual) && actual == EEPROM_CAPACITY; + auto const [err, actual] = write(file, m_eeprom_data, EEPROM_CAPACITY); + return !err; } int sda2006_device::read_data() diff --git a/src/devices/machine/sensorboard.cpp b/src/devices/machine/sensorboard.cpp index 4136831a6fd..3b6bee774f2 100644 --- a/src/devices/machine/sensorboard.cpp +++ b/src/devices/machine/sensorboard.cpp @@ -214,15 +214,15 @@ void sensorboard_device::nvram_default() bool sensorboard_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_curstate, sizeof(m_curstate), actual) && actual == sizeof(m_curstate); + auto const [err, actual] = read(file, m_curstate, sizeof(m_curstate)); + return !err && (sizeof(m_curstate) == actual); } bool sensorboard_device::nvram_write(util::write_stream &file) { // save last board position - size_t actual; - return !file.write(m_curstate, sizeof(m_curstate), actual) && actual == sizeof(m_curstate); + auto const [err, actual] = write(file, m_curstate, sizeof(m_curstate)); + return !err; } bool sensorboard_device::nvram_can_write() const diff --git a/src/devices/machine/smartmed.cpp b/src/devices/machine/smartmed.cpp index 18c86f7cc70..75473c8922d 100644 --- a/src/devices/machine/smartmed.cpp +++ b/src/devices/machine/smartmed.cpp @@ -24,6 +24,8 @@ #include "softlist_dev.h" +#include <tuple> + namespace { @@ -69,18 +71,17 @@ enum */ std::error_condition smartmedia_image_device::smartmedia_format_1() { + std::error_condition err; + size_t bytes_read; + SM_disk_image_header custom_header; - const int bytes_read = fread(&custom_header, sizeof(custom_header)); - if (bytes_read != sizeof(custom_header)) - { - return std::errc::io_error; - } + std::tie(err, bytes_read) = read(image_core_file(), &custom_header, sizeof(custom_header)); + if (err || (bytes_read != sizeof(custom_header))) + return err ? err : std::errc::io_error; if (custom_header.version > 1) - { return image_error::INVALIDIMAGE; - } m_page_data_size = get_UINT32BE(custom_header.page_data_size); m_page_total_size = get_UINT32BE(custom_header.page_total_size); @@ -116,7 +117,10 @@ std::error_condition smartmedia_image_device::smartmedia_format_1() fread(&m_mp_opcode, 1); fread(m_data_uid_ptr.get(), 256 + 16); } - fread(m_feeprom_data, m_page_total_size*m_num_pages); + + std::tie(err, m_feeprom_data, bytes_read) = read(image_core_file(), m_page_total_size * m_num_pages); + if (err || (bytes_read != (m_page_total_size * m_num_pages))) + return err ? err : std::errc::io_error; #ifdef SMARTMEDIA_IMAGE_SAVE m_image_format = 1; @@ -163,23 +167,20 @@ int smartmedia_image_device::detect_geometry( uint8_t id1, uint8_t id2) std::error_condition smartmedia_image_device::smartmedia_format_2() { + std::error_condition err; + size_t bytes_read; + disk_image_format_2_header custom_header; - const int bytes_read = fread(&custom_header, sizeof(custom_header)); - if (bytes_read != sizeof(custom_header)) - { - return std::errc::io_error; - } + std::tie(err, bytes_read) = read(image_core_file(), &custom_header, sizeof(custom_header)); + if (err || (bytes_read != sizeof(custom_header))) + return err ? err : std::errc::io_error; if ((custom_header.data1[0] != 0xEC) && (custom_header.data1[0] != 0x98)) - { return image_error::INVALIDIMAGE; - } if (!detect_geometry(custom_header.data1[0], custom_header.data1[1])) - { return image_error::INVALIDIMAGE; - } m_feeprom_data = std::make_unique<uint8_t[]>(m_page_total_size*m_num_pages); m_data_uid_ptr = std::make_unique<uint8_t[]>(256 + 16); @@ -207,7 +208,9 @@ std::error_condition smartmedia_image_device::smartmedia_format_2() } memcpy(m_data_uid_ptr.get() + 256, custom_header.data3, 16); - fread(m_feeprom_data, m_page_total_size*m_num_pages); + std::tie(err, m_feeprom_data, bytes_read) = read(image_core_file(), m_page_total_size * m_num_pages); + if (err || (bytes_read != (m_page_total_size * m_num_pages))) + return err ? err : std::errc::io_error; #ifdef SMARTMEDIA_IMAGE_SAVE m_image_format = 2; diff --git a/src/devices/machine/strata.cpp b/src/devices/machine/strata.cpp index 15841fe4597..7ed6251bba0 100644 --- a/src/devices/machine/strata.cpp +++ b/src/devices/machine/strata.cpp @@ -68,8 +68,8 @@ void strataflash_device::nvram_default() bool strataflash_device::nvram_read(util::read_stream &file) { - size_t actual; - if (file.read(m_flashmemory.get(), COMPLETE_SIZE, actual) || actual != COMPLETE_SIZE) + auto const [err, actual] = read(file, m_flashmemory.get(), COMPLETE_SIZE); + if (err || (COMPLETE_SIZE != actual)) return false; // TODO @@ -176,8 +176,8 @@ bool strataflash_device::nvram_write(util::write_stream &file) return 0; */ - size_t actual; - return !file.write(m_flashmemory.get(), COMPLETE_SIZE, actual) && actual == COMPLETE_SIZE; + auto const [err, actual] = write(file, m_flashmemory.get(), COMPLETE_SIZE); + return !err; } //------------------------------------------------- diff --git a/src/devices/machine/timekpr.cpp b/src/devices/machine/timekpr.cpp index c8c0d194430..5acf210afd0 100644 --- a/src/devices/machine/timekpr.cpp +++ b/src/devices/machine/timekpr.cpp @@ -470,8 +470,8 @@ void timekeeper_device::nvram_default() bool timekeeper_device::nvram_read(util::read_stream &file) { - size_t actual; - if (file.read(&m_data[0], m_size, actual) || actual != m_size) + auto const [err, actual] = util::read(file, &m_data[0], m_size); + if (err || (actual != m_size)) return false; counters_to_ram(); @@ -486,6 +486,6 @@ bool timekeeper_device::nvram_read(util::read_stream &file) bool timekeeper_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_data[0], m_size, actual) && actual == m_size; + auto const [err, actual] = util::write(file, &m_data[0], m_size); + return !err; } diff --git a/src/devices/machine/x2201.cpp b/src/devices/machine/x2201.cpp index 77007435e9b..28a404963d5 100644 --- a/src/devices/machine/x2201.cpp +++ b/src/devices/machine/x2201.cpp @@ -99,8 +99,8 @@ void x2201_device::nvram_default() bool x2201_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_eeprom[0], 1024 / 8, actual) && actual == 1024 / 8; + auto const [err, actual] = util::read(file, &m_eeprom[0], 1024 / 8); + return !err && (actual == 1024 / 8); } @@ -111,8 +111,8 @@ bool x2201_device::nvram_read(util::read_stream &file) bool x2201_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_eeprom[0], 1024 / 8, actual) && actual == 1024 / 8; + auto const [err, actual] = util::write(file, &m_eeprom[0], 1024 / 8); + return !err; } diff --git a/src/devices/machine/x2212.cpp b/src/devices/machine/x2212.cpp index f8c7fb906e3..b549fc76583 100644 --- a/src/devices/machine/x2212.cpp +++ b/src/devices/machine/x2212.cpp @@ -82,8 +82,8 @@ void x2212_device::nvram_default() bool x2212_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_e2prom[0], m_size_data, actual) && actual == m_size_data; + auto const [err, actual] = util::read(file, &m_e2prom[0], m_size_data); + return !err && (actual == m_size_data); } @@ -98,8 +98,8 @@ bool x2212_device::nvram_write(util::write_stream &file) if (m_auto_save) do_store(); - size_t actual; - return !file.write(&m_e2prom[0], m_size_data, actual) && actual == m_size_data; + auto const [err, actual] = util::write(file, &m_e2prom[0], m_size_data); + return !err; } diff --git a/src/devices/machine/x76f041.cpp b/src/devices/machine/x76f041.cpp index 366c4f03569..deaa79d0a69 100644 --- a/src/devices/machine/x76f041.cpp +++ b/src/devices/machine/x76f041.cpp @@ -17,6 +17,8 @@ #include "machine/x76f041.h" #include <cstdarg> +#include <tuple> + #define VERBOSE_LEVEL ( 0 ) @@ -25,7 +27,7 @@ inline void ATTR_PRINTF( 3, 4 ) x76f041_device::verboselog( int n_level, const c if( VERBOSE_LEVEL >= n_level ) { va_list v; - char buf[ 32768 ]; + char buf[32768]; va_start( v, s_fmt ); vsprintf( buf, s_fmt, v ); va_end( v ); @@ -33,11 +35,12 @@ inline void ATTR_PRINTF( 3, 4 ) x76f041_device::verboselog( int n_level, const c } } + // device type definition DEFINE_DEVICE_TYPE(X76F041, x76f041_device, "x76f041", "X76F041 Secure SerialFlash") -x76f041_device::x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) - : device_t( mconfig, X76F041, tag, owner, clock ), +x76f041_device::x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) : + device_t( mconfig, X76F041, tag, owner, clock ), device_nvram_interface(mconfig, *this), m_region(*this, DEVICE_SELF), m_cs( 0 ), @@ -169,8 +172,8 @@ uint8_t *x76f041_device::password() void x76f041_device::password_ok() { - if( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_RESET_BIT ) - m_configuration_registers[ CONFIG_RC ] = 0; + if( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_RESET_BIT ) + m_configuration_registers[CONFIG_RC] = 0; switch( m_command & 0xe0 ) { @@ -233,9 +236,9 @@ void x76f041_device::load_address() verboselog( 1, "-> address: %02x\n", m_address ); - if( ( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && - m_configuration_registers[ CONFIG_RR ] == m_configuration_registers[ CONFIG_RC ] && - ( m_configuration_registers[ CONFIG_CR ] & CR_UNAUTHORIZED_ACCESS_BITS ) == 0x80 ) + if( ( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && + m_configuration_registers[CONFIG_RR] == m_configuration_registers[CONFIG_RC] && + ( m_configuration_registers[CONFIG_CR] & CR_UNAUTHORIZED_ACCESS_BITS ) == 0x80 ) { // No commands are allowed verboselog( 1, "unauthorized access rejected\n" ); @@ -266,9 +269,9 @@ void x76f041_device::load_address() return; } - if( ( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && - m_configuration_registers[ CONFIG_RR ] == m_configuration_registers[ CONFIG_RC ] && - ( m_configuration_registers[ CONFIG_CR ] & CR_UNAUTHORIZED_ACCESS_BITS ) != 0x80 ) + if( ( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && + m_configuration_registers[CONFIG_RR] == m_configuration_registers[CONFIG_RC] && + ( m_configuration_registers[CONFIG_CR] & CR_UNAUTHORIZED_ACCESS_BITS ) != 0x80 ) { // Only configuration commands are allowed verboselog( 1, "unauthorized access rejected\n" ); @@ -278,7 +281,7 @@ void x76f041_device::load_address() return; } - int bcr = m_configuration_registers[ ( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1 ]; + int bcr = m_configuration_registers[( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1]; if( ( m_address & 0x80 ) != 0 ) { bcr >>= 4; @@ -287,7 +290,7 @@ void x76f041_device::load_address() if( ( ( m_command & 0xe0 ) == COMMAND_READ && ( bcr & BCR_Z ) != 0 && ( bcr & BCR_T ) != 0 ) || ( ( m_command & 0xe0 ) == COMMAND_WRITE && ( bcr & BCR_Z ) != 0 ) ) { - /* todo: find out when this is really checked. */ + /* TODO: find out when this is really checked. */ verboselog( 1, "command not allowed\n" ); m_state = STATE_STOP; m_sdar = 1; @@ -333,7 +336,7 @@ void x76f041_device::write_scl(int state) case STATE_RESPONSE_TO_RESET: if( m_scl != 0 && state == 0 ) { - m_sdar = ( m_response_to_reset[ m_byte ] >> m_bit ) & 1; + m_sdar = ( m_response_to_reset[m_byte] >> m_bit ) & 1; verboselog( 2, "in response to reset %d (%d/%d)\n", m_sdar, m_byte, m_bit ); m_bit++; @@ -390,7 +393,7 @@ void x76f041_device::write_scl(int state) case STATE_LOAD_COMMAND: m_command = m_shift; verboselog( 1, "-> command: %02x\n", m_command ); - /* todo: verify command is valid? */ + /* TODO: verify command is valid? */ m_state = STATE_LOAD_ADDRESS; break; @@ -400,7 +403,7 @@ void x76f041_device::write_scl(int state) case STATE_LOAD_PASSWORD: verboselog( 1, "-> password: %02x\n", m_shift ); - m_write_buffer[ m_byte++ ] = m_shift; + m_write_buffer[m_byte++] = m_shift; if( m_byte == sizeof( m_write_buffer ) ) { @@ -412,8 +415,8 @@ void x76f041_device::write_scl(int state) m_is_password_accepted = memcmp( password(), m_write_buffer, sizeof( m_write_buffer ) ) == 0; if( !m_is_password_accepted ) { - if( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_ENABLE_BIT ) - m_configuration_registers[ CONFIG_RC ]++; + if( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_ENABLE_BIT ) + m_configuration_registers[CONFIG_RC]++; } } break; @@ -421,10 +424,10 @@ void x76f041_device::write_scl(int state) case STATE_VERIFY_PASSWORD: verboselog( 1, "-> verify password: %02x\n", m_shift ); - /* todo: this should probably be handled as a command */ + /* TODO: this should probably be handled as a command */ if( m_shift == 0xc0 ) { - /* todo: this should take 10ms before it returns ok. */ + /* TODO: this should take 10ms before it returns ok. */ if( m_is_password_accepted ) { password_ok(); @@ -438,11 +441,11 @@ void x76f041_device::write_scl(int state) case STATE_WRITE_DATA: verboselog( 2, "-> data: %02x\n", m_shift ); - m_write_buffer[ m_byte++ ] = m_shift; + m_write_buffer[m_byte++] = m_shift; if( m_byte == sizeof( m_write_buffer ) ) { - int bcr = m_configuration_registers[ ( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1 ]; + int bcr = m_configuration_registers[( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1]; if( ( m_address & 0x80 ) != 0 ) { bcr >>= 4; @@ -456,7 +459,7 @@ void x76f041_device::write_scl(int state) for( m_byte = 0; m_byte < sizeof( m_write_buffer ); m_byte++ ) { int offset = data_offset(); - if( m_write_buffer[ m_byte ] < m_data[ offset ] ) + if( m_write_buffer[m_byte] < m_data[offset] ) { verboselog( 1, "tried to unset bits while in program only mode\n" ); is_unauthorized_write = true; @@ -475,8 +478,8 @@ void x76f041_device::write_scl(int state) for( m_byte = 0; m_byte < sizeof( m_write_buffer ); m_byte++ ) { int offset = data_offset(); - verboselog( 1, "-> data[ %03x ]: %02x\n", offset, m_write_buffer[ m_byte ] ); - m_data[ offset ] = m_write_buffer[ m_byte ]; + verboselog( 1, "-> data[%03x]: %02x\n", offset, m_write_buffer[m_byte] ); + m_data[offset] = m_write_buffer[m_byte]; } m_byte = 0; @@ -489,14 +492,14 @@ void x76f041_device::write_scl(int state) // Unlike normal writes, configuration writes aren't required to be exactly 8 bytes // TODO: Store data in a temporary buffer until the proper end of the command before writing verboselog( 2, "-> data: %02x\n", m_shift ); - m_data[ data_offset() ] = m_shift; + m_data[data_offset()] = m_shift; m_byte++; break; case STATE_WRITE_CONFIGURATION_REGISTERS: - verboselog( 1, "-> configuration register[ %d ]: %02x\n", m_byte, m_shift ); - /* todo: write after all bytes received? */ - m_configuration_registers[ m_byte++ ] = m_shift; + verboselog( 1, "-> configuration register[%d]: %02x\n", m_byte, m_shift ); + /* TODO: write after all bytes received? */ + m_configuration_registers[m_byte++] = m_shift; if( m_byte == sizeof( m_configuration_registers ) ) { @@ -505,13 +508,13 @@ void x76f041_device::write_scl(int state) break; case STATE_PROGRAM_WRITE_PASSWORD: - verboselog( 1, "-> program write password[ %d ]: %02x\n", m_byte, m_shift ); - m_password_temp[ m_byte++ ] = m_shift; + verboselog( 1, "-> program write password[%d]: %02x\n", m_byte, m_shift ); + m_password_temp[m_byte++] = m_shift; if( m_byte == sizeof( m_password_temp ) ) { // Read in the password twice and if the two copies match then write it to the password field - if( memcmp( &m_password_temp[ 0 ], &m_password_temp[ 8 ], sizeof( m_write_password ) ) == 0 ) + if( memcmp( &m_password_temp[0], &m_password_temp[8], sizeof( m_write_password ) ) == 0 ) { std::copy_n( std::begin( m_password_temp ), sizeof( m_write_password ), std::begin ( m_write_password ) ); } @@ -526,12 +529,12 @@ void x76f041_device::write_scl(int state) break; case STATE_PROGRAM_READ_PASSWORD: - verboselog( 1, "-> program read password[ %d ]: %02x\n", m_byte, m_shift ); - m_password_temp[ m_byte++ ] = m_shift; + verboselog( 1, "-> program read password[%d]: %02x\n", m_byte, m_shift ); + m_password_temp[m_byte++] = m_shift; if( m_byte == sizeof( m_password_temp ) ) { - if( memcmp( &m_password_temp[ 0 ], &m_password_temp[ 8 ], sizeof( m_read_password ) ) == 0 ) + if( memcmp( &m_password_temp[0], &m_password_temp[8], sizeof( m_read_password ) ) == 0 ) { std::copy_n( std::begin( m_password_temp ), sizeof( m_read_password ), std::begin ( m_read_password ) ); } @@ -546,12 +549,12 @@ void x76f041_device::write_scl(int state) break; case STATE_PROGRAM_CONFIGURATION_PASSWORD: - verboselog( 1, "-> program configuration password[ %d ]: %02x\n", m_byte, m_shift ); - m_password_temp[ m_byte++ ] = m_shift; + verboselog( 1, "-> program configuration password[%d]: %02x\n", m_byte, m_shift ); + m_password_temp[m_byte++] = m_shift; if( m_byte == sizeof( m_password_temp ) ) { - if( memcmp( &m_password_temp[ 0 ], &m_password_temp[ 8 ], sizeof( m_configuration_password ) ) == 0 ) + if( memcmp( &m_password_temp[0], &m_password_temp[8], sizeof( m_configuration_password ) ) == 0 ) { std::copy_n( std::begin( m_password_temp ), sizeof( m_configuration_password ), std::begin ( m_configuration_password ) ); } @@ -611,14 +614,14 @@ void x76f041_device::write_scl(int state) { case STATE_READ_DATA: offset = data_offset(); - m_shift = m_data[ offset ]; - verboselog( 1, "<- data[ %03x ]: %02x\n", offset, m_shift ); + m_shift = m_data[offset]; + verboselog( 1, "<- data[%03x]: %02x\n", offset, m_shift ); break; case STATE_READ_CONFIGURATION_REGISTERS: offset = m_byte & 7; - m_shift = m_configuration_registers[ offset ]; - verboselog( 1, "<- configuration register[ %d ]: %02x\n", offset, m_shift ); + m_shift = m_configuration_registers[offset]; + verboselog( 1, "<- configuration register[%d]: %02x\n", offset, m_shift ); break; } } @@ -676,7 +679,7 @@ void x76f041_device::write_sda(int state) break; case STATE_LOAD_PASSWORD: - /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */ + /* TODO: this will be the 0xc0 command, but it's not handled as a command yet. */ verboselog( 1, "goto start\n" ); break; @@ -751,24 +754,54 @@ void x76f041_device::nvram_default() bool x76f041_device::nvram_read( util::read_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.read( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.read( m_write_password, sizeof( m_write_password ), actual ) && actual == sizeof( m_write_password ); - result = result && !file.read( m_read_password, sizeof( m_read_password ), actual ) && actual == sizeof( m_read_password ); - result = result && !file.read( m_configuration_password, sizeof( m_configuration_password ), actual ) && actual == sizeof( m_configuration_password ); - result = result && !file.read( m_configuration_registers, sizeof( m_configuration_registers ), actual ) && actual == sizeof( m_configuration_registers ); - result = result && !file.read( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + + std::tie( err, actual ) = read( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if( err || ( sizeof( m_response_to_reset ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_write_password, sizeof( m_write_password ) ); + if( err || ( sizeof( m_write_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_read_password, sizeof( m_read_password ) ); + if( err || ( sizeof( m_read_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_configuration_password, sizeof( m_configuration_password ) ); + if( err || ( sizeof( m_configuration_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_configuration_registers, sizeof( m_configuration_registers ) ); + if( err || ( sizeof( m_configuration_registers ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_data, sizeof( m_data ) ); + if( err || ( sizeof( m_data ) != actual ) ) + return false; + + return true; } bool x76f041_device::nvram_write( util::write_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.write( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.write( m_write_password, sizeof( m_write_password ), actual ) && actual == sizeof( m_write_password ); - result = result && !file.write( m_read_password, sizeof( m_read_password ), actual ) && actual == sizeof( m_read_password ); - result = result && !file.write( m_configuration_password, sizeof( m_configuration_password ), actual ) && actual == sizeof( m_configuration_password ); - result = result && !file.write( m_configuration_registers, sizeof( m_configuration_registers ), actual ) && actual == sizeof( m_configuration_registers ); - result = result && !file.write( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + + std::tie( err, actual ) = write( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_write_password, sizeof( m_write_password ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_read_password, sizeof( m_read_password ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_configuration_password, sizeof( m_configuration_password ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_configuration_registers, sizeof( m_configuration_registers ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_data, sizeof( m_data ) ); + if (err) + return false; + + return true; } diff --git a/src/devices/machine/x76f041.h b/src/devices/machine/x76f041.h index 0948de185af..cb28bccc54b 100644 --- a/src/devices/machine/x76f041.h +++ b/src/devices/machine/x76f041.h @@ -18,7 +18,7 @@ class x76f041_device : public device_t, { public: // construction/destruction - x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + x76f041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); void write_cs(int state); void write_rst(int state); @@ -33,11 +33,11 @@ protected: // device_nvram_interface overrides virtual void nvram_default() override; - virtual bool nvram_read( util::read_stream &file ) override; - virtual bool nvram_write( util::write_stream &file ) override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; private: - inline void ATTR_PRINTF( 3, 4 ) verboselog( int n_level, const char *s_fmt, ... ); + inline void ATTR_PRINTF(3, 4) verboselog(int n_level, const char *s_fmt, ...); uint8_t *password(); void password_ok(); void load_address(); @@ -134,14 +134,14 @@ private: int m_command; int m_address; bool m_is_password_accepted; - uint8_t m_write_buffer[ 8 ]; - uint8_t m_response_to_reset[ 4 ]; - uint8_t m_write_password[ 8 ]; - uint8_t m_read_password[ 8 ]; - uint8_t m_configuration_password[ 8 ]; - uint8_t m_configuration_registers[ 8 ]; - uint8_t m_data[ 512 ]; - uint8_t m_password_temp[ 16 ]; + uint8_t m_write_buffer[8]; + uint8_t m_response_to_reset[4]; + uint8_t m_write_password[8]; + uint8_t m_read_password[8]; + uint8_t m_configuration_password[8]; + uint8_t m_configuration_registers[8]; + uint8_t m_data[512]; + uint8_t m_password_temp[16]; }; diff --git a/src/devices/machine/x76f100.cpp b/src/devices/machine/x76f100.cpp index 4385c5a4b0f..d4213a53200 100644 --- a/src/devices/machine/x76f100.cpp +++ b/src/devices/machine/x76f100.cpp @@ -15,6 +15,8 @@ #include "machine/x76f100.h" #include <cstdarg> +#include <tuple> + #define VERBOSE_LEVEL ( 0 ) @@ -23,7 +25,7 @@ inline void ATTR_PRINTF( 3, 4 ) x76f100_device::verboselog( int n_level, const c if( VERBOSE_LEVEL >= n_level ) { va_list v; - char buf[ 32768 ]; + char buf[32768]; va_start( v, s_fmt ); vsprintf( buf, s_fmt, v ); va_end( v ); @@ -31,11 +33,13 @@ inline void ATTR_PRINTF( 3, 4 ) x76f100_device::verboselog( int n_level, const c } } + // device type definition DEFINE_DEVICE_TYPE(X76F100, x76f100_device, "x76f100", "X76F100 Secure SerialFlash") -x76f100_device::x76f100_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) - : device_t( mconfig, X76F100, tag, owner, clock ), + +x76f100_device::x76f100_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) : + device_t( mconfig, X76F100, tag, owner, clock ), device_nvram_interface(mconfig, *this), m_region(*this, DEVICE_SELF), m_cs( 0 ), @@ -49,7 +53,7 @@ x76f100_device::x76f100_device( const machine_config &mconfig, const char *tag, m_byte( 0 ), m_command( 0 ), m_password_retry_counter( 0 ), - m_is_password_accepted ( false ) + m_is_password_accepted( false ) { } @@ -197,7 +201,7 @@ void x76f100_device::write_scl(int state) { if( m_bit == 0 ) { - m_shift = m_response_to_reset[ m_byte ]; + m_shift = m_response_to_reset[m_byte]; verboselog( 1, "<- response_to_reset[%d]: %02x\n", m_byte, m_shift ); } @@ -248,13 +252,13 @@ void x76f100_device::write_scl(int state) case STATE_LOAD_COMMAND: m_command = m_shift; verboselog( 1, "-> command: %02x\n", m_command ); - /* todo: verify command is valid? */ + /* TODO: verify command is valid? */ m_state = STATE_LOAD_PASSWORD; break; case STATE_LOAD_PASSWORD: verboselog( 1, "-> password: %02x\n", m_shift ); - m_write_buffer[ m_byte++ ] = m_shift; + m_write_buffer[m_byte++] = m_shift; if( m_byte == sizeof( m_write_buffer ) ) { @@ -284,10 +288,10 @@ void x76f100_device::write_scl(int state) case STATE_VERIFY_PASSWORD: verboselog( 1, "-> verify password: %02x\n", m_shift ); - /* todo: this should probably be handled as a command */ + /* TODO: this should probably be handled as a command */ if( m_shift == COMMAND_ACK_PASSWORD ) { - /* todo: this should take 10ms before it returns ok. */ + /* TODO: this should take 10ms before it returns ok. */ if( m_is_password_accepted ) { password_ok(); @@ -301,7 +305,7 @@ void x76f100_device::write_scl(int state) case STATE_WRITE_DATA: verboselog( 2, "-> data: %02x\n", m_shift ); - m_write_buffer[ m_byte++ ] = m_shift; + m_write_buffer[m_byte++] = m_shift; if( m_byte == sizeof( m_write_buffer ) ) { @@ -321,8 +325,8 @@ void x76f100_device::write_scl(int state) if( offset != -1 ) { - verboselog( 1, "-> data[ %03x ]: %02x\n", offset, m_write_buffer[ m_byte ] ); - m_data[ offset ] = m_write_buffer[ m_byte ]; + verboselog( 1, "-> data[%03x]: %02x\n", offset, m_write_buffer[m_byte] ); + m_data[offset] = m_write_buffer[m_byte]; } else { @@ -363,8 +367,8 @@ void x76f100_device::write_scl(int state) if( offset != -1 ) { - m_shift = m_data[ offset ]; - verboselog( 1, "<- data[ %02x ]: %02x\n", offset, m_shift ); + m_shift = m_data[offset]; + verboselog( 1, "<- data[%02x]: %02x\n", offset, m_shift ); } else { @@ -429,7 +433,7 @@ void x76f100_device::write_sda(int state) break; case STATE_LOAD_PASSWORD: - /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */ + /* TODO: this will be the 0xc0 command, but it's not handled as a command yet. */ verboselog( 1, "goto start\n" ); break; @@ -468,10 +472,10 @@ int x76f100_device::read_sda() void x76f100_device::nvram_default() { - m_response_to_reset[ 0 ] = 0x19; - m_response_to_reset[ 1 ] = 0x00; - m_response_to_reset[ 2 ] = 0xaa; - m_response_to_reset[ 3 ] = 0x55, + m_response_to_reset[0] = 0x19; + m_response_to_reset[1] = 0x00; + m_response_to_reset[2] = 0xaa; + m_response_to_reset[3] = 0x55, memset( m_write_password, 0, sizeof( m_write_password ) ); memset( m_read_password, 0, sizeof( m_read_password ) ); @@ -500,20 +504,42 @@ void x76f100_device::nvram_default() bool x76f100_device::nvram_read( util::read_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.read( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.read( m_write_password, sizeof( m_write_password ), actual ) && actual == sizeof( m_write_password ); - result = result && !file.read( m_read_password, sizeof( m_read_password ), actual ) && actual == sizeof( m_read_password ); - result = result && !file.read( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + + std::tie( err, actual ) = read( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if( err || ( sizeof( m_response_to_reset ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_write_password, sizeof( m_write_password ) ); + if( err || ( sizeof( m_write_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_read_password, sizeof( m_read_password ) ); + if( err || ( sizeof( m_read_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_data, sizeof( m_data ) ); + if( err || ( sizeof( m_data ) != actual ) ) + return false; + + return true; } bool x76f100_device::nvram_write( util::write_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.write( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.write( m_write_password, sizeof( m_write_password ), actual ) && actual == sizeof( m_write_password ); - result = result && !file.write( m_read_password, sizeof( m_read_password ), actual ) && actual == sizeof( m_read_password ); - result = result && !file.write( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + + std::tie( err, actual ) = write( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if ( err ) + return false; + std::tie( err, actual ) = write( file, m_write_password, sizeof( m_write_password ) ); + if ( err ) + return false; + std::tie( err, actual ) = write( file, m_read_password, sizeof( m_read_password ) ); + if ( err ) + return false; + std::tie( err, actual ) = write( file, m_data, sizeof( m_data ) ); + if ( err ) + return false; + + return true; } diff --git a/src/devices/machine/x76f100.h b/src/devices/machine/x76f100.h index 9ede683723f..a323ff40fa6 100644 --- a/src/devices/machine/x76f100.h +++ b/src/devices/machine/x76f100.h @@ -17,7 +17,7 @@ class x76f100_device : public device_t, public device_nvram_interface { public: // construction/destruction - x76f100_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + x76f100_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); void write_cs(int state); void write_rst(int state); @@ -26,14 +26,14 @@ public: int read_sda(); protected: - // device-level overrides + // device_t implementation virtual void device_start() override; virtual void device_reset() override; - // device_nvram_interface overrides + // device_nvram_interface implementation virtual void nvram_default() override; - virtual bool nvram_read( util::read_stream &file ) override; - virtual bool nvram_write( util::write_stream &file ) override; + virtual bool nvram_read(util::read_stream &file) override; + virtual bool nvram_write(util::write_stream &file) override; private: inline void verboselog(int n_level, const char *s_fmt, ...) ATTR_PRINTF(3,4); @@ -77,11 +77,11 @@ private: int m_command; int m_password_retry_counter; bool m_is_password_accepted; - uint8_t m_write_buffer[ 8 ]; - uint8_t m_response_to_reset[ 4 ]; - uint8_t m_write_password[ 8 ]; - uint8_t m_read_password[ 8 ]; - uint8_t m_data[ 112 ]; + uint8_t m_write_buffer[8]; + uint8_t m_response_to_reset[4]; + uint8_t m_write_password[8]; + uint8_t m_read_password[8]; + uint8_t m_data[112]; }; // device type definition diff --git a/src/devices/video/hlcd0515.cpp b/src/devices/video/hlcd0515.cpp index 0984c1e218d..aa9066fc5ec 100644 --- a/src/devices/video/hlcd0515.cpp +++ b/src/devices/video/hlcd0515.cpp @@ -16,7 +16,9 @@ TODO: */ #include "emu.h" -#include "video/hlcd0515.h" +#include "hlcd0515.h" + +#include <tuple> DEFINE_DEVICE_TYPE(HLCD0515, hlcd0515_device, "hlcd0515", "Hughes HLCD 0515 LCD Driver") @@ -110,6 +112,7 @@ void hlcd0515_device::device_start() bool hlcd0515_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; // misc internal registers @@ -121,13 +124,16 @@ bool hlcd0515_device::nvram_write(util::write_stream &file) buf[4] = m_rowout; buf[5] = m_rowsel; - if (file.write(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) + std::tie(err, actual) = write(file, &buf, sizeof(buf)); + if (err) return false; // shift register and RAM - if (file.write(&m_buffer, sizeof(m_buffer), actual) || (sizeof(m_buffer) != actual)) + std::tie(err, actual) = write(file, &m_buffer, sizeof(m_buffer)); + if (err) return false; - if (file.write(&m_ram, sizeof(m_ram), actual) || (sizeof(m_ram) != actual)) + std::tie(err, actual) = write(file, &m_ram, sizeof(m_ram)); + if (err) return false; return true; @@ -135,11 +141,13 @@ bool hlcd0515_device::nvram_write(util::write_stream &file) bool hlcd0515_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; // misc internal registers u8 buf[6]; - if (file.read(&buf, sizeof(buf), actual) || (sizeof(buf) != actual)) + std::tie(err, actual) = read(file, &buf, sizeof(buf)); + if (err || (sizeof(buf) != actual)) return false; m_count = buf[0]; @@ -150,9 +158,11 @@ bool hlcd0515_device::nvram_read(util::read_stream &file) m_rowsel = buf[5] & 7; // shift register and RAM - if (file.read(&m_buffer, sizeof(m_buffer), actual) || (sizeof(m_buffer) != actual)) + std::tie(err, actual) = read(file, &m_buffer, sizeof(m_buffer)); + if (err || (sizeof(m_buffer) != actual)) return false; - if (file.read(&m_ram, sizeof(m_ram), actual) || (sizeof(m_ram) != actual)) + std::tie(err, actual) = read(file, &m_ram, sizeof(m_ram)); + if (err || (sizeof(m_ram) != actual)) return false; return true; diff --git a/src/devices/video/lc7580.cpp b/src/devices/video/lc7580.cpp index f97ab2161fd..81b705769f9 100644 --- a/src/devices/video/lc7580.cpp +++ b/src/devices/video/lc7580.cpp @@ -16,6 +16,8 @@ TODO: #include "emu.h" #include "video/lc7580.h" +#include <tuple> + DEFINE_DEVICE_TYPE(LC7580, lc7580_device, "lc7580", "Sanyo LC7580 LCD Driver") DEFINE_DEVICE_TYPE(LC7582, lc7582_device, "lc7582", "Sanyo LC7582 LCD Driver") @@ -72,11 +74,14 @@ void lc7580_device::device_start() bool lc7580_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - if (file.write(&m_shift, sizeof(m_shift), actual) || (sizeof(m_shift) != actual)) + std::tie(err, actual) = write(file, &m_shift, sizeof(m_shift)); + if (err) return false; - if (file.write(&m_latch, sizeof(m_latch), actual) || (sizeof(m_latch) != actual)) + std::tie(err, actual) = write(file, &m_latch, sizeof(m_latch)); + if (err) return false; return true; @@ -84,11 +89,14 @@ bool lc7580_device::nvram_write(util::write_stream &file) bool lc7580_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - if (file.read(&m_shift, sizeof(m_shift), actual) || (sizeof(m_shift) != actual)) + std::tie(err, actual) = read(file, &m_shift, sizeof(m_shift)); + if (err || (sizeof(m_shift) != actual)) return false; - if (file.read(&m_latch, sizeof(m_latch), actual) || (sizeof(m_latch) != actual)) + std::tie(err, actual) = read(file, &m_latch, sizeof(m_latch)); + if (err || (sizeof(m_latch) != actual)) return false; return true; diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 900a4410a05..aa9c991c955 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -148,15 +148,13 @@ public: u32 fread(void *buffer, u32 length) { check_for_file(); - size_t actual; - m_file->read(buffer, length, actual); + auto const [err, actual] = read(*m_file, buffer, length); return actual; } u32 fwrite(const void *buffer, u32 length) { check_for_file(); - size_t actual; - m_file->write(buffer, length, actual); + auto const [err, actual] = write(*m_file, buffer, length); return actual; } std::error_condition fseek(s64 offset, int whence) @@ -172,10 +170,6 @@ public: return result; } - // allocate and read into buffers - u32 fread(std::unique_ptr<u8 []> &ptr, u32 length) { ptr = std::make_unique<u8 []>(length); return fread(ptr.get(), length); } - u32 fread(std::unique_ptr<u8 []> &ptr, u32 length, offs_t offset) { ptr = std::make_unique<u8 []>(length); return fread(ptr.get() + offset, length - offset); } - // access to software list item information const software_info *software_entry() const noexcept; const software_part *part_entry() const noexcept { return m_software_part_ptr; } diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp index 23426cb61fa..c0341b93368 100644 --- a/src/emu/fileio.cpp +++ b/src/emu/fileio.cpp @@ -14,6 +14,8 @@ #include "util/path.h" #include "util/unzip.h" +#include <tuple> + //#define VERBOSE 1 #define LOG_OUTPUT_FUNC osd_printf_verbose #include "logmacro.h" @@ -531,9 +533,10 @@ u32 emu_file::read(void *buffer, u32 length) return 0; // read the data if we can + std::error_condition err; size_t actual = 0; if (m_file) - m_file->read(buffer, length, actual); + std::tie(err, actual) = util::read(*m_file, buffer, length); return actual; } @@ -601,9 +604,10 @@ u32 emu_file::write(const void *buffer, u32 length) { // FIXME: need better interface to report errors // write the data if we can + std::error_condition err; size_t actual = 0; if (m_file) - m_file->write(buffer, length, actual); + std::tie(err, actual) = util::write(*m_file, buffer, length); return actual; } diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index 77e42c100c1..aed29b6324f 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -2946,9 +2946,13 @@ Type ioport_manager::playback_read(Type &result) return result = Type(0); // read the value; if we fail, end playback - size_t read; - m_playback_stream->read(&result, sizeof(result), read); - if (sizeof(result) != read) + auto const [err, actual] = read(*m_playback_stream, &result, sizeof(result)); + if (err) + { + playback_end("Read error"); + return result = Type(0); + } + else if (sizeof(result) != actual) { playback_end("End of file"); return result = Type(0); @@ -3132,9 +3136,8 @@ void ioport_manager::record_write(Type value) 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"); + if (write(*m_record_stream, &value, sizeof(value)).first) + record_end("Write error"); } template<> diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 8251eabb2ec..617b1bf3756 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -2119,11 +2119,10 @@ bool render_target::load_layout_file(const char *dirname, const internal_layout size_t decompressed = 0; do { - size_t actual; - std::error_condition const err = inflater->read( + auto const [err, actual] = read( + *inflater, &tempout[decompressed], - layout_data.decompressed_size - decompressed, - actual); + layout_data.decompressed_size - decompressed); decompressed += actual; if (err) { diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp index 171a8f6d7f5..2712a5121a7 100644 --- a/src/emu/rendfont.cpp +++ b/src/emu/rendfont.cpp @@ -129,13 +129,12 @@ public: bool read(util::read_stream &f) { - std::size_t actual(0); - return !f.read(m_data, sizeof(m_data), actual) && actual == sizeof(m_data); + auto const [err, actual] = util::read(f, m_data, sizeof(m_data)); + return !err && (actual == sizeof(m_data)); } bool write(util::write_stream &f) { - std::size_t actual(0); - return !f.write(m_data, sizeof(m_data), actual) && actual == sizeof(m_data); + return !util::write(f, m_data, sizeof(m_data)).first; } bool check_magic() const @@ -1346,6 +1345,11 @@ bool render_font::load_cached(util::random_read &file, u64 length, u32 hash) // now read the rest of the data u64 const remaining(filesize - filepos); + if (remaining > std::numeric_limits<std::size_t>::max()) + { + osd_printf_error("render_font::load_cached: BDC file is too large to read into memory\n"); + return false; + } try { m_rawdata.resize(std::size_t(remaining)); @@ -1353,18 +1357,14 @@ bool render_font::load_cached(util::random_read &file, u64 length, u32 hash) catch (...) { osd_printf_error("render_font::load_cached: allocation error\n"); + return false; } - for (u64 bytes_read = 0; remaining > bytes_read; ) + auto const [err, bytes] = read(file, &m_rawdata[0], remaining); + if (err || (bytes != remaining)) { - u32 const chunk((std::min)(u64(std::numeric_limits<u32>::max()), remaining)); - std::size_t bytes(0); - if (file.read(&m_rawdata[bytes_read], chunk, bytes) || bytes != chunk) - { - osd_printf_error("render_font::load_cached: error reading BDC data\n"); - m_rawdata.clear(); - return false; - } - bytes_read += chunk; + osd_printf_error("render_font::load_cached: error reading BDC data\n"); + m_rawdata.clear(); + return false; } // extract the data from the data @@ -1446,11 +1446,11 @@ bool render_font::save_cached(util::random_write &file, u64 length, u32 hash) hdr.set_y_offset(m_yoffs); hdr.set_default_character(m_defchar); if (!hdr.write(file)) - throw emu_fatalerror("Error writing cached file"); + throw emu_fatalerror("Error writing cached font file"); } u64 table_offs; if (file.tell(table_offs)) - throw emu_fatalerror("Error writing cached file"); + throw emu_fatalerror("Error writing cached font file"); // allocate an array to hold the character data std::vector<u8> chartable(std::size_t(numchars) * bdc_table_entry::size(), 0); @@ -1459,9 +1459,8 @@ bool render_font::save_cached(util::random_write &file, u64 length, u32 hash) std::vector<u8> tempbuffer(65536); // write the empty table to the beginning of the file - std::size_t bytes_written(0); - if (file.write(&chartable[0], chartable.size(), bytes_written) || bytes_written != chartable.size()) - throw emu_fatalerror("Error writing cached file"); + if (write(file, &chartable[0], chartable.size()).first) + throw emu_fatalerror("Error writing cached font file"); // loop over all characters bdc_table_entry table_entry(chartable.empty() ? nullptr : &chartable[0]); @@ -1503,8 +1502,8 @@ bool render_font::save_cached(util::random_write &file, u64 length, u32 hash) *dest++ = accum; // write the data - if (file.write(&tempbuffer[0], dest - &tempbuffer[0], bytes_written) || bytes_written != dest - &tempbuffer[0]) - throw emu_fatalerror("Error writing cached file"); + if (write(file, &tempbuffer[0], dest - &tempbuffer[0]).first) + throw emu_fatalerror("Error writing cached font file"); // free the bitmap and texture m_manager.texture_free(gl.texture); @@ -1529,15 +1528,8 @@ bool render_font::save_cached(util::random_write &file, u64 length, u32 hash) LOG("render_font::save_cached: writing character table\n"); if (file.seek(table_offs, SEEK_SET)) return false; - u8 const *bytes(&chartable[0]); - for (u64 remaining = chartable.size(); remaining; ) - { - u32 const chunk((std::min<u64>)(std::numeric_limits<u32>::max(), remaining)); - if (file.write(bytes, chunk, bytes_written) || chunk != bytes_written) - throw emu_fatalerror("Error writing cached file"); - bytes += chunk; - remaining -= chunk; - } + if (write(file, &chartable[0], chartable.size()).first) + throw emu_fatalerror("Error writing cached font file"); } // no trouble? @@ -1588,6 +1580,11 @@ void render_font::render_font_command_glyph() // now read the rest of the data u64 const remaining(filesize - filepos); + if (remaining > std::numeric_limits<std::size_t>::max()) + { + osd_printf_error("render_font::render_font_command_glyph: BDC file is too large to read into memory\n"); + return; + } try { m_rawdata_cmd.resize(std::size_t(remaining)); @@ -1595,18 +1592,14 @@ void render_font::render_font_command_glyph() catch (...) { osd_printf_error("render_font::render_font_command_glyph: allocation error\n"); + return; } - for (u64 bytes_read = 0; remaining > bytes_read; ) + auto const [err, bytes] = read(*file, &m_rawdata_cmd[0], remaining); + if (err || (bytes != remaining)) { - u32 const chunk((std::min)(u64(std::numeric_limits<u32>::max()), remaining)); - std::size_t bytes(0); - if (file->read(&m_rawdata_cmd[bytes_read], chunk, bytes) || bytes != chunk) - { - osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n"); - m_rawdata_cmd.clear(); - return; - } - bytes_read += chunk; + osd_printf_error("render_font::render_font_command_glyph: error reading BDC data\n"); + m_rawdata_cmd.clear(); + return; } // extract the data from the data diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index a447fffec64..76d13250bfa 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -2069,17 +2069,12 @@ private: return; } svgbuf[len] = '\0'; - for (char *ptr = svgbuf.get(); len; ) + size_t actual; + std::tie(filerr, actual) = read(file, svgbuf.get(), len); + if (filerr || (actual < len)) { - size_t read; - filerr = file.read(ptr, size_t(len), read); - if (filerr || !read) - { - osd_printf_warning("Error reading component image '%s'\n", m_imagefile); - return; - } - ptr += read; - len -= read; + osd_printf_warning("Error reading component image '%s'\n", m_imagefile); + return; } parse_svg(svgbuf.get()); } diff --git a/src/emu/rendutil.cpp b/src/emu/rendutil.cpp index db7220351b8..5d09061ab70 100644 --- a/src/emu/rendutil.cpp +++ b/src/emu/rendutil.cpp @@ -41,8 +41,7 @@ private: { jpeg_corefile_source &src = *static_cast<jpeg_corefile_source *>(cinfo->src); - size_t nbytes; - src.infile->read(src.buffer, INPUT_BUF_SIZE, nbytes); // TODO: check error return + auto [err, nbytes] = read(*src.infile, src.buffer, INPUT_BUF_SIZE); // TODO: check error return if (0 >= nbytes) { diff --git a/src/emu/save.cpp b/src/emu/save.cpp index d2f1f0e328e..6f49e6b2b06 100644 --- a/src/emu/save.cpp +++ b/src/emu/save.cpp @@ -216,8 +216,8 @@ save_error save_manager::check_file(running_machine &machine, util::core_file &f // seek to the beginning and read the header file.seek(0, SEEK_SET); u8 header[HEADER_SIZE]; - size_t actual(0); - if (file.read(header, sizeof(header), actual) || actual != sizeof(header)) + auto const [err, actual] = read(file, header, sizeof(header)); + if (err || (actual != sizeof(header))) { if (errormsg != nullptr) (*errormsg)("Could not read %s save file header", emulator_info::get_appname()); @@ -264,9 +264,8 @@ save_error save_manager::write_file(util::core_file &file) [] (size_t total_size) { return true; }, [&writer] (const void *data, size_t size) { - size_t written; - std::error_condition filerr = writer->write(data, size, written); - return !filerr && (size == written); + auto const [filerr, written] = write(*writer, data, size); + return !filerr; }, [&file, &writer] () { @@ -297,9 +296,8 @@ save_error save_manager::read_file(util::core_file &file) [] (size_t total_size) { return true; }, [&reader] (void *data, size_t size) { - std::size_t read; - std::error_condition filerr = reader->read(data, size, read); - return !filerr && (read == size); + auto const [filerr, actual] = read(*reader, data, size); + return !filerr && (actual == size); }, [&file, &reader] () { diff --git a/src/emu/softlist.cpp b/src/emu/softlist.cpp index 4892a5ca5d8..c6bb7161be3 100644 --- a/src/emu/softlist.cpp +++ b/src/emu/softlist.cpp @@ -286,8 +286,7 @@ softlist_parser::softlist_parser( char buffer[1024]; for (bool done = false; !done; ) { - size_t length; - file.read(buffer, sizeof(buffer), length); // TODO: better error handling + auto const [err, length] = read(file, buffer, sizeof(buffer)); // TODO: better error handling if (!length) done = true; if (XML_Parse(m_parser, buffer, length, done) == XML_STATUS_ERROR) diff --git a/src/frontend/mame/ui/icorender.cpp b/src/frontend/mame/ui/icorender.cpp index f76b80e2c5a..7b7a58fa923 100644 --- a/src/frontend/mame/ui/icorender.cpp +++ b/src/frontend/mame/ui/icorender.cpp @@ -27,6 +27,7 @@ #include <cassert> #include <cstdint> #include <cstring> +#include <tuple> // need to set LOG_OUTPUT_FUNC or LOG_OUTPUT_STREAM because there's no logerror outside devices #define LOG_OUTPUT_FUNC osd_printf_verbose @@ -182,7 +183,7 @@ bool load_ico_image(util::random_read &fp, unsigned count, unsigned index, bitma icon_dir_entry_t dir; err = fp.seek(sizeof(icon_dir_t) + (sizeof(icon_dir_entry_t) * index), SEEK_SET); if (!err) - err = fp.read(&dir, sizeof(dir), actual); + std::tie(err, actual) = read(fp, &dir, sizeof(dir)); if (err || (sizeof(dir) != actual)) { LOG("Failed to read ICO file directory entry %u\n", index); @@ -215,7 +216,7 @@ int images_in_ico(util::random_read &fp) icon_dir_t header; err = fp.seek(0, SEEK_SET); if (!err) - err = fp.read(&header, sizeof(header), actual); + std::tie(err, actual) = read(fp, &header, sizeof(header)); if (err || (sizeof(header) != actual)) { LOG("Failed to read ICO file header\n"); @@ -278,54 +279,66 @@ void render_load_ico_highest_detail(util::random_read &fp, bitmap_argb32 &bitmap { // read and check the icon file header - logs a message on error int const count(images_in_ico(fp)); - if (0 <= count) + if (0 > count) + { + bitmap.reset(); + return; + } + + // now load all the directory entries + size_t const dir_bytes(sizeof(icon_dir_entry_t) * count); + std::unique_ptr<icon_dir_entry_t []> dir(new (std::nothrow) icon_dir_entry_t [count]); + std::unique_ptr<unsigned []> index(new (std::nothrow) unsigned [count]); + if (count) { - // now load all the directory entries - size_t const dir_bytes(sizeof(icon_dir_entry_t) * count); - std::unique_ptr<icon_dir_entry_t []> dir(new (std::nothrow) icon_dir_entry_t [count]); - std::unique_ptr<unsigned []> index(new (std::nothrow) unsigned [count]); - size_t actual; - if (count && (!dir || !index || fp.read(dir.get(), dir_bytes, actual) || (dir_bytes != actual))) + if (!dir || !index) { - LOG("Failed to read ICO file directory entries\n"); + LOG("Failed to allocate memory for ICO file directory entries\n"); + bitmap.reset(); + return; } - else + auto const [err, actual] = read(fp, dir.get(), dir_bytes); + if (err || (dir_bytes != actual)) { - // byteswap and sort by (pixels, depth) - for (int i = 0; count > i; ++i) - { - dir[i].byteswap(); - index[i] = i; - } - std::stable_sort( - index.get(), - index.get() + count, - [&dir] (unsigned x, unsigned y) - { - unsigned const x_pixels(dir[x].get_width() * dir[x].get_height()); - unsigned const y_pixels(dir[y].get_width() * dir[y].get_height()); - if (x_pixels > y_pixels) - return true; - else if (x_pixels < y_pixels) - return false; - else - return dir[x].bpp > dir[y].bpp; - }); - - // walk down until something works - for (int i = 0; count > i; ++i) - { - LOG( - "Try loading ICO file entry %u: %u*%u, %u bits per pixel\n", - index[i], - dir[index[i]].get_width(), - dir[index[i]].get_height(), - dir[index[i]].bpp); - if (load_ico_image(fp, index[i], dir[index[i]], bitmap)) - return; - } + LOG("Failed to read ICO file directory entries\n"); + bitmap.reset(); + return; } } + + // byteswap and sort by (pixels, depth) + for (int i = 0; count > i; ++i) + { + dir[i].byteswap(); + index[i] = i; + } + std::stable_sort( + index.get(), + index.get() + count, + [&dir] (unsigned x, unsigned y) + { + unsigned const x_pixels(dir[x].get_width() * dir[x].get_height()); + unsigned const y_pixels(dir[y].get_width() * dir[y].get_height()); + if (x_pixels > y_pixels) + return true; + else if (x_pixels < y_pixels) + return false; + else + return dir[x].bpp > dir[y].bpp; + }); + + // walk down until something works + for (int i = 0; count > i; ++i) + { + LOG( + "Try loading ICO file entry %u: %u*%u, %u bits per pixel\n", + index[i], + dir[index[i]].get_width(), + dir[index[i]].get_height(), + dir[index[i]].bpp); + if (load_ico_image(fp, index[i], dir[index[i]], bitmap)) + return; + } bitmap.reset(); } diff --git a/src/lib/formats/abc800i_dsk.cpp b/src/lib/formats/abc800i_dsk.cpp index 1961dd9a9de..9a5a798c886 100644 --- a/src/lib/formats/abc800i_dsk.cpp +++ b/src/lib/formats/abc800i_dsk.cpp @@ -89,11 +89,10 @@ const abc800i_format FLOPPY_ABC800I_FORMAT; int abc800i_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[1]; - size_t actual; - io.read_at(0x810, h, 1, actual); + auto const [err, actual] = read_at(io, 0x810, h, 1); // start of directory - if (h[0] == 0x03) + if (!err && (actual == 1) && (h[0] == 0x03)) return FIFID_SIGN; return 0; diff --git a/src/lib/formats/acorn_dsk.cpp b/src/lib/formats/acorn_dsk.cpp index fa61c463e46..682b6424556 100644 --- a/src/lib/formats/acorn_dsk.cpp +++ b/src/lib/formats/acorn_dsk.cpp @@ -16,6 +16,7 @@ #include "multibyte.h" #include <cstring> +#include <tuple> acorn_ssd_format::acorn_ssd_format() : wd177x_format(formats) @@ -45,25 +46,24 @@ int acorn_ssd_format::find_size(util::random_read &io, uint32_t form_factor, con if (io.length(size)) 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.read_at(0x32800, cat, 8, actual); + read_at(io, 0x32800, cat, 8); // FIXME: check for errors and premature EOF if (memcmp(cat, "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd", 8) == 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.read_at(0x04610, cat, 8, actual); + read_at(io, 0x04610, cat, 8); // FIXME: check for errors and premature EOF if (memcmp(cat, "\x00\x28\x43\x29\x4a\x47\x48\x00", 8) == 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.read_at(0x0960, cat, 8, actual); + read_at(io, 0x0960, cat, 8); // FIXME: check for errors and premature EOF 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 @@ -75,7 +75,7 @@ int acorn_ssd_format::find_size(util::random_read &io, uint32_t form_factor, con } // read sector count from side 0 catalogue - io.read_at(0x100, cat, 8, actual); + read_at(io, 0x100, cat, 8); // FIXME: check for errors and premature EOF sectors0 = get_u16be(&cat[6]) & 0x3ff; LOG_FORMATS("ssd: sector count 0: %d %s\n", sectors0, sectors0 % 10 != 0 ? "invalid" : ""); @@ -84,11 +84,11 @@ int acorn_ssd_format::find_size(util::random_read &io, uint32_t form_factor, con if (f.head_count == 2) { // read sector count from side 2 catalogue - io.read_at((uint64_t)compute_track_size(f) * f.track_count + 0x100, cat, 8, actual); // sequential + read_at(io, (uint64_t)compute_track_size(f) * f.track_count + 0x100, cat, 8); // sequential sectors2 = get_u16be(&cat[6]) & 0x3ff; // exception case for Acorn CP/M System Disc 1 - io.read_at(0x367ec, cat, 8, actual); + read_at(io, 0x367ec, cat, 8); // FIXME: check for errors and premature EOF if (memcmp(cat, "/M ", 4) == 0) sectors2 = get_u16be(&cat[6]) & 0x3ff; @@ -192,39 +192,38 @@ int acorn_dsd_format::find_size(util::random_read &io, uint32_t form_factor, con 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.read_at(0x1200, cat, 8, actual); + read_at(io, 0x1200, cat, 8); // FIXME: check for errors and premature EOF if (memcmp(cat, "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd", 8) == 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.read_at(0x08c10, cat, 8, actual); + read_at(io, 0x08c10, cat, 8); // FIXME: check for errors and premature EOF if (memcmp(cat, "\x00\x28\x43\x29\x4a\x47\x48\x00", 8) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) return i; // test for FLEX - from System Information Record - io.read_at(0x0226, cat, 2, actual); + read_at(io, 0x0226, cat, 2); // FIXME: check for errors and premature EOF if ((memcmp(cat, "\x4f\x14", 2) == 0 || memcmp(cat, "\x4f\x0a", 2) == 0) && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) return i; // read sector count from side 0 catalogue - io.read_at(0x100, cat, 8, actual); + read_at(io, 0x100, cat, 8); // FIXME: check for errors and premature EOF sectors0 = get_u16be(&cat[6]) & 0x3ff; 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)) { // read sector count from side 2 catalogue - io.read_at(0xb00, cat, 8, actual); // interleaved + read_at(io, 0xb00, cat, 8); // interleaved sectors2 = get_u16be(&cat[6]) & 0x3ff; // exception case for Acorn CP/M System Disc 1 - io.read_at(0x97ec, cat, 8, actual); + read_at(io, 0x97ec, cat, 8); // FIXME: check for errors and premature EOF if (memcmp(cat, "/M ", 4) == 0) sectors2 = get_u16be(&cat[6]) & 0x3ff; @@ -295,12 +294,11 @@ const char *opus_ddos_format::extensions() const noexcept int opus_ddos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { - size_t actual; uint8_t cat[8]; uint32_t sectors0, sectors2; // read sector count from side 0 catalogue - io.read_at(0x1000, cat, 8, actual); + read_at(io, 0x1000, cat, 8); // FIXME: check for errors and premature EOF sectors0 = get_u16be(&cat[1]); LOG_FORMATS("ddos: sector count 0: %d %s\n", sectors0, sectors0 % 18 != 0 ? "invalid" : ""); @@ -319,7 +317,7 @@ int opus_ddos_format::find_size(util::random_read &io, uint32_t form_factor, con if (f.head_count == 2) { // read sector count from side 2 catalogue - io.read_at((uint64_t)compute_track_size(f) * f.track_count + 0x1000, cat, 8, actual); // sequential + read_at(io, (uint64_t)compute_track_size(f) * f.track_count + 0x1000, cat, 8); // sequential sectors2 = get_u16be(&cat[1]); LOG_FORMATS("ddos: sector count 2: %d %s\n", sectors2, sectors2 % 18 != 0 ? "invalid" : ""); } @@ -393,25 +391,30 @@ const char *acorn_adfs_old_format::extensions() const noexcept int acorn_adfs_old_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { + std::error_condition err; size_t actual; uint8_t map[3]; uint32_t sectors; uint8_t oldmap[4]; // read sector count from free space map - io.read_at(0xfc, map, 3, actual); + std::tie(err, actual) = read_at(io, 0xfc, map, 3); + if (err || (3 != actual)) + return -1; sectors = get_u24le(map); LOG_FORMATS("adfs_o: sector count %d %s\n", sectors, sectors % 16 != 0 ? "invalid" : ""); // read map identifier - io.read_at(0x201, oldmap, 4, actual); + std::tie(err, actual) = read_at(io, 0x201, oldmap, 4); + if (err || (4 != actual)) + return -1; LOG_FORMATS("adfs_o: map identifier %s %s\n", oldmap, memcmp(oldmap, "Hugo", 4) != 0 ? "invalid" : ""); uint64_t size; if (io.length(size)) return -1; - 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) @@ -429,7 +432,7 @@ int acorn_adfs_old_format::identify(util::random_read &io, uint32_t form_factor, { int type = find_size(io, form_factor, variants); - if(type != -1) + if (type != -1) return FIFID_STRUCT | FIFID_SIZE; return 0; @@ -491,14 +494,19 @@ const char *acorn_adfs_new_format::extensions() const noexcept int acorn_adfs_new_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { + std::error_condition err; size_t actual; uint8_t dform[4]; uint8_t eform[4]; // read map identifiers for D and E formats - io.read_at(0x401, dform, 4, actual); + std::tie(err, actual) = read_at(io, 0x401, dform, 4); + if (err || (4 != actual)) + return -1; LOG_FORMATS("adfs_n: map identifier (D format) %s %s\n", dform, (memcmp(dform, "Hugo", 4) != 0 && memcmp(dform, "Nick", 4) != 0) ? "invalid" : ""); - io.read_at(0x801, eform, 4, actual); + std::tie(err, actual) = read_at(io, 0x801, eform, 4); + if (err || (4 != actual)) + return -1; LOG_FORMATS("adfs_n: map identifier (E format) %s %s\n", eform, memcmp(eform, "Nick", 4) != 0 ? "invalid" : ""); uint64_t size; @@ -585,12 +593,14 @@ int acorn_dos_format::find_size(util::random_read &io, uint32_t form_factor, con if (size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) { // read media type ID from FAT - Acorn DOS = 0xfd - 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; + auto const [err, actual] = read_at(io, 0, &type, 1); + if (!err && (1 == actual)) + { + LOG_FORMATS("dos: 800k media type id %02X %s\n", type, type != 0xfd ? "invalid" : ""); + if (type == 0xfd) + return i; + } } } return -1; @@ -647,14 +657,14 @@ bool opus_ddcpm_format::supports_save() const noexcept int opus_ddcpm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { - size_t actual; uint8_t h[8]; - - io.read_at(0, h, 8, actual); + auto const [err, actual] = read_at(io, 0, h, 8); + if (err || (8 != actual)) + return 0; uint64_t size; if (io.length(size)) - return -1; + return 0; if (size == 819200 && memcmp(h, "Slogger ", 8) == 0) return FIFID_SIGN | FIFID_SIZE; @@ -686,8 +696,7 @@ bool opus_ddcpm_format::load(util::random_read &io, uint32_t form_factor, const desc_pc_sector sects[10]; uint8_t sectdata[10*512]; - size_t actual; - io.read_at(head * 80 * spt * 512 + track * spt * 512, sectdata, spt * 512, actual); + /*auto const [err, actual] =*/ read_at(io, head * 80 * spt * 512 + track * spt * 512, sectdata, spt * 512); // FIXME: check for errors and premature EOF for (int i = 0; i < spt; i++) { @@ -742,7 +751,7 @@ int cumana_dfs_format::find_size(util::random_read &io, uint32_t form_factor, co if (io.length(size)) return -1; - 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) @@ -750,9 +759,10 @@ int cumana_dfs_format::find_size(util::random_read &io, uint32_t form_factor, co if (size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) { - size_t actual; uint8_t info; - io.read_at(14, &info, 1, actual); + auto const [err, actual] = read_at(io, 14, &info, 1); + if (err || (actual != 1)) + return -1; if (f.head_count == (util::BIT(info, 6) ? 2 : 1) && f.track_count == (util::BIT(info, 7) ? 80 : 40)) return i; } diff --git a/src/lib/formats/aim_dsk.cpp b/src/lib/formats/aim_dsk.cpp index 88399204f37..c33cab8fb12 100644 --- a/src/lib/formats/aim_dsk.cpp +++ b/src/lib/formats/aim_dsk.cpp @@ -72,8 +72,8 @@ bool aim_format::load(util::random_read &io, uint32_t form_factor, const std::ve bool header = false; // Read track - size_t actual; - io.read_at((heads * track + head) * track_size, &track_data[0], track_size, actual); + /*auto const [err, actual] =*/ read_at(io, (heads * track + head) * track_size, &track_data[0], track_size); + // FIXME: check for error and premature EOF // Find first sector header or index mark for (int offset = 0; offset < track_size; offset += 2) diff --git a/src/lib/formats/ami_dsk.cpp b/src/lib/formats/ami_dsk.cpp index 6ad9145c7d8..d4c567050c8 100644 --- a/src/lib/formats/ami_dsk.cpp +++ b/src/lib/formats/ami_dsk.cpp @@ -81,8 +81,9 @@ bool adf_format::load(util::random_read &io, uint32_t form_factor, const std::ve image.set_variant(floppy_image::DSDD); 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); + auto const [err, actual] = read_at(io, (track*2 + side)*512*11, sectdata, 512*11); + if (err || (512*11 != actual)) + return false; generate_track(amiga_11, track, side, sectors, 11, 100000, image); } } @@ -90,8 +91,9 @@ bool adf_format::load(util::random_read &io, uint32_t form_factor, const std::ve image.set_variant(floppy_image::DSHD); 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); + auto const [err, actual] = read_at(io, (track*2 + side)*512*22, sectdata, 512*22); + if (err || (512*22 != actual)) + return false; generate_track(amiga_22, track, side, sectors, 22, 200000, image); } } @@ -151,8 +153,8 @@ bool adf_format::save(util::random_read_write &io, const std::vector<uint32_t> & *dest++ = val; } - size_t actual; - io.write_at((track*2 + side) * data_track_size, sectdata, data_track_size, actual); + // FIXME: check for errors + /*auto const [err, actual] =*/ write_at(io, (track*2 + side) * data_track_size, sectdata, data_track_size); } } } diff --git a/src/lib/formats/ap2_dsk.cpp b/src/lib/formats/ap2_dsk.cpp index 557800dcec2..9e8afc18c2a 100644 --- a/src/lib/formats/ap2_dsk.cpp +++ b/src/lib/formats/ap2_dsk.cpp @@ -114,8 +114,7 @@ int a2_16sect_format::identify(util::random_read &io, uint32_t form_factor, cons 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 }; - size_t actual; - io.read_at(0, sector_data, 256*2, actual); + /*auto const [err, actual] =*/ read_at(io, 0, sector_data, 256*2); // FIXME: check for errors and premature EOF bool prodos_order = false; // check ProDOS boot block @@ -188,8 +187,7 @@ bool a2_16sect_format::load(util::random_read &io, uint32_t form_factor, const s std::vector<uint32_t> track_data; uint8_t sector_data[256*16]; - size_t actual; - io.read_at(fpos, sector_data, 256*16, actual); + /*auto const [err, actual] =*/ read_at(io, fpos, sector_data, 256*16); // FIXME: check for errors and premature EOF fpos += 256*16; for(int i=0; i<49; i++) @@ -273,8 +271,8 @@ uint8_t a2_16sect_format::gb(const std::vector<bool> &buf, int &pos, int &wrap) bool a2_16sect_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { - int g_tracks, g_heads; - int visualgrid[16][APPLE2_TRACK_COUNT]; // visualizer grid, cleared/initialized below + int g_tracks, g_heads; + int visualgrid[16][APPLE2_TRACK_COUNT]; // visualizer grid, cleared/initialized below // lenient addr check: if unset, only accept an addr mark if the checksum was good // if set, accept an addr mark if the track and sector values are both sane @@ -294,206 +292,205 @@ bool a2_16sect_format::save(util::random_read_write &io, const std::vector<uint3 #define DATAGOOD 8 // data postamble is good #define DATAPOST 16 - for (auto & elem : visualgrid) { - for (int j = 0; j < APPLE2_TRACK_COUNT; j++) { - elem[j] = 0; - } + for (auto & elem : visualgrid) { + for (int j = 0; j < APPLE2_TRACK_COUNT; j++) { + elem[j] = 0; } - image.get_actual_geometry(g_tracks, g_heads); + } + image.get_actual_geometry(g_tracks, g_heads); - int head = 0; + int head = 0; - int pos_data = 0; + int pos_data = 0; - for(int track=0; track < g_tracks; track++) { - uint8_t sectdata[(256)*16]; - memset(sectdata, 0, sizeof(sectdata)); - int nsect = 16; - #ifdef VERBOSE_SAVE - fprintf(stderr,"DEBUG: a2_16sect_format::save() about to generate bitstream from track %d...", track); - #endif - auto buf = generate_bitstream_from_track(track, head, 3915, image); + for(int track=0; track < g_tracks; track++) { + uint8_t sectdata[(256)*16]; + memset(sectdata, 0, sizeof(sectdata)); + int nsect = 16; + #ifdef VERBOSE_SAVE + fprintf(stderr,"DEBUG: a2_16sect_format::save() about to generate bitstream from track %d...", track); + #endif + auto buf = generate_bitstream_from_track(track, head, 3915, image); + #ifdef VERBOSE_SAVE + fprintf(stderr,"done.\n"); + #endif + int pos = 0; + int wrap = 0; + int hb = 0; + int dosver = 0; // apple dos version; 0 = >=3.3, 1 = <3.3 + for(;;) { + uint8_t v = gb(buf, pos, wrap); + if(v == 0xff) { + hb = 1; + } + else if(hb == 1 && v == 0xd5){ + hb = 2; + } + else if(hb == 2 && v == 0xaa) { + hb = 3; + } + else if(hb == 3 && ((v == 0x96) || (v == 0xab))) { // 0x96 = dos 3.3/16sec, 0xab = dos 3.21 and below/13sec + hb = 4; + if (v == 0xab) dosver = 1; + } + else + hb = 0; + + if(hb == 4) { + uint8_t h[11]; + for(auto & elem : h) + elem = gb(buf, pos, wrap); + //uint8_t v2 = gcr6bw_tb[h[2]]; + uint8_t vl = gcr4_decode(h[0],h[1]); + uint8_t tr = gcr4_decode(h[2],h[3]); + uint8_t se = gcr4_decode(h[4],h[5]); + uint8_t chk = gcr4_decode(h[6],h[7]); #ifdef VERBOSE_SAVE - fprintf(stderr,"done.\n"); + uint32_t post = get_u24be(&h[8]); + printf("Address Mark:\tVolume %d, Track %d, Sector %2d, Checksum %02X: %s, Postamble %03X: %s\n", vl, tr, se, chk, (chk ^ vl ^ tr ^ se)==0?"OK":"BAD", post, (post&0xFFFF00)==0xDEAA00?"OK":"BAD"); #endif - int pos = 0; - int wrap = 0; - int hb = 0; - int dosver = 0; // apple dos version; 0 = >=3.3, 1 = <3.3 - for(;;) { - uint8_t v = gb(buf, pos, wrap); - if(v == 0xff) { + // sanity check + if (tr == track && se < nsect) { + visualgrid[se][track] |= ADDRFOUND; + visualgrid[se][track] |= ((chk ^ vl ^ tr ^ se)==0)?ADDRGOOD:0; +#ifdef LENIENT_ADDR_CHECK + if ((visualgrid[se][track] & ADDRFOUND) == ADDRFOUND) { +#else + if ((visualgrid[se][track] & ADDRGOOD) == ADDRGOOD) { +#endif + int opos = pos; + int owrap = wrap; + hb = 0; + for(int i=0; i<20 && hb != 4; i++) { + v = gb(buf, pos, wrap); + if(v == 0xff) hb = 1; - } - else if(hb == 1 && v == 0xd5){ + else if(hb == 1 && v == 0xd5) hb = 2; - } - else if(hb == 2 && v == 0xaa) { + else if(hb == 2 && v == 0xaa) hb = 3; - } - else if(hb == 3 && ((v == 0x96) || (v == 0xab))) { // 0x96 = dos 3.3/16sec, 0xab = dos 3.21 and below/13sec + else if(hb == 3 && v == 0xad) hb = 4; - if (v == 0xab) dosver = 1; - } else hb = 0; + } + if((hb == 4)&&(dosver == 0)) { + visualgrid[se][track] |= DATAFOUND; + uint8_t *dest; + uint8_t data[0x157]; + uint32_t dpost = 0; + uint8_t c = 0; + + if (m_prodos_order) + { + dest = sectdata+(256)*prodos_skewing[se]; + } + else + { + dest = sectdata+(256)*dos_skewing[se]; + } - if(hb == 4) { - uint8_t h[11]; - for(auto & elem : h) - elem = gb(buf, pos, wrap); - //uint8_t v2 = gcr6bw_tb[h[2]]; - uint8_t vl = gcr4_decode(h[0],h[1]); - uint8_t tr = gcr4_decode(h[2],h[3]); - uint8_t se = gcr4_decode(h[4],h[5]); - uint8_t chk = gcr4_decode(h[6],h[7]); - #ifdef VERBOSE_SAVE - uint32_t post = get_u24be(&h[8]); - printf("Address Mark:\tVolume %d, Track %d, Sector %2d, Checksum %02X: %s, Postamble %03X: %s\n", vl, tr, se, chk, (chk ^ vl ^ tr ^ se)==0?"OK":"BAD", post, (post&0xFFFF00)==0xDEAA00?"OK":"BAD"); - #endif - // sanity check - if (tr == track && se < nsect) { - visualgrid[se][track] |= ADDRFOUND; - visualgrid[se][track] |= ((chk ^ vl ^ tr ^ se)==0)?ADDRGOOD:0; -#ifdef LENIENT_ADDR_CHECK - if ((visualgrid[se][track] & ADDRFOUND) == ADDRFOUND) { -#else - if ((visualgrid[se][track] & ADDRGOOD) == ADDRGOOD) { -#endif - int opos = pos; - int owrap = wrap; - hb = 0; - for(int i=0; i<20 && hb != 4; i++) { - v = gb(buf, pos, wrap); - if(v == 0xff) - hb = 1; - else if(hb == 1 && v == 0xd5) - hb = 2; - else if(hb == 2 && v == 0xaa) - hb = 3; - else if(hb == 3 && v == 0xad) - hb = 4; - else - hb = 0; - } - if((hb == 4)&&(dosver == 0)) { - visualgrid[se][track] |= DATAFOUND; - uint8_t *dest; - uint8_t data[0x157]; - uint32_t dpost = 0; - uint8_t c = 0; - - if (m_prodos_order) - { - dest = sectdata+(256)*prodos_skewing[se]; - } - else - { - dest = sectdata+(256)*dos_skewing[se]; - } - - // first read in sector and decode to 6bit form - for(int i=0; i<0x156; i++) { - data[i] = gcr6bw_tb[gb(buf, pos, wrap)] ^ c; - c = data[i]; - // printf("%02x ", c); - // if (((i&0xf)+1)==0x10) printf("\n"); - } - // read the checksum byte - data[0x156] = gcr6bw_tb[gb(buf,pos,wrap)]; - // now read the postamble bytes - for(int i=0; i<3; i++) { - dpost <<= 8; - dpost |= gb(buf, pos, wrap); - } - // next combine in the upper 2 bits of each byte - uint8_t bit_swap[4] = { 0, 2, 1, 3 }; - for(int i=0; i<0x56; i++) - data[i+0x056] = data[i+0x056]<<2 | bit_swap[data[i]&3]; - for(int i=0; i<0x56; i++) - data[i+0x0ac] = data[i+0x0ac]<<2 | bit_swap[(data[i]>>2)&3]; - for(int i=0; i<0x54; i++) - data[i+0x102] = data[i+0x102]<<2 | bit_swap[(data[i]>>4)&3]; - // now decode it into 256 bytes - // but only write it if the bitfield of the track shows datagood is NOT set. - // if it is set we don't want to overwrite a guaranteed good read with a bad one - // if past read had a bad checksum or bad postamble... + // first read in sector and decode to 6bit form + for(int i=0; i<0x156; i++) { + data[i] = gcr6bw_tb[gb(buf, pos, wrap)] ^ c; + c = data[i]; + // printf("%02x ", c); + // if (((i&0xf)+1)==0x10) printf("\n"); + } + // read the checksum byte + data[0x156] = gcr6bw_tb[gb(buf,pos,wrap)]; + // now read the postamble bytes + for(int i=0; i<3; i++) { + dpost <<= 8; + dpost |= gb(buf, pos, wrap); + } + // next combine in the upper 2 bits of each byte + uint8_t bit_swap[4] = { 0, 2, 1, 3 }; + for(int i=0; i<0x56; i++) + data[i+0x056] = data[i+0x056]<<2 | bit_swap[data[i]&3]; + for(int i=0; i<0x56; i++) + data[i+0x0ac] = data[i+0x0ac]<<2 | bit_swap[(data[i]>>2)&3]; + for(int i=0; i<0x54; i++) + data[i+0x102] = data[i+0x102]<<2 | bit_swap[(data[i]>>4)&3]; + // now decode it into 256 bytes + // but only write it if the bitfield of the track shows datagood is NOT set. + // if it is set we don't want to overwrite a guaranteed good read with a bad one + // if past read had a bad checksum or bad postamble... #ifndef USE_OLD_BEST_SECTOR_PRIORITY - if (((visualgrid[se][track]&DATAGOOD)==0)||((visualgrid[se][track]&DATAPOST)==0)) { - // if the current read is good, and postamble is good, write it in, no matter what. - // if the current read is good and the current postamble is bad, write it in unless the postamble was good before - // if the current read is bad and the current postamble is good and the previous read had neither good, write it in - // if the current read isn't good and neither is the postamble but nothing better - // has been written before, write it anyway. - if ( ((data[0x156] == c) && (dpost&0xFFFF00)==0xDEAA00) || + if (((visualgrid[se][track]&DATAGOOD)==0)||((visualgrid[se][track]&DATAPOST)==0)) { + // if the current read is good, and postamble is good, write it in, no matter what. + // if the current read is good and the current postamble is bad, write it in unless the postamble was good before + // if the current read is bad and the current postamble is good and the previous read had neither good, write it in + // if the current read isn't good and neither is the postamble but nothing better + // has been written before, write it anyway. + if ( ((data[0x156] == c) && (dpost&0xFFFF00)==0xDEAA00) || (((data[0x156] == c) && (dpost&0xFFFF00)!=0xDEAA00) && ((visualgrid[se][track]&DATAPOST)==0)) || (((data[0x156] != c) && (dpost&0xFFFF00)==0xDEAA00) && (((visualgrid[se][track]&DATAGOOD)==0)&&(visualgrid[se][track]&DATAPOST)==0)) || (((data[0x156] != c) && (dpost&0xFFFF00)!=0xDEAA00) && (((visualgrid[se][track]&DATAGOOD)==0)&&(visualgrid[se][track]&DATAPOST)==0)) ) { - for(int i=0x56; i<0x156; i++) { - uint8_t dv = data[i]; - *dest++ = dv; - } - } - } -#else - if ((visualgrid[se][track]&DATAGOOD)==0) { - for(int i=0x56; i<0x156; i++) { - uint8_t dv = data[i]; - *dest++ = dv; - } - } -#endif - // do some checking - #ifdef VERBOSE_SAVE - if ((data[0x156] != c) || (dpost&0xFFFF00)!=0xDEAA00) - fprintf(stderr,"Data Mark:\tChecksum xpctd %d found %d: %s, Postamble %03X: %s\n", data[0x156], c, (data[0x156]==c)?"OK":"BAD", dpost, (dpost&0xFFFF00)==0xDEAA00?"OK":"BAD"); - #endif - if (data[0x156] == c) visualgrid[se][track] |= DATAGOOD; - if ((dpost&0xFFFF00)==0xDEAA00) visualgrid[se][track] |= DATAPOST; - } else if ((hb == 4)&&(dosver == 1)) { - fprintf(stderr,"ERROR: We don't handle dos sectors below 3.3 yet!\n"); - } else { - pos = opos; - wrap = owrap; - } + for(int i=0x56; i<0x156; i++) { + uint8_t dv = data[i]; + *dest++ = dv; } } - hb = 0; + } +#else + if ((visualgrid[se][track]&DATAGOOD)==0) { + for(int i=0x56; i<0x156; i++) { + uint8_t dv = data[i]; + *dest++ = dv; + } + } +#endif + // do some checking + #ifdef VERBOSE_SAVE + if ((data[0x156] != c) || (dpost&0xFFFF00)!=0xDEAA00) + fprintf(stderr,"Data Mark:\tChecksum xpctd %d found %d: %s, Postamble %03X: %s\n", data[0x156], c, (data[0x156]==c)?"OK":"BAD", dpost, (dpost&0xFFFF00)==0xDEAA00?"OK":"BAD"); + #endif + if (data[0x156] == c) visualgrid[se][track] |= DATAGOOD; + if ((dpost&0xFFFF00)==0xDEAA00) visualgrid[se][track] |= DATAPOST; + } else if ((hb == 4)&&(dosver == 1)) { + fprintf(stderr,"ERROR: We don't handle dos sectors below 3.3 yet!\n"); + } else { + pos = opos; + wrap = owrap; } - if(wrap) - break; - } - for(int i=0; i<nsect; i++) { - //if(nsect>0) printf("t%d,", track); - uint8_t const *const data = sectdata + (256)*i; - size_t actual; - io.write_at(pos_data, data, 256, actual); - pos_data += 256; + } } - //printf("\n"); + hb = 0; + } + if(wrap) + break; } - // display a little table of which sectors decoded ok - #ifdef VERBOSE_SAVE - int total_good = 0; - for (int j = 0; j < APPLE2_TRACK_COUNT; j++) { - printf("T%2d: ",j); - 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(" "); - } + for(int i=0; i<nsect; i++) { + //if(nsect>0) printf("t%d,", track); + uint8_t const *const data = sectdata + (256)*i; + /*auto const [err, actual] =*/ write_at(io, pos_data, data, 256); // FIXME: check for errors + pos_data += 256; + } + //printf("\n"); + } + // display a little table of which sectors decoded ok + #ifdef VERBOSE_SAVE + int total_good = 0; + for (int j = 0; j < APPLE2_TRACK_COUNT; j++) { + printf("T%2d: ",j); + 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(" "); } - printf("\n"); } - printf("Total Good Sectors: %d\n", total_good); - #endif + printf("\n"); + } + printf("Total Good Sectors: %d\n", total_good); + #endif - return true; + return true; } const a2_16sect_dos_format FLOPPY_A216S_DOS_FORMAT; @@ -796,8 +793,7 @@ bool a2_rwts18_format::save(util::random_read_write &io, const std::vector<uint3 for(int i=0; i<nsect; i++) { //if(nsect>0) printf("t%d,", track); uint8_t const *const data = sectdata + (256)*i; - size_t actual; - io.write_at(pos_data, data, 256, actual); + /*auto const [err, actual] =*/ write_at(io, pos_data, data, 256); // FIXME: check for errors pos_data += 256; } @@ -978,8 +974,7 @@ bool a2_rwts18_format::save(util::random_read_write &io, const std::vector<uint3 for(int i=0; i<nsect; i++) { //if(nsect>0) printf("t%d,", track); uint8_t const *const data = sectdata + (256)*i; - size_t actual; - io.write_at(pos_data, data, 256, actual); + /*auto const [err, actual] =*/ write_at(io, pos_data, data, 256); // FIXME: check for errors pos_data += 256; } //printf("\n"); @@ -1049,13 +1044,10 @@ bool a2_edd_format::load(util::random_read &io, uint32_t form_factor, const std: uint8_t nibble[16384], stream[16384]; int npos[16384]; - std::unique_ptr<uint8_t []> img(new (std::nothrow) uint8_t[2244608]); - if (!img) + auto [err, img, actual] = read_at(io, 0, 2'244'608); // TODO: check for premature EOF + if(err) return false; - size_t actual; - io.read_at(0, img.get(), 2244608, actual); - for(int i=0; i<137; i++) { uint8_t const *const trk = &img[16384*i]; int pos = 0; @@ -1290,8 +1282,7 @@ bool a2_nib_format::load(util::random_read &io, uint32_t form_factor, const std: std::vector<uint8_t> nibbles(nibbles_per_track); for (unsigned track = 0; track < nr_tracks; ++track) { - size_t actual; - io.read_at(track * nibbles_per_track, &nibbles[0], nibbles_per_track, actual); + /*auto const [err, actual] =*/ read_at(io, track * nibbles_per_track, &nibbles[0], nibbles_per_track); // FIXME: check for errors and premature EOF auto levels = generate_levels_from_nibbles(nibbles); generate_track_from_levels(track, 0, levels, diff --git a/src/lib/formats/ap_dsk35.cpp b/src/lib/formats/ap_dsk35.cpp index b4a82e5ff56..4096215c35f 100644 --- a/src/lib/formats/ap_dsk35.cpp +++ b/src/lib/formats/ap_dsk35.cpp @@ -142,27 +142,26 @@ int dc42_format::identify(util::random_read &io, uint32_t form_factor, const std return 0; uint8_t h[0x54]; - size_t actual; - io.read_at(0, h, 0x54, actual); - uint32_t dsize = get_u32be(&h[0x40]); - uint32_t tsize = get_u32be(&h[0x44]); + auto const [err, actual] = read_at(io, 0, h, 0x54); + if (err || (0x54 != actual)) + return 0; - uint8_t encoding = h[0x50]; - uint8_t format = h[0x51]; + uint32_t const dsize = get_u32be(&h[0x40]); + uint32_t const tsize = get_u32be(&h[0x44]); + + uint8_t const encoding = h[0x50]; + uint8_t const format = h[0x51]; // if it's a 1.44MB DC42 image, reject it so the generic PC MFM handler picks it up if ((encoding == 0x03) && (format == 0x02)) - { return 0; - } return (size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0) ? FIFID_STRUCT : 0; } bool dc42_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; uint8_t h[0x54]; - io.read_at(0, h, 0x54, actual); + read_at(io, 0, h, 0x54); // FIXME: check for errors and premature EOF int dsize = get_u32be(&h[0x40]); int tsize = get_u32be(&h[0x44]); @@ -218,14 +217,14 @@ bool dc42_format::load(util::random_read &io, uint32_t form_factor, const std::v sectors[si].sector = i; sectors[si].info = format; if(tsize) { - io.read_at(pos_tag, data, 12, actual); + read_at(io, pos_tag, data, 12); // FIXME: check for errors and premature EOF sectors[si].tag = data; pos_tag += 12; } else { sectors[si].tag = nullptr; } sectors[si].data = data+12; - io.read_at(pos_data, data+12, 512, actual); + read_at(io, pos_data, data+12, 512); // FIXME: check for errors and premature EOF pos_data += 512; si = (si + 2) % ns; if(si == 0) @@ -279,9 +278,8 @@ bool dc42_format::save(util::random_read_write &io, const std::vector<uint32_t> for(unsigned int i=0; i < sectors.size(); i++) { auto &sdata = sectors[i]; sdata.resize(512+12); - size_t actual; - io.write_at(pos_tag, &sdata[0], 12, actual); - io.write_at(pos_data, &sdata[12], 512, actual); + write_at(io, pos_tag, &sdata[0], 12); // FIXME: check for errors + write_at(io, pos_data, &sdata[12], 512); // FIXME: check for errors pos_tag += 12; pos_data += 512; if(track || head || i) @@ -294,8 +292,7 @@ bool dc42_format::save(util::random_read_write &io, const std::vector<uint32_t> put_u32be(&h[0x48], dchk); put_u32be(&h[0x4c], tchk); - size_t actual; - io.write_at(0, h, 0x54, actual); + write_at(io, 0, h, 0x54); // FIXME: check for errors return true; } @@ -340,14 +337,13 @@ int apple_gcr_format::identify(util::random_read &io, uint32_t form_factor, cons bool apple_gcr_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; desc_gcr_sector sectors[12]; uint8_t sdata[512*12]; int pos_data = 0; uint8_t header[64]; - io.read_at(0, header, 64, actual); + read_at(io, 0, header, 64); // FIXME: check for errors and premature EOF uint64_t size; if(io.length(size)) @@ -361,7 +357,7 @@ bool apple_gcr_format::load(util::random_read &io, uint32_t form_factor, const s for(int track=0; track < 80; track++) { for(int head=0; head < head_count; head++) { int ns = 12 - (track/16); - io.read_at(pos_data, sdata, 512*ns, actual); + read_at(io, pos_data, sdata, 512*ns); // FIXME: check for errors and premature EOF pos_data += 512*ns; int si = 0; @@ -398,8 +394,7 @@ bool apple_gcr_format::save(util::random_read_write &io, const std::vector<uint3 for(unsigned int i=0; i < sectors.size(); i++) { auto &sdata = sectors[i]; sdata.resize(512+12); - size_t actual; - io.write_at(pos_data, &sdata[12], 512, actual); + /*auto const [err, actual] =*/ write_at(io, pos_data, &sdata[12], 512); // FIXME: check for errors pos_data += 512; } } @@ -438,15 +433,19 @@ bool apple_2mg_format::supports_save() const noexcept int apple_2mg_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t signature[4]; - size_t actual; - io.read_at(0, signature, 4, actual); - if (!strncmp(reinterpret_cast<char *>(signature), "2IMG", 4)) + auto const [err, actual] = read_at(io, 0, signature, 4); + if (err || (4 != actual)) + { + return 0; + } + + if (!memcmp(signature, "2IMG", 4)) { return FIFID_SIGN; } // Bernie ][ The Rescue wrote 2MGs with the signature byte-flipped, other fields are valid - if (!strncmp(reinterpret_cast<char *>(signature), "GMI2", 4)) + if (!memcmp(signature, "GMI2", 4)) { return FIFID_SIGN; } @@ -456,10 +455,9 @@ int apple_2mg_format::identify(util::random_read &io, uint32_t form_factor, cons bool apple_2mg_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; desc_gcr_sector sectors[12]; uint8_t sdata[512*12], header[64]; - io.read_at(0, header, 64, actual); + read_at(io, 0, header, 64); // FIXME: check for errors and premature EOF uint32_t blocks = get_u32le(&header[0x14]); uint32_t pos_data = get_u32le(&header[0x18]); @@ -471,7 +469,7 @@ bool apple_2mg_format::load(util::random_read &io, uint32_t form_factor, const s for(int track=0; track < 80; track++) { for(int head=0; head < 2; head++) { int ns = 12 - (track/16); - io.read_at(pos_data, sdata, 512*ns, actual); + read_at(io, pos_data, sdata, 512*ns); // FIXME: check for errors and premature EOF pos_data += 512*ns; int si = 0; @@ -494,8 +492,6 @@ bool apple_2mg_format::load(util::random_read &io, uint32_t form_factor, const s bool apple_2mg_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { - size_t actual; - uint8_t header[0x40]; int pos_data = 0x40; @@ -516,7 +512,7 @@ bool apple_2mg_format::save(util::random_read_write &io, const std::vector<uint3 header[0x18] = 0x40; // bytes of disk data header[0x1c] = 0x00; header[0x1d] = 0x80; header[0x1e] = 0x0c; // 0xC8000 (819200) - io.write_at(0, header, 0x40, actual); + write_at(io, 0, header, 0x40); // FIXME: check for errors for(int track=0; track < 80; track++) { for(int head=0; head < 2; head++) { @@ -524,7 +520,7 @@ bool apple_2mg_format::save(util::random_read_write &io, const std::vector<uint3 for(unsigned int i=0; i < sectors.size(); i++) { auto &sdata = sectors[i]; sdata.resize(512+12); - io.write_at(pos_data, &sdata[12], 512, actual); + write_at(io, pos_data, &sdata[12], 512); // FIXME: check for errors pos_data += 512; } } diff --git a/src/lib/formats/apd_dsk.cpp b/src/lib/formats/apd_dsk.cpp index c1319e43cf4..55d722bdf38 100644 --- a/src/lib/formats/apd_dsk.cpp +++ b/src/lib/formats/apd_dsk.cpp @@ -101,8 +101,9 @@ int apd_format::identify(util::random_read &io, uint32_t form_factor, const std: return 0; std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [ioerr, actual] = read_at(io, 0, &img[0], size); + if (ioerr || (actual != size)) + return 0; int err; std::vector<uint8_t> gz_ptr(8); @@ -126,7 +127,7 @@ int apd_format::identify(util::random_read &io, uint32_t form_factor, const std: err = inflateEnd(&d_stream); if (err != Z_OK) return 0; - img = gz_ptr; + img = std::move(gz_ptr); } if (!memcmp(&img[0], APD_HEADER, sizeof(APD_HEADER))) { @@ -143,8 +144,9 @@ bool apd_format::load(util::random_read &io, uint32_t form_factor, const std::ve return false; std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [ioerr, actual] = read_at(io, 0, &img[0], size); + if (ioerr || (actual != size)) + return false; int err; std::vector<uint8_t> gz_ptr; diff --git a/src/lib/formats/apridisk.cpp b/src/lib/formats/apridisk.cpp index fafc12d9f3c..36ad6018336 100644 --- a/src/lib/formats/apridisk.cpp +++ b/src/lib/formats/apridisk.cpp @@ -38,8 +38,9 @@ const char *apridisk_format::extensions() const noexcept int apridisk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[APR_HEADER_SIZE]; - size_t actual; - io.read_at(0, header, APR_HEADER_SIZE, actual); + auto const [err, actual] = read_at(io, 0, header, APR_HEADER_SIZE); + if (err || (APR_HEADER_SIZE != actual)) + return 0; const char magic[] = "ACT Apricot disk image\x1a\x04"; @@ -64,11 +65,9 @@ bool apridisk_format::load(util::random_read &io, uint32_t form_factor, const st while (file_offset < file_size) { - size_t actual; - // read sector header uint8_t sector_header[16]; - io.read_at(file_offset, sector_header, 16, actual); + read_at(io, file_offset, sector_header, 16); // FIXME: check for errors and premature EOF uint32_t type = get_u32le(§or_header[0]); uint16_t compression = get_u16le(§or_header[4]); @@ -103,7 +102,7 @@ bool apridisk_format::load(util::random_read &io, uint32_t form_factor, const st case APR_COMPRESSED: { uint8_t comp[3]; - io.read_at(file_offset, comp, 3, actual); + read_at(io, file_offset, comp, 3); // FIXME: check for errors and premature EOF uint16_t length = get_u16le(&comp[0]); if (length != SECTOR_SIZE) @@ -117,7 +116,7 @@ bool apridisk_format::load(util::random_read &io, uint32_t form_factor, const st break; case APR_UNCOMPRESSED: - io.read_at(file_offset, data_ptr, SECTOR_SIZE, actual); + read_at(io, file_offset, data_ptr, SECTOR_SIZE); // FIXME: check for errors and premature EOF break; default: diff --git a/src/lib/formats/as_dsk.cpp b/src/lib/formats/as_dsk.cpp index 5c8a0545870..0fad7217585 100644 --- a/src/lib/formats/as_dsk.cpp +++ b/src/lib/formats/as_dsk.cpp @@ -4,55 +4,17 @@ // Applesauce solved output formats #include "as_dsk.h" + #include "ioprocs.h" +#include "multibyte.h" #include <string.h> -as_format::as_format() : floppy_image_format_t() -{ -} -uint32_t as_format::find_tag(const std::vector<uint8_t> &data, uint32_t tag) -{ - uint32_t offset = 12; - do { - if(r32(data, offset) == tag) - return offset + 8; - offset += r32(data, offset+4) + 8; - } while(offset < data.size() - 8); - return 0; -} +namespace { -uint32_t as_format::r32(const std::vector<uint8_t> &data, uint32_t offset) -{ - return data[offset] | (data[offset+1] << 8) | (data[offset+2] << 16) | (data[offset+3] << 24); -} - -uint16_t as_format::r16(const std::vector<uint8_t> &data, uint32_t offset) -{ - return data[offset] | (data[offset+1] << 8); -} - -void as_format::w32(std::vector<uint8_t> &data, int offset, uint32_t value) -{ - data[offset] = value; - data[offset+1] = value >> 8; - data[offset+2] = value >> 16; - data[offset+3] = value >> 24; -} - -void as_format::w16(std::vector<uint8_t> &data, int offset, uint16_t value) -{ - data[offset] = value; - data[offset+1] = value >> 8; -} - -uint8_t as_format::r8(const std::vector<uint8_t> &data, uint32_t offset) -{ - return data[offset]; -} - -uint32_t as_format::crc32r(const uint8_t *data, uint32_t size) +template <typename T> +uint32_t crc32r(T &&data, uint32_t size) { // Reversed crc32 uint32_t crc = 0xffffffff; @@ -67,15 +29,35 @@ uint32_t as_format::crc32r(const uint8_t *data, uint32_t size) return ~crc; } -bool as_format::load_bitstream_track(const std::vector<uint8_t> &img, floppy_image &image, int head, int track, int subtrack, uint8_t idx, uint32_t off_trks, bool may_be_short, bool set_variant) +template <typename T> +uint32_t find_tag(T &&data, size_t size, uint32_t tag) +{ + uint32_t offset = 12; + do { + if(get_u32le(&data[offset]) == tag) + return offset + 8; + offset += get_u32le(&data[offset+4]) + 8; + } while(offset < (size - 8)); + return 0; +} + +} // anonymous namespace + + +as_format::as_format() : floppy_image_format_t() +{ +} + + +bool as_format::load_bitstream_track(const uint8_t *img, floppy_image &image, int head, int track, int subtrack, uint8_t idx, uint32_t off_trks, bool may_be_short, bool set_variant) { uint32_t trks_off = off_trks + (idx * 8); - uint32_t track_size = r32(img, trks_off + 4); + uint32_t track_size = get_u32le(&img[trks_off + 4]); if (track_size == 0) return false; - uint32_t boff = (uint32_t)r16(img, trks_off + 0) * 512; + uint32_t boff = (uint32_t)get_u16le(&img[trks_off + 0]) * 512; // With 5.25 floppies the end-of-track may be missing // if unformatted. Accept track length down to 95% of @@ -92,15 +74,15 @@ bool as_format::load_bitstream_track(const std::vector<uint8_t> &img, floppy_ima generate_track_from_bitstream(track, head, &img[boff], track_size, image, subtrack, 0xffff); if(set_variant) - image.set_variant(r32(img, trks_off + 4) >= 90000 ? floppy_image::DSHD : floppy_image::DSDD); + image.set_variant(get_u32le(&img[trks_off + 4]) >= 90000 ? floppy_image::DSHD : floppy_image::DSDD); return true; } -void as_format::load_flux_track(const std::vector<uint8_t> &img, floppy_image &image, int head, int track, int subtrack, uint8_t fidx, uint32_t off_trks) +void as_format::load_flux_track(const uint8_t *img, floppy_image &image, int head, int track, int subtrack, uint8_t fidx, uint32_t off_trks) { uint32_t trks_off = off_trks + (fidx * 8); - uint32_t boff = (uint32_t)r16(img, trks_off + 0) * 512; - uint32_t track_size = r32(img, trks_off + 4); + uint32_t boff = (uint32_t)get_u16le(&img[trks_off + 0]) * 512; + uint32_t track_size = get_u32le(&img[trks_off + 4]); uint32_t total_ticks = 0; for(uint32_t i=0; i != track_size; i++) @@ -239,13 +221,13 @@ bool as_format::test_flux(const std::vector<tdata> &tracks) void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata> &tracks, uint32_t total_blocks, bool has_flux) { - w32(data, 80, 0x50414D54); // TMAP - w32(data, 84, 160); // size + put_u32le(&data[80], 0x50414d54); // TMAP + put_u32le(&data[84], 160); // size uint32_t fstart = 1536 + total_blocks*512; if(has_flux) { - w32(data, fstart, 0x58554c46); - w32(data, fstart+4, 160); + put_u32le(&data[fstart], 0x58554c46); + put_u32le(&data[fstart+4], 160); fstart += 8; } @@ -264,8 +246,8 @@ void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata> } } - w32(data, 248, 0x534B5254); // TRKS - w32(data, 252, 1280 + total_blocks*512); // size + put_u32le(&data[248], 0x534b5254); // TRKS + put_u32le(&data[252], 1280 + total_blocks*512); // size uint8_t tid = 0; uint16_t tb = 3; @@ -274,14 +256,14 @@ void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata> int size = tracks[i].data.size(); int blocks = (size + 511) / 512; memcpy(data.data() + tb*512, tracks[i].data.data(), size); - w16(data, 256 + tid*8, tb); - w16(data, 256 + tid*8 + 2, blocks); - w32(data, 256 + tid*8 + 4, tracks[i].track_size); + put_u16le(&data[256 + tid*8], tb); + put_u16le(&data[256 + tid*8 + 2], blocks); + put_u32le(&data[256 + tid*8 + 4], tracks[i].track_size); tb += blocks; tid ++; } - w32(data, 8, crc32r(&data[12], data.size() - 12)); + put_u32le(&data[8], crc32r(&data[12], data.size() - 12)); } @@ -316,10 +298,10 @@ const uint8_t woz_format::signature2[8] = { 0x57, 0x4f, 0x5a, 0x32, 0xff, 0x0a, int woz_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[8]; - size_t actual; - io.read_at(0, header, 8, actual); - if (!memcmp(header, signature, 8)) return FIFID_SIGN; - if (!memcmp(header, signature2, 8)) return FIFID_SIGN; + auto const [err, actual] = read_at(io, 0, header, 8); + if(err || (8 != actual)) return 0; + if(!memcmp(header, signature, 8)) return FIFID_SIGN; + if(!memcmp(header, signature2, 8)) return FIFID_SIGN; return 0; } @@ -328,9 +310,9 @@ bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::ve 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); + auto const [err, img, actual] = read_at(io, 0, image_size); + if(err || (actual != image_size)) + return false; // Check signature if((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8))) @@ -340,29 +322,29 @@ bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::ve if(!memcmp(&img[0], signature2, 8)) woz_vers = 2; // Check integrity - uint32_t crc = crc32r(&img[12], img.size() - 12); - if(crc != r32(img, 8)) + uint32_t crc = crc32r(&img[12], image_size - 12); + if(crc != get_u32le(&img[8])) return false; - uint32_t off_info = find_tag(img, 0x4f464e49); - uint32_t off_tmap = find_tag(img, 0x50414d54); - uint32_t off_trks = find_tag(img, 0x534b5254); -// uint32_t off_writ = find_tag(img, 0x54495257); + uint32_t off_info = find_tag(img, image_size, 0x4f464e49); + uint32_t off_tmap = find_tag(img, image_size, 0x50414d54); + uint32_t off_trks = find_tag(img, image_size, 0x534b5254); +// uint32_t off_writ = find_tag(img, image_size, 0x54495257); if(!off_info || !off_tmap || !off_trks) return false; - uint32_t info_vers = r8(img, off_info + 0); + uint32_t info_vers = img[off_info + 0]; if(info_vers < 1 || info_vers > 3) return false; - uint16_t off_flux = info_vers < 3 ? 0 : r16(img, off_info + 46); - uint16_t flux_size = info_vers < 3 ? 0 : r16(img, off_info + 48); + uint16_t off_flux = (info_vers < 3) ? 0 : get_u16le(&img[off_info + 46]); + uint16_t flux_size = (info_vers < 3) ? 0 : get_u16le(&img[off_info + 48]); if(!flux_size) off_flux = 0; - bool is_35 = r8(img, off_info + 1) == 2; + bool is_35 = img[off_info + 1] == 2; if((form_factor == floppy_image::FF_35 && !is_35) || (form_factor == floppy_image::FF_525 && is_35)) return false; @@ -374,36 +356,36 @@ bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::ve else image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); - if (woz_vers == 1) { + if(woz_vers == 1) { for (unsigned int trkid = 0; trkid != limit; trkid++) { int head = is_35 && trkid >= 80 ? 1 : 0; int track = is_35 ? trkid % 80 : trkid / 4; int subtrack = is_35 ? 0 : trkid & 3; - uint8_t idx = r8(img, off_tmap + trkid); + uint8_t idx = img[off_tmap + trkid]; if(idx != 0xff) { uint32_t boff = off_trks + 6656*idx; - if (r16(img, boff + 6648) == 0) + if (get_u16le(&img[boff + 6648]) == 0) return false; - generate_track_from_bitstream(track, head, &img[boff], r16(img, boff + 6648), image, subtrack, r16(img, boff + 6650)); + generate_track_from_bitstream(track, head, &img[boff], get_u16le(&img[boff + 6648]), image, subtrack, get_u16le(&img[boff + 6650])); if(is_35 && !track && head) image.set_variant(floppy_image::DSDD); } } - } else if (woz_vers == 2) { + } else if(woz_vers == 2) { for (unsigned int trkid = 0; trkid != limit; trkid++) { int head = is_35 && trkid & 1 ? 1 : 0; int track = is_35 ? trkid >> 1 : trkid / 4; int subtrack = is_35 ? 0 : trkid & 3; - uint8_t idx = r8(img, off_tmap + trkid); - uint8_t fidx = off_flux ? r8(img, off_flux*512 + 8 + trkid) : 0xff; + uint8_t idx = img[off_tmap + trkid]; + uint8_t fidx = off_flux ? img[off_flux*512 + 8 + trkid] : 0xff; - if(fidx != 0xff) - load_flux_track(img, image, head, track, subtrack, fidx, off_trks); + if(fidx != 0xff) { + load_flux_track(&img[0], image, head, track, subtrack, fidx, off_trks); - else if(idx != 0xff) { - if(!load_bitstream_track(img, image, head, track, subtrack, idx, off_trks, !is_35, is_35 && !track && head)) + } else if(idx != 0xff) { + if(!load_bitstream_track(&img[0], image, head, track, subtrack, idx, off_trks, !is_35, is_35 && !track && head)) return false; } } @@ -445,31 +427,30 @@ bool woz_format::save(util::random_read_write &io, const std::vector<uint32_t> & memcpy(&data[0], signature2, 8); - w32(data, 12, 0x4F464E49); // INFO - w32(data, 16, 60); // size - data[20] = 3; // chunk version + put_u32le(&data[12], 0x4f464e49); // INFO + put_u32le(&data[16], 60); // size + data[20] = 3; // chunk version data[21] = image.get_form_factor() == floppy_image::FF_525 ? 1 : 2; - data[22] = 0; // not write protected - data[23] = 1; // synchronized, since our internal format is - data[24] = 1; // weak bits are generated, not stored + data[22] = 0; // not write protected + data[23] = 1; // synchronized, since our internal format is + data[24] = 1; // weak bits are generated, not stored data[25] = 'M'; data[26] = 'A'; data[27] = 'M'; data[28] = 'E'; memset(&data[29], ' ', 32-4); data[57] = twosided ? 2 : 1; - data[58] = 0; // boot sector unknown + data[58] = 0; // boot sector unknown data[59] = image.get_form_factor() == floppy_image::FF_525 ? 32 : image.get_variant() == floppy_image::DSHD ? 8 : 16; - w16(data, 60, 0); // compatibility unknown - w16(data, 62, 0); // needed ram unknown - w16(data, 64, max_blocks); - w16(data, 66, has_flux ? total_blocks+3 : 0); - w16(data, 68, max_blocks); + put_u16le(&data[60], 0); // compatibility unknown + put_u16le(&data[62], 0); // needed RAM unknown + put_u16le(&data[64], max_blocks); + put_u16le(&data[66], has_flux ? total_blocks+3 : 0); + put_u16le(&data[68], max_blocks); save_tracks(data, tracks, total_blocks, has_flux); - size_t actual; - io.write_at(0, data.data(), data.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, data.data(), data.size()); // FIXME: check for errors return true; } @@ -505,9 +486,9 @@ const uint8_t moof_format::signature[8] = { 0x4d, 0x4f, 0x4f, 0x46, 0xff, 0x0a, int moof_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[8]; - size_t actual; - io.read_at(0, header, 8, actual); - if (!memcmp(header, signature, 8)) return FIFID_SIGN; + auto const [err, actual] = read_at(io, 0, header, 8); + if(err || (8 != actual)) return 0; + if(!memcmp(header, signature, 8)) return FIFID_SIGN; return 0; } @@ -516,37 +497,37 @@ bool moof_format::load(util::random_read &io, uint32_t form_factor, const std::v 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); + auto const [err, img, actual] = read_at(io, 0, image_size); + if(err || (actual != image_size)) + return false; // Check signature if(memcmp(&img[0], signature, 8)) return false; // Check integrity - uint32_t crc = crc32r(&img[12], img.size() - 12); - if(crc != r32(img, 8)) + uint32_t crc = crc32r(&img[12], image_size - 12); + if(crc != get_u32le(&img[8])) return false; - uint32_t off_info = find_tag(img, 0x4f464e49); - uint32_t off_tmap = find_tag(img, 0x50414d54); - uint32_t off_trks = find_tag(img, 0x534b5254); + uint32_t off_info = find_tag(img, image_size, 0x4f464e49); + uint32_t off_tmap = find_tag(img, image_size, 0x50414d54); + uint32_t off_trks = find_tag(img, image_size, 0x534b5254); if(!off_info || !off_tmap || !off_trks) return false; - uint32_t info_vers = r8(img, off_info + 0); + uint32_t info_vers = img[off_info + 0]; if(info_vers != 1) return false; - uint16_t off_flux = r16(img, off_info + 40); - uint16_t flux_size = r16(img, off_info + 42); + uint16_t off_flux = get_u16le(&img[off_info + 40]); + uint16_t flux_size = get_u16le(&img[off_info + 42]); if(!flux_size) off_flux = 0; - switch(r8(img, off_info + 1)) { + switch(img[off_info + 1]) { case 1: image.set_form_variant(floppy_image::FF_35, floppy_image::SSDD); break; @@ -564,14 +545,14 @@ bool moof_format::load(util::random_read &io, uint32_t form_factor, const std::v int head = trkid & 1; int track = trkid >> 1; - uint8_t idx = r8(img, off_tmap + trkid); - uint8_t fidx = off_flux ? r8(img, off_flux*512 + 8 + trkid) : 0xff; + uint8_t idx = img[off_tmap + trkid]; + uint8_t fidx = off_flux ? img[off_flux*512 + 8 + trkid] : 0xff; - if(fidx != 0xff) - load_flux_track(img, image, head, track, 0, fidx, off_trks); + if(fidx != 0xff) { + load_flux_track(&img[0], image, head, track, 0, fidx, off_trks); - else if(idx != 0xff) { - if(!load_bitstream_track(img, image, head, track, 0, idx, off_trks, false, false)) + } else if(idx != 0xff) { + if(!load_bitstream_track(&img[0], image, head, track, 0, idx, off_trks, false, false)) return false; } } @@ -606,27 +587,26 @@ bool moof_format::save(util::random_read_write &io, const std::vector<uint32_t> memcpy(&data[0], signature, 8); - w32(data, 12, 0x4F464E49); // INFO - w32(data, 16, 60); // size - data[20] = 1; // chunk version + put_u32le(&data[12], 0x4f464e49); // INFO + put_u32le(&data[16], 60); // size + data[20] = 1; // chunk version data[21] = is_hd ? 3 : twosided ? 2 : 1; // variant - data[22] = 0; // not write protected - data[23] = 1; // synchronized, since our internal format is - data[24] = is_hd ? 8 : 16; // optimal timing + data[22] = 0; // not write protected + data[23] = 1; // synchronized, since our internal format is + data[24] = is_hd ? 8 : 16; // optimal timing data[25] = 'M'; data[26] = 'A'; data[27] = 'M'; data[28] = 'E'; memset(&data[29], ' ', 32-4); - data[57] = 0; // pad - w16(data, 58, max_blocks); - w16(data, 60, has_flux ? total_blocks+3 : 0); - w16(data, 62, max_blocks); + data[57] = 0; // pad + put_u16le(&data[58], max_blocks); + put_u16le(&data[60], has_flux ? total_blocks+3 : 0); + put_u16le(&data[62], max_blocks); save_tracks(data, tracks, total_blocks, has_flux); - size_t actual; - io.write_at(0, data.data(), data.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, data.data(), data.size()); // FIXME: check for errors return true; } diff --git a/src/lib/formats/as_dsk.h b/src/lib/formats/as_dsk.h index ec0a785d151..8871bc1ed11 100644 --- a/src/lib/formats/as_dsk.h +++ b/src/lib/formats/as_dsk.h @@ -23,16 +23,8 @@ protected: bool flux = false; }; - static uint32_t r32(const std::vector<uint8_t> &data, uint32_t offset); - static uint16_t r16(const std::vector<uint8_t> &data, uint32_t offset); - static uint8_t r8(const std::vector<uint8_t> &data, uint32_t offset); - static void w32(std::vector<uint8_t> &data, int offset, uint32_t value); - static void w16(std::vector<uint8_t> &data, int offset, uint16_t value); - static uint32_t crc32r(const uint8_t *data, uint32_t size); - static uint32_t find_tag(const std::vector<uint8_t> &data, uint32_t tag); - - static bool load_bitstream_track(const std::vector<uint8_t> &img, floppy_image &image, int head, int track, int subtrack, uint8_t idx, uint32_t off_trks, bool may_be_short, bool set_variant); - static void load_flux_track(const std::vector<uint8_t> &img, floppy_image &image, int head, int track, int subtrack, uint8_t fidx, uint32_t off_trks); + static bool load_bitstream_track(const uint8_t *img, floppy_image &image, int head, int track, int subtrack, uint8_t idx, uint32_t off_trks, bool may_be_short, bool set_variant); + static void load_flux_track(const uint8_t *img, floppy_image &image, int head, int track, int subtrack, uint8_t fidx, uint32_t off_trks); static tdata analyze_for_save(const floppy_image &image, int head, int track, int subtrack, int speed_zone); static std::pair<int, int> count_blocks(const std::vector<tdata> &tracks); diff --git a/src/lib/formats/cassimg.cpp b/src/lib/formats/cassimg.cpp index 38be38db9b1..d1ae4651210 100644 --- a/src/lib/formats/cassimg.cpp +++ b/src/lib/formats/cassimg.cpp @@ -366,8 +366,7 @@ void cassette_image::change(util::random_read_write::ptr &&io, const Format *for void cassette_image::image_read(void *buffer, uint64_t offset, size_t length) { - size_t actual; - m_io->read_at(offset, buffer, length, actual); + /*auto const [err, actual] =*/ read_at(*m_io, offset, buffer, length); // FIXME: check for errors and premature EOF } @@ -383,8 +382,7 @@ uint8_t cassette_image::image_read_byte(uint64_t offset) void cassette_image::image_write(const void *buffer, uint64_t offset, size_t length) { - size_t actual; - m_io->write_at(offset, buffer, length, actual); + /*auto const [err, actual] =*/ write_at(*m_io, offset, buffer, length); // FIXME: check for errors } diff --git a/src/lib/formats/cbm_crt.cpp b/src/lib/formats/cbm_crt.cpp index b088507208f..6bc9e0f8d23 100644 --- a/src/lib/formats/cbm_crt.cpp +++ b/src/lib/formats/cbm_crt.cpp @@ -46,6 +46,8 @@ #include "osdcore.h" // osd_printf_* +#include <tuple> + //************************************************************************** // MACROS/CONSTANTS @@ -137,8 +139,7 @@ std::string cbm_crt_get_card(util::core_file &file) { // read the header cbm_crt_header header; - size_t actual; - std::error_condition err = file.read(&header, CRT_HEADER_LENGTH, actual); + auto const [err, actual] = read(file, &header, CRT_HEADER_LENGTH); if (!err && (CRT_HEADER_LENGTH == actual) && !memcmp(header.signature, CRT_SIGNATURE, 16)) { @@ -157,11 +158,13 @@ std::string cbm_crt_get_card(util::core_file &file) bool cbm_crt_read_header(util::core_file &file, size_t *roml_size, size_t *romh_size, int *exrom, int *game) { + std::error_condition err; size_t actual; // read the header cbm_crt_header header; - if (file.read(&header, CRT_HEADER_LENGTH, actual)) + std::tie(err, actual) = read(file, &header, CRT_HEADER_LENGTH); + if (err) return false; if ((CRT_HEADER_LENGTH != actual) || (memcmp(header.signature, CRT_SIGNATURE, 16) != 0)) @@ -184,7 +187,8 @@ bool cbm_crt_read_header(util::core_file &file, size_t *roml_size, size_t *romh_ while (!file.eof()) { cbm_crt_chip chip; - if (file.read(&chip, CRT_CHIP_LENGTH, actual) || (CRT_CHIP_LENGTH != actual)) + std::tie(err, actual) = read(file, &chip, CRT_CHIP_LENGTH); + if (err || (CRT_CHIP_LENGTH != actual)) return false; const uint16_t address = get_u16be(chip.start_address); @@ -228,21 +232,22 @@ bool cbm_crt_read_data(util::core_file &file, uint8_t *roml, uint8_t *romh) while (!file.eof()) { + std::error_condition err; size_t actual; cbm_crt_chip chip; - if (file.read(&chip, CRT_CHIP_LENGTH, actual) || (CRT_CHIP_LENGTH != actual)) + std::tie(err, actual) = read(file, &chip, CRT_CHIP_LENGTH); + if (err || (CRT_CHIP_LENGTH != actual)) return false; const uint16_t address = get_u16be(chip.start_address); const uint16_t size = get_u16be(chip.image_size); - std::error_condition err; switch (address) { - case 0x8000: err = file.read(roml + roml_offset, size, actual); roml_offset += size; break; - case 0xa000: err = file.read(romh + romh_offset, size, actual); romh_offset += size; break; - case 0xe000: err = file.read(romh + romh_offset, size, actual); romh_offset += size; break; + case 0x8000: std::tie(err, actual) = read(file, roml + roml_offset, size); roml_offset += size; break; + case 0xa000: std::tie(err, actual) = read(file, romh + romh_offset, size); romh_offset += size; break; + case 0xe000: std::tie(err, actual) = read(file, romh + romh_offset, size); romh_offset += size; break; // FIXME: surely one needs to report an error or skip over the data if the load address is not recognised? } if (err) // TODO: check size - all bets are off if the address isn't recognised anyway diff --git a/src/lib/formats/ccvf_dsk.cpp b/src/lib/formats/ccvf_dsk.cpp index 829be2a0019..d2c8da8e083 100644 --- a/src/lib/formats/ccvf_dsk.cpp +++ b/src/lib/formats/ccvf_dsk.cpp @@ -50,8 +50,10 @@ const ccvf_format::format ccvf_format::file_formats[] = { int ccvf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { char h[36]; - size_t actual; - io.read_at(0, h, 36, actual); + auto const [err, actual] = read_at(io, 0, h, 36); + if (err || (36 != actual)) + return 0; + if (!memcmp(h, "Compucolor Virtual Floppy Disk Image", 36)) return FIFID_SIGN; @@ -96,9 +98,9 @@ bool ccvf_format::load(util::random_read &io, uint32_t form_factor, const std::v if (io.length(size)) return false; - std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto [err, img, actual] = read_at(io, 0, size); + if (err || (actual != size)) + return false; std::string ccvf = std::string((const char *)&img[0], size); std::vector<uint8_t> bytes(78720); diff --git a/src/lib/formats/concept_dsk.cpp b/src/lib/formats/concept_dsk.cpp index e026090e19f..52950b3e57d 100644 --- a/src/lib/formats/concept_dsk.cpp +++ b/src/lib/formats/concept_dsk.cpp @@ -114,8 +114,7 @@ bool cc525dsdd_format::load(util::random_read &io, uint32_t form_factor, const s int track_size = sector_count*512; 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); + /*auto const [err, acutal] =*/ read_at(io, (track*head_count + head) * track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(cc_9_desc, track, head, sectors, sector_count, 100000, image); } } @@ -146,8 +145,7 @@ bool cc525dsdd_format::save(util::random_read_write &io, const std::vector<uint3 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); - size_t actual; - io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors } } diff --git a/src/lib/formats/coupedsk.cpp b/src/lib/formats/coupedsk.cpp index 6e43aa9c301..a3edc5c7b40 100644 --- a/src/lib/formats/coupedsk.cpp +++ b/src/lib/formats/coupedsk.cpp @@ -94,8 +94,7 @@ bool mgt_format::load(util::random_read &io, uint32_t form_factor, const std::ve int track_size = sector_count*512; for(int head=0; head < 2; head++) { for(int track=0; track < 80; track++) { - size_t actual; - io.read_at((track*2+head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ read_at(io, (track*2+head)*track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(desc_10, track, head, sectors, sector_count+1, 100000, image); } } @@ -120,8 +119,7 @@ bool mgt_format::save(util::random_read_write &io, const std::vector<uint32_t> & 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); - size_t actual; - io.write_at((track*2+head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, (track*2+head)*track_size, sectdata, track_size); // FIXME: check for errors } } diff --git a/src/lib/formats/cp68_dsk.cpp b/src/lib/formats/cp68_dsk.cpp index c6eb005f1c0..5872da350b6 100644 --- a/src/lib/formats/cp68_dsk.cpp +++ b/src/lib/formats/cp68_dsk.cpp @@ -51,6 +51,9 @@ #include "ioprocs.h" +#include <tuple> + + namespace { class cp68_formats : public wd177x_format @@ -115,8 +118,8 @@ int cp68_format::find_size(util::random_read &io, uint32_t form_factor, const st std::error_condition ec; // Look at the boot sector. - ec = io.read_at(128 * 0, &boot0, sizeof(boot0), actual); - if (ec || actual == 0) + std::tie(ec, actual) = read_at(io, 128 * 0, &boot0, sizeof(boot0)); + if (ec || actual == 0) // FIXME: what's the actual minimum size boot sector to probe? return -1; uint8_t boot0_sector_id = 1; // uint8_t boot1_sector_id = 2; @@ -125,8 +128,7 @@ int cp68_format::find_size(util::random_read &io, uint32_t form_factor, const st // set the numbering of the first two sectors. If this is shown to not // be practical in some common cases then a separate format variant // might be needed. - if (boot0[0] == 0xbd && boot0[3] == 0x86) - { + if (boot0[0] == 0xbd && boot0[3] == 0x86) { // Found a 6800 jsr and ldaa, looks like a CP68 6800 boot sector. boot0_sector_id = 0; } @@ -135,8 +137,8 @@ int cp68_format::find_size(util::random_read &io, uint32_t form_factor, const st const format &f = cp68_formats::formats[i]; // Look at the system information sector. - ec = io.read_at(f.sector_base_size * 2, &info, sizeof(struct cp68_formats::sysinfo_sector_cp68), actual); - if (ec || actual == 0) + std::tie(ec, actual) = read_at(io, f.sector_base_size * 2, &info, sizeof(struct cp68_formats::sysinfo_sector_cp68)); + if (ec || actual == 0) // FIXME: what's the actual minimum sector size? continue; LOG_FORMATS("CP68 floppy dsk: size %d bytes, %d total sectors, %d remaining bytes, expected form factor %x\n", (uint32_t)size, (uint32_t)size / f.sector_base_size, (uint32_t)size % f.sector_base_size, form_factor); diff --git a/src/lib/formats/cqm_dsk.cpp b/src/lib/formats/cqm_dsk.cpp index 47fa0fddfbe..850d223da7a 100644 --- a/src/lib/formats/cqm_dsk.cpp +++ b/src/lib/formats/cqm_dsk.cpp @@ -258,8 +258,9 @@ const char *cqm_format::extensions() const noexcept int cqm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[3]; - size_t actual; - io.read_at(0, h, 3, actual); + auto const [err, actual] = read_at(io, 0, h, 3); + if (err || (3 != actual)) + return 0; if (h[0] == 'C' && h[1] == 'Q' && h[2] == 0x14) return FIFID_SIGN; @@ -269,11 +270,10 @@ int cqm_format::identify(util::random_read &io, uint32_t form_factor, const std: bool cqm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - 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.read_at(0, header, CQM_HEADER_SIZE, actual); + read_at(io, 0, header, CQM_HEADER_SIZE); // FIXME: check for errors and premature EOF int sector_size = get_u16le(&header[0x03]); int sector_per_track = get_u16le(&header[0x10]); @@ -317,8 +317,9 @@ bool cqm_format::load(util::random_read &io, uint32_t form_factor, const std::ve uint64_t cqm_size; if (io.length(cqm_size)) return false; - std::vector<uint8_t> cqmbuf(cqm_size); - io.read_at(0, &cqmbuf[0], cqm_size, actual); + auto const [err, cqmbuf, actual] = read_at(io, 0, cqm_size); + if (err || (actual != cqm_size)) + return false; // decode the RLE data for (int s = 0, pos = CQM_HEADER_SIZE + comment_size; pos < cqm_size; ) diff --git a/src/lib/formats/d64_dsk.cpp b/src/lib/formats/d64_dsk.cpp index 56fec80c8c9..e1fb024e74d 100644 --- a/src/lib/formats/d64_dsk.cpp +++ b/src/lib/formats/d64_dsk.cpp @@ -127,8 +127,7 @@ int d64_format::get_disk_id_offset(const format &f) const void d64_format::get_disk_id(const format &f, util::random_read &io, uint8_t &id1, uint8_t &id2) const { uint8_t id[2]; - size_t actual; - io.read_at(get_disk_id_offset(f), id, 2, actual); + /*auto const [err, actual] =*/ read_at(io, get_disk_id_offset(f), id, 2); // FIXME: check for errors and premature EOF id1 = id[0]; id2 = id[1]; } @@ -238,8 +237,7 @@ bool d64_format::load(util::random_read &io, uint32_t form_factor, const std::ve img.resize(size); } - size_t actual; - io.read_at(0, &img[0], size, actual); + /*auto const [err, actual] =*/ read_at(io, 0, &img[0], size); // FIXME: check for errors and premature EOF int track_offset = 0, error_offset = f.sector_count*f.sector_base_size; @@ -294,8 +292,7 @@ bool d64_format::save(util::random_read_write &io, const std::vector<uint32_t> & build_sector_description(f, sectdata, 0, 0, sectors, sector_count); extract_sectors(image, f, sectors, track, head, sector_count); - size_t actual; - io.write_at(offset, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, offset, sectdata, track_size); // FIXME: check for errors } } diff --git a/src/lib/formats/d88_dsk.cpp b/src/lib/formats/d88_dsk.cpp index e0482dadbf3..a6b809eb7a1 100644 --- a/src/lib/formats/d88_dsk.cpp +++ b/src/lib/formats/d88_dsk.cpp @@ -35,6 +35,8 @@ #include "ioprocs.h" #include "multibyte.h" +#include <tuple> + #define D88_HEADER_LEN 0x2b0 @@ -411,9 +413,11 @@ int d88_format::identify(util::random_read &io, uint32_t form_factor, const std: return 0; uint8_t h[32]; - size_t actual; - io.read_at(0, h, 32, actual); - if((little_endianize_int32(*(uint32_t *)(h+0x1c)) == size) && + auto const [err, actual] = read_at(io, 0, h, 32); + if(err || (32 != actual)) + return 0; + + if((get_u32le(h+0x1c) == size) && (h[0x1b] == 0x00 || h[0x1b] == 0x10 || h[0x1b] == 0x20 || h[0x1b] == 0x30 || h[0x1b] == 0x40)) return FIFID_SIZE|FIFID_STRUCT; @@ -422,10 +426,13 @@ int d88_format::identify(util::random_read &io, uint32_t form_factor, const std: bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; uint8_t h[32]; - io.read_at(0, h, 32, actual); + std::tie(err, actual) = read_at(io, 0, h, 32); + if(err || (32 != actual)) + return false; int cell_count = 0; int track_count = 0; @@ -471,7 +478,7 @@ bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::ve return false; uint32_t track_pos[164]; - io.read_at(32, track_pos, 164*4, actual); + std::tie(err, actual) = read_at(io, 32, track_pos, 164*4); // FIXME: check for errors and premature EOF uint64_t file_size; if(io.length(file_size)) @@ -493,7 +500,7 @@ bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::ve return true; uint8_t hs[16]; - io.read_at(pos, hs, 16, actual); + std::tie(err, actual) = read_at(io, pos, hs, 16); // FIXME: check for errors and premature EOF pos += 16; uint16_t size = little_endianize_int16(*(uint16_t *)(hs+14)); @@ -520,7 +527,7 @@ bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::ve if(size) { sects[i].data = sect_data + sdatapos; - io.read_at(pos, sects[i].data, size, actual); + std::tie(err, actual) = read_at(io, pos, sects[i].data, size); // FIXME: check for errors and premature EOF pos += size; sdatapos += size; diff --git a/src/lib/formats/dcp_dsk.cpp b/src/lib/formats/dcp_dsk.cpp index f7740a0ea29..dfc9eea27dc 100644 --- a/src/lib/formats/dcp_dsk.cpp +++ b/src/lib/formats/dcp_dsk.cpp @@ -54,8 +54,7 @@ int dcp_format::identify(util::random_read &io, uint32_t form_factor, const std: int heads, tracks, spt, bps, count_tracks = 0; bool is_hdb = false; - size_t actual; - io.read_at(0, h, 0xa2, actual); + /*auto const [err, actual] =*/ read_at(io, 0, h, 0xa2); // FIXME: check for errors and premature EOF // First byte is the disk format (see below in load() for details) switch (h[0]) @@ -119,12 +118,11 @@ int dcp_format::identify(util::random_read &io, uint32_t form_factor, const std: bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; uint8_t h[0xa2]; int heads, tracks, spt, bps; bool is_hdb = false; - io.read_at(0, h, 0xa2, actual); + /*auto const [err, actual] =*/ read_at(io, 0, h, 0xa2); // FIXME: check for errors and premature EOF // First byte is the disk format: switch (h[0]) @@ -221,7 +219,7 @@ bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::ve for (int track = 0; track < tracks; track++) for (int head = 0; head < heads; head++) { - io.read_at(0xa2 + bps * spt * (track * heads + head), sect_data, bps * spt, actual); + /*auto const [err, actual] =*/ read_at(io, 0xa2 + bps * spt * (track * heads + head), sect_data, bps * spt); // FIXME: check for errors and premature EOF for (int i = 0; i < spt; i++) { @@ -241,7 +239,7 @@ bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::ve 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.read_at(0xa2, sect_data, 128 * spt, actual); + /*auto const [err, actual] =*/ read_at(io, 0xa2, sect_data, 128 * spt); // FIXME: check for errors and premature EOF for (int i = 0; i < spt; i++) { @@ -258,7 +256,7 @@ bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::ve 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.read_at(0xa2 + 128 * spt, sect_data, bps * spt, actual); + /*auto const [err, actual] =*/ read_at(io, 0xa2 + 128 * spt, sect_data, bps * spt); // FIXME: check for errors and premature EOF for (int i = 0; i < spt; i++) { @@ -279,7 +277,7 @@ bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::ve for (int track = 1; track < tracks; track++) for (int head = 0; head < heads; head++) { - io.read_at(data_offs + bps * spt * ((track - 1) * heads + head), sect_data, bps * spt, actual); + /*auto const [err, actual] =*/ read_at(io, data_offs + bps * spt * ((track - 1) * heads + head), sect_data, bps * spt); // FIXME: check for errors and premature EOF for (int i = 0; i < spt; i++) { diff --git a/src/lib/formats/dfi_dsk.cpp b/src/lib/formats/dfi_dsk.cpp index a0d216002bd..e2ea1fda0e3 100644 --- a/src/lib/formats/dfi_dsk.cpp +++ b/src/lib/formats/dfi_dsk.cpp @@ -18,6 +18,8 @@ #include "osdcore.h" // osd_printf_* +#include <tuple> + #define NUMBER_OF_MULTIREADS 3 // thresholds for brickwall windowing @@ -63,16 +65,23 @@ bool dfi_format::supports_save() const noexcept int dfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { char sign[4]; - size_t actual; - io.read_at(0, sign, 4, actual); + auto const [err, actual] = read_at(io, 0, sign, 4); + if(err || (4 != actual)) { + return 0; + } return memcmp(sign, "DFE2", 4) ? 0 : FIFID_SIGN; } bool dfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; + char sign[4]; - io.read_at(0, sign, 4, actual); + std::tie(err, actual) = read_at(io, 0, sign, 4); + if(err || (4 != actual)) { + return false; + } if(memcmp(sign, "DFER", 4) == 0) { osd_printf_error("dfi_dsk: Old type Discferret image detected; the MAME Discferret decoder will not handle this properly, bailing out!\n"); return false; @@ -89,7 +98,7 @@ bool dfi_format::load(util::random_read &io, uint32_t form_factor, const std::ve [[maybe_unused]] int rpm=360; // drive rpm while(pos < size) { uint8_t h[10]; - io.read_at(pos, h, 10, actual); + std::tie(err, actual) = read_at(io, pos, h, 10); // FIXME: check for errors and premature EOF uint16_t track = get_u16be(&h[0]); uint16_t head = get_u16be(&h[2]); // Ignore sector @@ -105,7 +114,7 @@ bool dfi_format::load(util::random_read &io, uint32_t form_factor, const std::ve data.resize(tsize); pos += 10; // skip the header, we already read it - io.read_at(pos, &data[0], tsize, actual); + std::tie(err, actual) = read_at(io, pos, &data[0], tsize); // FIXME: check for errors and premature EOF 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/dim_dsk.cpp b/src/lib/formats/dim_dsk.cpp index 52d3dfc1566..1f0902c2859 100644 --- a/src/lib/formats/dim_dsk.cpp +++ b/src/lib/formats/dim_dsk.cpp @@ -13,6 +13,8 @@ #include "ioprocs.h" #include <cstring> +#include <tuple> + dim_format::dim_format() { @@ -36,9 +38,9 @@ const char *dim_format::extensions() const noexcept int dim_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[16]; - - size_t actual; - io.read_at(0xab, h, 16, actual); + auto const [err, actual] = read_at(io, 0xab, h, 16); + if(err || (16 != actual)) + return 0; if(strncmp((const char *)h, "DIFC HEADER", 11) == 0) return FIFID_SIGN; @@ -48,13 +50,16 @@ int dim_format::identify(util::random_read &io, uint32_t form_factor, const std: bool dim_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; 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.read_at(0, &h, 1, actual); + std::tie(err, actual) = read_at(io, 0, &h, 1); + if (err || (1 != actual)) + return false; int spt, gap3, bps, size; switch(h) { @@ -114,7 +119,7 @@ bool dim_format::load(util::random_read &io, uint32_t form_factor, const std::ve sects[i].deleted = false; sects[i].bad_crc = false; sects[i].data = §_data[sdatapos]; - io.read_at(offset, sects[i].data, bps, actual); + std::tie(err, actual) = read_at(io, offset, sects[i].data, bps); // FIXME: check for errors and premature EOF offset += bps; sdatapos += bps; } diff --git a/src/lib/formats/dip_dsk.cpp b/src/lib/formats/dip_dsk.cpp index ecbd12bde1e..3ef8261d1da 100644 --- a/src/lib/formats/dip_dsk.cpp +++ b/src/lib/formats/dip_dsk.cpp @@ -72,8 +72,7 @@ bool dip_format::load(util::random_read &io, uint32_t form_factor, const std::ve for (int track = 0; track < tracks; track++) for (int head = 0; head < heads; head++) { - size_t actual; - io.read_at(0x100 + bps * spt * (track * heads + head), sect_data, bps * spt, actual); + /*auto const [err, actual] =*/ read_at(io, 0x100 + bps * spt * (track * heads + head), sect_data, bps * spt); // FIXME: check for errors and premature EOF for (int i = 0; i < spt; i++) { diff --git a/src/lib/formats/dmk_dsk.cpp b/src/lib/formats/dmk_dsk.cpp index 68257ff1f2b..c79987d3656 100644 --- a/src/lib/formats/dmk_dsk.cpp +++ b/src/lib/formats/dmk_dsk.cpp @@ -8,7 +8,7 @@ TODO: - Add write/format support. -- Check support on other drivers besides msx. +- Check support on other drivers besides MSX. *********************************************************************/ @@ -18,9 +18,13 @@ TODO: #include "ioprocs.h" #include "multibyte.h" +#include <tuple> + namespace { +constexpr int HEADER_SIZE = 16; + uint32_t wide_fm(uint16_t val) { uint32_t res = 0; @@ -72,10 +76,10 @@ int dmk_format::identify(util::random_read &io, uint32_t form_factor, const std: if (io.length(size)) return 0; - const int header_size = 16; - uint8_t header[header_size]; - size_t actual; - io.read_at(0, header, header_size, actual); + uint8_t header[HEADER_SIZE]; + auto const [err, actual] = read_at(io, 0, header, HEADER_SIZE); + if (err || (HEADER_SIZE != actual)) + return 0; int tracks = header[1]; int track_size = get_u16le(&header[2]); @@ -99,7 +103,7 @@ int dmk_format::identify(util::random_read &io, uint32_t form_factor, const std: return 0; } - if (size == header_size + heads * tracks * track_size) + if (size == HEADER_SIZE + heads * tracks * track_size) { return FIFID_STRUCT|FIFID_SIZE; } @@ -110,11 +114,13 @@ int dmk_format::identify(util::random_read &io, uint32_t form_factor, const std: bool dmk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; - const int header_size = 16; - uint8_t header[header_size]; - io.read_at(0, header, header_size, actual); + uint8_t header[HEADER_SIZE]; + std::tie(err, actual) = read_at(io, 0, header, HEADER_SIZE); + if (err || (HEADER_SIZE != actual)) + return false; const int tracks = header[1]; const int track_size = get_u16le(&header[2]); @@ -161,7 +167,7 @@ bool dmk_format::load(util::random_read &io, uint32_t form_factor, const std::ve int iam_location = -1; // Read track - io.read_at(header_size + (heads * track + head) * track_size, &track_data[0], track_size, actual); + std::tie(err, actual) = read_at(io, HEADER_SIZE + (heads * track + head) * track_size, &track_data[0], track_size); // FIXME: check for errors and premature EOF for (int i = 0; i < 64*2+1; i++) { diff --git a/src/lib/formats/ds9_dsk.cpp b/src/lib/formats/ds9_dsk.cpp index 396a6ae3235..c0cbf0dccbc 100644 --- a/src/lib/formats/ds9_dsk.cpp +++ b/src/lib/formats/ds9_dsk.cpp @@ -109,8 +109,7 @@ bool ds9_format::load(util::random_read &io, uint32_t form_factor, const std::ve { for (int head = 0; head < head_count; head++) { - size_t actual; - io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ read_at(io, (track * head_count + head) * track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image); } } diff --git a/src/lib/formats/dsk_dsk.cpp b/src/lib/formats/dsk_dsk.cpp index adfbe7735ed..e10e94f80be 100644 --- a/src/lib/formats/dsk_dsk.cpp +++ b/src/lib/formats/dsk_dsk.cpp @@ -311,13 +311,14 @@ bool dsk_format::supports_save() const noexcept int dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[16]; - - size_t actual; - io.read_at(0, &header, sizeof(header), actual); - if ( memcmp( header, DSK_FORMAT_HEADER, 8 ) ==0) { + auto const [err, actual] = read_at(io, 0, &header, sizeof(header)); + if (err) { + return 0; + } + if ((8 <= actual) && !memcmp(header, DSK_FORMAT_HEADER, 8)) { return FIFID_SIGN; } - if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) { + if ((16 <= actual) && !memcmp(header, EXT_FORMAT_HEADER, 16)) { return FIFID_SIGN; } return 0; @@ -356,8 +357,6 @@ struct sector_header bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; - uint8_t header[0x100]; bool extendformat = false; @@ -365,7 +364,7 @@ bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::ve if (io.length(image_size)) return false; - io.read_at(0, &header, sizeof(header), actual); + read_at(io, 0, &header, sizeof(header)); // FIXME: check for errors and premature EOF if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) { extendformat = true; } @@ -431,7 +430,7 @@ bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::ve if(track_offsets[(track<<1)+side] >= image_size) continue; track_header tr; - io.read_at(track_offsets[(track<<1)+side], &tr, sizeof(tr), actual); + read_at(io, track_offsets[(track<<1)+side], &tr, sizeof(tr)); // FIXME: check for errors and premature EOF // skip if there are no sectors in this track if (tr.number_of_sector == 0) @@ -441,7 +440,7 @@ bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::ve int first_sector_code = -1; for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; - io.read_at(track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector), actual); + read_at(io, track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector)); // FIXME: check for errors and premature EOF if (j == 0) first_sector_code = sector.sector_size_code; @@ -460,7 +459,7 @@ bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::ve for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; - io.read_at(track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector), actual); + read_at(io, track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector)); // FIXME: check for errors and premature EOF sects[j].track = sector.track; sects[j].head = sector.side; @@ -483,7 +482,7 @@ bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::ve if(!(sector.fdc_status_reg1 & 0x04)) { sects[j].data = sect_data + sdatapos; - io.read_at(pos, sects[j].data, sects[j].actual_size, actual); + read_at(io, pos, sects[j].data, sects[j].actual_size); // FIXME: check for errors and premature EOF sdatapos += sects[j].actual_size; } else diff --git a/src/lib/formats/dvk_mx_dsk.cpp b/src/lib/formats/dvk_mx_dsk.cpp index 83eb0782f96..c384dc38e00 100644 --- a/src/lib/formats/dvk_mx_dsk.cpp +++ b/src/lib/formats/dvk_mx_dsk.cpp @@ -103,8 +103,7 @@ int dvk_mx_format::identify(util::random_read &io, uint32_t form_factor, const s if (track_count) { uint8_t sectdata[512]; - size_t actual; - io.read_at(512, sectdata, 512, actual); + /*auto const [err, actual] =*/ read_at(io, 512, sectdata, 512); // FIXME: check for errors and premature EOF // check value in RT-11 home block. see src/tools/imgtool/modules/rt11.cpp if (get_u16le(§data[0724]) == 6) return FIFID_SIGN|FIFID_SIZE; @@ -137,8 +136,7 @@ bool dvk_mx_format::load(util::random_read &io, uint32_t form_factor, const std: { for (int head = 0; head < head_count; head++) { - size_t actual; - io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ read_at(io, (track * head_count + head) * track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(dvk_mx_new_desc, track, head, sectors, sector_count, 45824, image); } } @@ -177,10 +175,10 @@ bool dvk_mx_format::save(util::random_read_write &io, const std::vector<uint32_t uint8_t sector_data[MX_SECTORS * MX_SECTOR_SIZE]; if (get_next_sector(bitstream, sector_data)) { - unsigned offset_in_image = (cyl * heads + head) * MX_SECTOR_SIZE * MX_SECTORS; - size_t actual; + unsigned const offset_in_image = (cyl * heads + head) * MX_SECTOR_SIZE * MX_SECTORS; res = true; - io.write_at(offset_in_image, sector_data, MX_SECTOR_SIZE * MX_SECTORS, actual); + // FIXME: check for errors + /*auto const [err, actual] =*/ write_at(io, offset_in_image, sector_data, MX_SECTOR_SIZE * MX_SECTORS); } } } diff --git a/src/lib/formats/esq16_dsk.cpp b/src/lib/formats/esq16_dsk.cpp index a7e181b2cc7..f487e835665 100644 --- a/src/lib/formats/esq16_dsk.cpp +++ b/src/lib/formats/esq16_dsk.cpp @@ -113,8 +113,7 @@ bool esqimg_format::load(util::random_read &io, uint32_t form_factor, const std: int track_size = sector_count*512; 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); + /*auto const [err, actual] =*/ read_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(esq_10_desc, track, head, sectors, sector_count, 110528, image); } } @@ -145,8 +144,7 @@ bool esqimg_format::save(util::random_read_write &io, const std::vector<uint32_t 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); - size_t actual; - io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors } } diff --git a/src/lib/formats/esq8_dsk.cpp b/src/lib/formats/esq8_dsk.cpp index fb3bdb112d6..b7225d839a9 100644 --- a/src/lib/formats/esq8_dsk.cpp +++ b/src/lib/formats/esq8_dsk.cpp @@ -132,8 +132,7 @@ bool esq8img_format::load(util::random_read &io, uint32_t form_factor, const std { for(int head=0; head < head_count; head++) { - size_t actual; - io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ read_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(esq_6_desc, track, head, sectors, sector_count, 109376, image); } } @@ -180,8 +179,7 @@ bool esq8img_format::save(util::random_read_write &io, const std::vector<uint32_ return false; } - size_t actual; - io.write_at(file_offset, sectors[sector].data(), sector_expected_size, actual); + /*auto const [err, actual] =*/ write_at(io, file_offset, sectors[sector].data(), sector_expected_size); // FIXME: check for errors file_offset += sector_expected_size; } } diff --git a/src/lib/formats/fdd_dsk.cpp b/src/lib/formats/fdd_dsk.cpp index fc0741f2f5a..7519eb593dd 100644 --- a/src/lib/formats/fdd_dsk.cpp +++ b/src/lib/formats/fdd_dsk.cpp @@ -62,10 +62,11 @@ const char *fdd_format::extensions() const noexcept int fdd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[7]; - size_t actual; - io.read_at(0, h, 7, actual); + auto const [err, actual] = read_at(io, 0, h, 7); // FIXME: should it really be reading six bytes? also check for premature EOF. + if (err) + return false; - if (strncmp((const char *)h, "VFD1.0", 6) == 0) + if (memcmp(h, "VFD1.0", 6) == 0) return FIFID_SIGN; return 0; @@ -92,8 +93,7 @@ bool fdd_format::load(util::random_read &io, uint32_t form_factor, const std::ve for (int sect = 0; sect < 26; sect++) { // read sector map for this sector - size_t actual; - io.read_at(pos, hsec, 0x0c, actual); + /*auto const [err, actual] =*/ read_at(io, pos, hsec, 0x0c); // FIXME: check for errors and premature EOF pos += 0x0c; if (hsec[0] == 0xff) // unformatted/unused sector @@ -125,11 +125,10 @@ bool fdd_format::load(util::random_read &io, uint32_t form_factor, const std::ve 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.read_at(sec_offs[cur_sec_map], sect_data + cur_pos, sector_size, actual); + /*auto const [err, actual] =*/ read_at(io, sec_offs[cur_sec_map], sect_data + cur_pos, sector_size); // FIXME: check for errors and premature EOF sects[i].track = tracks[cur_sec_map]; sects[i].head = heads[cur_sec_map]; diff --git a/src/lib/formats/fdos_dsk.cpp b/src/lib/formats/fdos_dsk.cpp index 2980376160e..138ad986011 100644 --- a/src/lib/formats/fdos_dsk.cpp +++ b/src/lib/formats/fdos_dsk.cpp @@ -39,9 +39,12 @@ #include "fdos_dsk.h" #include "imageutl.h" -#include "multibyte.h" #include "ioprocs.h" +#include "multibyte.h" + +#include <tuple> + namespace { @@ -116,7 +119,7 @@ int fdos_format::find_size(util::random_read &io, uint32_t form_factor, const st // 00330 2403 DE OB RESTRT LDX PROGX // Should be $BD and $DE respectively // There could be additional variations - ec = io.read_at(0, &boot0, f.sector_base_size, actual); + std::tie(ec, actual) = read_at(io, 0, &boot0, f.sector_base_size); if (ec || actual != f.sector_base_size) return -1; if (boot0[0] != 0xbd && boot0[3] != 0xde) @@ -129,7 +132,7 @@ int fdos_format::find_size(util::random_read &io, uint32_t form_factor, const st form_factor); // Directory entries start at Track 2 Sector 0 - ec = io.read_at(2 * f.sector_count * f.sector_base_size, &info, sizeof(struct fdos_formats::dirent_entry_fdos), actual); + std::tie(ec, actual) = read_at(io, 2 * f.sector_count * f.sector_base_size, &info, sizeof(struct fdos_formats::dirent_entry_fdos)); if (ec || actual != sizeof(struct fdos_formats::dirent_entry_fdos)) continue; diff --git a/src/lib/formats/flex_dsk.cpp b/src/lib/formats/flex_dsk.cpp index 778e6c990b9..11a72963471 100644 --- a/src/lib/formats/flex_dsk.cpp +++ b/src/lib/formats/flex_dsk.cpp @@ -91,12 +91,11 @@ int flex_format::find_size(util::random_read &io, uint32_t form_factor, const st return -1; uint8_t boot0[256], boot1[256]; - size_t actual; // Look at the boot sector. // Density, sides, link?? - io.read_at(256 * 0, &boot0, sizeof(boot0), actual); - io.read_at(256 * 1, &boot1, sizeof(boot1), actual); + read_at(io, 256 * 0, &boot0, sizeof(boot0)); // FIXME: check for errors and premature EOF + read_at(io, 256 * 1, &boot1, sizeof(boot1)); // FIXME: check for errors and premature EOF 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); @@ -129,7 +128,7 @@ int flex_format::find_size(util::random_read &io, uint32_t form_factor, const st if (f.sector_base_size == 128) { // FLEX 1.0: Look at the system information sector. sysinfo_sector_flex10 info; - io.read_at(f.sector_base_size * 2, &info, sizeof(struct sysinfo_sector_flex10), actual); + read_at(io, f.sector_base_size * 2, &info, sizeof(struct sysinfo_sector_flex10)); // FIXME: check for errors and premature EOF 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 / f.sector_base_size, (uint32_t)size % f.sector_base_size, form_factor); @@ -142,7 +141,7 @@ int flex_format::find_size(util::random_read &io, uint32_t form_factor, const st } else { // FLEX 2+: Look at the system information sector. sysinfo_sector info; - io.read_at(f.sector_base_size * 2, &info, sizeof(struct sysinfo_sector), actual); + read_at(io, f.sector_base_size * 2, &info, sizeof(struct sysinfo_sector)); // FIXME: check for errors and premature EOF 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 / f.sector_base_size, (uint32_t)size % f.sector_base_size, form_factor); diff --git a/src/lib/formats/flopimg_legacy.cpp b/src/lib/formats/flopimg_legacy.cpp index 5b8aee0a72b..c209b7cab58 100644 --- a/src/lib/formats/flopimg_legacy.cpp +++ b/src/lib/formats/flopimg_legacy.cpp @@ -349,16 +349,14 @@ util::random_read_write &floppy_get_io(floppy_image_legacy *floppy) void floppy_image_read(floppy_image_legacy *floppy, void *buffer, uint64_t offset, size_t length) { - size_t actual; - floppy->io->read_at(offset, buffer, length, actual); + /*auto const [err, actual] =*/ read_at(*floppy->io, offset, buffer, length); // FIXME: check for errors and premature EOF } void floppy_image_write(floppy_image_legacy *floppy, const void *buffer, uint64_t offset, size_t length) { - size_t actual; - floppy->io->write_at(offset, buffer, length, actual); + /*auto const [err, actual] =*/ write_at(*floppy->io, offset, buffer, length); // FIXME: check for errors } @@ -371,8 +369,7 @@ void floppy_image_write_filler(floppy_image_legacy *floppy, uint8_t filler, uint while (length) { size_t const block = std::min(sizeof(buffer), length); - size_t actual; - floppy->io->write_at(offset, buffer, block, actual); + /*auto const [err, actual] =*/ write_at(*floppy->io, offset, buffer, block); // FIXME: check for errors offset += block; length -= block; } diff --git a/src/lib/formats/fsd_dsk.cpp b/src/lib/formats/fsd_dsk.cpp index e4909ba37f3..b386dc026c6 100644 --- a/src/lib/formats/fsd_dsk.cpp +++ b/src/lib/formats/fsd_dsk.cpp @@ -91,9 +91,11 @@ bool fsd_format::supports_save() const noexcept int fsd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[3]; - - size_t actual; - io.read_at(0, h, 3, actual); + auto const [err, actual] = read_at(io, 0, h, 3); + if (err || (3 != actual)) { + LOG_FORMATS("fsd: read error\n"); + return 0; + } if (memcmp(h, "FSD", 3) == 0) { return FIFID_SIGN; } @@ -111,9 +113,9 @@ bool fsd_format::load(util::random_read &io, uint32_t form_factor, const std::ve uint64_t size; if(io.length(size)) return false; - std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [err, img, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; uint64_t pos; std::string title; diff --git a/src/lib/formats/g64_dsk.cpp b/src/lib/formats/g64_dsk.cpp index 568cc8f5027..177438dc9a6 100644 --- a/src/lib/formats/g64_dsk.cpp +++ b/src/lib/formats/g64_dsk.cpp @@ -36,9 +36,10 @@ const uint32_t g64_format::c1541_cell_size[] = int g64_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { char h[8]; + auto const [err, actual] = read_at(io, 0, h, 8); + if (err || (8 != actual)) + return 0; - size_t actual; - io.read_at(0, h, 8, actual); if (!memcmp(h, G64_FORMAT_HEADER, 8)) return FIFID_SIGN; @@ -51,9 +52,9 @@ bool g64_format::load(util::random_read &io, uint32_t form_factor, const std::ve if (io.length(size)) return false; - std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [err, img, actual] = read_at(io, 0, size); + if (err || (actual != size)) + return false; if (img[POS_VERSION]) { @@ -124,7 +125,6 @@ bool g64_format::save(util::random_read_write &io, const std::vector<uint32_t> & { 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); @@ -132,7 +132,7 @@ bool g64_format::save(util::random_read_write &io, const std::vector<uint32_t> & // 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.write_at(POS_SIGNATURE, header, sizeof(header), actual); + write_at(io, POS_SIGNATURE, header, sizeof(header)); // FIXME: check for errors // write tracks for (int head = 0; head < heads; head++) { @@ -145,8 +145,8 @@ bool g64_format::save(util::random_read_write &io, const std::vector<uint32_t> & uint32_t const spos = tpos + (tracks * 4); uint32_t const dpos = POS_TRACK_OFFSET + (tracks * 4 * 2) + (tracks_written * TRACK_LENGTH); - io.write_at(tpos, zerofill, 4, actual); - io.write_at(spos, zerofill, 4, actual); + write_at(io, tpos, zerofill, 4); // FIXME: check for errors + write_at(io, spos, zerofill, 4); // FIXME: check for errors if (image.get_buffer(track, head).size() <= 1) continue; @@ -178,11 +178,11 @@ bool g64_format::save(util::random_read_write &io, const std::vector<uint32_t> & put_u32le(speed_offset, speed_zone); put_u16le(track_length, 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); + write_at(io, tpos, track_offset, 4); // FIXME: check for errors + write_at(io, spos, speed_offset, 4); // FIXME: check for errors + write_at(io, dpos, prefill.data(), TRACK_LENGTH); // FIXME: check for errors + write_at(io, dpos, track_length, 2); // FIXME: check for errors + write_at(io, dpos + 2, packed.data(), packed.size()); // FIXME: check for errors tracks_written++; } diff --git a/src/lib/formats/hpi_dsk.cpp b/src/lib/formats/hpi_dsk.cpp index 84836207222..952ec0a2709 100644 --- a/src/lib/formats/hpi_dsk.cpp +++ b/src/lib/formats/hpi_dsk.cpp @@ -162,9 +162,10 @@ bool hpi_format::load(util::random_read &io, uint32_t form_factor, const std::ve image.set_variant(heads == 2 ? floppy_image::DSDD : floppy_image::SSDD); // Suck in the whole image - std::vector<uint8_t> image_data(size); - size_t actual; - io.read_at(0, image_data.data(), size, actual); + auto const [err, image_data, actual] = read_at(io, 0, size); + if (err || (actual != size)) { + return false; + } // Get interleave factor from image unsigned il = (unsigned)image_data[ IL_OFFSET ] * 256 + image_data[ IL_OFFSET + 1 ]; @@ -209,8 +210,7 @@ bool hpi_format::save(util::random_read_write &io, const std::vector<uint32_t> & 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; - size_t actual; - io.write_at(offset_in_image, sector_data, HPI_SECTOR_SIZE, actual); + /*auto const [err, actual] =*/ write_at(io, offset_in_image, sector_data, HPI_SECTOR_SIZE); // FIXME: check for errors } } } diff --git a/src/lib/formats/hti_tape.cpp b/src/lib/formats/hti_tape.cpp index f4a5727d591..7d6119860f1 100644 --- a/src/lib/formats/hti_tape.cpp +++ b/src/lib/formats/hti_tape.cpp @@ -11,6 +11,8 @@ #include "ioprocs.h" #include "multibyte.h" +#include <tuple> + 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" @@ -54,10 +56,12 @@ bool hti_format_t::load_tape(util::random_read &io) return false; } - size_t actual; - uint8_t tmp[ 4 ]; + uint8_t tmp[4]; + auto const [err, actual] = read(io, tmp, 4); + if (err || (4 != actual)) { + return false; + } - io.read(tmp, 4, actual); auto magic = get_u32be(tmp); 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)) { @@ -65,7 +69,7 @@ bool hti_format_t::load_tape(util::random_read &io) } for (unsigned i = 0; i < no_of_tracks(); i++) { - tape_track_t& track = m_tracks[ i ]; + tape_track_t &track = m_tracks[i]; if (!load_track(io, track, magic == OLD_FILE_MAGIC)) { clear_tape(); return false; @@ -77,17 +81,16 @@ bool hti_format_t::load_tape(util::random_read &io) void hti_format_t::save_tape(util::random_read_write &io) { - io.seek(0, SEEK_SET); + io.seek(0, SEEK_SET); // FIXME: check for errors - size_t actual; - uint8_t tmp[ 4 ]; + uint8_t tmp[4]; put_u32be(tmp, m_img_format == HTI_MANCHESTER_MOD ? FILE_MAGIC_MANCHESTER : FILE_MAGIC_DELTA); - io.write(tmp, 4, actual); + write(io, tmp, 4); // FIXME: check for errors for (unsigned i = 0; i < no_of_tracks(); i++) { - const tape_track_t& track = m_tracks[ i ]; - tape_pos_t next_pos = (tape_pos_t)-1; + const tape_track_t &track = m_tracks[i]; + tape_pos_t next_pos = tape_pos_t(-1); unsigned n_words = 0; tape_track_t::const_iterator it_start; for (tape_track_t::const_iterator it = track.cbegin(); it != track.cend(); ++it) { @@ -102,20 +105,20 @@ void hti_format_t::save_tape(util::random_read_write &io) dump_sequence(io, it_start, n_words); // End of track put_u32le(tmp, (uint32_t)-1); - io.write(tmp, 4, actual); + write(io, tmp, 4); // FIXME: check for errors } } void hti_format_t::clear_tape() { - for (tape_track_t& track : m_tracks) { + for (tape_track_t &track : m_tracks) { track.clear(); } } hti_format_t::tape_pos_t hti_format_t::word_length(tape_word_t w) const { - unsigned zeros , ones; + unsigned zeros, ones; // pop count of w ones = (w & 0x5555) + ((w >> 1) & 0x5555); @@ -128,7 +131,7 @@ hti_format_t::tape_pos_t hti_format_t::word_length(tape_word_t w) const return zeros * bit_length(false) + ones * bit_length(true); } -hti_format_t::tape_pos_t hti_format_t::farthest_end(const track_iterator_t& it , bool forward) const +hti_format_t::tape_pos_t hti_format_t::farthest_end(const track_iterator_t &it, bool forward) const { if (forward) { return word_end_pos(it); @@ -137,7 +140,7 @@ hti_format_t::tape_pos_t hti_format_t::farthest_end(const track_iterator_t& it , } } -bool hti_format_t::pos_offset(tape_pos_t& pos , bool forward , tape_pos_t offset) +bool hti_format_t::pos_offset(tape_pos_t &pos, bool forward, tape_pos_t offset) { if (offset == 0) { return true; @@ -161,7 +164,7 @@ bool hti_format_t::pos_offset(tape_pos_t& pos , bool forward , tape_pos_t offset } } -hti_format_t::tape_pos_t hti_format_t::next_hole(tape_pos_t pos , bool forward) +hti_format_t::tape_pos_t hti_format_t::next_hole(tape_pos_t pos, bool forward) { if (forward) { for (tape_pos_t hole : tape_holes) { @@ -172,9 +175,9 @@ hti_format_t::tape_pos_t hti_format_t::next_hole(tape_pos_t pos , bool forward) // No more holes: will hit end of tape return NULL_TAPE_POS; } else { - for (int i = (sizeof(tape_holes) / sizeof(tape_holes[ 0 ])) - 1; i >= 0; i--) { - if (tape_holes[ i ] < pos) { - return tape_holes[ i ]; + for (int i = (sizeof(tape_holes) / sizeof(tape_holes[0])) - 1; i >= 0; i--) { + if (tape_holes[i] < pos) { + return tape_holes[i]; } } // No more holes: will hit start of tape @@ -182,16 +185,16 @@ hti_format_t::tape_pos_t hti_format_t::next_hole(tape_pos_t pos , bool forward) } } -void hti_format_t::write_word(unsigned track_no , tape_pos_t start , tape_word_t word , tape_pos_t& length , bool forward) +void hti_format_t::write_word(unsigned track_no, tape_pos_t start, tape_word_t word, tape_pos_t &length, bool forward) { - tape_track_t& track = m_tracks[ track_no ]; + tape_track_t &track = m_tracks[track_no]; track_iterator_t it_low = track.lower_bound(start); - adjust_it(track , it_low , start); + adjust_it(track, it_low, start); length = word_length(word); tape_pos_t end_pos = start + length; track_iterator_t it_high = track.lower_bound(end_pos); - track.erase(it_low , it_high); + track.erase(it_low, it_high); // A 0 word is inserted after the word being written, if space allows. // This is meant to avoid fragmentation of the slack space at the end of a record @@ -203,24 +206,24 @@ void hti_format_t::write_word(unsigned track_no , tape_pos_t start , tape_word_t it_high--; } - track.insert(it_high , std::make_pair(start, word)); + track.insert(it_high, std::make_pair(start, word)); } -void hti_format_t::write_gap(unsigned track_no , tape_pos_t a , tape_pos_t b) +void hti_format_t::write_gap(unsigned track_no, tape_pos_t a, tape_pos_t b) { - ensure_a_lt_b(a , b); - tape_track_t& track = m_tracks[ track_no ]; + ensure_a_lt_b(a, b); + tape_track_t &track = m_tracks[track_no]; track_iterator_t it_low = track.lower_bound(a); - adjust_it(track , it_low , a); + adjust_it(track, it_low, a); track_iterator_t it_high = track.lower_bound(b); track.erase(it_low, it_high); } -bool hti_format_t::just_gap(unsigned track_no , tape_pos_t a , tape_pos_t b) +bool hti_format_t::just_gap(unsigned track_no, tape_pos_t a, tape_pos_t b) { - ensure_a_lt_b(a , b); - tape_track_t& track = m_tracks[ track_no ]; + ensure_a_lt_b(a, b); + tape_track_t &track = m_tracks[track_no]; track_iterator_t it_low = track.lower_bound(a); track_iterator_t it_high = track.lower_bound(b); @@ -229,9 +232,9 @@ bool hti_format_t::just_gap(unsigned track_no , tape_pos_t a , tape_pos_t b) return it_low == it_high; } -bool hti_format_t::next_data(unsigned track_no , tape_pos_t pos , bool forward , bool inclusive , track_iterator_t& it) +bool hti_format_t::next_data(unsigned track_no, tape_pos_t pos, bool forward, bool inclusive, track_iterator_t &it) { - tape_track_t& track = m_tracks[ track_no ]; + tape_track_t &track = m_tracks[track_no]; it = track.lower_bound(pos); if (forward) { if (inclusive) { @@ -251,9 +254,9 @@ bool hti_format_t::next_data(unsigned track_no , tape_pos_t pos , bool forward , } } -hti_format_t::adv_res_t hti_format_t::adv_it(unsigned track_no , bool forward , track_iterator_t& it) +hti_format_t::adv_res_t hti_format_t::adv_it(unsigned track_no, bool forward, track_iterator_t &it) { - tape_track_t& track = m_tracks[ track_no ]; + tape_track_t &track = m_tracks[track_no]; if (forward) { tape_pos_t prev_pos = word_end_pos(it); ++it; @@ -275,7 +278,7 @@ hti_format_t::adv_res_t hti_format_t::adv_it(unsigned track_no , bool forward , } } -bool hti_format_t::sync_with_record(unsigned track_no , track_iterator_t& it , unsigned& bit_idx) +bool hti_format_t::sync_with_record(unsigned track_no, track_iterator_t &it, unsigned &bit_idx) { while ((it->second & (1U << bit_idx)) == 0) { if (bit_idx) { @@ -296,7 +299,7 @@ bool hti_format_t::sync_with_record(unsigned track_no , track_iterator_t& it , u return true; } -hti_format_t::adv_res_t hti_format_t::next_word(unsigned track_no , track_iterator_t& it , unsigned& bit_idx , tape_word_t& word) +hti_format_t::adv_res_t hti_format_t::next_word(unsigned track_no, track_iterator_t &it, unsigned &bit_idx, tape_word_t &word) { if (bit_idx == 15) { auto res = adv_it(track_no, true, it); @@ -319,13 +322,13 @@ hti_format_t::adv_res_t hti_format_t::next_word(unsigned track_no , track_iterat } } -bool hti_format_t::next_gap(unsigned track_no , tape_pos_t& pos , bool forward , tape_pos_t min_gap) +bool hti_format_t::next_gap(unsigned track_no, tape_pos_t &pos, bool forward, tape_pos_t min_gap) { tape_track_t::iterator it; // First align with next data - next_data(track_no , pos , forward , true , it); + next_data(track_no, pos, forward, true, it); // Then scan for 1st gap - tape_track_t& track = m_tracks[ track_no ]; + tape_track_t &track = m_tracks[track_no]; bool done = false; track_iterator_t prev_it; unsigned n_gaps = 1; @@ -346,7 +349,7 @@ bool hti_format_t::next_gap(unsigned track_no , tape_pos_t& pos , bool forward , adv_res_t adv_res; do { prev_it = it; - adv_res = adv_it(track_no , forward , it); + adv_res = adv_it(track_no, forward, it); } while (adv_res == ADV_CONT_DATA); pos = word_end_pos(prev_it); } @@ -366,32 +369,36 @@ bool hti_format_t::next_gap(unsigned track_no , tape_pos_t& pos , bool forward , adv_res_t adv_res; do { prev_it = it; - adv_res = adv_it(track_no , forward , it); + adv_res = adv_it(track_no, forward, it); } while (adv_res == ADV_CONT_DATA); pos = prev_it->first; } } // Set "pos" where minimum gap size is met - pos_offset(pos , forward , min_gap); + pos_offset(pos, forward, min_gap); return n_gaps == 0; } -bool hti_format_t::load_track(util::random_read &io , 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; tape_pos_t last_word_end = 0; track.clear(); while (1) { - // Read no. of words to follow - io.read(tmp, 4, actual); + std::error_condition err; + size_t actual; + uint8_t tmp[4]; + uint32_t tmp32; + // Read no. of words to follow + std::tie(err, actual) = read(io, tmp, 4); + if (err || (4 != actual)) { + return false; + } tmp32 = get_u32le(tmp); // Track ends @@ -402,8 +409,10 @@ bool hti_format_t::load_track(util::random_read &io , tape_track_t& track , bool unsigned n_words = tmp32; // Read tape position of block - io.read(tmp, 4, actual); - + std::tie(err, actual) = read(io, tmp, 4); + if (err || (4 != actual)) { + return false; + } tmp32 = get_u32le(tmp); tape_pos_t pos = (tape_pos_t)tmp32 + delta_pos; @@ -414,11 +423,14 @@ bool hti_format_t::load_track(util::random_read &io , tape_track_t& track , bool for (unsigned i = 0; i < n_words; i++) { uint16_t tmp16; - io.read(tmp, 2, actual); + std::tie(err, actual) = read(io, tmp, 2); + if (err || (2 != actual)) { + return false; + } tmp16 = get_u16le(tmp); if (!old_format) { - track.insert(std::make_pair(pos , tmp16)); + track.insert(std::make_pair(pos, tmp16)); pos += word_length(tmp16); } else if (m_img_format == HTI_DELTA_MOD_16_BITS) { // Convert HP9845 & HP85 old format @@ -471,29 +483,28 @@ bool hti_format_t::load_track(util::random_read &io , tape_track_t& track , bool } } -void hti_format_t::dump_sequence(util::random_read_write &io , 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 ]; - put_u32le(&tmp[ 0 ], n_words); - put_u32le(&tmp[ 4 ], it_start->first); - io.write(tmp, 8, actual); + uint8_t tmp[8]; + put_u32le(&tmp[0], n_words); + put_u32le(&tmp[4], it_start->first); + write(io, tmp, 8); // FIXME: check for errors for (unsigned i = 0; i < n_words; i++) { put_u16le(tmp, it_start->second); - io.write(tmp, 2, actual); + write(io, tmp, 2); // FIXME: check for errors ++it_start; } } } -hti_format_t::tape_pos_t hti_format_t::word_end_pos(const track_iterator_t& it) const +hti_format_t::tape_pos_t hti_format_t::word_end_pos(const track_iterator_t &it) const { return it->first + word_length(it->second); } -void hti_format_t::adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos) const +void hti_format_t::adjust_it(tape_track_t &track, track_iterator_t &it, tape_pos_t pos) const { if (it != track.begin()) { --it; @@ -503,7 +514,7 @@ void hti_format_t::adjust_it(tape_track_t& track , track_iterator_t& it , tape_p } } -void hti_format_t::ensure_a_lt_b(tape_pos_t& a , tape_pos_t& b) +void hti_format_t::ensure_a_lt_b(tape_pos_t &a, tape_pos_t &b) { if (a > b) { // Ensure A always comes before B diff --git a/src/lib/formats/hti_tape.h b/src/lib/formats/hti_tape.h index 373c971d174..d343133583f 100644 --- a/src/lib/formats/hti_tape.h +++ b/src/lib/formats/hti_tape.h @@ -22,8 +22,6 @@ class hti_format_t { public: - hti_format_t(); - // Tape position, 1 unit = 1 inch / (968 * 1024) typedef int32_t tape_pos_t; @@ -55,7 +53,6 @@ public: // Iterator to access words on tape typedef tape_track_t::iterator track_iterator_t; - // Set image format enum image_format_t { // Delta modulation, 16 bits per word, 2 tracks per cartridge // HP 9845 & HP 85 @@ -68,6 +65,16 @@ public: HTI_MANCHESTER_MOD }; + enum adv_res_t + { + ADV_NO_MORE_DATA, + ADV_CONT_DATA, + ADV_DISCONT_DATA + }; + + hti_format_t(); + + // Set image format void set_image_format(image_format_t fmt) { m_img_format = fmt; } // Return number of tracks @@ -86,55 +93,48 @@ public: // Return physical length of a 16-bit word on tape tape_pos_t word_length(tape_word_t w) const; - tape_pos_t farthest_end(const track_iterator_t& it , bool forward) const; + tape_pos_t farthest_end(const track_iterator_t &it, bool forward) const; - static bool pos_offset(tape_pos_t& pos , bool forward , tape_pos_t offset); + static bool pos_offset(tape_pos_t &pos, bool forward, tape_pos_t offset); // Position of next hole tape will reach in a given direction - static tape_pos_t next_hole(tape_pos_t pos , bool forward); + static tape_pos_t next_hole(tape_pos_t pos, bool forward); // Write a data word on tape - void write_word(unsigned track_no , tape_pos_t start , tape_word_t word , tape_pos_t& length , bool forward = true); + void write_word(unsigned track_no, tape_pos_t start, tape_word_t word, tape_pos_t &length, bool forward = true); // Write a gap on tape - void write_gap(unsigned track_no , tape_pos_t a , tape_pos_t b); + void write_gap(unsigned track_no, tape_pos_t a, tape_pos_t b); // Check that a section of tape has no data (it's just gap) - bool just_gap(unsigned track_no , tape_pos_t a , tape_pos_t b); + bool just_gap(unsigned track_no, tape_pos_t a, tape_pos_t b); // Return position of next data word in a given direction - bool next_data(unsigned track_no , tape_pos_t pos , bool forward , bool inclusive , track_iterator_t& it); - - enum adv_res_t - { - ADV_NO_MORE_DATA, - ADV_CONT_DATA, - ADV_DISCONT_DATA - }; + bool next_data(unsigned track_no, tape_pos_t pos, bool forward, bool inclusive, track_iterator_t &it); // Advance an iterator to next word of data - adv_res_t adv_it(unsigned track_no , bool forward , track_iterator_t& it); + adv_res_t adv_it(unsigned track_no, bool forward, track_iterator_t &it); // Sync with the preamble of a record - bool sync_with_record(unsigned track_no , track_iterator_t& it , unsigned& bit_idx); + bool sync_with_record(unsigned track_no, track_iterator_t &it, unsigned &bit_idx); // Get a data word from record, after syncing - adv_res_t next_word(unsigned track_no , track_iterator_t& it , unsigned& bit_idx , tape_word_t& word); + adv_res_t next_word(unsigned track_no, track_iterator_t &it, unsigned &bit_idx, tape_word_t &word); // Scan for beginning of next gap in a given direction - bool next_gap(unsigned track_no , tape_pos_t& pos , bool forward , tape_pos_t min_gap); + bool next_gap(unsigned track_no, tape_pos_t &pos, bool forward, tape_pos_t min_gap); private: // Content of tape tracks - tape_track_t m_tracks[ 2 ]; + tape_track_t m_tracks[2]; // Image format image_format_t m_img_format; - 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); + 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; - static void ensure_a_lt_b(tape_pos_t& a , tape_pos_t& b); + 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; + static void ensure_a_lt_b(tape_pos_t &a, tape_pos_t &b); }; #endif // MAME_FORMATS_HTI_TAPE_H diff --git a/src/lib/formats/hxchfe_dsk.cpp b/src/lib/formats/hxchfe_dsk.cpp index a8cf09feaf2..da8d660bb33 100644 --- a/src/lib/formats/hxchfe_dsk.cpp +++ b/src/lib/formats/hxchfe_dsk.cpp @@ -106,6 +106,8 @@ #include "osdcore.h" // osd_printf_* +#include <tuple> + #define HFE_FORMAT_HEADER "HXCPICFE" @@ -139,10 +141,11 @@ bool hfe_format::supports_save() const noexcept int hfe_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[8]; - - size_t actual; - io.read_at(0, &header, sizeof(header), actual); - if ( memcmp( header, HFE_FORMAT_HEADER, 8 ) ==0) { + auto const [err, actual] = read_at(io, 0, &header, sizeof(header)); + if (err || (sizeof(header) != actual)) { + return 0; + } + if (!memcmp(header, HFE_FORMAT_HEADER, 8)) { return FIFID_SIGN; } return 0; @@ -150,16 +153,15 @@ int hfe_format::identify(util::random_read &io, uint32_t form_factor, const std: bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; - uint8_t header[HEADER_LENGTH]; - uint8_t track_table[TRACK_TABLE_LENGTH]; - header_info info; int drivecyl, driveheads; image.get_maximal_geometry(drivecyl, driveheads); // read header - io.read_at(0, header, HEADER_LENGTH, actual); + uint8_t header[HEADER_LENGTH]; + std::tie(err, actual) = read_at(io, 0, header, HEADER_LENGTH); // FIXME: check for errors and premature EOF // get values // Format revision must be 0 @@ -169,6 +171,7 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve return false; } + header_info info; info.m_cylinders = header[9] & 0xff; info.m_heads = header[10] & 0xff; @@ -194,7 +197,7 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve return false; } - info.m_track_encoding = (encoding_t)(header[11] & 0xff); + info.m_track_encoding = encoding_t(header[11] & 0xff); if (info.m_track_encoding > EMU_FM_ENCODING) { @@ -231,7 +234,8 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve // read track lookup table (multiple of 512) int table_offset = get_u16le(&header[18]); - io.read_at(table_offset<<9, track_table, TRACK_TABLE_LENGTH, actual); + uint8_t track_table[TRACK_TABLE_LENGTH]; + std::tie(err, actual) = read_at(io, table_offset<<9, track_table, TRACK_TABLE_LENGTH); // FIXME: check for errors and premature EOF for (int i=0; i < info.m_cylinders; i++) { @@ -244,10 +248,9 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve for(int cyl=0; cyl < info.m_cylinders; cyl++) { // actual data read - // The HFE format defines an interleave of the two sides per cylinder - // at every 256 bytes + // The HFE format defines an interleave of the two sides per cylinder at every 256 bytes cylinder_buffer.resize(info.m_cyl_length[cyl]); - io.read_at(info.m_cyl_offset[cyl]<<9, &cylinder_buffer[0], info.m_cyl_length[cyl], actual); + std::tie(err, actual) = read_at(io, info.m_cyl_offset[cyl]<<9, &cylinder_buffer[0], info.m_cyl_length[cyl]); // FIXME: check for errors and premature EOF generate_track_from_hfe_bitstream(cyl, 0, samplelength, &cylinder_buffer[0], info.m_cyl_length[cyl], image); if (info.m_heads == 2) diff --git a/src/lib/formats/hxcmfm_dsk.cpp b/src/lib/formats/hxcmfm_dsk.cpp index 0390b55bca0..d9fda047dea 100644 --- a/src/lib/formats/hxcmfm_dsk.cpp +++ b/src/lib/formats/hxcmfm_dsk.cpp @@ -6,6 +6,7 @@ #include "ioprocs.h" #include <cstring> +#include <tuple> #define MFM_FORMAT_HEADER "HXCMFM" @@ -63,10 +64,11 @@ bool mfm_format::supports_save() const noexcept int mfm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[7]; - - size_t actual; - io.read_at(0, &header, sizeof(header), actual); - if ( memcmp( header, MFM_FORMAT_HEADER, 6 ) ==0) { + auto const [err, actual] = read_at(io, 0, &header, sizeof(header)); // FIXME: does this really need to read 7 bytes? only 6 are checked. also check for premature EOF + if (err) { + return 0; + } + if (!memcmp(header, MFM_FORMAT_HEADER, 6)) { return FIFID_SIGN; } return 0; @@ -74,12 +76,13 @@ int mfm_format::identify(util::random_read &io, uint32_t form_factor, const std: bool mfm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; MFMIMG header; MFMTRACKIMG trackdesc; // read header - io.read_at(0, &header, sizeof(header), actual); + std::tie(err, actual) = read_at(io, 0, &header, sizeof(header)); // FIXME: check for errors and premature EOF int drivecyl, driveheads; image.get_maximal_geometry(drivecyl, driveheads); @@ -91,12 +94,12 @@ bool mfm_format::load(util::random_read &io, uint32_t form_factor, const std::ve for(int side=0; side < header.number_of_side; side++) { if (!skip_odd || track%2 == 0) { // read location of - io.read_at((header.mfmtracklistoffset)+( counter *sizeof(trackdesc)), &trackdesc, sizeof(trackdesc), actual); + std::tie(err, actual) = read_at(io, header.mfmtracklistoffset + (counter * sizeof(trackdesc)), &trackdesc, sizeof(trackdesc)); // FIXME: check for errors and premature EOF trackbuf.resize(trackdesc.mfmtracksize); // actual data read - io.read_at(trackdesc.mfmtrackoffset, &trackbuf[0], trackdesc.mfmtracksize, actual); + std::tie(err, actual) = read_at(io, trackdesc.mfmtrackoffset, &trackbuf[0], trackdesc.mfmtracksize); // FIXME: check for errors and premature EOF if (skip_odd) { generate_track_from_bitstream(track/2, side, &trackbuf[0], trackdesc.mfmtracksize*8, image); @@ -117,7 +120,6 @@ bool mfm_format::load(util::random_read &io, uint32_t form_factor, const std::ve bool mfm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { // TODO: HD support - size_t actual; MFMIMG header; int track_count, head_count; image.get_actual_geometry(track_count, head_count); @@ -130,7 +132,7 @@ bool mfm_format::save(util::random_read_write &io, const std::vector<uint32_t> & header.floppyiftype = 4; header.mfmtracklistoffset = sizeof(MFMIMG); - io.write_at(0, &header, sizeof(MFMIMG), actual); + write_at(io, 0, &header, sizeof(MFMIMG)); // FIXME: check for errors int tpos = sizeof(MFMIMG); int dpos = tpos + track_count*head_count*sizeof(MFMTRACKIMG); @@ -149,8 +151,8 @@ bool mfm_format::save(util::random_read_write &io, const std::vector<uint32_t> & trackdesc.mfmtracksize = packed.size(); trackdesc.mfmtrackoffset = dpos; - io.write_at(tpos, &trackdesc, sizeof(MFMTRACKIMG), actual); - io.write_at(dpos, packed.data(), packed.size(), actual); + write_at(io, tpos, &trackdesc, sizeof(MFMTRACKIMG)); // FIXME: check for errors + write_at(io, dpos, packed.data(), packed.size()); // FIXME: check for errors tpos += sizeof(MFMTRACKIMG); dpos += packed.size(); diff --git a/src/lib/formats/ibmxdf_dsk.cpp b/src/lib/formats/ibmxdf_dsk.cpp index 5fb1f3da411..c9704361f65 100644 --- a/src/lib/formats/ibmxdf_dsk.cpp +++ b/src/lib/formats/ibmxdf_dsk.cpp @@ -186,8 +186,8 @@ bool ibmxdf_format::load(util::random_read &io, uint32_t form_factor, const std: const format &f = formats[type]; - for(int track=0; track < f.track_count; track++) - for(int head=0; head < f.head_count; head++) { + for(int track = 0; track < f.track_count; track++) { + for(int head = 0; head < f.head_count; head++) { uint8_t sectdata[23 * 2 * 512]; // XXX magic desc_s sectors[40]; floppy_image_format_t::desc_e *desc; @@ -213,10 +213,10 @@ bool ibmxdf_format::load(util::random_read &io, uint32_t form_factor, const std: build_sector_description(tf, sectdata, sectors, track, head); 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); + /*auto const [err, actual] =*/ read_at(io, get_image_offset(f, head, track), sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(desc, track, head, sectors, tf.sector_count, total_size, image); } + } image.set_variant(f.variant); diff --git a/src/lib/formats/imd_dsk.cpp b/src/lib/formats/imd_dsk.cpp index fde013f3113..907440dc922 100644 --- a/src/lib/formats/imd_dsk.cpp +++ b/src/lib/formats/imd_dsk.cpp @@ -425,9 +425,10 @@ void imd_format::fixnum(char *start, char *end) const int imd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { char h[4]; + auto const [err, actual] = read_at(io, 0, h, 4); + if(err || (4 != actual)) + return 0; - size_t actual; - io.read_at(0, h, 4, actual); if(!memcmp(h, "IMD ", 4)) return FIFID_SIGN; @@ -451,9 +452,9 @@ bool imd_format::load(util::random_read &io, uint32_t form_factor, const std::ve uint64_t size; if(io.length(size)) return false; - std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [err, img, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; uint64_t pos, savepos; for(pos=0; pos < size && img[pos] != 0x1a; pos++) { } diff --git a/src/lib/formats/img_dsk.cpp b/src/lib/formats/img_dsk.cpp index fb6f1a3bfb3..66e097c281e 100644 --- a/src/lib/formats/img_dsk.cpp +++ b/src/lib/formats/img_dsk.cpp @@ -72,9 +72,10 @@ bool img_format::load(util::random_read &io, uint32_t form_factor, const std::ve image.set_variant(is_dd ? floppy_image::SSDD : floppy_image::SSSD); // Suck in the whole image - std::vector<uint8_t> image_data(size); - size_t actual; - io.read_at(0, image_data.data(), size, actual); + auto const [err, image_data, actual] = read_at(io, 0, size); + if (err || (actual != size)) { + return false; + } for (unsigned cyl = 0; cyl < TRACKS; cyl++) { if (is_dd) { @@ -134,7 +135,7 @@ bool img_format::load(util::random_read &io, uint32_t form_factor, const std::ve sects[ sector ].sector = real_sector; sects[ sector ].bad_crc = false; sects[ sector ].deleted = false; - sects[ sector ].data = image_data.data() + offset_in_image; + sects[ sector ].data = &image_data[offset_in_image]; } build_pc_track_fm(cyl, 0, image, 83333, SECTORS_FM, sects, 33, 46, 32, 11); } @@ -155,8 +156,7 @@ bool img_format::save(util::random_read_write &io, const std::vector<uint32_t> & 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; - size_t actual; - io.write_at(offset_in_image, sector_data, SECTOR_SIZE, actual); + /*auto const [err, actual] =*/ write_at(io, offset_in_image, sector_data, SECTOR_SIZE); // FIXME: check for errors } } } else { @@ -164,8 +164,7 @@ bool img_format::save(util::random_read_write &io, const std::vector<uint32_t> & auto sects = extract_sectors_from_bitstream_fm_pc(bitstream); for (unsigned s = 1; s <= SECTORS_FM; s++) { unsigned offset_in_image = (cyl * SECTORS_FM + s - 1) * SECTOR_SIZE; - size_t actual; - io.write_at(offset_in_image, sects[ s ].data(), SECTOR_SIZE, actual); + /*auto const [err, actual] =*/ write_at(io, offset_in_image, sects[ s ].data(), SECTOR_SIZE); // FIXME: check for errors and premature EOF } } } diff --git a/src/lib/formats/ipf_dsk.cpp b/src/lib/formats/ipf_dsk.cpp index 072dd96c99e..b47eca030f2 100644 --- a/src/lib/formats/ipf_dsk.cpp +++ b/src/lib/formats/ipf_dsk.cpp @@ -8,6 +8,72 @@ #include <cstring> +struct ipf_format::ipf_decode { + struct track_info { + uint32_t cylinder = 0, head = 0, type = 0; + uint32_t sigtype = 0, process = 0, reserved[3] = { 0, 0, 0 }; + uint32_t size_bytes = 0, size_cells = 0; + uint32_t index_bytes = 0, index_cells = 0; + uint32_t datasize_cells = 0, gapsize_cells = 0; + uint32_t block_count = 0, weak_bits = 0; + + uint32_t data_size_bits = 0; + + bool info_set = false; + + const uint8_t *data = nullptr; + uint32_t data_size = 0; + }; + + std::vector<track_info> tinfos; + uint32_t tcount = 0; + + uint32_t type = 0, release = 0, revision = 0; + uint32_t encoder_type = 0, encoder_revision = 0, origin = 0; + uint32_t min_cylinder = 0, max_cylinder = 0, min_head = 0, max_head = 0; + uint32_t credit_day = 0, credit_time = 0; + uint32_t platform[4] = {}, extra[5] = {}; + + uint32_t crc32r(const uint8_t *data, uint32_t size); + + bool parse_info(const uint8_t *info); + bool parse_imge(const uint8_t *imge); + bool parse_data(const uint8_t *data, uint32_t &pos, uint32_t max_extra_size); + + bool scan_one_tag(uint8_t *data, size_t size, uint32_t &pos, uint8_t *&tag, uint32_t &tsize); + bool scan_all_tags(uint8_t *data, size_t size); + static uint32_t rb(const uint8_t *&p, int count); + + track_info *get_index(uint32_t idx); + + void track_write_raw(std::vector<uint32_t>::iterator &tpos, const uint8_t *data, uint32_t cells, bool &context); + void track_write_mfm(std::vector<uint32_t>::iterator &tpos, const uint8_t *data, uint32_t start_offset, uint32_t patlen, uint32_t cells, bool &context); + void track_write_weak(std::vector<uint32_t>::iterator &tpos, uint32_t cells); + bool generate_block_data(const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator tpos, std::vector<uint32_t>::iterator tlimit, bool &context); + + bool gap_description_to_reserved_size(const uint8_t *&data, const uint8_t *dlimit, uint32_t &res_size); + bool generate_gap_from_description(const uint8_t *&data, const uint8_t *dlimit, std::vector<uint32_t>::iterator tpos, uint32_t size, bool pre, bool &context); + bool generate_block_gap_0(uint32_t gap_cells, uint8_t pattern, uint32_t &spos, uint32_t ipos, std::vector<uint32_t>::iterator &tpos, bool &context); + bool generate_block_gap_1(uint32_t gap_cells, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator &tpos, bool &context); + bool generate_block_gap_2(uint32_t gap_cells, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator &tpos, bool &context); + bool generate_block_gap_3(uint32_t gap_cells, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator &tpos, bool &context); + bool generate_block_gap(uint32_t gap_type, uint32_t gap_cells, uint8_t pattern, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator tpos, bool &context); + + bool generate_block(const track_info &t, uint32_t idx, uint32_t ipos, std::vector<uint32_t> &track, uint32_t &pos, uint32_t &dpos, uint32_t &gpos, uint32_t &spos, bool &context); + uint32_t block_compute_real_size(const track_info &t); + + void timing_set(std::vector<uint32_t> &track, uint32_t start, uint32_t end, uint32_t time); + bool generate_timings(const track_info &t, std::vector<uint32_t> &track, const std::vector<uint32_t> &data_pos, const std::vector<uint32_t> &gap_pos); + + void rotate(std::vector<uint32_t> &track, uint32_t offset, uint32_t size); + void mark_track_splice(std::vector<uint32_t> &track, uint32_t offset, uint32_t size); + bool generate_track(track_info &t, floppy_image &image); + bool generate_tracks(floppy_image &image); + + bool parse(uint8_t *data, size_t size, floppy_image &image); +}; + + const ipf_format FLOPPY_IPF_FORMAT; const char *ipf_format::name() const noexcept @@ -34,8 +100,9 @@ int ipf_format::identify(util::random_read &io, uint32_t form_factor, const std: { static const uint8_t refh[12] = { 0x43, 0x41, 0x50, 0x53, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0xd5, 0x73, 0xba }; uint8_t h[12]; - size_t actual; - io.read_at(0, h, 12, actual); + auto const [err, actual] = read_at(io, 0, h, 12); + if(err || (12 != actual)) + return 0; if(!memcmp(h, refh, 12)) return FIFID_SIGN; @@ -46,13 +113,13 @@ int ipf_format::identify(util::random_read &io, uint32_t form_factor, const std: bool ipf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { uint64_t size; - if (io.length(size)) + if(io.length(size)) + return false; + auto const [err, data, actual] = read_at(io, 0, size); + if(err || (actual != size)) return false; - std::vector<uint8_t> data(size); - size_t actual; - io.read_at(0, &data[0], size, actual); ipf_decode dec; - return dec.parse(data, image); + return dec.parse(data.get(), size, image); } @@ -79,12 +146,12 @@ uint32_t ipf_format::ipf_decode::crc32r(const uint8_t *data, uint32_t size) return ~crc; } -bool ipf_format::ipf_decode::parse(std::vector<uint8_t> &data, floppy_image &image) +bool ipf_format::ipf_decode::parse(uint8_t *data, size_t size, floppy_image &image) { image.set_variant(floppy_image::DSDD); // Not handling anything else yet tcount = 84*2+1; // Usual max tinfos.resize(tcount); - bool res = scan_all_tags(data); + bool res = scan_all_tags(data, size); if(res) res = generate_tracks(image); tinfos.clear(); @@ -177,13 +244,13 @@ bool ipf_format::ipf_decode::parse_data(const uint8_t *data, uint32_t &pos, uint return true; } -bool ipf_format::ipf_decode::scan_one_tag(std::vector<uint8_t> &data, uint32_t &pos, uint8_t *&tag, uint32_t &tsize) +bool ipf_format::ipf_decode::scan_one_tag(uint8_t *data, size_t size, uint32_t &pos, uint8_t *&tag, uint32_t &tsize) { - if(data.size()-pos < 12) + if(size-pos < 12) return false; tag = &data[pos]; tsize = get_u32be(tag+4); - if(data.size()-pos < tsize) + if(size-pos < tsize) return false; uint32_t crc = get_u32be(tag+8); tag[8] = tag[9] = tag[10] = tag[11] = 0; @@ -193,15 +260,14 @@ bool ipf_format::ipf_decode::scan_one_tag(std::vector<uint8_t> &data, uint32_t & return true; } -bool ipf_format::ipf_decode::scan_all_tags(std::vector<uint8_t> &data) +bool ipf_format::ipf_decode::scan_all_tags(uint8_t *data, size_t size) { uint32_t pos = 0; - uint32_t size = data.size(); while(pos != size) { uint8_t *tag; uint32_t tsize; - if(!scan_one_tag(data, pos, tag, tsize)) + if(!scan_one_tag(data, size, pos, tag, tsize)) return false; switch(get_u32be(tag)) { diff --git a/src/lib/formats/ipf_dsk.h b/src/lib/formats/ipf_dsk.h index 9e63b2bff38..a1c36f02f8d 100644 --- a/src/lib/formats/ipf_dsk.h +++ b/src/lib/formats/ipf_dsk.h @@ -21,71 +21,7 @@ public: virtual bool supports_save() const noexcept override; private: - struct ipf_decode { - struct track_info { - uint32_t cylinder = 0, head = 0, type = 0; - uint32_t sigtype = 0, process = 0, reserved[3] = { 0, 0, 0 }; - uint32_t size_bytes = 0, size_cells = 0; - uint32_t index_bytes = 0, index_cells = 0; - uint32_t datasize_cells = 0, gapsize_cells = 0; - uint32_t block_count = 0, weak_bits = 0; - - uint32_t data_size_bits = 0; - - bool info_set = false; - - const uint8_t *data = nullptr; - uint32_t data_size = 0; - }; - - std::vector<track_info> tinfos; - uint32_t tcount = 0; - - uint32_t type = 0, release = 0, revision = 0; - uint32_t encoder_type = 0, encoder_revision = 0, origin = 0; - uint32_t min_cylinder = 0, max_cylinder = 0, min_head = 0, max_head = 0; - uint32_t credit_day = 0, credit_time = 0; - uint32_t platform[4] = {}, extra[5] = {}; - - uint32_t crc32r(const uint8_t *data, uint32_t size); - - bool parse_info(const uint8_t *info); - bool parse_imge(const uint8_t *imge); - bool parse_data(const uint8_t *data, uint32_t &pos, uint32_t max_extra_size); - - bool scan_one_tag(std::vector<uint8_t> &data, uint32_t &pos, uint8_t *&tag, uint32_t &tsize); - bool scan_all_tags(std::vector<uint8_t> &data); - static uint32_t r32(const uint8_t *p); - static uint32_t rb(const uint8_t *&p, int count); - - track_info *get_index(uint32_t idx); - - void track_write_raw(std::vector<uint32_t>::iterator &tpos, const uint8_t *data, uint32_t cells, bool &context); - void track_write_mfm(std::vector<uint32_t>::iterator &tpos, const uint8_t *data, uint32_t start_offset, uint32_t patlen, uint32_t cells, bool &context); - void track_write_weak(std::vector<uint32_t>::iterator &tpos, uint32_t cells); - bool generate_block_data(const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator tpos, std::vector<uint32_t>::iterator tlimit, bool &context); - - bool gap_description_to_reserved_size(const uint8_t *&data, const uint8_t *dlimit, uint32_t &res_size); - bool generate_gap_from_description(const uint8_t *&data, const uint8_t *dlimit, std::vector<uint32_t>::iterator tpos, uint32_t size, bool pre, bool &context); - bool generate_block_gap_0(uint32_t gap_cells, uint8_t pattern, uint32_t &spos, uint32_t ipos, std::vector<uint32_t>::iterator &tpos, bool &context); - bool generate_block_gap_1(uint32_t gap_cells, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator &tpos, bool &context); - bool generate_block_gap_2(uint32_t gap_cells, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator &tpos, bool &context); - bool generate_block_gap_3(uint32_t gap_cells, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator &tpos, bool &context); - bool generate_block_gap(uint32_t gap_type, uint32_t gap_cells, uint8_t pattern, uint32_t &spos, uint32_t ipos, const uint8_t *data, const uint8_t *dlimit, std::vector<uint32_t>::iterator tpos, bool &context); - - bool generate_block(const track_info &t, uint32_t idx, uint32_t ipos, std::vector<uint32_t> &track, uint32_t &pos, uint32_t &dpos, uint32_t &gpos, uint32_t &spos, bool &context); - uint32_t block_compute_real_size(const track_info &t); - - void timing_set(std::vector<uint32_t> &track, uint32_t start, uint32_t end, uint32_t time); - bool generate_timings(const track_info &t, std::vector<uint32_t> &track, const std::vector<uint32_t> &data_pos, const std::vector<uint32_t> &gap_pos); - - void rotate(std::vector<uint32_t> &track, uint32_t offset, uint32_t size); - void mark_track_splice(std::vector<uint32_t> &track, uint32_t offset, uint32_t size); - bool generate_track(track_info &t, floppy_image &image); - bool generate_tracks(floppy_image &image); - - bool parse(std::vector<uint8_t> &data, floppy_image &image); - }; + struct ipf_decode; }; extern const ipf_format FLOPPY_IPF_FORMAT; diff --git a/src/lib/formats/jfd_dsk.cpp b/src/lib/formats/jfd_dsk.cpp index 813c7192ca9..46e933cedf1 100644 --- a/src/lib/formats/jfd_dsk.cpp +++ b/src/lib/formats/jfd_dsk.cpp @@ -197,8 +197,9 @@ int jfd_format::identify(util::random_read &io, uint32_t form_factor, const std: return 0; std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [ioerr, actual] = read_at(io, 0, &img[0], size); + if (ioerr || (actual != size)) + return 0; int err; std::vector<uint8_t> gz_ptr(4); @@ -222,7 +223,7 @@ int jfd_format::identify(util::random_read &io, uint32_t form_factor, const std: err = inflateEnd(&d_stream); if (err != Z_OK) return 0; - img = gz_ptr; + img = std::move(gz_ptr); } if (!memcmp(&img[0], JFD_HEADER, sizeof(JFD_HEADER))) { @@ -239,8 +240,9 @@ bool jfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve return false; std::vector<uint8_t> img(size); - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [ioerr, actual] = read_at(io, 0, &img[0], size); + if (ioerr || (actual != size)) + return false; int err; std::vector<uint8_t> gz_ptr; @@ -274,7 +276,7 @@ bool jfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve return false; } size = inflate_size; - img = gz_ptr; + img = std::move(gz_ptr); } osd_printf_verbose("jfd_dsk: loading %s\n", &img[48]); diff --git a/src/lib/formats/jvc_dsk.cpp b/src/lib/formats/jvc_dsk.cpp index ce0083a9deb..fcc5d97a5b5 100644 --- a/src/lib/formats/jvc_dsk.cpp +++ b/src/lib/formats/jvc_dsk.cpp @@ -141,11 +141,14 @@ bool jvc_format::parse_header(util::random_read &io, int &header_size, int &trac 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)) + if (header_size >= sizeof(header)) // TODO: wouldn't this make more sense with > than >=? The first case in the following switch statement is unreachable as-is. return false; if (header_size > 0) - io.read_at(0, header, header_size, actual); + { + auto const [err, actual] = read_at(io, 0, header, header_size); + if (err || (actual != header_size)) + return false; + } // default values heads = 1; @@ -241,8 +244,7 @@ bool jvc_format::load(util::random_read &io, uint32_t form_factor, const std::ve sectors[interleave[i]].bad_crc = false; sectors[interleave[i]].data = §or_data[sector_offset]; - size_t actual; - io.read_at(file_offset, sectors[interleave[i]].data, sector_size, actual); + /*auto const [err, actual] =*/ read_at(io, file_offset, sectors[interleave[i]].data, sector_size); // FIXME: check for errors and premature EOF sector_offset += sector_size; file_offset += sector_size; @@ -268,8 +270,7 @@ bool jvc_format::save(util::random_read_write &io, const std::vector<uint32_t> & uint8_t header[2]; header[0] = 18; header[1] = 2; - size_t actual; - io.write_at(file_offset, header, sizeof(header), actual); + /*auto const [err, actual] =*/ write_at(io, file_offset, header, sizeof(header)); // FIXME: check for errors file_offset += sizeof(header); } @@ -289,8 +290,7 @@ bool jvc_format::save(util::random_read_write &io, const std::vector<uint32_t> & return false; } - size_t actual; - io.write_at(file_offset, sectors[1 + i].data(), 256, actual); + /*auto const [err, actual] =*/ write_at(io, file_offset, sectors[1 + i].data(), 256); // FIXME: check for errors file_offset += 256; } } diff --git a/src/lib/formats/lw30_dsk.cpp b/src/lib/formats/lw30_dsk.cpp index dd5eef5da5f..dd1536755d5 100644 --- a/src/lib/formats/lw30_dsk.cpp +++ b/src/lib/formats/lw30_dsk.cpp @@ -138,9 +138,11 @@ static constexpr int raw_track_size = 2/*0xaa*/ + 48/*0xaa*/ + SECTORS_PER_TRACK int lw30_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint64_t size = 0; - io.length(size); + if(io.length(size)) + return 0; + if(size == TRACKS_PER_DISK * SECTORS_PER_TRACK * SECTOR_SIZE) - return 50; // identified by size + return FIFID_SIZE; // identified by size return 0; } @@ -150,9 +152,8 @@ bool lw30_format::load(util::random_read &io, uint32_t form_factor, const std::v uint8_t trackdata[SECTORS_PER_TRACK * SECTOR_SIZE], rawdata[CELLS_PER_REV / 8]; memset(rawdata, 0xaa, sizeof(rawdata)); for(int track = 0; track < TRACKS_PER_DISK; track++) { - size_t actual{}; - io.read_at(track * SECTORS_PER_TRACK * SECTOR_SIZE, trackdata, SECTORS_PER_TRACK * SECTOR_SIZE, actual); - if(actual != SECTORS_PER_TRACK * SECTOR_SIZE) + auto const [err, actual] = read_at(io, track * SECTORS_PER_TRACK * SECTOR_SIZE, trackdata, SECTORS_PER_TRACK * SECTOR_SIZE); + if(err || (actual != SECTORS_PER_TRACK * SECTOR_SIZE)) return false; size_t i = 0; for(int x = 0; x < 2 + 48; x++) diff --git a/src/lib/formats/m20_dsk.cpp b/src/lib/formats/m20_dsk.cpp index 10c6cf51cf1..02905ecfa0d 100644 --- a/src/lib/formats/m20_dsk.cpp +++ b/src/lib/formats/m20_dsk.cpp @@ -62,8 +62,7 @@ bool m20_format::load(util::random_read &io, uint32_t form_factor, const std::ve bool mfm = track || head; desc_pc_sector sects[16]; uint8_t sectdata[16*256]; - size_t actual; - io.read_at(16*256*(track*2+head), sectdata, 16*256, actual); + /*auto const [err, actual] =*/ read_at(io, 16*256*(track*2+head), sectdata, 16*256); // FIXME: check for errors and premature EOF for (int i = 0; i < 16; i++) { int j = i/2 + (i & 1 ? 0 : 8); sects[i].track = track; @@ -92,17 +91,16 @@ bool m20_format::save(util::random_read_write &io, const std::vector<uint32_t> & int track_count, head_count; track_count = 35; head_count = 2; //FIXME: use image.get_actual_geometry(track_count, head_count) instead - // initial fm track + // initial FM track 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++) { - size_t actual; - io.write_at(file_offset, sectors[i + 1].data(), 128, actual); + /*auto const [err, actual] =*/ write_at(io, file_offset, sectors[i + 1].data(), 128); // FIXME: check for errors file_offset += 256; //128; } - // rest are mfm tracks + // rest are MFM tracks for (int track = 0; track < track_count; track++) { for (int head = 0; head < head_count; head++) { // skip track 0, head 0 @@ -115,8 +113,7 @@ bool m20_format::save(util::random_read_write &io, const std::vector<uint32_t> & sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < 16; i++) { - size_t actual; - io.write_at(file_offset, sectors[i + 1].data(), 256, actual); + /*auto const [err, actual] =*/ write_at(io, file_offset, sectors[i + 1].data(), 256); // FIXME: check for errors file_offset += 256; } } diff --git a/src/lib/formats/mdos_dsk.cpp b/src/lib/formats/mdos_dsk.cpp index 765ce1bc63c..a14df309db4 100644 --- a/src/lib/formats/mdos_dsk.cpp +++ b/src/lib/formats/mdos_dsk.cpp @@ -55,6 +55,8 @@ #include "ioprocs.h" #include "multibyte.h" +#include <tuple> + mdos_format::mdos_format() : wd177x_format(formats) { @@ -77,10 +79,10 @@ const char *mdos_format::extensions() const noexcept int mdos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { - int type = find_size(io, form_factor, variants); + int const type = find_size(io, form_factor, variants); if (type != -1) - return FIFID_SIZE; + return FIFID_SIZE | FIFID_STRUCT; return 0; } @@ -115,18 +117,22 @@ int mdos_format::parse_date_field(const uint8_t *str) int mdos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { + std::error_condition err; size_t actual; + uint64_t size; if (io.length(size)) return -1; + // Look at the disk ID sector. disk_id_sector info; - // Look at the disk id sector. - io.read_at(0, &info, sizeof(struct disk_id_sector), actual); + std::tie(err, actual) = read_at(io, 0, &info, sizeof(disk_id_sector)); + if (err || (sizeof(disk_id_sector) != actual)) + return -1; 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); - // The 'unused' area is not necessarily zero filled and is ignoded + // The 'unused' area is not necessarily zero filled and is ignored // in the identification of a MDOS format image. // Expect an ASCII id, version, revision, and 'user name' strings. @@ -146,9 +152,9 @@ int mdos_format::find_size(util::random_read &io, uint32_t form_factor, const st return -1; // The date should be the numeric day, month and year. - int month = parse_date_field(info.date); - int day = parse_date_field(info.date + 2); - int year = parse_date_field(info.date + 4); + int const month = parse_date_field(info.date); + int const day = parse_date_field(info.date + 2); + int const year = parse_date_field(info.date + 4); LOG_FORMATS(" day %d, month %d, year %d\n", day, month, year); if (day < 1 || day > 32 || month < 1 || month > 12 || year < 0) @@ -182,8 +188,12 @@ int mdos_format::find_size(util::random_read &io, uint32_t form_factor, const st // the extent of the disk are free or available. uint8_t cluster_allocation[128], cluster_available[128]; - io.read_at(1 * 128, &cluster_allocation, sizeof(cluster_allocation), actual); - io.read_at(2 * 128, &cluster_available, sizeof(cluster_available), actual); + std::tie(err, actual) = read_at(io, 1 * 128, &cluster_allocation, sizeof(cluster_allocation)); + if (err || (sizeof(cluster_allocation) != actual)) + return -1; + std::tie(err, actual) = read_at(io, 2 * 128, &cluster_available, sizeof(cluster_available)); + if (err || (sizeof(cluster_available) != actual)) + return -1; for (int cluster = 0; cluster < sizeof(cluster_allocation) * 8; cluster++) { if (cluster * 4 * 128 + 4 * 128 > size) { @@ -202,7 +212,7 @@ int mdos_format::find_size(util::random_read &io, uint32_t form_factor, const st } } - for (int i=0; formats[i].form_factor; i++) { + for (int i = 0; formats[i].form_factor; i++) { const format &f = formats[i]; LOG_FORMATS(" checking format %d with form factor %02x, %d sectors, %d heads\n", i, f.form_factor, f.sector_count, f.head_count); diff --git a/src/lib/formats/mfi_dsk.cpp b/src/lib/formats/mfi_dsk.cpp index e6700f8f18f..e8ab99ee852 100644 --- a/src/lib/formats/mfi_dsk.cpp +++ b/src/lib/formats/mfi_dsk.cpp @@ -8,6 +8,7 @@ #include <cstring> #include <functional> +#include <tuple> /* @@ -99,38 +100,46 @@ bool mfi_format::supports_save() const noexcept int mfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { header h; + auto const [err, actual] = read_at(io, 0, &h, sizeof(header)); + if (err || (sizeof(header) != actual)) + return 0; - size_t actual; - io.read_at(0, &h, sizeof(header), actual); - if((memcmp( h.sign, sign, 16) == 0 || memcmp( h.sign, sign_old, 16) == 0) && + if((!memcmp(h.sign, sign, 16) || !memcmp(h.sign, sign_old, 16)) && (h.cyl_count & CYLINDER_MASK) <= 84 && (h.cyl_count >> RESOLUTION_SHIFT) < 3 && h.head_count <= 2 && (!form_factor || !h.form_factor || h.form_factor == form_factor)) return FIFID_SIGN|FIFID_STRUCT; + return 0; } bool mfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; + header h; - entry entries[84*2*4]; - io.read_at(0, &h, sizeof(header), actual); - int resolution = h.cyl_count >> RESOLUTION_SHIFT; + std::tie(err, actual) = read_at(io, 0, &h, sizeof(header)); + if(err || (sizeof(header) != actual)) + return false; + int const resolution = h.cyl_count >> RESOLUTION_SHIFT; h.cyl_count &= CYLINDER_MASK; - 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); if(!h.cyl_count) return true; + entry entries[84*2*4]; + std::tie(err, actual) = read_at(io, sizeof(header), &entries, (h.cyl_count << resolution)*h.head_count*sizeof(entry)); + if(err || (((h.cyl_count << resolution)*h.head_count*sizeof(entry)) != actual)) + return false; + std::function<void (const std::vector<uint32_t> &src, std::vector<uint32_t> &track)> converter; - if(!memcmp( h.sign, sign, 16)) { - converter = [](const std::vector<uint32_t> &src, std::vector<uint32_t> &track) -> void { + if(!memcmp(h.sign, sign, 16)) { + converter = [] (const std::vector<uint32_t> &src, std::vector<uint32_t> &track) { uint32_t ctime = 0; for(uint32_t mg : src) { ctime += mg & TIME_MASK; @@ -139,7 +148,7 @@ bool mfi_format::load(util::random_read &io, uint32_t form_factor, const std::ve }; } else { - converter = [](const std::vector<uint32_t> &src, std::vector<uint32_t> &track) -> void { + converter = [] (const std::vector<uint32_t> &src, std::vector<uint32_t> &track) { unsigned int cell_count = src.size(); uint32_t mg = src[0] & MG_MASK; uint32_t wmg = src[cell_count - 1] & MG_MASK; @@ -184,7 +193,7 @@ bool mfi_format::load(util::random_read &io, uint32_t form_factor, const std::ve compressed.resize(ent->compressed_size); uncompressed.resize(cell_count); - io.read_at(ent->offset, &compressed[0], ent->compressed_size, actual); + std::tie(err, actual) = read_at(io, ent->offset, &compressed[0], ent->compressed_size); // FIXME: check for errors and premature EOF uLongf size = ent->uncompressed_size; if(uncompress((Bytef *)uncompressed.data(), &size, &compressed[0], ent->compressed_size) != Z_OK) { @@ -204,7 +213,6 @@ bool mfi_format::load(util::random_read &io, uint32_t form_factor, const std::ve bool mfi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { - size_t actual; int tracks, heads; image.get_actual_geometry(tracks, heads); int resolution = image.get_resolution(); @@ -224,7 +232,7 @@ bool mfi_format::save(util::random_read_write &io, const std::vector<uint32_t> & h.form_factor = image.get_form_factor(); h.variant = image.get_variant(); - io.write_at(0, &h, sizeof(header), actual); + write_at(io, 0, &h, sizeof(header)); // FIXME: check for errors memset(entries, 0, sizeof(entries)); @@ -258,11 +266,11 @@ bool mfi_format::save(util::random_read_write &io, const std::vector<uint32_t> & entries[epos].write_splice = image.get_write_splice_position(track >> 2, head, track & 3); epos++; - io.write_at(pos, postcomp.get(), csize, actual); + write_at(io, pos, postcomp.get(), csize); // FIXME: check for errors pos += csize; } - io.write_at(sizeof(header), entries, (tracks << resolution)*heads*sizeof(entry), actual); + write_at(io, sizeof(header), entries, (tracks << resolution)*heads*sizeof(entry)); // FIXME: check for errors return true; } diff --git a/src/lib/formats/mfi_dsk.h b/src/lib/formats/mfi_dsk.h index 89201c6db8a..7241bcfab32 100644 --- a/src/lib/formats/mfi_dsk.h +++ b/src/lib/formats/mfi_dsk.h @@ -45,13 +45,13 @@ private: static const char sign[16]; struct header { - char sign[16]; - unsigned int cyl_count, head_count; - unsigned int form_factor, variant; + uint8_t sign[16]; + uint32_t cyl_count, head_count; + uint32_t form_factor, variant; }; struct entry { - unsigned int offset, compressed_size, uncompressed_size, write_splice; + uint32_t offset, compressed_size, uncompressed_size, write_splice; }; }; diff --git a/src/lib/formats/nabupc_dsk.cpp b/src/lib/formats/nabupc_dsk.cpp index 79d67a5e25f..00205c1e560 100644 --- a/src/lib/formats/nabupc_dsk.cpp +++ b/src/lib/formats/nabupc_dsk.cpp @@ -18,6 +18,7 @@ #include "ioprocs.h" #include "strformat.h" + const nabupc_format::format nabupc_format::formats[] = { { // 200k 40 track single sided double density (nabu) @@ -167,8 +168,7 @@ bool nabupc_format::load(util::random_read &io, uint32_t form_factor, const std: for (int head = 0; head < f.head_count; head++) { desc_pc_sector sects[sector_count]; uint8_t sectdata[sector_count * sector_size]; - size_t actual; - io.read_at((track * f.head_count + head) * sector_count * sector_size, sectdata, sector_count * sector_size, actual); + /*auto const [err, actual] =*/ read_at(io, (track * f.head_count + head) * sector_count * sector_size, sectdata, sector_count * sector_size); // FIXME: check for errors and premature EOF for (int i = 0; i < sector_count; i++) { sects[i].track = track; sects[i].head = head; @@ -196,8 +196,7 @@ bool nabupc_format::save(util::random_read_write &io, const std::vector<uint32_t auto bitstream = generate_bitstream_from_track(track, head, 2000, image); auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < sector_count; i++) { - size_t actual; - io.write_at(file_offset, sectors[i + 1].data(), sector_size, actual); + /*auto const [err, actual] =*/ write_at(io, file_offset, sectors[i + 1].data(), sector_size); // FIXME: check for errors file_offset += sector_size; } } diff --git a/src/lib/formats/nfd_dsk.cpp b/src/lib/formats/nfd_dsk.cpp index 773b35d8aef..7e61463fd7e 100644 --- a/src/lib/formats/nfd_dsk.cpp +++ b/src/lib/formats/nfd_dsk.cpp @@ -108,10 +108,11 @@ const char *nfd_format::extensions() const noexcept int nfd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[16]; - size_t actual; - io.read_at(0, h, 16, actual); + auto const [err, actual] = read_at(io, 0, h, 16); // TODO: does it really need 16 bytes? it only looks at 14. + if (err || (16 != actual)) + return 0; - if (strncmp((const char *)h, "T98FDDIMAGE.R0", 14) == 0 || strncmp((const char *)h, "T98FDDIMAGE.R1", 14) == 0) + if (!memcmp(h, "T98FDDIMAGE.R0", 14) || !memcmp(h, "T98FDDIMAGE.R1", 14)) return FIFID_SIGN; return 0; @@ -119,13 +120,12 @@ int nfd_format::identify(util::random_read &io, uint32_t form_factor, const std: bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; uint64_t size; if (io.length(size)) return false; uint8_t h[0x120], hsec[0x10]; - io.read_at(0, h, 0x120, actual); - int format_version = !strncmp((const char *)h, "T98FDDIMAGE.R0", 14) ? 0 : 1; + read_at(io, 0, h, 0x120); // FIXME: check for errors and premature EOF + int format_version = !memcmp(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) uint8_t disk_type = 0; @@ -149,7 +149,7 @@ bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve { int curr_track_size = 0; // read sector map absolute location - io.read_at(pos, hsec, 4, actual); + read_at(io, pos, hsec, 4); // FIXME: check for errors and premature EOF pos += 4; uint32_t secmap_addr = little_endianize_int32(*(uint32_t *)(hsec)); @@ -158,14 +158,14 @@ bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve // 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.read_at(secmap_addr, hsec, 0x10, actual); + read_at(io, secmap_addr, hsec, 0x10); // FIXME: check for errors and premature EOF 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.read_at(secmap_addr, hsec, 0x10, actual); + read_at(io, secmap_addr, hsec, 0x10); // FIXME: check for errors and premature EOF if (track == 0 && sect == 0) disk_type = hsec[0xb]; // can this change across the disk? I don't think so... @@ -184,7 +184,7 @@ bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve { for (int sect = 0; sect < num_specials[track]; sect++) { - io.read_at(secmap_addr, hsec, 0x10, actual); + read_at(io, secmap_addr, hsec, 0x10); // FIXME: check for errors and premature EOF secmap_addr += 0x10; curr_track_size += (hsec[9] + 1) * little_endianize_int32(*(uint32_t *)(hsec + 0x0a)); } @@ -207,7 +207,7 @@ bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve { // read sector map for this sector // for rev.0 format each sector uses 0x10 bytes - io.read_at(pos, hsec, 0x10, actual); + read_at(io, pos, hsec, 0x10); // FIXME: check for errors and premature EOF if (track == 0 && sect == 0) disk_type = hsec[0xa]; // can this change across the disk? I don't think so... @@ -254,7 +254,7 @@ bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::ve for (int track = 0; track < 163 && pos < size; track++) { - io.read_at(pos, sect_data, track_sizes[track], actual); + read_at(io, pos, sect_data, track_sizes[track]); // FIXME: check for errors and premature EOF for (int i = 0; i < num_secs[track]; i++) { diff --git a/src/lib/formats/oric_dsk.cpp b/src/lib/formats/oric_dsk.cpp index f4d9b78faa9..23433f1c3aa 100644 --- a/src/lib/formats/oric_dsk.cpp +++ b/src/lib/formats/oric_dsk.cpp @@ -39,8 +39,7 @@ bool oric_dsk_format::supports_save() const noexcept int oric_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[256]; - size_t actual; - io.read_at(0, h, 256, actual); + /*auto const [err, actual] =*/ read_at(io, 0, h, 256); // FIXME: check for errors and premature EOF if(memcmp(h, "MFM_DISK", 8)) return 0; @@ -60,19 +59,18 @@ int oric_dsk_format::identify(util::random_read &io, uint32_t form_factor, const bool oric_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; uint8_t h[256]; uint8_t t[6250+3]; t[6250] = t[6251] = t[6252] = 0; - io.read_at(0, h, 256, actual); + read_at(io, 0, h, 256); // FIXME: check for errors and premature EOF int sides = get_u32le(&h[ 8]); int tracks = get_u32le(&h[12]); for(int side=0; side<sides; side++) for(int track=0; track<tracks; track++) { - io.read_at(256+6400*(tracks*side + track), t, 6250, actual); + read_at(io, 256+6400*(tracks*side + track), t, 6250); // FIXME: check for errors and premature EOF std::vector<uint32_t> stream; int sector_size = 128; for(int i=0; i<6250; i++) { @@ -157,9 +155,9 @@ bool oric_jasmin_format::load(util::random_read &io, uint32_t form_factor, const int const heads = size == 41*17*256 ? 1 : 2; - std::vector<uint8_t> data(size); - size_t actual; - io.read_at(0, data.data(), size, actual); + auto const [err, data, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; for(int head = 0; head != heads; head++) for(int track = 0; track != 41; track++) { @@ -171,7 +169,7 @@ bool oric_jasmin_format::load(util::random_read &io, uint32_t form_factor, const sdesc[s].sector = sector + 1; sdesc[s].size = 1; sdesc[s].actual_size = 256; - sdesc[s].data = data.data() + 256 * (sector + track*17 + head*17*41); + sdesc[s].data = &data[256 * (sector + track*17 + head*17*41)]; sdesc[s].deleted = false; sdesc[s].bad_crc = false; } @@ -203,8 +201,7 @@ bool oric_jasmin_format::save(util::random_read_write &io, const std::vector<uin auto sectors = extract_sectors_from_bitstream_mfm_pc(generate_bitstream_from_track(track, head, 2000, image)); for(unsigned int sector = 0; sector != 17; sector ++) { 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); + /*auto const [err, actual] =*/ write_at(io, 256 * (sector + track*17 + head*17*41), data, 256); // FIXME: check for errors } } return true; diff --git a/src/lib/formats/os9_dsk.cpp b/src/lib/formats/os9_dsk.cpp index f74cd7fb3a6..ca79ced2145 100644 --- a/src/lib/formats/os9_dsk.cpp +++ b/src/lib/formats/os9_dsk.cpp @@ -88,8 +88,7 @@ int os9_format::find_size(util::random_read &io, uint32_t form_factor, const std return -1; uint8_t os9_header[0x60]; - size_t actual; - io.read_at(0, os9_header, sizeof(os9_header), actual); + /*auto const [err, actual] =*/ read_at(io, 0, os9_header, sizeof(os9_header)); // FIXME: check for errors and premature EOF int os9_total_sectors = get_u24be(&os9_header[0x00]); int os9_heads = util::BIT(os9_header[0x10], 0) ? 2 : 1; diff --git a/src/lib/formats/pasti_dsk.cpp b/src/lib/formats/pasti_dsk.cpp index 1390072b97c..ae82ee7939b 100644 --- a/src/lib/formats/pasti_dsk.cpp +++ b/src/lib/formats/pasti_dsk.cpp @@ -45,11 +45,10 @@ bool pasti_format::supports_save() const noexcept int pasti_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t h[16]; - size_t actual; - io.read_at(0, h, 16, actual); + /*auto const [err, actual] =*/ read_at(io, 0, h, 16); // FIXME: check for errors and premature EOF if(!memcmp(h, "RSY\0\3\0", 6) && - (1 || (h[10] >= 80 && h[10] <= 82) || (h[10] >= 160 && h[10] <= 164))) + (1 || (h[10] >= 80 && h[10] <= 82) || (h[10] >= 160 && h[10] <= 164))) // TODO: why is this check disabled? return FIFID_SIGN; return 0; @@ -67,9 +66,8 @@ static void hexdump(const uint8_t *d, int s) bool pasti_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; uint8_t fh[16]; - io.read_at(0, fh, 16, actual); + read_at(io, 0, fh, 16); // FIXME: check for errors and premature EOF std::vector<uint8_t> raw_track; @@ -84,7 +82,7 @@ bool pasti_format::load(util::random_read &io, uint32_t form_factor, const std:: for(int track=0; track < tracks; track++) { for(int head=0; head < heads; head++) { uint8_t th[16]; - io.read_at(pos, th, 16, actual); + read_at(io, pos, th, 16); // FIXME: check for errors and premature EOF int entry_len = get_u32le(&th[0]); int fuzz_len = get_u32le(&th[4]); int sect = get_u16le(&th[8]); @@ -95,7 +93,7 @@ bool pasti_format::load(util::random_read &io, uint32_t form_factor, const std:: raw_track.resize(entry_len-16); - io.read_at(pos+16, &raw_track[0], entry_len-16, actual); + read_at(io, pos+16, &raw_track[0], entry_len-16); // FIXME: check for errors and premature EOF 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/pc98fdi_dsk.cpp b/src/lib/formats/pc98fdi_dsk.cpp index b331ad8b521..10822ab316d 100644 --- a/src/lib/formats/pc98fdi_dsk.cpp +++ b/src/lib/formats/pc98fdi_dsk.cpp @@ -11,8 +11,9 @@ #include "pc98fdi_dsk.h" #include "ioprocs.h" +#include "multibyte.h" -#include "osdcomm.h" // little_endianize_int32 +#include <tuple> pc98fdi_format::pc98fdi_format() @@ -41,15 +42,16 @@ int pc98fdi_format::identify(util::random_read &io, uint32_t form_factor, const return 0; 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)); + auto const [err, actual] = read_at(io, 0, h, 32); + if(err || (32 != actual)) + return 0; + + uint32_t const hsize = get_u32le(h + 0x8); + uint32_t const psize = get_u32le(h + 0xc); + uint32_t const ssize = get_u32le(h + 0x10); + uint32_t const scnt = get_u32le(h + 0x14); + uint32_t const sides = get_u32le(h + 0x18); + uint32_t const ntrk = get_u32le(h + 0x1c); if(size == hsize + psize && psize == ssize*scnt*sides*ntrk) return FIFID_STRUCT; @@ -58,16 +60,19 @@ int pc98fdi_format::identify(util::random_read &io, uint32_t form_factor, const bool pc98fdi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; uint8_t h[32]; - io.read_at(0, h, 32, actual); + std::tie(err, actual) = read_at(io, 0, h, 32); + if(err || (32 != actual)) + return false; - 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)); + uint32_t const hsize = get_u32le(h + 0x8); + uint32_t const sector_size = get_u32le(h + 0x10); + uint32_t const sector_count = get_u32le(h + 0x14); + uint32_t const head_count = get_u32le(h + 0x18); + uint32_t const track_count = get_u32le(h + 0x1c); int const cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666; @@ -78,9 +83,9 @@ bool pc98fdi_format::load(util::random_read &io, uint32_t form_factor, const std desc_pc_sector sects[256]; uint8_t sect_data[65536]; - for(int track=0; track < track_count; track++) + for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { - io.read_at(hsize + sector_size*sector_count*(track*head_count + head), sect_data, sector_size*sector_count, actual); + std::tie(err, actual) = read_at(io, hsize + sector_size*sector_count*(track*head_count + head), sect_data, sector_size*sector_count); // FIXME: check for errors and premature EOF for(int i=0; i<sector_count; i++) { sects[i].track = track; @@ -95,6 +100,7 @@ bool pc98fdi_format::load(util::random_read &io, uint32_t form_factor, const std build_pc_track_mfm(track, head, image, cell_count, sector_count, sects, calc_default_pc_gap3_size(form_factor, sector_size)); } + } return true; } diff --git a/src/lib/formats/poly_dsk.cpp b/src/lib/formats/poly_dsk.cpp index 4a264e293a1..8b8f48780f8 100644 --- a/src/lib/formats/poly_dsk.cpp +++ b/src/lib/formats/poly_dsk.cpp @@ -50,9 +50,8 @@ int poly_cpm_format::identify(util::random_read &io, uint32_t form_factor, const { // check for Poly CP/M boot sector 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) + auto const [err, actual] = read_at(io, 0, boot, 16); + if (!err && (16 == actual) && !memcmp(boot, "\x86\xc3\xb7\x00\x00\x8e\x10\xc0\xbf\x00\x01\xbf\xe0\x60\x00\x00", 16)) { return FIFID_SIZE|FIFID_SIGN; } @@ -114,8 +113,7 @@ bool poly_cpm_format::load(util::random_read &io, uint32_t form_factor, const st sects[i].deleted = false; sects[i].bad_crc = false; sects[i].data = §_data[sdatapos]; - size_t actual; - io.read(sects[i].data, bps, actual); + /*auto const [err, actual] =*/ read(io, sects[i].data, bps); // FIXME: check for errors and premature EOF sdatapos += bps; } // gap sizes unverified diff --git a/src/lib/formats/rx50_dsk.cpp b/src/lib/formats/rx50_dsk.cpp index cefc2725209..853caf0dbc1 100644 --- a/src/lib/formats/rx50_dsk.cpp +++ b/src/lib/formats/rx50_dsk.cpp @@ -139,7 +139,7 @@ int rx50img_format::identify(util::random_read &io, uint32_t form_factor, const return 0; } - // /* Sectors are numbered 1 to 10 */ +// Sectors are numbered 1 to 10 bool rx50img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { uint8_t track_count, head_count, sector_count; @@ -158,8 +158,7 @@ bool rx50img_format::load(util::random_read &io, uint32_t form_factor, const std int track_size = sector_count*512; 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); + /*auto const [err, actual] =*/ read_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(rx50_10_desc, track, head, sectors, sector_count, 102064, image); // 98480 } } @@ -205,8 +204,7 @@ bool rx50img_format::save(util::random_read_write &io, const std::vector<uint32_ 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); - size_t actual; - io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors } } return true; diff --git a/src/lib/formats/sdf_dsk.cpp b/src/lib/formats/sdf_dsk.cpp index 6e3f1147167..92a6b9fb653 100644 --- a/src/lib/formats/sdf_dsk.cpp +++ b/src/lib/formats/sdf_dsk.cpp @@ -50,8 +50,11 @@ int sdf_format::identify(util::random_read &io, uint32_t form_factor, const std: return 0; } - size_t actual; - io.read_at(0, header, HEADER_SIZE, actual); + auto const [err, actual] = read_at(io, 0, header, HEADER_SIZE); + if (err || (HEADER_SIZE != actual)) + { + return 0; + } int tracks = header[4]; int heads = header[5]; @@ -79,12 +82,11 @@ int sdf_format::identify(util::random_read &io, uint32_t form_factor, const std: bool sdf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - 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.read_at(0, header, HEADER_SIZE, actual); + read_at(io, 0, header, HEADER_SIZE); // FIXME: check for errors and premature EOF const int tracks = header[4]; const int heads = header[5]; @@ -108,7 +110,7 @@ bool sdf_format::load(util::random_read &io, uint32_t form_factor, const std::ve raw_track_data.clear(); // Read track - io.read_at(HEADER_SIZE + (heads * track + head) * TOTAL_TRACK_SIZE, &track_data[0], TOTAL_TRACK_SIZE, actual); + read_at(io, HEADER_SIZE + (heads * track + head) * TOTAL_TRACK_SIZE, &track_data[0], TOTAL_TRACK_SIZE); // FIXME: check for errors and premature EOF int sector_count = track_data[0]; diff --git a/src/lib/formats/st_dsk.cpp b/src/lib/formats/st_dsk.cpp index 17e0d9efc17..fc105de6fcb 100644 --- a/src/lib/formats/st_dsk.cpp +++ b/src/lib/formats/st_dsk.cpp @@ -79,8 +79,7 @@ bool st_format::load(util::random_read &io, uint32_t form_factor, const std::vec int track_size = sector_count*512; 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); + /*auto const [err, actual] =*/ read_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(atari_st_fcp_get_desc(track, head, head_count, sector_count), track, head, sectors, sector_count, 100000, image); } @@ -116,8 +115,7 @@ bool st_format::save(util::random_read_write &io, const std::vector<uint32_t> &v 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); - size_t actual; - io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, (track*head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors } } @@ -152,8 +150,7 @@ bool msa_format::supports_save() const noexcept 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]; - size_t actual; - io.read_at(0, h, 10, actual); + /*auto const [err, actual] =*/ read_at(io, 0, h, 10); // FIXME: check for errors and premature EOF sign = get_u16be(&h[0]); sect = get_u16be(&h[2]); head = get_u16be(&h[4]); @@ -247,12 +244,11 @@ bool msa_format::load(util::random_read &io, uint32_t form_factor, const std::ve for(int track=strack; track <= etrack; track++) { for(int head=0; head <= heads; head++) { - size_t actual; uint8_t th[2]; - io.read_at(pos, th, 2, actual); + read_at(io, pos, th, 2); // FIXME: check for errors and premature EOF pos += 2; int tsize = get_u16be(th); - io.read_at(pos, sectdata, tsize, actual); + read_at(io, pos, sectdata, tsize); // FIXME: check for errors and premature EOF pos += tsize; if(tsize < track_size) { if(!uncompress(sectdata, tsize, track_size)) @@ -301,8 +297,7 @@ bool msa_format::save(util::random_read_write &io, const std::vector<uint32_t> & if(io.seek(0, SEEK_SET)) return false; - size_t actual; - io.write(header, 10, actual); + write(io, header, 10); // FIXME: check for errors uint8_t sectdata[11*512]; uint8_t compdata[11*512]; @@ -315,13 +310,13 @@ bool msa_format::save(util::random_read_write &io, const std::vector<uint32_t> & if(compress(sectdata, track_size, compdata, csize)) { uint8_t th[2]; put_u16be(th, csize); - io.write(th, 2, actual); - io.write(compdata, csize, actual); + write(io, th, 2); // FIXME: check for errors + write(io, compdata, csize); // FIXME: check for errors } else { uint8_t th[2]; put_u16be(th, track_size); - io.write(th, 2, actual); - io.write(sectdata, track_size, actual); + write(io, th, 2); // FIXME: check for errors + write(io, sectdata, track_size); // FIXME: check for errors } } } diff --git a/src/lib/formats/svi_dsk.cpp b/src/lib/formats/svi_dsk.cpp index a60491fb20d..4d326542ad5 100644 --- a/src/lib/formats/svi_dsk.cpp +++ b/src/lib/formats/svi_dsk.cpp @@ -83,8 +83,7 @@ bool svi_format::load(util::random_read &io, uint32_t form_factor, const std::ve sectors[i].bad_crc = false; sectors[i].data = §or_data[sector_offset]; - size_t actual; - io.read(sectors[i].data, sector_size, actual); + /*auto const [err, actual] =*/ read(io, sectors[i].data, sector_size); // FIXME: check for errors and premature EOF sector_offset += sector_size; } @@ -113,8 +112,7 @@ bool svi_format::save(util::random_read_write &io, const std::vector<uint32_t> & for (int i = 0; i < 18; i++) { - size_t actual; - io.write(sectors[i + 1].data(), 128, actual); + /*auto const [err, actual] =*/ write(io, sectors[i + 1].data(), 128); // FIXME: check for errors } // rest are mfm tracks @@ -130,8 +128,7 @@ bool svi_format::save(util::random_read_write &io, const std::vector<uint32_t> & for (int i = 0; i < 17; i++) { - size_t actual; - io.write(sectors[i + 1].data(), 256, actual); + /*auto const [err, actual] =*/ write(io, sectors[i + 1].data(), 256); // FIXME: check for errors } } } diff --git a/src/lib/formats/td0_dsk.cpp b/src/lib/formats/td0_dsk.cpp index a9ba54022a0..956bbd002c7 100644 --- a/src/lib/formats/td0_dsk.cpp +++ b/src/lib/formats/td0_dsk.cpp @@ -20,6 +20,7 @@ #include "multibyte.h" #include <cstring> +#include <tuple> #define BUFSZ 512 // new input buffer @@ -330,8 +331,7 @@ int td0dsk_t::data_read(uint8_t *buf, uint16_t size) if (size > image_size - floppy_file_offset) { size = image_size - floppy_file_offset; } - size_t actual; - floppy_file.read_at(floppy_file_offset, buf, size, actual); + /*auto const [err, actual] =*/ read_at(floppy_file, floppy_file_offset, buf, size); // FIXME: check for errors and premature EOF floppy_file_offset += size; return size; } @@ -810,10 +810,13 @@ const char *td0_format::extensions() const noexcept int td0_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { - size_t actual; uint8_t h[7]; + auto const [err, actual] = read_at(io, 0, h, 7); // FIXME: does this need to read 7 bytes? it only check 2 bytes. Also check for premature EOF. + if(err) + { + return 0; + } - io.read_at(0, h, 7, actual); if(((h[0] == 'T') && (h[1] == 'D')) || ((h[0] == 't') && (h[1] == 'd'))) { return FIFID_SIGN; @@ -823,6 +826,7 @@ int td0_format::identify(util::random_read &io, uint32_t form_factor, const std: bool td0_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { + std::error_condition err; size_t actual; int track_count = 0; int head_count = 0; @@ -830,9 +834,10 @@ bool td0_format::load(util::random_read &io, uint32_t form_factor, const std::ve int offset = 0; 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[12]; - if(io.read_at(0, header, 12, actual) || actual != 12) + uint8_t header[12]; + std::tie(err, actual) = read_at(io, 0, header, 12); + if(err || (actual != 12)) return false; head_count = header[9]; @@ -849,7 +854,8 @@ bool td0_format::load(util::random_read &io, uint32_t form_factor, const std::ve uint64_t image_size; if(io.length(image_size)) return false; - if(io.read_at(12, &imagebuf[0], image_size - 12, actual) || actual != (image_size - 12)) + std::tie(err, actual) = read_at(io, 12, &imagebuf[0], image_size - 12); + if(err || (actual != (image_size - 12))) return false; } diff --git a/src/lib/formats/ti99_dsk.cpp b/src/lib/formats/ti99_dsk.cpp index 64b8d81aa67..4cca5bdb996 100644 --- a/src/lib/formats/ti99_dsk.cpp +++ b/src/lib/formats/ti99_dsk.cpp @@ -954,8 +954,7 @@ int ti99_sdf_format::identify(util::random_read &io, uint32_t form_factor, const { // Read first sector (Volume Information Block) ti99vib vib; - size_t actual; - io.read_at(0, &vib, sizeof(ti99vib), actual); + /*auto const [err, actual] =*/ read_at(io, 0, &vib, sizeof(ti99vib)); // FIXME: check for errors and premature EOF // Check from contents if ((vib.id[0]=='D')&&(vib.id[1]=='S')&&(vib.id[2]=='K')) @@ -993,8 +992,7 @@ void ti99_sdf_format::determine_sizes(util::random_read &io, int& cell_size, int // Read first sector ti99vib vib; - size_t actual; - io.read_at(0, &vib, sizeof(ti99vib), actual); + /*auto const [err, actual] =*/ read_at(io, 0, &vib, sizeof(ti99vib)); // FIXME: check for errors and premature EOF // Check from contents if ((vib.id[0]=='D')&&(vib.id[1]=='S')&&(vib.id[2]=='K')) @@ -1079,8 +1077,7 @@ void ti99_sdf_format::load_track(util::random_read &io, uint8_t *sectordata, int int logicaltrack = (head==0)? track : (2*trackcount - track - 1); int position = logicaltrack * get_track_size(sectorcount); - size_t actual; - io.read_at(position, sectordata, sectorcount*SECTOR_SIZE, actual); + /*auto const [err, actual] =*/ read_at(io, position, sectordata, sectorcount*SECTOR_SIZE); // FIXME: check for errors and premature EOF // Interleave and skew int interleave = 7; @@ -1158,8 +1155,7 @@ void ti99_sdf_format::write_track(util::random_read_write &io, uint8_t *sectorda { 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); - size_t actual; - io.write_at(trackoffset + sector[i] * SECTOR_SIZE, buf, SECTOR_SIZE, actual); + /*auto const [err, actual] =*/ write_at(io, trackoffset + sector[i] * SECTOR_SIZE, buf, SECTOR_SIZE); // FIXME: check for errors } } @@ -1246,8 +1242,7 @@ int ti99_tdf_format::identify(util::random_read &io, uint32_t form_factor, const LOGMASKED(LOG_INFO, "[ti99_dsk] Image file length matches TDF\n"); // Fetch track 0 - size_t actual; - io.read_at(0, fulltrack, get_track_size(sector_count), actual); + /*auto const [err, actual] =*/ read_at(io, 0, fulltrack, get_track_size(sector_count)); // FIXME: check for errors and premature EOF if (sector_count == 9) { @@ -1358,12 +1353,11 @@ void ti99_tdf_format::determine_sizes(util::random_read &io, int& cell_size, int */ 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) const { - 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.read_at(0, fulltrack, 100, actual); + read_at(io, 0, fulltrack, 100); // FIXME: check for errors and premature EOF int offset = 0; int tracksize = get_track_size(sectorcount); @@ -1404,7 +1398,7 @@ void ti99_tdf_format::load_track(util::random_read &io, uint8_t *sectordata, int int base = (head * trackcount + track) * tracksize; int position = 0; - io.read_at(base, fulltrack, tracksize, actual); + read_at(io, base, fulltrack, tracksize); // FIXME: check for errors and premature EOF for (int i=0; i < sectorcount; i++) { @@ -1506,8 +1500,7 @@ void ti99_tdf_format::write_track(util::random_read_write &io, uint8_t *sectorda for (int i=0; i < param[WGAP3]; i++) trackdata[pos++] = param[WGAPBYTE]; } for (int i=0; i < param[WGAP4]; i++) trackdata[pos++] = param[WGAPBYTE]; - size_t actual; - io.write_at(offset, trackdata, get_track_size(sector_count), actual); + /*auto const [err, actual] =*/ write_at(io, offset, trackdata, get_track_size(sector_count)); // FIXME: check for errors } int ti99_tdf_format::get_track_size(int sector_count) const diff --git a/src/lib/formats/trd_dsk.cpp b/src/lib/formats/trd_dsk.cpp index 4ec6d4a962a..cf1a7f00445 100644 --- a/src/lib/formats/trd_dsk.cpp +++ b/src/lib/formats/trd_dsk.cpp @@ -12,6 +12,8 @@ #include "ioprocs.h" +#include <tuple> + trd_format::trd_format() : wd177x_format(formats) { @@ -51,16 +53,19 @@ int trd_format::find_size(util::random_read &io, uint32_t form_factor, const std { index = i; // at least size match, save it for the case if there will be no exact matches + std::error_condition err; size_t actual; uint8_t sectdata[0x100]; if (f.encoding == floppy_image::MFM) - io.read_at(0x800, sectdata, 0x100, actual); + std::tie(err, actual) = read_at(io, 0x800, sectdata, 0x100); else { - io.read_at(0x100, sectdata, 0x100, actual); + std::tie(err, actual) = read_at(io, 0x100, sectdata, 0x100); for (int i = 0; i < 0x100; i++) sectdata[i] ^= 0xff; } + if (err || (0x100 != actual)) + continue; uint8_t disktype = sectdata[0xe3]; // 16 - DS80, 17 - DS40, 18 - SS80, 19 - SS40 if (disktype < 0x16 || disktype > 0x19) diff --git a/src/lib/formats/trs80_dsk.cpp b/src/lib/formats/trs80_dsk.cpp index 511d9fdfbf1..f670273a5af 100644 --- a/src/lib/formats/trs80_dsk.cpp +++ b/src/lib/formats/trs80_dsk.cpp @@ -146,9 +146,9 @@ int jv3_format::identify(util::random_read &io, uint32_t form_factor, const std: if (image_size < 0x2200) return 0; // too small, silent return - std::vector<uint8_t> data(image_size); - size_t actual; - io.read_at(0, data.data(), image_size, actual); + auto const [err, data, actual] = read_at(io, 0, image_size); + if (err || (actual != image_size)) + return 0; const uint32_t entries = 2901; const uint32_t header_size = entries *3 +1; @@ -238,9 +238,9 @@ bool jv3_format::load(util::random_read &io, uint32_t form_factor, const std::ve uint64_t image_size; if (io.length(image_size)) return false; - std::vector<uint8_t> data(image_size); - size_t actual; - io.read_at(0, data.data(), data.size(), actual); + auto const [err, data, actual] = read_at(io, 0, image_size); + if (err || (actual != image_size)) + return 0; const uint32_t entries = 2901; const uint32_t header_size = entries *3 +1; bool is_dd = false, is_ds = false; @@ -365,13 +365,14 @@ bool jv3_format::save(util::random_read_write &io, const std::vector<uint32_t> & { // If the disk already exists, find out if it's writable uint64_t image_size; - if (!io.length(image_size)) + if (!io.length(image_size) && (image_size >= 0x2200)) { - std::vector<uint8_t> data(image_size); - size_t actual; - io.read_at(0, data.data(), data.size(), actual); - if ((data.size() >= 0x2200) && (data[0x21ff] == 0)) - return false; // disk is readonly + uint8_t flag; + auto const [err, actual] = read_at(io, 0x21ff, &flag, 1); + if (err || (1 != actual)) // TODO: should we save over the top if we couldn’t read the read-only flag? + return false; + if (flag == 0) + return false; // disk is read-only } } @@ -413,8 +414,7 @@ bool jv3_format::save(util::random_read_write &io, const std::vector<uint32_t> & header[sect_ptr++] = track; header[sect_ptr++] = i; header[sect_ptr++] = head ? 0x10 : 0; - size_t actual; - io.write_at(data_ptr, &dummy[0], 256, actual); + /*auto const [err, actual] =*/ write_at(io, data_ptr, &dummy[0], 256); // FIXME: check for errors data_ptr += 256; } } @@ -435,16 +435,14 @@ bool jv3_format::save(util::random_read_write &io, const std::vector<uint32_t> & flags |= (sectors[i].size() >> 8) ^1; flags |= head ? 0x10 : 0; header[sect_ptr++] = flags; - size_t actual; - io.write_at(data_ptr, sectors[i].data(), sectors[i].size(), actual); + /*auto const [err, actual] =*/ write_at(io, data_ptr, sectors[i].data(), sectors[i].size()); // FIXME: check for errors data_ptr += sectors[i].size(); } } } } // Save the header - size_t actual; - io.write_at(0, header, 0x2200, actual); + /*auto const [err, actual] =*/ write_at(io, 0, header, 0x2200); // FIXME: check for errors return true; } diff --git a/src/lib/formats/uniflex_dsk.cpp b/src/lib/formats/uniflex_dsk.cpp index 0143bf8cf0e..063d3c877f9 100644 --- a/src/lib/formats/uniflex_dsk.cpp +++ b/src/lib/formats/uniflex_dsk.cpp @@ -53,8 +53,9 @@ int uniflex_format::find_size(util::random_read &io, uint32_t form_factor, const // Look at the SIR sector, the second sector. uint8_t sir[192]; - size_t actual; - io.read_at(1 * 512, sir, sizeof(sir), actual); + auto const [err, actual] = read_at(io, 1 * 512, sir, sizeof(sir)); // FIXME: check for premature EOF + if (err) + return -1; uint16_t fdn_block_count = get_u16be(&sir[0x10]); uint32_t last_block_number = get_u24be(&sir[0x12]); diff --git a/src/lib/formats/upd765_dsk.cpp b/src/lib/formats/upd765_dsk.cpp index f3f08f37b4e..589ab1e1666 100644 --- a/src/lib/formats/upd765_dsk.cpp +++ b/src/lib/formats/upd765_dsk.cpp @@ -231,8 +231,7 @@ bool upd765_format::load(util::random_read &io, uint32_t form_factor, const std: for(int track=0; track < f.track_count; track++) for(int head=0; head < f.head_count; head++) { build_sector_description(f, sectdata, sectors, track, head); - size_t actual; - io.read_at((track*f.head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ read_at(io, (track*f.head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(desc, track, head, sectors, f.sector_count, total_size, image); } @@ -345,20 +344,19 @@ bool upd765_format::save(util::random_read_write &io, const std::vector<uint32_t if(chosen_candidate == -1) chosen_candidate = 0; - const format &f = formats[chosen_candidate]; int track_size = compute_track_size(f); uint8_t sectdata[40*512]; desc_s sectors[40]; - for(int track=0; track < f.track_count; track++) + for(int track=0; track < f.track_count; track++) { for(int head=0; head < f.head_count; head++) { build_sector_description(f, sectdata, sectors, track, head); extract_sectors(image, f, sectors, track, head); - size_t actual; - io.write_at((track*f.head_count + head)*track_size, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, (track*f.head_count + head)*track_size, sectdata, track_size); // FIXME: check for errors } + } return true; } diff --git a/src/lib/formats/vdk_dsk.cpp b/src/lib/formats/vdk_dsk.cpp index e47d3502981..02e25ec5df9 100644 --- a/src/lib/formats/vdk_dsk.cpp +++ b/src/lib/formats/vdk_dsk.cpp @@ -36,9 +36,10 @@ const char *vdk_format::extensions() const noexcept int vdk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { - size_t actual; uint8_t id[2]; - io.read_at(0, id, 2, actual); + auto const [err, actual] = read_at(io, 0, id, 2); + if (err || (2 != actual)) + return 0; if (id[0] == 'd' && id[1] == 'k') return FIFID_SIGN; @@ -48,12 +49,11 @@ int vdk_format::identify(util::random_read &io, uint32_t form_factor, const std: bool vdk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - size_t actual; if (io.seek(0, SEEK_SET)) return false; uint8_t header[0x100]; - io.read(header, 0x100, actual); + read(io, header, 0x100); // FIXME: check for errors and premature EOF int const header_size = header[3] * 0x100 + header[2]; int const track_count = header[8]; @@ -81,7 +81,7 @@ bool vdk_format::load(util::random_read &io, uint32_t form_factor, const std::ve sectors[i].bad_crc = false; sectors[i].data = §or_data[sector_offset]; - io.read(sectors[i].data, SECTOR_SIZE, actual); + read(io, sectors[i].data, SECTOR_SIZE); // FIXME: check for errors and premature EOF sector_offset += SECTOR_SIZE; } @@ -95,7 +95,6 @@ bool vdk_format::load(util::random_read &io, uint32_t form_factor, const std::ve bool vdk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { - size_t actual; if (io.seek(0, SEEK_SET)) return false; @@ -118,7 +117,7 @@ bool vdk_format::save(util::random_read_write &io, const std::vector<uint32_t> & header[10] = 0; header[11] = 0; - io.write(header, sizeof(header), actual); + write(io, header, sizeof(header)); // FIXME: check for errors // write disk data for (int track = 0; track < track_count; track++) @@ -129,7 +128,7 @@ bool vdk_format::save(util::random_read_write &io, const std::vector<uint32_t> & auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < SECTOR_COUNT; i++) - io.write(sectors[FIRST_SECTOR_ID + i].data(), SECTOR_SIZE, actual); + write(io, sectors[FIRST_SECTOR_ID + i].data(), SECTOR_SIZE); // FIXME: check for errors } } diff --git a/src/lib/formats/vgi_dsk.cpp b/src/lib/formats/vgi_dsk.cpp index ae6cd53018e..b31ef0b51e9 100644 --- a/src/lib/formats/vgi_dsk.cpp +++ b/src/lib/formats/vgi_dsk.cpp @@ -18,8 +18,8 @@ http://www.bitsavers.org/pdf/micropolis/metafloppy/1084-01_1040_1050_Users_Manua #include <cstring> -static const int track_size = 100'000; -static const int half_bitcell_size = 2000; +static constexpr int TRACK_SIZE = 100'000; +static constexpr int HALF_BITCELL_SIZE = 2000; micropolis_vgi_format::micropolis_vgi_format() : floppy_image_format_t() { @@ -76,14 +76,14 @@ bool micropolis_vgi_format::load(util::random_read &io, uint32_t form_factor, co for (int track = 0; track < fmt.track_count; track++) { for (int sector = 0; sector < 16; sector++) { for (int i = 0; i < 40; i++) - mfm_w(buf, 8, 0, half_bitcell_size); - std::size_t actual; - if (io.read(sector_bytes, std::size(sector_bytes), actual)) + mfm_w(buf, 8, 0, HALF_BITCELL_SIZE); + auto const [err, actual] = read(io, sector_bytes, std::size(sector_bytes)); + if (err || (actual != std::size(sector_bytes))) return false; for (int i = 0; i < std::size(sector_bytes); i++) - mfm_w(buf, 8, sector_bytes[i], half_bitcell_size); - while (buf.size() < track_size/16 * (sector+1)) - mfm_w(buf, 8, 0, half_bitcell_size); + mfm_w(buf, 8, sector_bytes[i], HALF_BITCELL_SIZE); + while (buf.size() < TRACK_SIZE/16 * (sector+1)) + mfm_w(buf, 8, 0, HALF_BITCELL_SIZE); } generate_track_from_levels(track, head, buf, 0, image); buf.clear(); @@ -116,9 +116,9 @@ bool micropolis_vgi_format::save(util::random_read_write &io, const std::vector< uint8_t sector_bytes[275]; for (int head = 0; head < fmt.head_count; head++) { for (int track = 0; track < fmt.track_count; track++) { - std::vector<bool> bitstream = generate_bitstream_from_track(track, head, half_bitcell_size, image); + std::vector<bool> bitstream = generate_bitstream_from_track(track, head, HALF_BITCELL_SIZE, image); for (int sector = 0; sector < 16; sector++) { - int sector_start = track_size/16 * sector; + int sector_start = TRACK_SIZE/16 * sector; uint32_t pos = sector_start + 512 - 16; uint16_t shift_reg = 0; while (pos < sector_start + 60*16 && pos < bitstream.size()) { @@ -134,8 +134,8 @@ bool micropolis_vgi_format::save(util::random_read_write &io, const std::vector< memset(sector_bytes, 0, std::size(sector_bytes)); } - std::size_t actual; - if (io.write(sector_bytes, std::size(sector_bytes), actual)) + auto const [err, actual] = write(io, sector_bytes, std::size(sector_bytes)); + if (err) return false; } } diff --git a/src/lib/formats/victor9k_dsk.cpp b/src/lib/formats/victor9k_dsk.cpp index a0fdaedab5a..803c75303d8 100644 --- a/src/lib/formats/victor9k_dsk.cpp +++ b/src/lib/formats/victor9k_dsk.cpp @@ -136,12 +136,12 @@ const char *victor9k_format::extensions() const noexcept int victor9k_format::find_size(util::random_read &io) { uint64_t size; - if(io.length(size)) + if (io.length(size)) return -1; - for(int i=0; formats[i].sector_count; i++) { + 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) + if(size == uint32_t(f.sector_count*f.sector_base_size)) return i; } @@ -155,7 +155,7 @@ int victor9k_format::find_size(util::random_read &io, uint32_t form_factor) int victor9k_format::identify(const floppy_image &image) { - for(int i=0; formats[i].form_factor; i++) { + for (int i = 0; formats[i].form_factor; i++) { const format &f = formats[i]; if(f.variant == image.get_variant()) return i; @@ -291,7 +291,7 @@ void victor9k_format::build_sector_description(const format &f, uint8_t *sectdat bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { int const type = find_size(io, form_factor); - if(type == -1) + if (type == -1) return false; const format &f = formats[type]; @@ -300,15 +300,12 @@ bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const st f.head_count, f.sector_count); uint64_t size; - if(io.length(size)) + if (io.length(size)) return false; - std::vector<uint8_t> img; - try { img.resize(size); } - catch (...) { return false; } - - size_t actual; - io.read_at(0, &img[0], size, actual); + auto const [err, img, actual] = read_at(io, 0, size); + if (err || (actual != size)) + return false; log_boot_sector(&img[0]); @@ -449,17 +446,17 @@ bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32 { int type = victor9k_format::identify(image); uint64_t size; - io.length(size); + io.length(size); // FIXME: check for errors osd_printf_verbose("save type: %01d, size: %d\n", type, size); - if(type == -1) + if (type == -1) return false; const format &f = formats[type]; osd_printf_verbose("save Heads: %01d Tracks: %02d Sectors/track head[1]track[1]: %02d\n ", f.head_count, f.track_count, sectors_per_track[1][1]); - for(int head=0; head < f.head_count; head++) { + for (int head = 0; head < f.head_count; head++) { for(int track=0; track < f.track_count; track++) { int sector_count = sectors_per_track[head][track]; int track_size = compute_track_size(f, head, track); @@ -471,8 +468,7 @@ bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32 build_sector_description(f, sectdata, 0, sectors, sector_count); extract_sectors(image, f, sectors, track, head, sector_count); - size_t actual; - io.write_at(offset, sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, offset, sectdata, track_size); // FIXME: check for errors } } @@ -481,7 +477,6 @@ bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32 void victor9k_format::extract_sectors(const floppy_image &image, const format &f, desc_s *sdesc, int track, int head, int sector_count) { - // Extract the sectors auto bitstream = generate_bitstream_from_track(track, head, cell_size[speed_zone[head][track]], image); auto sectors = extract_sectors_from_bitstream_victor_gcr5(bitstream); @@ -493,14 +488,14 @@ void victor9k_format::extract_sectors(const floppy_image &image, const format &f } } - for(int i=0; i<sector_count; i++) { + for (int i = 0; i<sector_count; i++) { desc_s &ds = sdesc[i]; const auto &data = sectors[ds.sector_id]; osd_printf_verbose("Head: %01d TracK: %02d Total Sectors: %02d Current Sector: %02d ", head, track, sector_count, i); - if(data.empty()) { + if (data.empty()) { memset((uint8_t *)ds.data, 0, ds.size); - } else if(data.size() < ds.size) { + } else if (data.size() < ds.size) { memcpy((uint8_t *)ds.data, data.data(), data.size() - 1); memset((uint8_t *)ds.data + data.size() - 1, 0, data.size() - ds.size); osd_printf_verbose("data.size(): %01d\n", data.size()); diff --git a/src/lib/formats/vt_dsk.cpp b/src/lib/formats/vt_dsk.cpp index 202ec784187..8792ba86525 100644 --- a/src/lib/formats/vt_dsk.cpp +++ b/src/lib/formats/vt_dsk.cpp @@ -35,13 +35,13 @@ void vtech_common_format::wbyte(std::vector<uint32_t> &buffer, uint32_t &pos, ui wbit(buffer, pos, (byte >> i) & 1); } -void vtech_common_format::image_to_flux(const std::vector<uint8_t> &bdata, floppy_image &image) +void vtech_common_format::image_to_flux(const uint8_t *bdata, size_t size, floppy_image &image) { static const uint8_t sector_map[16] = { 0x0, 0xb, 0x6, 0x1, 0xc, 0x7, 0x2, 0xd, 0x8, 0x3, 0xe, 0x9, 0x4, 0xf, 0xa, 0x5 }; - for(int track = 0; track != 40; track ++) { + for(int track = 0; track != 40; track++) { uint32_t pos = 0; std::vector<uint32_t> &buffer = image.get_buffer(track, 0); buffer.clear(); @@ -49,7 +49,7 @@ void vtech_common_format::image_to_flux(const std::vector<uint8_t> &bdata, flopp // One window of pad at the start to avoid problems with the write splice wbit(buffer, pos, 0); - for(int sector = 0; sector != 16; sector ++) { + for(int sector = 0; sector != 16; sector++) { uint8_t sid = sector_map[sector]; for(int i=0; i != 7; i++) wbyte(buffer, pos, 0x80); @@ -69,7 +69,7 @@ void vtech_common_format::image_to_flux(const std::vector<uint8_t> &bdata, flopp wbyte(buffer, pos, 0xe7); wbyte(buffer, pos, 0xfe); uint16_t chk = 0; - const uint8_t *src = bdata.data() + 16*128*track + 128*sid; + const uint8_t *src = &bdata[16*128*track + 128*sid]; for(int i=0; i != 128; i++) { chk += src[i]; wbyte(buffer, pos, src[i]); @@ -106,7 +106,7 @@ std::vector<uint8_t> vtech_common_format::flux_to_image(const floppy_image &imag for(;;) { int npos = cpos; for(;;) { - npos ++; + npos++; if(npos == sz) npos = 0; if((buffer[npos] & floppy_image::MG_MASK) == floppy_image::MG_F) @@ -135,7 +135,7 @@ std::vector<uint8_t> vtech_common_format::flux_to_image(const floppy_image &imag buf = (buf << 1) | bitstream[sz-64+i]; for(;;) { buf = (buf << 1) | bitstream[pos]; - count ++; + count++; switch(mode) { case 0: // idle if(buf == 0x80808000fee718c3) @@ -243,15 +243,15 @@ int vtech_dsk_format::identify(util::random_read &io, uint32_t form_factor, cons if(size < 256) return 0; - std::vector<uint8_t> bdata(size); - size_t actual; - io.read_at(0, bdata.data(), size, actual); + auto const [err, bdata, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return 0; // Structurally validate the presence of sector headers and data int count_sh = 0, count_sd = 0; uint64_t buf = 0; - for(uint8_t b : bdata) { - buf = (buf << 8) | b; + for(size_t i = 0; size > i; ++i) { + buf = (buf << 8) | bdata[i]; if(buf == 0x80808000fee718c3) count_sh++; else if(buf == 0x80808000c318e7fe) @@ -267,11 +267,11 @@ bool vtech_bin_format::load(util::random_read &io, uint32_t form_factor, const s if(io.length(size) || (size != 40*16*256)) return false; - std::vector<uint8_t> bdata(size); - size_t actual; - io.read_at(0, bdata.data(), size, actual); + auto const [err, bdata, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; - image_to_flux(bdata, image); + image_to_flux(bdata.get(), size, image); image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); return true; } @@ -281,9 +281,9 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s uint64_t size; if(io.length(size)) return false; - std::vector<uint8_t> bdata(size); - size_t actual; - io.read_at(0, bdata.data(), size, actual); + auto const [err, bdata, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; std::vector<uint8_t> bdatax(128*16*40, 0); @@ -293,9 +293,9 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s uint64_t buf = 0; uint8_t *dest = nullptr; - for(uint8_t b : bdata) { - buf = (buf << 8) | b; - count ++; + for(size_t i = 0; size > i; ++i) { + buf = (buf << 8) | bdata[i]; + count++; switch(mode) { case 0: // idle if(buf == 0x80808000fee718c3) @@ -305,14 +305,14 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s case 1: // sector header if(count == 3) { - uint8_t trk = buf >> 16; - uint8_t sector = buf >> 8; - uint8_t chk = buf; + const uint8_t trk = buf >> 16; + const uint8_t sector = buf >> 8; + const uint8_t chk = buf; if(chk != sector + trk) { mode = 0; break; } - dest = bdatax.data() + 128*16*trk + sector*128; + dest = &bdatax[128*16*trk + sector*128]; checksum = 0; mode = 2; } @@ -328,7 +328,7 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s case 3: // sector data if(count <= 128) { - uint8_t byte = buf; + const uint8_t byte = buf; checksum += byte; *dest++ = byte; @@ -341,7 +341,7 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s } } - image_to_flux(bdatax, image); + image_to_flux(bdatax.data(), bdatax.size(), image); image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); return true; } @@ -354,8 +354,7 @@ bool vtech_bin_format::save(util::random_read_write &io, const std::vector<uint3 return false; auto bdata = flux_to_image(image); - size_t actual; - io.write_at(0, bdata.data(), bdata.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, bdata.data(), bdata.size()); // FIXME: check for errors return true; } @@ -376,8 +375,8 @@ bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint3 }; int pos = 0; - for(int track = 0; track != 40; track ++) { - for(int sector = 0; sector != 16; sector ++) { + for(int track = 0; track != 40; track++) { + for(int sector = 0; sector != 16; sector++) { uint8_t sid = sector_map[sector]; for(int i=0; i != 7; i++) bdatax[pos++] = 0x80; @@ -407,8 +406,7 @@ bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint3 } } - size_t actual; - io.write_at(0, bdatax.data(), bdatax.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, bdatax.data(), bdatax.size()); // FIXME: check for errors return true; } diff --git a/src/lib/formats/vt_dsk.h b/src/lib/formats/vt_dsk.h index db2687d4108..1348f9dbd4d 100644 --- a/src/lib/formats/vt_dsk.h +++ b/src/lib/formats/vt_dsk.h @@ -19,7 +19,7 @@ public: virtual bool supports_save() const noexcept override { return true; } protected: - static void image_to_flux(const std::vector<uint8_t> &bdata, floppy_image &image); + static void image_to_flux(const uint8_t *bdata, size_t size, floppy_image &image); static std::vector<uint8_t> flux_to_image(const floppy_image &image); static void wbit(std::vector<uint32_t> &buffer, uint32_t &pos, bool bit); diff --git a/src/lib/formats/wd177x_dsk.cpp b/src/lib/formats/wd177x_dsk.cpp index c3bba8f7724..e5b02f02e32 100644 --- a/src/lib/formats/wd177x_dsk.cpp +++ b/src/lib/formats/wd177x_dsk.cpp @@ -262,8 +262,7 @@ bool wd177x_format::load(util::random_read &io, uint32_t form_factor, const std: build_sector_description(tf, sectdata, sectors, track, head); int track_size = compute_track_size(tf); - size_t actual; - io.read_at(get_image_offset(f, head, track), sectdata, track_size, actual); + /*auto const [err, actual] =*/ read_at(io, get_image_offset(f, head, track), sectdata, track_size); // FIXME: check for errors and premature EOF generate_track(desc, track, head, sectors, tf.sector_count, total_size, image); } @@ -389,8 +388,7 @@ bool wd177x_format::save(util::random_read_write &io, const std::vector<uint32_t build_sector_description(tf, sectdata, sectors, track, head); extract_sectors(image, tf, sectors, track, head); int track_size = compute_track_size(tf); - size_t actual; - io.write_at(get_image_offset(f, head, track), sectdata, track_size, actual); + /*auto const [err, actual] =*/ write_at(io, get_image_offset(f, head, track), sectdata, track_size); // FIXME: check for errors } } diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp index 56ce590bc6c..ee415cba1b0 100644 --- a/src/lib/util/cdrom.cpp +++ b/src/lib/util/cdrom.cpp @@ -25,6 +25,7 @@ #include <cassert> #include <cstdlib> +#include <tuple> /*************************************************************************** @@ -400,11 +401,11 @@ std::error_condition cdrom_file::read_partial_sector(void *dest, uint32_t lbasec if (EXTRA_VERBOSE) printf("Reading %u bytes from sector %d from track %d at offset %lu\n", (unsigned)length, chdsector, tracknum + 1, (unsigned long)sourcefileoffset); - size_t actual; result = srcfile.seek(sourcefileoffset, SEEK_SET); + size_t actual; if (!result) - result = srcfile.read(dest, length, actual); - // FIXME: if (actual < length) report error + std::tie(result, actual) = read(srcfile, dest, length); + // FIXME: if (!result && (actual < length)) report error needswap = cdtrack_info.track[tracknum].swap; } @@ -414,7 +415,8 @@ std::error_condition cdrom_file::read_partial_sector(void *dest, uint32_t lbasec uint8_t *buffer = (uint8_t *)dest - startoffs; for (int swapindex = startoffs; swapindex < 2352; swapindex += 2 ) { - std::swap(buffer[ swapindex ], buffer[ swapindex + 1 ]); + using std::swap; + swap(buffer[ swapindex ], buffer[ swapindex + 1 ]); } } return result; diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp index b0e1c1ee510..f5e5ec8e0cc 100644 --- a/src/lib/util/chd.cpp +++ b/src/lib/util/chd.cpp @@ -27,6 +27,7 @@ #include <cstdlib> #include <ctime> #include <new> +#include <tuple> //************************************************************************** @@ -165,13 +166,16 @@ inline void chd_file::file_read(uint64_t offset, void *dest, uint32_t length) co throw std::error_condition(error::NOT_OPEN); // seek and read - m_file->seek(offset, SEEK_SET); + std::error_condition err; + err = m_file->seek(offset, SEEK_SET); + if (err) + throw err; size_t count; - std::error_condition err = m_file->read(dest, length, count); + std::tie(err, count) = read(*m_file, dest, length); if (err) throw err; else if (count != length) - throw std::error_condition(std::errc::io_error); // TODO: revisit this error code (happens if file is cut off) + throw std::error_condition(std::errc::io_error); // TODO: revisit this error code (happens if file is truncated) } @@ -187,13 +191,13 @@ inline void chd_file::file_write(uint64_t offset, const void *source, uint32_t l throw std::error_condition(error::NOT_OPEN); // seek and write - m_file->seek(offset, SEEK_SET); - size_t count; - std::error_condition err = m_file->write(source, length, count); + std::error_condition err; + err = m_file->seek(offset, SEEK_SET); + if (err) + throw err; + std::tie(err, std::ignore) = write(*m_file, source, length); if (err) throw err; - else if (count != length) - throw std::error_condition(std::errc::interrupted); // can theoretically happen if write is inuterrupted by a signal } @@ -232,7 +236,7 @@ inline uint64_t chd_file::file_append(const void *source, uint32_t length, uint3 { uint32_t bytes_to_write = std::min<std::size_t>(sizeof(buffer), delta); size_t count; - err = m_file->write(buffer, bytes_to_write, count); + std::tie(err, count) = write(*m_file, buffer, bytes_to_write); if (err) throw err; delta -= count; @@ -245,12 +249,9 @@ inline uint64_t chd_file::file_append(const void *source, uint32_t length, uint3 err = m_file->tell(offset); if (err) throw err; - size_t count; - err = m_file->write(source, length, count); + std::tie(err, std::ignore) = write(*m_file, source, length); if (err) throw err; - else if (count != length) - throw std::error_condition(std::errc::interrupted); // can theoretically happen if write is interrupted by a signal return offset; } diff --git a/src/lib/util/corefile.cpp b/src/lib/util/corefile.cpp index 3d5c705ab86..0c6bfc3cee9 100644 --- a/src/lib/util/corefile.cpp +++ b/src/lib/util/corefile.cpp @@ -48,13 +48,13 @@ public: virtual std::error_condition tell(std::uint64_t &result) noexcept override { return m_file.tell(result); } virtual std::error_condition length(std::uint64_t &result) noexcept override { return m_file.length(result); } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.read(buffer, length, actual); } - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.read_at(offset, buffer, length, actual); } + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.read_some(buffer, length, actual); } + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.read_some_at(offset, buffer, length, actual); } virtual std::error_condition finalize() noexcept override { return m_file.finalize(); } virtual std::error_condition flush() noexcept override { return m_file.flush(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.write(buffer, length, actual); } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.write_at(offset, buffer, length, actual); } + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.write_some(buffer, length, actual); } + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { return m_file.write_some_at(offset, buffer, length, actual); } virtual bool eof() const override { return m_file.eof(); } @@ -167,13 +167,13 @@ public: ~core_in_memory_file() override { purge(); } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override; - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override; + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override; + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override; virtual std::error_condition finalize() noexcept override { return std::error_condition(); } virtual std::error_condition flush() noexcept override { clear_putback(); return std::error_condition(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0; return std::errc::bad_file_descriptor; } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0; return std::errc::bad_file_descriptor; } + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0; return std::errc::bad_file_descriptor; } + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0; return std::errc::bad_file_descriptor; } void const *buffer() const { return m_data; } @@ -217,13 +217,13 @@ public: } ~core_osd_file() override; - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override; - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override; + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override; + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override; virtual std::error_condition finalize() noexcept override; virtual std::error_condition flush() noexcept override; - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override; - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override; + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override; + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override; virtual std::error_condition truncate(std::uint64_t offset) override; @@ -260,9 +260,8 @@ int core_text_file::getc() { if (!pos) { - std::size_t readlen; std::uint8_t bom[4]; - read(bom, 4, readlen); + auto const [err, readlen] = read(*this, bom, 4); // FIXME: check for errors if (readlen == 4) { if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) @@ -303,15 +302,14 @@ int core_text_file::getc() // fetch the next character // FIXME: all of this plays fast and loose with error checking and seeks backwards far too frequently char16_t utf16_buffer[UTF16_CHAR_MAX]; - auto uchar = char32_t(~0); + char32_t uchar = ~char32_t(0); switch (m_text_type) { default: case text_file_type::OSD: { char default_buffer[16]; - std::size_t readlen; - read(default_buffer, sizeof(default_buffer), readlen); + auto const [err, readlen] = read(*this, default_buffer, sizeof(default_buffer)); if (readlen > 0) { auto const charlen = osd_uchar_from_osdchar(&uchar, default_buffer, readlen / sizeof(default_buffer[0])); @@ -323,8 +321,7 @@ int core_text_file::getc() case text_file_type::UTF8: { char utf8_buffer[UTF8_CHAR_MAX]; - std::size_t readlen; - read(utf8_buffer, sizeof(utf8_buffer), readlen); + auto const [err, readlen] = read(*this, utf8_buffer, sizeof(utf8_buffer)); if (readlen > 0) { auto const charlen = uchar_from_utf8(&uchar, utf8_buffer, readlen / sizeof(utf8_buffer[0])); @@ -335,8 +332,7 @@ int core_text_file::getc() case text_file_type::UTF16BE: { - std::size_t readlen; - read(utf16_buffer, sizeof(utf16_buffer), readlen); + auto const [err, readlen] = read(*this, utf16_buffer, sizeof(utf16_buffer)); if (readlen > 0) { auto const charlen = uchar_from_utf16be(&uchar, utf16_buffer, readlen / sizeof(utf16_buffer[0])); @@ -347,8 +343,7 @@ int core_text_file::getc() case text_file_type::UTF16LE: { - std::size_t readlen; - read(utf16_buffer, sizeof(utf16_buffer), readlen); + auto const [err, readlen] = read(*this, utf16_buffer, sizeof(utf16_buffer)); if (readlen > 0) { auto const charlen = uchar_from_utf16le(&uchar, utf16_buffer, readlen / sizeof(utf16_buffer[0])); @@ -360,8 +355,7 @@ int core_text_file::getc() case text_file_type::UTF32BE: { // FIXME: deal with read returning short - std::size_t readlen; - read(&uchar, sizeof(uchar), readlen); + auto const [err, readlen] = read(*this, &uchar, sizeof(uchar)); if (sizeof(uchar) == readlen) uchar = big_endianize_int32(uchar); } @@ -370,8 +364,7 @@ int core_text_file::getc() case text_file_type::UTF32LE: { // FIXME: deal with read returning short - std::size_t readlen; - read(&uchar, sizeof(uchar), readlen); + auto const [err, readlen] = read(*this, &uchar, sizeof(uchar)); if (sizeof(uchar) == readlen) uchar = little_endianize_int32(uchar); } @@ -467,7 +460,7 @@ char *core_text_file::gets(char *s, int n) int core_text_file::puts(std::string_view s) { - // TODO: what to do about write errors or short writes (interrupted)? + // TODO: what to do about write errors? // The API doesn't lend itself to reporting the error as the return // value includes extra bytes inserted like the UTF-8 marker and // carriage returns. @@ -511,8 +504,7 @@ int core_text_file::puts(std::string_view s) // if we overflow, break into chunks if (pconvbuf >= convbuf + std::size(convbuf) - 10) { - std::size_t written; - write(convbuf, pconvbuf - convbuf, written); // FIXME: error ignored here + auto const [err, written] = write(*this, convbuf, pconvbuf - convbuf); // FIXME: error ignored here count += written; pconvbuf = convbuf; } @@ -521,8 +513,7 @@ int core_text_file::puts(std::string_view s) // final flush if (pconvbuf != convbuf) { - std::size_t written; - write(convbuf, pconvbuf - convbuf, written); // FIXME: error ignored here + auto const [err, written] = write(*this, convbuf, pconvbuf - convbuf); // FIXME: error ignored here count += written; } @@ -646,7 +637,7 @@ std::size_t core_basic_file::safe_buffer_copy( // read - read from a file //------------------------------------------------- -std::error_condition core_in_memory_file::read(void *buffer, std::size_t length, std::size_t &actual) noexcept +std::error_condition core_in_memory_file::read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept { clear_putback(); @@ -659,7 +650,7 @@ std::error_condition core_in_memory_file::read(void *buffer, std::size_t length, return std::error_condition(); } -std::error_condition core_in_memory_file::read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept +std::error_condition core_in_memory_file::read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept { clear_putback(); @@ -705,17 +696,17 @@ core_osd_file::~core_osd_file() // read - read from a file //------------------------------------------------- -std::error_condition core_osd_file::read(void *buffer, std::size_t length, std::size_t &actual) noexcept +std::error_condition core_osd_file::read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept { // since osd_file works like pread/pwrite, implement in terms of read_at // core_osd_file is declared final, so a derived class can't interfere - std::error_condition err = read_at(index(), buffer, length, actual); + std::error_condition err = read_some_at(index(), buffer, length, actual); add_offset(actual); return err; } -std::error_condition core_osd_file::read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept +std::error_condition core_osd_file::read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept { if (!m_file) { @@ -750,18 +741,12 @@ std::error_condition core_osd_file::read_at(std::uint64_t offset, void *buffer, } else { - // read the remainder directly from the file - do - { - // may need to split into chunks if size_t is larger than 32 bits - std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length - actual); - std::uint32_t bytes_read; - err = m_file->read(reinterpret_cast<std::uint8_t *>(buffer) + actual, offset + actual, chunk, bytes_read); - if (err || !bytes_read) - break; + // read the remainder directly from the file - may need to return short if size_t is larger than 32 bits + std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length - actual); + std::uint32_t bytes_read; + err = m_file->read(reinterpret_cast<std::uint8_t *>(buffer) + actual, offset + actual, chunk, bytes_read); + if (!err) actual += bytes_read; - } - while (actual < length); } } @@ -774,17 +759,17 @@ std::error_condition core_osd_file::read_at(std::uint64_t offset, void *buffer, // write - write to a file //------------------------------------------------- -std::error_condition core_osd_file::write(void const *buffer, std::size_t length, std::size_t &actual) noexcept +std::error_condition core_osd_file::write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept { // since osd_file works like pread/pwrite, implement in terms of write_at // core_osd_file is declared final, so a derived class can't interfere - std::error_condition err = write_at(index(), buffer, length, actual); + std::error_condition err = write_some_at(index(), buffer, length, actual); add_offset(actual); return err; } -std::error_condition core_osd_file::write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept +std::error_condition core_osd_file::write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept { // flush any buffered char clear_putback(); @@ -792,21 +777,20 @@ std::error_condition core_osd_file::write_at(std::uint64_t offset, void const *b // invalidate any buffered data m_bufferbytes = 0U; - // do the write - may need to split into chunks if size_t is larger than 32 bits - actual = 0U; - while (length) + // do the write - may need to return short if size_t is larger than 32 bits + std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); + std::uint32_t bytes_written; + std::error_condition err = m_file->write(buffer, offset, chunk, bytes_written); + if (err) { // bytes written not valid on error - std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); - std::uint32_t bytes_written; - std::error_condition err = m_file->write(buffer, offset, chunk, bytes_written); - if (err) - return err; + actual = 0U; + } + else + { assert(chunk >= bytes_written); offset += bytes_written; - buffer = reinterpret_cast<std::uint8_t const *>(buffer) + bytes_written; - length -= bytes_written; - actual += bytes_written; + actual = bytes_written; set_size((std::max)(size(), offset)); } return std::error_condition(); @@ -968,7 +952,7 @@ core_file::~core_file() // pointer //------------------------------------------------- -std::error_condition core_file::load(std::string_view filename, void **data, std::uint32_t &length) noexcept +std::error_condition core_file::load(std::string_view filename, void **data, std::size_t &length) noexcept { std::error_condition err; @@ -983,20 +967,20 @@ std::error_condition core_file::load(std::string_view filename, void **data, std err = file->length(size); if (err) return err; - else if (std::uint32_t(size) != size) // TODO: change interface to use size_t rather than uint32_t for output size + else if (std::size_t(size) != size) return std::errc::file_too_large; // allocate memory *data = std::malloc(std::size_t(size)); if (!*data) return std::errc::not_enough_memory; - length = std::uint32_t(size); + length = std::size_t(size); // read the data if (size) { std::size_t actual; - err = file->read(*data, std::size_t(size), actual); + std::tie(err, actual) = read(*file, *data, std::size_t(size)); if (err || (size != actual)) { std::free(*data); @@ -1004,7 +988,7 @@ std::error_condition core_file::load(std::string_view filename, void **data, std if (err) return err; else - return std::errc::io_error; // TODO: revisit this error code - either interrupted by an async signal or file truncated out from under us + return std::errc::io_error; // TODO: revisit this error code - file truncated out from under us } } @@ -1038,14 +1022,14 @@ std::error_condition core_file::load(std::string_view filename, std::vector<uint if (size) { std::size_t actual; - err = file->read(&data[0], std::size_t(size), actual); + std::tie(err, actual) = read(*file, &data[0], std::size_t(size)); if (err || (size != actual)) { data.clear(); if (err) return err; else - return std::errc::io_error; // TODO: revisit this error code - either interrupted by an async signal or file truncated out from under us + return std::errc::io_error; // TODO: revisit this error code - file truncated out from under us } } diff --git a/src/lib/util/corefile.h b/src/lib/util/corefile.h index 315645d4e2c..fda5015d8ba 100644 --- a/src/lib/util/corefile.h +++ b/src/lib/util/corefile.h @@ -77,7 +77,7 @@ public: virtual char *gets(char *s, int n) = 0; // open a file with the specified filename, read it into memory, and return a pointer - static std::error_condition load(std::string_view filename, void **data, std::uint32_t &length) noexcept; + static std::error_condition load(std::string_view filename, void **data, std::size_t &length) noexcept; static std::error_condition load(std::string_view filename, std::vector<uint8_t> &data) noexcept; diff --git a/src/lib/util/flac.cpp b/src/lib/util/flac.cpp index 66114e0e192..3b76bb14303 100644 --- a/src/lib/util/flac.cpp +++ b/src/lib/util/flac.cpp @@ -18,6 +18,7 @@ #include <cstring> #include <iterator> #include <new> +#include <tuple> //************************************************************************** @@ -266,8 +267,7 @@ FLAC__StreamEncoderWriteStatus flac_encoder::write_callback(const FLAC__byte buf int count = bytes - offset; if (m_file) { - size_t actual; - m_file->write(buffer, count, actual); // TODO: check for errors + /*auto const [err, actual] =*/ write(*m_file, buffer, count); // FIXME: check for errors } else { @@ -537,7 +537,8 @@ FLAC__StreamDecoderReadStatus flac_decoder::read_callback(FLAC__byte buffer[], s if (m_file) // if a file, just read { - m_file->read(buffer, expected, *bytes); // TODO: check for errors + std::error_condition err; + std::tie(err, *bytes) = read(*m_file, buffer, expected); // FIXME: check for errors } else // otherwise, copy from memory { diff --git a/src/lib/util/harddisk.cpp b/src/lib/util/harddisk.cpp index 6eb12b38091..266e5d25a2b 100644 --- a/src/lib/util/harddisk.cpp +++ b/src/lib/util/harddisk.cpp @@ -16,6 +16,7 @@ #include "osdcore.h" #include <cstdlib> +#include <tuple> /*------------------------------------------------- @@ -118,7 +119,7 @@ bool hard_disk_file::read(uint32_t lbasector, void *buffer) size_t actual = 0; std::error_condition err = fhandle->seek(fileoffset + (lbasector * hdinfo.sectorbytes), SEEK_SET); if (!err) - err = fhandle->read(buffer, hdinfo.sectorbytes, actual); + std::tie(err, actual) = util::read(*fhandle, buffer, hdinfo.sectorbytes); return !err && (actual == hdinfo.sectorbytes); } } @@ -151,8 +152,8 @@ bool hard_disk_file::write(uint32_t lbasector, const void *buffer) size_t actual = 0; std::error_condition err = fhandle->seek(fileoffset + (lbasector * hdinfo.sectorbytes), SEEK_SET); if (!err) - err = fhandle->write(buffer, hdinfo.sectorbytes, actual); - return !err && (actual == hdinfo.sectorbytes); + std::tie(err, actual) = util::write(*fhandle, buffer, hdinfo.sectorbytes); + return !err; } } diff --git a/src/lib/util/hash.cpp b/src/lib/util/hash.cpp index 9100ff6abde..f2c528e9b22 100644 --- a/src/lib/util/hash.cpp +++ b/src/lib/util/hash.cpp @@ -410,14 +410,13 @@ std::error_condition hash_collection::compute(random_read &stream, uint64_t offs unsigned const chunk_length = std::min(length, sizeof(buffer)); // read one chunk - std::size_t bytes_read; - std::error_condition err = stream.read_at(offset, buffer, chunk_length, bytes_read); + auto const [err, bytes_read] = read_at(stream, offset, buffer, chunk_length); if (err) return err; if (!bytes_read) // EOF? break; offset += bytes_read; - length -= chunk_length; + length -= bytes_read; // append the chunk creator->append(buffer, bytes_read); diff --git a/src/lib/util/ioprocs.cpp b/src/lib/util/ioprocs.cpp index 0477f1efae1..37a958713b3 100644 --- a/src/lib/util/ioprocs.cpp +++ b/src/lib/util/ioprocs.cpp @@ -20,6 +20,7 @@ #include <cstring> #include <iterator> #include <limits> +#include <new> #include <type_traits> @@ -120,14 +121,14 @@ public: { } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { do_read(this->m_pointer, buffer, length, actual); this->m_pointer += actual; return std::error_condition(); } - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { do_read(offset, buffer, length, actual); return std::error_condition(); @@ -239,7 +240,7 @@ public: { } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { if (m_dangling_write) { @@ -270,7 +271,7 @@ public: return std::error_condition(); } - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0U; @@ -338,7 +339,7 @@ public: return std::error_condition(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { if (m_dangling_read) { @@ -361,7 +362,7 @@ public: return std::error_condition(); } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0U; @@ -409,7 +410,7 @@ public: set_filler(fill); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0U; @@ -473,7 +474,7 @@ public: return std::error_condition(); } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = 0U; @@ -634,18 +635,12 @@ public: { } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { - // TODO: should the client have to deal with reading less than expected even if EOF isn't hit? - if (std::numeric_limits<std::uint32_t>::max() < length) - { - actual = 0U; - return std::errc::invalid_argument; - } - // actual length not valid on error + std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); std::uint32_t count; - std::error_condition err = file().read(buffer, m_pointer, std::uint32_t(length), count); + std::error_condition err = file().read(buffer, m_pointer, chunk, count); if (!err) { m_pointer += count; @@ -658,18 +653,12 @@ public: return err; } - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { - // TODO: should the client have to deal with reading less than expected even if EOF isn't hit? - if (std::numeric_limits<std::uint32_t>::max() < length) - { - actual = 0U; - return std::errc::invalid_argument; - } - // actual length not valid on error + std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); std::uint32_t count; - std::error_condition err = file().read(buffer, offset, std::uint32_t(length), count); + std::error_condition err = file().read(buffer, offset, chunk, count); if (!err) actual = std::size_t(count); else @@ -696,48 +685,146 @@ public: return file().flush(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { - actual = 0U; - while (length) + // actual length not valid on error + std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); + std::uint32_t count; + std::error_condition err = file().write(buffer, m_pointer, chunk, count); + if (!err) { - // actual length not valid on error - std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); - std::uint32_t written; - std::error_condition err = file().write(buffer, m_pointer, chunk, written); - if (err) - return err; - m_pointer += written; - buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written; - length -= written; - actual += written; + actual = std::size_t(count); + m_pointer += count; } - return std::error_condition(); + else + { + actual = 0U; + } + return err; } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { - actual = 0U; - while (length) - { - // actual length not valid on error - std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); - std::uint32_t written; - std::error_condition err = file().write(buffer, offset, chunk, written); - if (err) - return err; - offset += written; - buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written; - length -= written; - actual += written; - } - return std::error_condition(); + // actual length not valid on error + std::uint32_t const chunk = std::min<std::common_type_t<std::uint32_t, std::size_t> >(std::numeric_limits<std::uint32_t>::max(), length); + std::uint32_t count; + std::error_condition err = file().write(buffer, offset, chunk, count); + if (!err) + actual = std::size_t(count); + else + actual = 0U; + return err; } }; } // anonymous namespace +// helper functions for common patterns + +std::pair<std::error_condition, std::size_t> read(read_stream &stream, void *buffer, std::size_t length) noexcept +{ + std::size_t actual = 0; + do + { + std::size_t count; + std::error_condition err = stream.read_some(buffer, length, count); + actual += count; + if (!err) + { + if (!count) + break; + } + else if (std::errc::interrupted != err) + { + return std::make_pair(err, actual); + } + buffer = reinterpret_cast<std::uint8_t *>(buffer) + count; + length -= count; + } + while (length); + return std::make_pair(std::error_condition(), actual); +} + +std::tuple<std::error_condition, std::unique_ptr<std::uint8_t []>, std::size_t> read(read_stream &stream, std::size_t length) noexcept +{ + std::unique_ptr<std::uint8_t []> buffer(new (std::nothrow) std::uint8_t [length]); + if (!buffer) + return std::make_tuple(std::errc::not_enough_memory, std::move(buffer), std::size_t(0)); + auto [err, actual] = read(stream, buffer.get(), length); + return std::make_tuple(err, std::move(buffer), actual); +} + +std::pair<std::error_condition, std::size_t> read_at(random_read &stream, std::uint64_t offset, void *buffer, std::size_t length) noexcept +{ + std::size_t actual = 0; + do + { + std::size_t count; + std::error_condition err = stream.read_some_at(offset, buffer, length, count); + actual += count; + if (!err) + { + if (!count) + break; + } + else if (std::errc::interrupted != err) + { + return std::make_pair(err, actual); + } + offset += count; + buffer = reinterpret_cast<std::uint8_t *>(buffer) + count; + length -= count; + } + while (length); + return std::make_pair(std::error_condition(), actual); +} + +std::tuple<std::error_condition, std::unique_ptr<std::uint8_t []>, std::size_t> read_at(random_read &stream, std::uint64_t offset, std::size_t length) noexcept +{ + std::unique_ptr<std::uint8_t []> buffer(new (std::nothrow) std::uint8_t [length]); + if (!buffer) + return std::make_tuple(std::errc::not_enough_memory, std::move(buffer), std::size_t(0)); + auto [err, actual] = read_at(stream, offset, buffer.get(), length); + return std::make_tuple(err, std::move(buffer), actual); +} + +std::pair<std::error_condition, std::size_t> write(write_stream &stream, void const *buffer, std::size_t length) noexcept +{ + std::size_t actual = 0; + do + { + std::size_t written; + std::error_condition err = stream.write_some(buffer, length, written); + actual += written; + if (err && (std::errc::interrupted != err)) + return std::make_pair(err, actual); + buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written; + length -= written; + } + while (length); + return std::make_pair(std::error_condition(), actual); +} + +std::pair<std::error_condition, std::size_t> write_at(random_write &stream, std::uint64_t offset, void const *buffer, std::size_t length) noexcept +{ + std::size_t actual = 0; + do + { + std::size_t written; + std::error_condition err = stream.write_some_at(offset, buffer, length, written); + actual += written; + if (err && (std::errc::interrupted != err)) + return std::make_pair(err, actual); + offset += written; + buffer = reinterpret_cast<std::uint8_t const *>(buffer) + written; + length -= written; + } + while (length); + return std::make_pair(std::error_condition(), actual); +} + + // creating RAM read adapters random_read::ptr ram_read(void const *data, std::size_t size) noexcept diff --git a/src/lib/util/ioprocs.h b/src/lib/util/ioprocs.h index efe0a231a11..9e2c29d2a14 100644 --- a/src/lib/util/ioprocs.h +++ b/src/lib/util/ioprocs.h @@ -19,6 +19,8 @@ #include <cstdlib> #include <memory> #include <system_error> +#include <tuple> +#include <utility> // FIXME: make a proper place for OSD forward declarations @@ -56,7 +58,7 @@ public: /// \param [out] actual Number of bytes actually read. Will always /// be less than or equal to the requested length. /// \return An error condition if reading stopped due to an error. - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept = 0; + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept = 0; }; @@ -100,7 +102,7 @@ public: /// \param [out] actual Number of bytes actually written. Will /// always be less than or equal to the requested length. /// \return An error condition if writing stopped due to an error. - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0; + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0; }; @@ -184,7 +186,7 @@ public: /// be less than or equal to the requested length. /// \return An error condition if seeking failed or reading stopped /// due to an error. - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept = 0; + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept = 0; }; @@ -214,7 +216,7 @@ public: /// always be less than or equal to the requested length. /// \return An error condition if seeking failed or writing stopped /// due to an error. - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0; + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept = 0; }; @@ -229,6 +231,123 @@ public: using ptr = std::unique_ptr<random_read_write>; }; + +/// \brief Read from the current position in the stream +/// +/// Reads up to the specified number of bytes from the stream into the +/// supplied buffer, continuing if interrupted by asynchronous signals. +/// May read less than the requested number of bytes if the end of the +/// stream is reached or an error occurs. If the stream supports +/// seeking, reading starts at the current position in the stream, and +/// the current position is incremented by the number of bytes read. +/// The operation may not be atomic if it is interrupted before the +/// requested number of bytes is read. +/// \param [in] stream The stream to read from. +/// \param [out] buffer Destination buffer. Must be large enough to +/// hold the requested number of bytes. +/// \param [in] length Maximum number of bytes to read. +/// \return A pair containing an error condition if reading stopped due +/// to an error, and the actual number of bytes read. +std::pair<std::error_condition, std::size_t> read(read_stream &stream, void *buffer, std::size_t length) noexcept; + +/// \brief Allocate memory and read from the current position in the +/// stream +/// +/// Allocates the specified number of bytes and then reads up to that +/// number of bytes from the stream into the newly allocated buffer, +/// continuing if interrupted by asynchronous signals. May read less +/// than the requested number of bytes if the end of the stream is +/// reached or an error occurs. If the stream supports seeking, +/// reading starts at the current position in the stream, and the +/// current position is incremented by the number of bytes read. The +/// operation may not be atomic if it is interrupted before the +/// requested number of bytes is read. No data will be read if +/// allocation fails. +/// \param [in] stream The stream to read from. +/// hold the requested number of bytes. +/// \param [in] length Maximum number of bytes to read. +/// \return A tuple containing an error condition if allocation failed +/// or reading stopped due to an error, the allocated buffer, and the +/// actual number of bytes read. +std::tuple<std::error_condition, std::unique_ptr<std::uint8_t []>, std::size_t> read(read_stream &stream, std::size_t length) noexcept; + +/// \brief Read from the specified position +/// +/// Reads up to the specified number of bytes from the stream into the +/// supplied buffer, continuing if interrupted by asynchronous signals. +/// May read less than the requested number of bytes if the end of the +/// stream is reached or an error occurs. If seeking is supported, +/// reading starts at the specified position and the current position is +/// unaffected. The operation may not be atomic if it is interrupted +/// before the requested number of bytes is read. +/// \param [in] stream The stream to read from. +/// \param [in] offset The position to start reading from, specified as +/// a number of bytes from the beginning of the stream. +/// \param [out] buffer Destination buffer. Must be large enough to +/// hold the requested number of bytes. +/// \param [in] length Maximum number of bytes to read. +/// \return A pair containing an error condition if reading stopped due +/// to an error, and the actual number of bytes read. +std::pair<std::error_condition, std::size_t> read_at(random_read &stream, std::uint64_t offset, void *buffer, std::size_t length) noexcept; + +/// \brief Allocate memory and read from the specified position +/// +/// Allocates the specified number of bytes and then reads up to that +/// number of bytes from the stream into the newly allocated buffer, +/// continuing if interrupted by asynchronous signals. May read less +/// than the requested number of bytes if the end of the stream is +/// reached or an error occurs. If seeking is supported, reading +/// starts at the specified position and the current position is +/// unaffected. The operation may not be atomic if it is interrupted +/// before the requested number of bytes is read. No data will be read +/// if allocation fails. +/// \param [in] stream The stream to read from. +/// \param [in] offset The position to start reading from, specified as +/// a number of bytes from the beginning of the stream. +/// \param [out] buffer Destination buffer. Must be large enough to +/// hold the requested number of bytes. +/// \param [in] length Maximum number of bytes to read. +/// \return A tuple containing an error condition if allocation failed +/// or reading stopped due to an error, the allocated buffer, and the +/// actual number of bytes read. +std::tuple<std::error_condition, std::unique_ptr<std::uint8_t []>, std::size_t> read_at(random_read &stream, std::uint64_t offset, std::size_t length) noexcept; + +/// \brief Write at the current position in the stream +/// +/// Writes up to the specified number of bytes from the supplied +/// buffer to the stream, continuing if interrupted by asynchronous +/// signals. May write less than the requested number of bytes if an +/// error occurs. If the stream supports seeking, writing starts at the +/// current position in the stream, and the current position is +/// incremented by the number of bytes written. The operation may not +/// be atomic if it is interrupted before the requested number of bytes +/// is written. +/// \param [in] stream The stream to write to. +/// \param [in] buffer Buffer containing the data to write. Must +/// contain at least the specified number of bytes. +/// \param [in] length Number of bytes to write. +/// \return A pair containing an error condition if writing stopped due +/// to an error, and the actual number of bytes written. +std::pair<std::error_condition, std::size_t> write(write_stream &stream, void const *buffer, std::size_t length) noexcept; + +/// \brief Write at specified position +/// +/// Writes up to the specified number of bytes from the supplied buffer, +/// continuing if interrupted by asynchronous signals. If seeking is +/// supported, writing starts at the specified position and the current +/// position is unaffected. May write less than the requested number +/// of bytes if an error occurs. The operation may not be atomic if it +/// is interrupted before the requested number of bytes is written. +/// \param [in] stream The stream to write to. +/// \param [in] offset The position to start writing at, specified as a +/// number of bytes from the beginning of the stream. +/// \param [in] buffer Buffer containing the data to write. Must +/// contain at least the specified number of bytes. +/// \param [in] length Number of bytes to write. +/// \return A pair containing an error condition if writing stopped due +/// to an error, and the actual number of bytes written. +std::pair<std::error_condition, std::size_t> write_at(random_write &stream, std::uint64_t offset, void const *buffer, std::size_t length) noexcept; + /// \} diff --git a/src/lib/util/ioprocsfill.h b/src/lib/util/ioprocsfill.h index e49b10687f0..7179d61852c 100644 --- a/src/lib/util/ioprocsfill.h +++ b/src/lib/util/ioprocsfill.h @@ -45,9 +45,21 @@ class read_stream_fill_wrapper : public Base, public virtual fill_wrapper_base<D public: using Base::Base; - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { - std::error_condition err = Base::read(buffer, length, actual); + // not atomic with respect to other read/write calls + actual = 0U; + std::error_condition err; + std::size_t chunk; + do + { + err = Base::read_some( + reinterpret_cast<std::uint8_t *>(buffer) + actual, + length - actual, + chunk); + actual += chunk; + } + while ((length > actual) && ((!err && chunk) || (std::errc::interrupted == err))); assert(length >= actual); std::fill( reinterpret_cast<std::uint8_t *>(buffer) + actual, @@ -64,9 +76,23 @@ class random_read_fill_wrapper : public read_stream_fill_wrapper<Base, DefaultFi public: using read_stream_fill_wrapper<Base, DefaultFiller>::read_stream_fill_wrapper; - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { - std::error_condition err = Base::read_at(offset, buffer, length, actual); + // not atomic with respect to other read/write calls + actual = 0U; + std::error_condition err; + std::size_t chunk; + do + { + err = Base::read_some_at( + offset, + reinterpret_cast<std::uint8_t *>(buffer) + actual, + length - actual, + chunk); + offset += chunk; + actual += chunk; + } + while ((length > actual) && ((!err && chunk) || (std::errc::interrupted == err))); assert(length >= actual); std::fill( reinterpret_cast<std::uint8_t *>(buffer) + actual, @@ -83,8 +109,9 @@ class random_write_fill_wrapper : public Base, public virtual fill_wrapper_base< public: using Base::Base; - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { + // not atomic with respect to other read/write calls std::error_condition err; actual = 0U; @@ -108,23 +135,22 @@ public: do { std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled); - err = Base::write_at(current, fill_buffer, chunk, actual); - if (err) - { - actual = 0U; + std::size_t filled; + err = Base::write_some_at(current, fill_buffer, chunk, filled); + current += filled; + unfilled -= filled; + if (err && (std::errc::interrupted != err)) return err; - } - current += chunk; - unfilled -= chunk; } while (unfilled); } - return Base::write(buffer, length, actual); + return Base::write_some(buffer, length, actual); } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { + // not atomic with respect to other read/write calls std::error_condition err; std::uint64_t current; err = Base::length(current); @@ -139,18 +165,19 @@ public: do { std::size_t const chunk = std::min<std::common_type_t<std::size_t, std::uint64_t> >(FillBlock, unfilled); - err = Base::write_at(current, fill_buffer, chunk, actual); - current += chunk; - unfilled -= chunk; + std::size_t filled; + err = Base::write_some_at(current, fill_buffer, chunk, filled); + current += filled; + unfilled -= filled; } - while (unfilled && !err); + while (unfilled && (!err || (std::errc::interrupted == err))); } if (err) { actual = 0U; return err; } - return Base::write_at(offset, buffer, length, actual); + return Base::write_some_at(offset, buffer, length, actual); } }; diff --git a/src/lib/util/ioprocsfilter.cpp b/src/lib/util/ioprocsfilter.cpp index 68b9c90d018..b8d4cc3e786 100644 --- a/src/lib/util/ioprocsfilter.cpp +++ b/src/lib/util/ioprocsfilter.cpp @@ -21,6 +21,7 @@ #include <cstdint> #include <limits> #include <system_error> +#include <tuple> #include <type_traits> #include <utility> @@ -372,9 +373,9 @@ class read_stream_proxy : public virtual read_stream, public T public: using T::T; - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { - return this->object().read(buffer, length, actual); + return this->object().read_some(buffer, length, actual); } }; @@ -397,9 +398,9 @@ public: return this->object().flush(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { - return this->object().write(buffer, length, actual); + return this->object().write_some(buffer, length, actual); } }; @@ -437,9 +438,9 @@ class random_read_proxy : public virtual random_read, public read_stream_proxy<T public: using read_stream_proxy<T>::read_stream_proxy; - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { - return this->object().read_at(offset, buffer, length, actual); + return this->object().read_some_at(offset, buffer, length, actual); } }; @@ -452,9 +453,9 @@ class random_write_proxy : public virtual random_write, public write_stream_prox public: using write_stream_proxy<T>::write_stream_proxy; - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { - return this->object().write_at(offset, buffer, length, actual); + return this->object().write_some_at(offset, buffer, length, actual); } }; @@ -487,7 +488,7 @@ public: { } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { std::error_condition err; actual = 0U; @@ -504,7 +505,7 @@ public: { auto const space = get_unfilled_input(); std::size_t filled; - err = this->object().read(space.first, space.second, filled); + std::tie(err, filled) = read(this->object(), space.first, space.second); add_input(filled); short_input = space.second > filled; } @@ -598,8 +599,7 @@ public: auto const output = get_output(); if (output.second) { - std::size_t written; - std::error_condition err = object().write(output.first, output.second, written); + auto const [err, written] = write(object(), output.first, output.second); consume_output(written); if (err) { @@ -611,7 +611,7 @@ public: return object().flush(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { std::error_condition err; actual = 0U; @@ -651,7 +651,7 @@ private: { auto const output = get_output(); std::size_t written; - std::error_condition err = object().write(output.first, output.second, written); + std::error_condition const err = object().write_some(output.first, output.second, written); consume_output(written); return err; } diff --git a/src/lib/util/ioprocsvec.h b/src/lib/util/ioprocsvec.h index d3c1c7fe01b..e66000b5729 100644 --- a/src/lib/util/ioprocsvec.h +++ b/src/lib/util/ioprocsvec.h @@ -90,14 +90,14 @@ public: return std::error_condition(); } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { do_read(m_pointer, buffer, length, actual); m_pointer += actual; return std::error_condition(); } - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { do_read(offset, buffer, length, actual); return std::error_condition(); @@ -113,14 +113,14 @@ public: return std::error_condition(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { std::error_condition result = do_write(m_pointer, buffer, length, actual); m_pointer += actual; return result; } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { return do_write(offset, buffer, length, actual); } diff --git a/src/lib/util/jedparse.cpp b/src/lib/util/jedparse.cpp index 5915886b1a6..b347a2dd2b5 100644 --- a/src/lib/util/jedparse.cpp +++ b/src/lib/util/jedparse.cpp @@ -24,6 +24,7 @@ #include <cstdlib> #include <cstring> #include <cctype> +#include <tuple> @@ -194,7 +195,6 @@ static void process_field(jed_data *data, const uint8_t *cursrc, const uint8_t * int jed_parse(util::random_read &src, jed_data *result) { jed_parse_info pinfo; - int i; std::size_t actual; std::error_condition err; @@ -206,7 +206,7 @@ int jed_parse(util::random_read &src, jed_data *result) uint8_t ch; do { - err = src.read(&ch, 1, actual); + std::tie(err, actual) = read(src, &ch, 1); if (err) { if (LOG_PARSE) printf("Read error searching for JED start marker\n"); @@ -225,7 +225,7 @@ int jed_parse(util::random_read &src, jed_data *result) uint16_t checksum = ch; do { - err = src.read(&ch, 1, actual); + std::tie(err, actual) = read(src, &ch, 1); if (err) { if (LOG_PARSE) printf("Read error searching for JED end marker\n"); @@ -261,7 +261,8 @@ int jed_parse(util::random_read &src, jed_data *result) /* see if there is a transmission checksum at the end */ uint8_t sumbuf[4]; - if (!src.read(&sumbuf[0], 4, actual) && actual == 4 && ishex(sumbuf[0]) && ishex(sumbuf[1]) && ishex(sumbuf[2]) && ishex(sumbuf[3])) + std::tie(err, actual) = read(src, &sumbuf[0], 4); + if (!err && (actual == 4) && ishex(sumbuf[0]) && ishex(sumbuf[1]) && ishex(sumbuf[2]) && ishex(sumbuf[3])) { uint16_t dessum = (hexval(sumbuf[0]) << 12) | (hexval(sumbuf[1]) << 8) | (hexval(sumbuf[2]) << 4) | hexval(sumbuf[3] << 0); if (dessum != 0 && dessum != checksum) @@ -281,7 +282,8 @@ int jed_parse(util::random_read &src, jed_data *result) } } auto srcdata = std::make_unique<uint8_t[]>(endpos - startpos); - if (src.read(&srcdata[0], endpos - startpos, actual) || actual != endpos - startpos) + std::tie(err, actual) = read(src, &srcdata[0], endpos - startpos); + if (err || ((endpos - startpos) != actual)) { if (LOG_PARSE) printf("Error reading JED data\n"); return JEDERR_INVALID_DATA; @@ -325,7 +327,7 @@ int jed_parse(util::random_read &src, jed_data *result) /* validate the checksum */ checksum = 0; - for (i = 0; i < (result->numfuses + 7) / 8; i++) + for (int i = 0; i < ((result->numfuses + 7) / 8); i++) checksum += result->fusemap[i]; if (pinfo.checksum != 0 && checksum != pinfo.checksum) { @@ -441,13 +443,16 @@ size_t jed_output(const jed_data *data, void *result, size_t length) int jedbin_parse(util::read_stream &src, jed_data *result) { + std::error_condition err; + std::size_t actual; + /* initialize the output */ memset(result, 0, sizeof(*result)); /* need at least 4 bytes */ uint8_t buf[4]; - std::size_t actual; - if (src.read(&buf[0], 4, actual) || actual != 4) + std::tie(err, actual) = read(src, &buf[0], 4); + if (err || (4 != actual)) return JEDERR_INVALID_DATA; /* first unpack the number of fuses */ @@ -457,7 +462,8 @@ int jedbin_parse(util::read_stream &src, jed_data *result) /* now make sure we have enough data in the source */ /* copy in the data */ - if (src.read(result->fusemap, (result->numfuses + 7) / 8, actual) || actual != (result->numfuses + 7) / 8) + std::tie(err, actual) = read(src, result->fusemap, (result->numfuses + 7) / 8); + if (err || (((result->numfuses + 7) / 8) != actual)) return JEDERR_INVALID_DATA; return JEDERR_NONE; } diff --git a/src/lib/util/language.cpp b/src/lib/util/language.cpp index 3a00fe80ad7..50b518acd1b 100644 --- a/src/lib/util/language.cpp +++ b/src/lib/util/language.cpp @@ -61,11 +61,10 @@ void load_translation(random_read &file) return; } - std::size_t read; - file.read(translation_data.get(), size, read); - if (read != size) + auto const [err, actual] = read(file, translation_data.get(), size); + if (err || (actual != size)) { - osd_printf_error("Error reading translation file: requested %u bytes but got %u bytes\n", size, read); + osd_printf_error("Error reading translation file: requested %u bytes but got %u bytes\n", size, actual); translation_data.reset(); return; } diff --git a/src/lib/util/msdib.cpp b/src/lib/util/msdib.cpp index e70ba1b592a..bf33991f116 100644 --- a/src/lib/util/msdib.cpp +++ b/src/lib/util/msdib.cpp @@ -20,6 +20,7 @@ #include <cassert> #include <cstdlib> #include <cstring> +#include <tuple> #define LOG_GENERAL (1U << 0) @@ -127,11 +128,10 @@ std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits) noexcept msdib_error dib_read_file_header(read_stream &fp, std::uint32_t &filelen) noexcept { - std::size_t actual; - // the bitmap file header doesn't use natural alignment bitmap_file_header file_header; - if (fp.read(file_header, sizeof(file_header), actual) || (sizeof(file_header) != actual)) + auto const [err, actual] = read(fp, file_header, sizeof(file_header)); + if (err || (sizeof(file_header) != actual)) { LOG("Error reading DIB file header\n"); return msdib_error::FILE_TRUNCATED; @@ -167,6 +167,7 @@ msdib_error dib_read_bitmap_header( std::size_t &row_bytes, std::uint32_t length) noexcept { + std::error_condition err; std::size_t actual; // check that these things haven't been padded somehow @@ -178,7 +179,8 @@ msdib_error dib_read_bitmap_header( if (sizeof(header.core) > length) return msdib_error::FILE_TRUNCATED; std::memset(&header, 0, sizeof(header)); - if (fp.read(&header.core.size, sizeof(header.core.size), actual) || (sizeof(header.core.size) != actual)) + std::tie(err, actual) = read(fp, &header.core.size, sizeof(header.core.size)); + if (err || (sizeof(header.core.size) != actual)) { LOG("Error reading DIB header size (length %u)\n", length); return msdib_error::FILE_TRUNCATED; @@ -208,7 +210,8 @@ msdib_error dib_read_bitmap_header( { palette_bytes = 3U; std::uint32_t const header_read(std::min<std::uint32_t>(header.core.size, sizeof(header.core)) - sizeof(header.core.size)); - if (fp.read(&header.core.width, header_read, actual) || (header_read != actual)) + std::tie(err, actual) = read(fp, &header.core.width, header_read); + if (err || (header_read != actual)) { LOG("Error reading DIB core header from image data (%u bytes)\n", length); return msdib_error::FILE_TRUNCATED; @@ -261,7 +264,8 @@ msdib_error dib_read_bitmap_header( { palette_bytes = 4U; std::uint32_t const header_read(std::min<std::uint32_t>(header.info.size, sizeof(header.info)) - sizeof(header.info.size)); - if (fp.read(&header.info.width, header_read, actual) || (header_read != actual)) + std::tie(err, actual) = read(fp, &header.info.width, header_read); + if (err || (header_read != actual)) { LOG("Error reading DIB info header from image data (%u bytes)\n", length); return msdib_error::FILE_TRUNCATED; @@ -445,7 +449,6 @@ msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap) noexcept msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight) noexcept { // read the bitmap header - std::size_t actual; bitmap_headers header; unsigned palette_bytes; bool indexed; @@ -492,7 +495,8 @@ msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std:: std::unique_ptr<std::uint8_t []> palette_data(new (std::nothrow) std::uint8_t [palette_size]); if (!palette_data) return msdib_error::OUT_OF_MEMORY; - if (fp.read(palette_data.get(), palette_size, actual) || (palette_size != actual)) + auto const [err, actual] = read(fp, palette_data.get(), palette_size); + if (err || (palette_size != actual)) { LOG("Error reading palette from DIB image data (%u bytes)\n", length); return msdib_error::FILE_TRUNCATED; @@ -575,7 +579,8 @@ msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std:: int const y_inc(top_down ? 1 : -1); for (std::int32_t i = 0, y = top_down ? 0 : (header.info.height - 1); header.info.height > i; ++i, y += y_inc) { - if (fp.read(row_data.get(), row_bytes, actual) || (row_bytes != actual)) + auto const [err, actual] = read(fp, row_data.get(), row_bytes); + if (err || (row_bytes != actual)) { LOG("Error reading DIB row %d data from image data\n", i); return msdib_error::FILE_TRUNCATED; @@ -638,7 +643,8 @@ msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std:: { for (std::int32_t i = 0, y = top_down ? 0 : (header.info.height - 1); header.info.height > i; ++i, y += y_inc) { - if (fp.read(row_data.get(), mask_row_bytes, actual) || (mask_row_bytes != actual)) + auto const [err, actual] = read(fp, row_data.get(), mask_row_bytes); + if (err || (mask_row_bytes != actual)) { LOG("Error reading DIB mask row %d data from image data\n", i); return msdib_error::FILE_TRUNCATED; diff --git a/src/lib/util/plaparse.cpp b/src/lib/util/plaparse.cpp index 423939b41a8..9f4d1c0bc14 100644 --- a/src/lib/util/plaparse.cpp +++ b/src/lib/util/plaparse.cpp @@ -68,11 +68,14 @@ static uint32_t suck_number(util::random_read &src) uint32_t value = 0; // find first digit - uint8_t ch; - std::size_t actual; bool found = false; - while (!src.read(&ch, 1, actual) && actual == 1) + while (true) { + uint8_t ch; + auto const [err, actual] = read(src, &ch, 1); + if (err || (1 != actual)) + break; + // loop over and accumulate digits if (isdigit(ch)) { @@ -189,8 +192,8 @@ static bool process_terms(jed_data *data, util::random_read &src, uint8_t ch, pa curoutput = 0; } - std::size_t actual; - if (src.read(&ch, 1, actual)) + auto const [err, actual] = read(src, &ch, 1); + if (err) return false; if (actual != 1) return true; @@ -227,9 +230,11 @@ static bool process_field(jed_data *data, util::random_read &src, parse_info *pi int destptr = 0; uint8_t seek; - std::size_t actual; - while (!src.read(&seek, 1, actual) && actual == 1 && isalpha(seek)) + while (true) { + auto const [err, actual] = read(src, &seek, 1); + if (err || (actual != 1) || !isalpha(seek)) + break; dest[destptr++] = tolower(seek); if (destptr == sizeof(dest)) break; @@ -275,8 +280,11 @@ static bool process_field(jed_data *data, util::random_read &src, parse_info *pi // output polarity (optional) case KW_PHASE: if (LOG_PARSE) printf("Phase...\n"); - while (!src.read(&seek, 1, actual) && actual == 1 && !iscrlf(seek) && pinfo->xorptr < (JED_MAX_FUSES/2)) + while (true) { + auto const [err, actual] = read(src, &seek, 1); + if (err || (actual != 1) || iscrlf(seek) || (pinfo->xorptr >= (JED_MAX_FUSES / 2))) + break; if (seek == '0' || seek == '1') { // 0 is negative @@ -322,19 +330,23 @@ int pla_parse(util::random_read &src, jed_data *result) result->numfuses = 0; memset(result->fusemap, 0, sizeof(result->fusemap)); - uint8_t ch; - std::size_t actual; - while (!src.read(&ch, 1, actual) && actual == 1) + while (true) { + std::error_condition err; + size_t actual; + uint8_t ch; + std::tie(err, actual) = read(src, &ch, 1); + if (err || (actual != 1)) + break; switch (ch) { // comment line case '#': - while (!src.read(&ch, 1, actual) && actual == 1) + do { - if (iscrlf(ch)) - break; + std::tie(err, actual) = read(src, &ch, 1); } + while (!err && (actual == 1) && !iscrlf(ch)); break; // keyword diff --git a/src/lib/util/png.cpp b/src/lib/util/png.cpp index 8e077f92114..ce28a866604 100644 --- a/src/lib/util/png.cpp +++ b/src/lib/util/png.cpp @@ -24,6 +24,7 @@ #include <cstdlib> #include <cstring> #include <new> +#include <tuple> namespace util { @@ -452,7 +453,7 @@ private: std::uint8_t tempbuff[4]; // fetch the length of this chunk - err = fp.read(tempbuff, 4, actual); + std::tie(err, actual) = read(fp, tempbuff, 4); if (err) return err; else if (4 != actual) @@ -460,7 +461,7 @@ private: length = fetch_32bit(tempbuff); // fetch the type of this chunk - err = fp.read(tempbuff, 4, actual); + std::tie(err, actual) = read(fp, tempbuff, 4); if (err) return err; else if (4 != actual) @@ -477,13 +478,8 @@ private: // read the chunk itself into an allocated memory buffer if (length) { - // allocate memory for this chunk - data.reset(new (std::nothrow) std::uint8_t [length]); - if (!data) - return std::errc::not_enough_memory; - - // read the data from the file - err = fp.read(data.get(), length, actual); + // allocate memory and read the data from the file + std::tie(err, data, actual) = read(fp, length); if (err) { data.reset(); @@ -500,7 +496,7 @@ private: } // read the CRC - err = fp.read(tempbuff, 4, actual); + std::tie(err, actual) = read(fp, tempbuff, 4); if (err) { data.reset(); @@ -789,8 +785,7 @@ public: std::uint8_t signature[sizeof(PNG_SIGNATURE)]; // read 8 bytes - std::size_t actual; - std::error_condition err = fp.read(signature, sizeof(signature), actual); + auto const [err, actual] = read(fp, signature, sizeof(signature)); if (err) return err; else if (sizeof(signature) != actual) @@ -941,7 +936,6 @@ std::error_condition png_info::add_text(std::string_view keyword, std::string_vi static std::error_condition write_chunk(write_stream &fp, const uint8_t *data, uint32_t type, uint32_t length) noexcept { std::error_condition err; - std::size_t written; std::uint8_t tempbuff[8]; std::uint32_t crc; @@ -951,30 +945,24 @@ static std::error_condition write_chunk(write_stream &fp, const uint8_t *data, u crc = crc32(0, tempbuff + 4, 4); // write that data - err = fp.write(tempbuff, 8, written); + std::tie(err, std::ignore) = write(fp, tempbuff, 8); if (err) return err; - else if (8 != written) - return std::errc::io_error; // append the actual data if (length > 0) { - err = fp.write(data, length, written); + std::tie(err, std::ignore) = write(fp, data, length); if (err) return err; - else if (length != written) - return std::errc::io_error; crc = crc32(crc, data, length); } // write the CRC put_32bit(tempbuff, crc); - err = fp.write(tempbuff, 4, written); + std::tie(err, std::ignore) = write(fp, tempbuff, 4); if (err) return err; - else if (4 != written) - return std::errc::io_error; return std::error_condition(); } @@ -993,7 +981,6 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data if (err) return err; - std::size_t written; std::uint8_t tempbuff[8192]; std::uint32_t zlength = 0; z_stream stream; @@ -1006,11 +993,9 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data crc = crc32(0, tempbuff + 4, 4); // write that data - err = fp.write(tempbuff, 8, written); + std::tie(err, std::ignore) = write(fp, tempbuff, 8); if (err) return err; - else if (8 != written) - return std::errc::io_error; // initialize the stream memset(&stream, 0, sizeof(stream)); @@ -1036,17 +1021,12 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data if (stream.avail_out < sizeof(tempbuff)) { int bytes = sizeof(tempbuff) - stream.avail_out; - err = fp.write(tempbuff, bytes, written); + std::tie(err, std::ignore) = write(fp, tempbuff, bytes); if (err) { deflateEnd(&stream); return err; } - else if (bytes != written) - { - deflateEnd(&stream); - return std::errc::io_error; - } crc = crc32(crc, tempbuff, bytes); zlength += bytes; } @@ -1079,22 +1059,18 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data // write the CRC put_32bit(tempbuff, crc); - err = fp.write(tempbuff, 4, written); + std::tie(err, std::ignore) = write(fp, tempbuff, 4); if (err) return err; - else if (4 != written) - return std::errc::io_error; // seek back and update the length err = fp.seek(lengthpos, SEEK_SET); if (err) return err; put_32bit(tempbuff + 0, zlength); - err = fp.write(tempbuff, 4, written); + std::tie(err, std::ignore) = write(fp, tempbuff, 4); if (err) return err; - else if (4 != written) - return std::errc::io_error; // return to the end return fp.seek(lengthpos + 8 + zlength + 4, SEEK_SET); @@ -1326,12 +1302,9 @@ std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t info = &pnginfo; // write the PNG signature - std::size_t written; - std::error_condition err = fp.write(PNG_SIGNATURE, sizeof(PNG_SIGNATURE), written); + auto const [err, written] = write(fp, PNG_SIGNATURE, sizeof(PNG_SIGNATURE)); if (err) return err; - else if (sizeof(PNG_SIGNATURE) != written) - return std::errc::io_error; // write the rest of the PNG data return write_png_stream(fp, *info, bitmap, palette_length, palette); @@ -1347,12 +1320,9 @@ std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t std::error_condition mng_capture_start(random_write &fp, bitmap_t const &bitmap, unsigned rate) noexcept { - std::size_t written; - std::error_condition err = fp.write(MNG_Signature, 8, written); + auto const [err, written] = write(fp, MNG_Signature, 8); if (err) return err; - else if (8 != written) - return std::errc::io_error; uint8_t mhdr[28]; memset(mhdr, 0, 28); diff --git a/src/lib/util/simh_tape_file.cpp b/src/lib/util/simh_tape_file.cpp index 4fe1af5ae88..ffd6a48aeb3 100644 --- a/src/lib/util/simh_tape_file.cpp +++ b/src/lib/util/simh_tape_file.cpp @@ -119,16 +119,14 @@ void simh_tape_file::raw_seek(const osd::u64 pos) const void simh_tape_file::raw_read(osd::u8 *const buf, const osd::u32 len) const { - size_t actual_len; - std::error_condition err = m_file.read(buf, len, actual_len); + auto const [err, actual_len] = read(m_file, buf, len); if (err || actual_len != len) // error: we failed to read expected number of bytes throw std::runtime_error(std::string("failed read: ") + (err ? err.message() : std::string("unexpected length"))); } void simh_tape_file::raw_write(const osd::u8 *const buf, const osd::u32 len) const { - size_t actual_len; - std::error_condition err = m_file.write(buf, len, actual_len); + auto const [err, actual_len] = write(m_file, buf, len); if (err || actual_len != len) // error: we failed to write expected number of bytes throw std::runtime_error(std::string("failed write: ") + (err ? err.message() : std::string("unexpected length"))); } diff --git a/src/lib/util/un7z.cpp b/src/lib/util/un7z.cpp index 362c95ee235..5ee97d62777 100644 --- a/src/lib/util/un7z.cpp +++ b/src/lib/util/un7z.cpp @@ -71,8 +71,7 @@ private: if (!size) return SZ_OK; - std::size_t read_length(0); - std::error_condition const err = file->read_at(currfpos, data, size, read_length); + auto const [err, read_length] = read_at(*file, currfpos, data, size); size = read_length; currfpos += read_length; diff --git a/src/lib/util/unzip.cpp b/src/lib/util/unzip.cpp index c1df469fed4..281b5f06664 100644 --- a/src/lib/util/unzip.cpp +++ b/src/lib/util/unzip.cpp @@ -154,8 +154,7 @@ public: while (cd_remaining) { std::size_t const chunk(std::size_t(std::min<std::uint64_t>(std::numeric_limits<std::size_t>::max(), cd_remaining))); - std::size_t read_length(0); - std::error_condition const filerr = m_file->read_at(m_ecd.cd_start_disk_offset + cd_offs, &m_cd[cd_offs], chunk, read_length); + auto const [filerr, read_length] = read_at(*m_file, m_ecd.cd_start_disk_offset + cd_offs, &m_cd[cd_offs], chunk); if (filerr) { osd_printf_error( @@ -979,7 +978,7 @@ std::error_condition zip_file_impl::read_ecd() noexcept } // read in one buffers' worth of data - filerr = m_file->read_at(m_length - buflen, &buffer[0], buflen, read_length); + std::tie(filerr, read_length) = read_at(*m_file, m_length - buflen, &buffer[0], buflen); if (filerr) { osd_printf_error( @@ -1024,11 +1023,11 @@ std::error_condition zip_file_impl::read_ecd() noexcept } // try to read the ZIP64 ECD locator - filerr = m_file->read_at( + std::tie(filerr, read_length) = read_at( + *m_file, m_length - buflen + offset - ecd64_locator_reader::minimum_length(), &buffer[0], - ecd64_locator_reader::minimum_length(), - read_length); + ecd64_locator_reader::minimum_length()); if (filerr) { osd_printf_error( @@ -1058,7 +1057,7 @@ std::error_condition zip_file_impl::read_ecd() noexcept } // try to read the ZIP64 ECD - filerr = m_file->read_at(ecd64_loc_rd.ecd64_offset(), &buffer[0], ecd64_reader::minimum_length(), read_length); + std::tie(filerr, read_length) = read_at(*m_file, ecd64_loc_rd.ecd64_offset(), &buffer[0], ecd64_reader::minimum_length()); if (filerr) { osd_printf_error( @@ -1160,8 +1159,7 @@ std::error_condition zip_file_impl::get_compressed_data_offset(std::uint64_t &of return ziperr; // now go read the fixed-sized part of the local file header - std::size_t read_length; - std::error_condition const filerr = m_file->read_at(m_header.local_header_offset, &m_buffer[0], local_file_header_reader::minimum_length(), read_length); + auto const [filerr, read_length] = read_at(*m_file, m_header.local_header_offset, &m_buffer[0], local_file_header_reader::minimum_length()); if (filerr) { osd_printf_error( @@ -1205,8 +1203,7 @@ std::error_condition zip_file_impl::get_compressed_data_offset(std::uint64_t &of std::error_condition zip_file_impl::decompress_data_type_0(std::uint64_t offset, void *buffer, std::size_t length) noexcept { // the data is uncompressed; just read it - std::size_t read_length(0); - std::error_condition const filerr = m_file->read_at(offset, buffer, m_header.compressed_length, read_length); + auto const [filerr, read_length] = read_at(*m_file, offset, buffer, m_header.compressed_length); if (filerr) { osd_printf_error( @@ -1277,12 +1274,11 @@ std::error_condition zip_file_impl::decompress_data_type_8(std::uint64_t offset, while (true) { // read in the next chunk of data - std::size_t read_length(0); - auto const filerr = m_file->read_at( + auto const [filerr, read_length] = read_at( + *m_file, offset, &m_buffer[0], - std::size_t(std::min<std::uint64_t>(input_remaining, m_buffer.size())), - read_length); + std::size_t(std::min<std::uint64_t>(input_remaining, m_buffer.size()))); if (filerr) { osd_printf_error( @@ -1393,7 +1389,7 @@ std::error_condition zip_file_impl::decompress_data_type_14(std::uint64_t offset m_header.file_name, m_filename); return archive_file::error::DECOMPRESS_ERROR; } - filerr = m_file->read_at(offset, &m_buffer[0], 4, read_length); + std::tie(filerr, read_length) = read_at(*m_file, offset, &m_buffer[0], 4); if (filerr) { osd_printf_error( @@ -1425,7 +1421,7 @@ std::error_condition zip_file_impl::decompress_data_type_14(std::uint64_t offset m_header.file_name, m_filename); return archive_file::error::DECOMPRESS_ERROR; } - filerr = m_file->read_at(offset, &m_buffer[0], props_size, read_length); + std::tie(filerr, read_length) = read_at(*m_file, offset, &m_buffer[0], props_size); if (filerr) { osd_printf_error( @@ -1472,11 +1468,11 @@ std::error_condition zip_file_impl::decompress_data_type_14(std::uint64_t offset while (0 < input_remaining) { // read in the next chunk of data - filerr = m_file->read_at( + std::tie(filerr, read_length) = read_at( + *m_file, offset, &m_buffer[0], - std::size_t((std::min<std::uint64_t>)(input_remaining, m_buffer.size())), - read_length); + std::size_t((std::min<std::uint64_t>)(input_remaining, m_buffer.size()))); if (filerr) { osd_printf_error( @@ -1569,12 +1565,11 @@ std::error_condition zip_file_impl::decompress_data_type_93(std::uint64_t offset while (input_remaining && length) { // read in the next chunk of data - std::size_t read_length(0); - auto const filerr = m_file->read_at( + auto const [filerr, read_length] = read_at( + *m_file, offset, &m_buffer[0], - std::size_t(std::min<std::uint64_t>(input_remaining, m_buffer.size())), - read_length); + std::size_t(std::min<std::uint64_t>(input_remaining, m_buffer.size()))); if (filerr) { osd_printf_error( diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp index 39604a29a87..7cd6a4eecda 100644 --- a/src/lib/util/xmlfile.cpp +++ b/src/lib/util/xmlfile.cpp @@ -41,14 +41,14 @@ constexpr unsigned TEMP_BUFFER_SIZE(4096U); void write_escaped(core_file &file, std::string const &str) { + // FIXME: check for errors std::string::size_type pos = 0; while ((str.size() > pos) && (std::string::npos != pos)) { std::string::size_type const found = str.find_first_of("\"&<>", pos); if (found != std::string::npos) { - std::size_t written; - file.write(&str[pos], found - pos, written); + write(file, &str[pos], found - pos); switch (str[found]) { case '"': file.puts("""); pos = found + 1; break; @@ -60,8 +60,7 @@ void write_escaped(core_file &file, std::string const &str) } else { - std::size_t written; - file.write(&str[pos], str.size() - pos, written); + write(file, &str[pos], str.size() - pos); pos = found; } } @@ -134,8 +133,7 @@ file::ptr file::read(read_stream &file, parse_options const *opts) char tempbuf[TEMP_BUFFER_SIZE]; // read as much as we can - size_t bytes; - file.read(tempbuf, sizeof(tempbuf), bytes); // TODO: better error handling + auto const [err, bytes] = util::read(file, tempbuf, sizeof(tempbuf)); // FIXME: better error handling done = !bytes; // parse the data diff --git a/src/mame/acorn/z88_impexp.cpp b/src/mame/acorn/z88_impexp.cpp index bd712c875af..a4b01e77580 100644 --- a/src/mame/acorn/z88_impexp.cpp +++ b/src/mame/acorn/z88_impexp.cpp @@ -181,9 +181,8 @@ std::pair<std::error_condition, std::string> z88_impexp_device::call_load() std::error_condition err; while (true) { - size_t actual; uint8_t b; - err = file.read(&b, 1, actual); + auto const [err, actual] = read(file, &b, 1); if (err || actual != 1) break; diff --git a/src/mame/apple/cuda.cpp b/src/mame/apple/cuda.cpp index 4bf4860c20c..7087dbf76d9 100644 --- a/src/mame/apple/cuda.cpp +++ b/src/mame/apple/cuda.cpp @@ -484,8 +484,8 @@ void cuda_device::nvram_default() bool cuda_device::nvram_read(util::read_stream &file) { - size_t actual; - if (!file.read(m_disk_pram, 0x100, actual) && actual == 0x100) + auto const [err, actual] = read(file, m_disk_pram, 0x100); + if (!err && (actual == 0x100)) { LOGMASKED(LOG_PRAM, "Loaded PRAM from disk\n"); return true; @@ -496,9 +496,9 @@ bool cuda_device::nvram_read(util::read_stream &file) bool cuda_device::nvram_write(util::write_stream &file) { - size_t actual; LOGMASKED(LOG_PRAM, "Writing PRAM to disk\n"); - return !file.write(m_pram, 0x100, actual) && actual == 0x100; + auto const [err, actual] = write(file, m_pram, 0x100); + return !err; } // Cuda v2.XX ------------------------------------------------------------------------ diff --git a/src/mame/apple/egret.cpp b/src/mame/apple/egret.cpp index 2f404e7aaa7..8e9a70a17f6 100644 --- a/src/mame/apple/egret.cpp +++ b/src/mame/apple/egret.cpp @@ -549,8 +549,8 @@ void egret_device::nvram_default() bool egret_device::nvram_read(util::read_stream &file) { - size_t actual; - if (!file.read(m_disk_pram, 0x100, actual) && actual == 0x100) + auto const [err, actual] = read(file, m_disk_pram, 0x100); + if (!err && (actual == 0x100)) { LOGMASKED(LOG_PRAM, "PRAM read from disk OK"); m_pram_loaded = false; @@ -561,6 +561,6 @@ bool egret_device::nvram_read(util::read_stream &file) bool egret_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_pram, 0x100, actual) && actual == 0x100; + auto const [err, actual] = write(file, m_pram, 0x100); + return !err; } diff --git a/src/mame/apple/heathrow.cpp b/src/mame/apple/heathrow.cpp index 086df680036..10236f40727 100644 --- a/src/mame/apple/heathrow.cpp +++ b/src/mame/apple/heathrow.cpp @@ -675,8 +675,8 @@ void ohare_device::nvram_default() bool ohare_device::nvram_read(util::read_stream &file) { - size_t actual; - if (!file.read(m_nvram, 0x8000, actual) && actual == 0x8000) + auto const [err, actual] = read(file, m_nvram, 0x8000); + if (!err && (actual == 0x8000)) { return true; } @@ -685,8 +685,8 @@ bool ohare_device::nvram_read(util::read_stream &file) bool ohare_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_nvram, 0x8000, actual) && actual == 0x8000; + auto const [err, actual] = write(file, m_nvram, 0x8000); + return !err; } // Audio support diff --git a/src/mame/apple/macrtc.cpp b/src/mame/apple/macrtc.cpp index e684d15b751..ba7b003a7b0 100644 --- a/src/mame/apple/macrtc.cpp +++ b/src/mame/apple/macrtc.cpp @@ -419,24 +419,24 @@ void rtc3430042_device::nvram_default() bool rtc3430042_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_pram, 0x100, actual) && actual == 0x100; + auto const [err, actual] = read(file, m_pram, 0x100); + return !err && (actual == 0x100); } bool rtc3430042_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_pram, 0x100, actual) && actual == 0x100; + auto const [err, actual] = write(file, m_pram, 0x100); + return !err; } bool rtc3430040_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_pram, 20, actual) && actual == 20; + auto const [err, actual] = read(file, m_pram, 20); + return !err && (actual == 20); } bool rtc3430040_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_pram, 20, actual) && actual == 20; + auto const [err, actual] = write(file, m_pram, 20); + return !err; } diff --git a/src/mame/konami/zs01.cpp b/src/mame/konami/zs01.cpp index 400d72cca9b..a77d0e74f00 100644 --- a/src/mame/konami/zs01.cpp +++ b/src/mame/konami/zs01.cpp @@ -15,6 +15,8 @@ #include "zs01.h" #include <cstdarg> +#include <tuple> + #define VERBOSE_LEVEL ( 0 ) @@ -694,22 +696,32 @@ void zs01_device::nvram_default() bool zs01_device::nvram_read( util::read_stream &file ) { + std::error_condition err; std::size_t actual; - bool result = !file.read( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.read( m_command_key, sizeof( m_command_key ), actual ) && actual == sizeof( m_command_key ); - result = result && !file.read( m_data_key, sizeof( m_data_key ), actual ) && actual == sizeof( m_data_key ); - result = result && !file.read( m_configuration_registers, sizeof( m_configuration_registers ), actual ) && actual == sizeof( m_configuration_registers ); - result = result && !file.read( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + std::tie( err, actual ) = read( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if( err || ( sizeof( m_response_to_reset ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_command_key, sizeof( m_command_key ) ); + if( err || ( sizeof( m_command_key ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_data_key, sizeof( m_data_key ) ); + if( err || ( sizeof( m_data_key ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_configuration_registers, sizeof( m_configuration_registers ) ); + if( err || ( sizeof( m_configuration_registers ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_data, sizeof( m_data ) ); + if( err || ( sizeof( m_data ) != actual ) ) + return false; + return true; } bool zs01_device::nvram_write( util::write_stream &file ) { - std::size_t actual; - bool result = !file.write( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.write( m_command_key, sizeof( m_command_key ), actual ) && actual == sizeof( m_command_key ); - result = result && !file.write( m_data_key, sizeof( m_data_key ), actual ) && actual == sizeof( m_data_key ); - result = result && !file.write( m_configuration_registers, sizeof( m_configuration_registers ), actual ) && actual == sizeof( m_configuration_registers ); - result = result && !file.write( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); + bool result = !write( file, m_response_to_reset, sizeof( m_response_to_reset ) ).first; + result = result && !write( file, m_command_key, sizeof( m_command_key ) ).first; + result = result && !write( file, m_data_key, sizeof( m_data_key ) ).first; + result = result && !write( file, m_configuration_registers, sizeof( m_configuration_registers ) ).first; + result = result && !write( file, m_data, sizeof( m_data ) ).first; return result; } diff --git a/src/mame/midway/midwayic.cpp b/src/mame/midway/midwayic.cpp index e8ec1d82356..67538fa78a3 100644 --- a/src/mame/midway/midwayic.cpp +++ b/src/mame/midway/midwayic.cpp @@ -640,14 +640,14 @@ void midway_serial_pic2_device::nvram_default() bool midway_serial_pic2_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_nvram, sizeof(m_nvram), actual) && actual == sizeof(m_nvram); + auto const [err, actual] = util::read(file, m_nvram, sizeof(m_nvram)); + return !err && (actual == sizeof(m_nvram)); } bool midway_serial_pic2_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_nvram, sizeof(m_nvram), actual) && actual == sizeof(m_nvram); + auto const [err, actual] = util::write(file, m_nvram, sizeof(m_nvram)); + return !err; } diff --git a/src/mame/msx/msx_matsushita.cpp b/src/mame/msx/msx_matsushita.cpp index f912fadf2e3..1f6078559f6 100644 --- a/src/mame/msx/msx_matsushita.cpp +++ b/src/mame/msx/msx_matsushita.cpp @@ -51,14 +51,14 @@ void msx_matsushita_device::nvram_default() bool msx_matsushita_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(&m_sram[0], m_sram.size(), actual) && actual == m_sram.size(); + auto const [err, actual] = read(file, &m_sram[0], m_sram.size()); + return !err && (actual == m_sram.size()); } bool msx_matsushita_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(&m_sram[0], m_sram.size(), actual) && actual == m_sram.size(); + auto const [err, actual] = write(file, &m_sram[0], m_sram.size()); + return !err; } u8 msx_matsushita_device::switched_read(offs_t offset) diff --git a/src/mame/msx/msx_s1985.cpp b/src/mame/msx/msx_s1985.cpp index 188815691e9..4dddce31dbd 100644 --- a/src/mame/msx/msx_s1985.cpp +++ b/src/mame/msx/msx_s1985.cpp @@ -37,15 +37,15 @@ void msx_s1985_device::nvram_default() bool msx_s1985_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_backup_ram, sizeof(m_backup_ram), actual) && actual == sizeof(m_backup_ram); + auto const [err, actual] = read(file, m_backup_ram, sizeof(m_backup_ram)); + return !err && (actual == sizeof(m_backup_ram)); } bool msx_s1985_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_backup_ram, sizeof(m_backup_ram), actual) && actual == sizeof(m_backup_ram); + auto const [err, actual] = write(file, m_backup_ram, sizeof(m_backup_ram)); + return !err; } diff --git a/src/mame/nascom/nascom1.cpp b/src/mame/nascom/nascom1.cpp index d1e50e3ccd1..a0f31ba6a4a 100644 --- a/src/mame/nascom/nascom1.cpp +++ b/src/mame/nascom/nascom1.cpp @@ -44,6 +44,8 @@ Cassette (nascom2): #include "softlist_dev.h" #include "screen.h" +#include <tuple> + namespace { @@ -319,15 +321,19 @@ TIMER_DEVICE_CALLBACK_MEMBER( nascom2_state::nascom2_kansas_r ) template<int Dest> SNAPSHOT_LOAD_MEMBER(nascom_state::snapshot_cb) { - util::core_file &file = image.image_core_file(); - uint8_t line[29]; - + util::random_read &file = image.image_core_file(); std::error_condition err; - size_t actual; - while (!(err = file.read(&line, sizeof(line), actual)) && actual == sizeof(line)) + + while (true) { - unsigned int addr, b[8], dummy; + size_t actual; + uint8_t line[29]; + std::tie(err, actual) = read(file, &line, sizeof(line)); + if (err || (sizeof(line) != actual)) + break; + + unsigned int addr, b[8]; if (sscanf((char *)line, "%4x %x %x %x %x %x %x %x %x", &addr, &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]) == 9) { @@ -348,13 +354,14 @@ SNAPSHOT_LOAD_MEMBER(nascom_state::snapshot_cb) { return std::make_pair(image_error::INVALIDIMAGE, "Unsupported file format"); } - dummy = 0x00; - while (dummy != 0x0a && dummy != 0x1f) + int dummy = 0x00; + do { - err = file.read(&dummy, 1, actual); - if (err || actual != 1) + std::tie(err, actual) = read(file, &dummy, 1); + if (err || (actual != 1)) return std::make_pair(err, std::string()); } + while (dummy != 0x0a && dummy != 0x1f); } return std::make_pair(err, std::string()); @@ -378,8 +385,7 @@ std::pair<std::error_condition, std::string> nascom2_state::load_cart( slot->rom_alloc(slot->length(), GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - size_t actual; - std::error_condition const err = slot->image_core_file().read(slot->get_rom_base(), slot->length(), actual); + auto const [err, actual] = read(slot->image_core_file(), slot->get_rom_base(), slot->length()); if (err || actual != slot->length()) return std::make_pair(err ? err : std::errc::io_error, std::string()); diff --git a/src/mame/nec/pc9801_memsw.cpp b/src/mame/nec/pc9801_memsw.cpp index 5efcd07b9d9..e0d732a84f6 100644 --- a/src/mame/nec/pc9801_memsw.cpp +++ b/src/mame/nec/pc9801_memsw.cpp @@ -144,14 +144,14 @@ void pc9801_memsw_device::nvram_default() bool pc9801_memsw_device::nvram_read(util::read_stream &file) { - size_t actual_size; - return !file.read(m_bram, m_bram_size, actual_size) && actual_size == m_bram_size; + auto const [err, actual_size] = util::read(file, m_bram, m_bram_size); + return !err && (actual_size == m_bram_size); } bool pc9801_memsw_device::nvram_write(util::write_stream &file) { - size_t actual_size; - return !file.write(m_bram, m_bram_size, actual_size) && actual_size == m_bram_size; + auto const [err, actual_size] = util::write(file, m_bram, m_bram_size); + return !err; } //************************************************************************** diff --git a/src/mame/pc/tosh1000_bram.cpp b/src/mame/pc/tosh1000_bram.cpp index 6dce3a8ad78..fb79c67aceb 100644 --- a/src/mame/pc/tosh1000_bram.cpp +++ b/src/mame/pc/tosh1000_bram.cpp @@ -56,8 +56,8 @@ void tosh1000_bram_device::nvram_default() bool tosh1000_bram_device::nvram_read(util::read_stream &file) { - size_t actual; - return !file.read(m_bram, BRAM_SIZE, actual) && actual == BRAM_SIZE; + auto const [err, actual] = util::read(file, m_bram, BRAM_SIZE); + return !err && (actual == BRAM_SIZE); } //------------------------------------------------- @@ -67,8 +67,8 @@ bool tosh1000_bram_device::nvram_read(util::read_stream &file) bool tosh1000_bram_device::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_bram, BRAM_SIZE, actual) && actual == BRAM_SIZE; + auto const [err, actual] = util::write(file, m_bram, BRAM_SIZE); + return !err; } //------------------------------------------------- diff --git a/src/mame/snk/ngp.cpp b/src/mame/snk/ngp.cpp index c1937355128..797ac3f6ec0 100644 --- a/src/mame/snk/ngp.cpp +++ b/src/mame/snk/ngp.cpp @@ -805,8 +805,8 @@ void ngp_state::nvram_default() bool ngp_state::nvram_read(util::read_stream &file) { - size_t actual; - if (!file.read(m_mainram, 0x3000, actual) && actual == 0x3000) + auto const [err, actual] = read(file, m_mainram, 0x3000); + if (!err && (actual == 0x3000)) { m_nvram_loaded = true; return true; @@ -817,8 +817,8 @@ bool ngp_state::nvram_read(util::read_stream &file) bool ngp_state::nvram_write(util::write_stream &file) { - size_t actual; - return !file.write(m_mainram, 0x3000, actual) && actual == 0x3000; + auto const [err, actual] = write(file, m_mainram, 0x3000); + return !err; } diff --git a/src/mame/tigertel/docg3.cpp b/src/mame/tigertel/docg3.cpp index 4d2464c19d3..2efd8c2c428 100644 --- a/src/mame/tigertel/docg3.cpp +++ b/src/mame/tigertel/docg3.cpp @@ -823,11 +823,18 @@ void diskonchip_g3_device::nvram_default() bool diskonchip_g3_device::nvram_read(util::read_stream &file) { + std::error_condition err; size_t actual; - bool result = !file.read(m_data[0].get(), m_data_size[0], actual) && actual == m_data_size[0]; - result = result && !file.read(m_data[1].get(), m_data_size[1], actual) && actual == m_data_size[1]; - result = result && !file.read(m_data[2].get(), m_data_size[2], actual) && actual == m_data_size[2]; - return result; + std::tie(err, actual) = read(file, m_data[0].get(), m_data_size[0]); + if (err || (actual != m_data_size[0])) + return false; + std::tie(err, actual) = read(file, m_data[1].get(), m_data_size[1]); + if (err || (actual != m_data_size[1])) + return false; + std::tie(err, actual) = read(file, m_data[2].get(), m_data_size[2]); + if (err || (actual != m_data_size[2])) + return false; + return true; } //------------------------------------------------- @@ -837,9 +844,12 @@ bool diskonchip_g3_device::nvram_read(util::read_stream &file) bool diskonchip_g3_device::nvram_write(util::write_stream &file) { + std::error_condition err; size_t actual; - bool result = !file.write(m_data[0].get(), m_data_size[0], actual) && actual == m_data_size[0]; - result = result && !file.write(m_data[1].get(), m_data_size[1], actual) && actual == m_data_size[1]; - result = result && !file.write(m_data[2].get(), m_data_size[2], actual) && actual == m_data_size[2]; - return result; + std::tie(err, actual) = write(file, m_data[0].get(), m_data_size[0]); + if (!err) + std::tie(err, actual) = write(file, m_data[1].get(), m_data_size[1]); + if (!err) + std::tie(err, actual) = write(file, m_data[2].get(), m_data_size[2]); + return !err; } diff --git a/src/mame/trs/trs80_quik.cpp b/src/mame/trs/trs80_quik.cpp index dfdf6460929..d0abe2af39f 100644 --- a/src/mame/trs/trs80_quik.cpp +++ b/src/mame/trs/trs80_quik.cpp @@ -11,6 +11,8 @@ #include "cpu/z80/z80.h" +#include <tuple> + #define VERBOSE 1 #include "logmacro.h" @@ -65,10 +67,10 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) size_t actual; while (true) { - err = file.read(&type, 1, actual); + std::tie(err, actual) = read(file, &type, 1); if (actual != 1) break; - err = file.read(&length, 1, actual); + std::tie(err, actual) = read(file, &length, 1); if (actual != 1) break; @@ -78,7 +80,7 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) { length -= 2; u16 block_length = length ? length : 256; - err = file.read(&addr, 2, actual); + std::tie(err, actual) = read(file, &addr, 2); if (actual != 2) { logerror("/CMD error reading address of data block\n"); @@ -93,7 +95,7 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) image_error::INVALIDIMAGE, util::string_format("Object code block at address %04x is outside RAM", address)); } - err = file.read(ptr, block_length, actual); + std::tie(err, actual) = read(file, ptr, block_length); if (actual != block_length) { logerror("/CMD error reading data block at address %04x\n", address); @@ -104,7 +106,7 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) case CMD_TYPE_TRANSFER_ADDRESS: // 02 - go address { - err = file.read(&addr, 2, actual); + std::tie(err, actual) = read(file, &addr, 2); if (actual != 2) { logerror("/CMD error reading transfer address\n"); @@ -117,7 +119,7 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) return std::make_pair(std::error_condition(), std::string()); case CMD_TYPE_LOAD_MODULE_HEADER: // 05 - name - err = file.read(&data, length, actual); + std::tie(err, actual) = read(file, &data, length); if (actual != length) { logerror("/CMD error reading block type %02x\n", type); @@ -126,7 +128,7 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) LOG("/CMD load module header '%s'\n", data); break; - case CMD_TYPE_COPYRIGHT_BLOCK: // 1F - copyright info err = file.read(&data, length, actual); + case CMD_TYPE_COPYRIGHT_BLOCK: // 1F - copyright info std::tie(err, actual) = read(file, &data, length); if (actual != length) { logerror("/CMD error reading block type %02x\n", type); @@ -136,7 +138,7 @@ QUICKLOAD_LOAD_MEMBER(trs80_quickload_device::quickload_cb) break; default: - err = file.read(&data, length, actual); + std::tie(err, actual) = read(file, &data, length); if (actual != length) { logerror("/CMD error reading block type %02x\n", type); diff --git a/src/mame/tvgames/spg29x.cpp b/src/mame/tvgames/spg29x.cpp index 8fe1dada319..494524c5ede 100644 --- a/src/mame/tvgames/spg29x.cpp +++ b/src/mame/tvgames/spg29x.cpp @@ -438,9 +438,9 @@ QUICKLOAD_LOAD_MEMBER(spg29x_game_state::quickload_hyper_exe) { const uint32_t length = image.length(); - std::unique_ptr<u8 []> ptr; - if (image.fread(ptr, length) != length) - return std::make_pair(image_error::UNSPECIFIED, std::string()); + auto [err, ptr, actual] = read(image.image_core_file(), length); + if (err || (actual != length)) + return std::make_pair(err ? err : std::errc::io_error, std::string()); auto &space = m_maincpu->space(AS_PROGRAM); for (uint32_t i = 0; i < length; i++) diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp index 9d79d88f170..9bbcc116297 100644 --- a/src/tools/chdman.cpp +++ b/src/tools/chdman.cpp @@ -284,8 +284,7 @@ public: length = m_maxoffset - offset; if (m_file.seek(offset, SEEK_SET)) // FIXME: better error reporting? return 0; - std::size_t actual; - m_file.read(dest, length, actual); // FIXME: check for error return + auto const [err, actual] = read(m_file, dest, length); // FIXME: check for error return return actual; } @@ -459,7 +458,7 @@ public: SEEK_SET); std::size_t count = 0; if (!err) - err = m_file->read(dest, bytesperframe, count); + std::tie(err, count) = read(*m_file, dest, bytesperframe); if (err || (count != bytesperframe)) report_error(1, "Error reading input file (%s)'", m_lastfile); } @@ -2545,9 +2544,8 @@ static void do_extract_raw(parameters_map ¶ms) report_error(1, "Error reading CHD file (%s): %s", *params.find(OPTION_INPUT)->second, err.message()); // write to the output - size_t count; - std::error_condition const writerr = output_file->write(&buffer[0], bytes_to_read, count); - if (writerr || (count != bytes_to_read)) + auto const [writerr, count] = write(*output_file, &buffer[0], bytes_to_read); + if (writerr) report_error(1, "Error writing to file; check disk space (%s)", *output_file_str->second); // advance @@ -2771,9 +2769,8 @@ static void do_extract_cd(parameters_map ¶ms) if (bufferoffs == buffer.size() || frame == actualframes - 1) { output_bin_file->seek(outputoffs, SEEK_SET); - size_t byteswritten; - std::error_condition const writerr = output_bin_file->write(&buffer[0], bufferoffs, byteswritten); - if (writerr || (byteswritten != bufferoffs)) + auto const [writerr, byteswritten] = write(*output_bin_file, &buffer[0], bufferoffs); + if (writerr) report_error(1, "Error writing frame %d to file (%s): %s\n", frame, *output_file_str->second, "Write error"); outputoffs += bufferoffs; bufferoffs = 0; @@ -3123,10 +3120,10 @@ static void do_dump_metadata(parameters_map ¶ms) // output the metadata size_t count; - filerr = output_file->write(&buffer[0], buffer.size(), count); + std::tie(filerr, count) = write(*output_file, &buffer[0], buffer.size()); if (!filerr) filerr = output_file->flush(); - if (filerr || (count != buffer.size())) + if (filerr) report_error(1, "Error writing file (%s)", *output_file_str->second); output_file.reset(); diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp index 05f105afbc2..f68f8b4eac6 100644 --- a/src/tools/imgtool/stream.cpp +++ b/src/tools/imgtool/stream.cpp @@ -21,6 +21,7 @@ #include <cstdarg> #include <cstdio> #include <cstring> +#include <tuple> @@ -70,7 +71,7 @@ public: return std::error_condition(); } - virtual std::error_condition read(void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some(void *buffer, std::size_t length, std::size_t &actual) noexcept override { actual = m_stream->read(buffer, length); if (actual < length) @@ -78,7 +79,7 @@ public: return std::error_condition(); } - virtual std::error_condition read_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition read_some_at(std::uint64_t offset, void *buffer, std::size_t length, std::size_t &actual) noexcept override { std::uint64_t const pos = m_stream->tell(); m_stream->seek(offset, SEEK_SET); @@ -111,7 +112,7 @@ public: return std::error_condition(); } - virtual std::error_condition write(void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some(void const *buffer, std::size_t length, std::size_t &actual) noexcept override { std::uint64_t const pos = m_stream->tell(); std::uint64_t size = m_stream->size(); @@ -124,7 +125,7 @@ public: return (actual == length) ? std::error_condition() : std::errc::io_error; } - virtual std::error_condition write_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override + virtual std::error_condition write_some_at(std::uint64_t offset, void const *buffer, std::size_t length, std::size_t &actual) noexcept override { std::uint64_t const pos = m_stream->tell(); std::uint64_t size = m_stream->size(); @@ -391,13 +392,14 @@ util::core_file *stream::core_file() uint32_t stream::read(void *buf, uint32_t sz) { + std::error_condition err; size_t result = 0; switch(imgtype) { case IMG_FILE: if (!file->seek(position, SEEK_SET)) - file->read(buf, sz, result); // FIXME: check error return + std::tie(err, result) = util::read(*file, buf, sz); // FIXME: check error return break; case IMG_MEM: @@ -424,6 +426,7 @@ uint32_t stream::read(void *buf, uint32_t sz) uint32_t stream::write(const void *buf, uint32_t sz) { + std::error_condition err; size_t result = 0; switch(imgtype) @@ -455,7 +458,7 @@ uint32_t stream::write(const void *buf, uint32_t sz) case IMG_FILE: if (!file->seek(position, SEEK_SET)) - file->write(buf, sz, result); // FIXME: check error return + std::tie(err, result) = util::write(*file, buf, sz); // FIXME: check error return break; default: diff --git a/src/tools/regrep.cpp b/src/tools/regrep.cpp index fd6f002ac89..21254acfe3c 100644 --- a/src/tools/regrep.cpp +++ b/src/tools/regrep.cpp @@ -224,7 +224,7 @@ static inline int get_unique_index(const summary_file *curfile, int index) int main(int argc, char *argv[]) { - uint32_t bufsize; + size_t bufsize; void *buffer; int listnum; int result; @@ -577,8 +577,7 @@ static util::core_file::ptr create_file_and_output_header(std::string_view filen /* print a header */ std::string modified(templatefile); strreplace(modified, "<!--TITLE-->", title); - std::size_t written; - file->write(modified.c_str(), modified.length(), written); // FIXME: check for errors + /*auto const [err, written] =*/ write(*file, modified.c_str(), modified.length()); // FIXME: check for errors /* return the file */ return file; @@ -594,8 +593,7 @@ static void output_footer_and_close_file(util::write_stream::ptr &&file, std::st { std::string modified(templatefile); strreplace(modified, "<!--TITLE-->", title); - std::size_t written; - file->write(modified.c_str(), modified.length(), written); // FIXME: check for errors + /*auto const [err, written] =*/ write(*file, modified.c_str(), modified.length()); // FIXME: check for errors file.reset(); } diff --git a/src/tools/split.cpp b/src/tools/split.cpp index 10078060448..5668e6e254c 100644 --- a/src/tools/split.cpp +++ b/src/tools/split.cpp @@ -12,11 +12,13 @@ #include "corestr.h" #include "hashing.h" +#include <cassert> +#include <cctype> #include <cstdio> #include <cstdlib> #include <cstring> -#include <cctype> -#include <cassert> +#include <tuple> +#include <type_traits> #define DEFAULT_SPLIT_SIZE 100 #define MAX_PARTS 1000 @@ -34,11 +36,19 @@ hash over a buffer and return a string -------------------------------------------------*/ -static void compute_hash_as_string(std::string &buffer, void *data, uint32_t length) +static void compute_hash_as_string(std::string &buffer, const void *data, size_t length) { // compute the SHA1 util::sha1_creator sha1; - sha1.append(data, length); + do + { + // deal with size_t potentially being bigger than 32 bits + auto const chunk = std::min<std::common_type_t<size_t, uint32_t> >(length, std::numeric_limits<uint32_t>::max()); + sha1.append(data, chunk); + length -= chunk; + data = reinterpret_cast<const uint8_t *>(data) + chunk; + } + while (length); const util::sha1_t sha1digest = sha1.finish(); // expand the digest to a string @@ -141,7 +151,7 @@ static int split_file(const char *filename, const char *basename, uint32_t split // read as much as we can from the file size_t length; - infile->read(splitbuffer, splitsize, length); // FIXME check error return + std::tie(filerr, length) = read(*infile, splitbuffer, splitsize); // FIXME check error return if (length == 0) break; @@ -167,8 +177,8 @@ static int split_file(const char *filename, const char *basename, uint32_t split // write the data size_t actual; - filerr = outfile->write(splitbuffer, length, actual); - if (filerr || (actual != length) || outfile->flush()) + std::tie(filerr, actual) = write(*outfile, splitbuffer, length); + if (filerr || outfile->flush()) { printf("\n"); fprintf(stderr, "Fatal error: Error writing output file (out of space?)\n"); @@ -302,7 +312,7 @@ static int join_file(const char *filename, const char *outname, int write_output // read the file's contents infilename.insert(0, basepath); - uint32_t length; + size_t length; filerr = util::core_file::load(infilename.c_str(), &splitbuffer, length); if (filerr) { @@ -328,8 +338,8 @@ static int join_file(const char *filename, const char *outname, int write_output printf(" writing..."); size_t actual; - filerr = outfile->write(splitbuffer, length, actual); - if (filerr || (actual != length) || outfile->flush()) + std::tie(filerr, actual) = write(*outfile, splitbuffer, length); + if (filerr || outfile->flush()) { printf("\n"); fprintf(stderr, "Fatal error: Error writing output file (out of space?)\n"); diff --git a/src/tools/srcclean.cpp b/src/tools/srcclean.cpp index d5429ae4823..63809b57f1e 100644 --- a/src/tools/srcclean.cpp +++ b/src/tools/srcclean.cpp @@ -2305,11 +2305,22 @@ int main(int argc, char *argv[]) ++failures; continue; } - std::size_t block; - while (remaining && !infile->read(original, (std::min)(std::uint64_t(sizeof(original)), remaining), block) && block) + while (remaining) { - remaining -= block; - cleaner->process(original, original + block); + std::size_t block((std::min)(std::uint64_t(sizeof(original)), remaining)); + std::size_t actual; + std::error_condition const readerr(infile->read_some(original, block, actual)); + if (readerr) + { + if (std::errc::interrupted != readerr) + break; + } + else if (!actual) + { + break; + } + remaining -= actual; + cleaner->process(original, original + actual); } if (remaining) { diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index a5971c28b93..9ff8c0e3c66 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -1301,8 +1301,7 @@ int disasm_file(util::random_read &file, u64 length, options &opts) base_buffer.data.resize(rounded_size + 8, 0x00); base_buffer.size = length; base_buffer.base_pc = opts.basepc; - std::size_t actual; - std::error_condition filerr = file.read_at(opts.skip, &base_buffer.data[0], length - opts.skip, actual); + auto const [filerr, actual] = read_at(file, opts.skip, &base_buffer.data[0], length - opts.skip); if(filerr) { std::fprintf(stderr, "Error reading from file '%s' (%s)\n", opts.filename, filerr.message().c_str()); return 1; |