diff options
Diffstat (limited to 'src/devices/bus/vic20/exp.cpp')
-rw-r--r-- | src/devices/bus/vic20/exp.cpp | 159 |
1 files changed, 134 insertions, 25 deletions
diff --git a/src/devices/bus/vic20/exp.cpp b/src/devices/bus/vic20/exp.cpp index c7f0120b25f..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> + //************************************************************************** @@ -29,8 +33,8 @@ DEFINE_DEVICE_TYPE(VIC20_EXPANSION_SLOT, vic20_expansion_slot_device, "vic20_exp device_vic20_expansion_card_interface::device_vic20_expansion_card_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "vic20exp") + , m_slot(dynamic_cast<vic20_expansion_slot_device *>(device.owner())) { - m_slot = dynamic_cast<vic20_expansion_slot_device *>(device.owner()); } @@ -55,7 +59,7 @@ device_vic20_expansion_card_interface::~device_vic20_expansion_card_interface() vic20_expansion_slot_device::vic20_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, VIC20_EXPANSION_SLOT, tag, owner, clock), device_single_card_slot_interface<device_vic20_expansion_card_interface>(mconfig, *this), - device_image_interface(mconfig, *this), + device_cartrom_image_interface(mconfig, *this), m_write_irq(*this), m_write_nmi(*this), m_write_res(*this), @@ -71,11 +75,6 @@ vic20_expansion_slot_device::vic20_expansion_slot_device(const machine_config &m void vic20_expansion_slot_device::device_start() { m_card = get_card_device(); - - // resolve callbacks - m_write_irq.resolve_safe(); - m_write_nmi.resolve_safe(); - m_write_res.resolve_safe(); } @@ -92,36 +91,146 @@ void vic20_expansion_slot_device::device_reset() // call_load - //------------------------------------------------- -image_init_result vic20_expansion_slot_device::call_load() +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 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 image_init_result::FAIL; + 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 { @@ -132,7 +241,7 @@ image_init_result vic20_expansion_slot_device::call_load() } } - return image_init_result::PASS; + return std::make_pair(err, std::string()); } |