diff options
Diffstat (limited to 'src/devices/bus/vic20/exp.cpp')
-rw-r--r-- | src/devices/bus/vic20/exp.cpp | 185 |
1 files changed, 137 insertions, 48 deletions
diff --git a/src/devices/bus/vic20/exp.cpp b/src/devices/bus/vic20/exp.cpp index 1b634cd0321..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> + //************************************************************************** @@ -28,14 +32,9 @@ 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_slot_card_interface(mconfig, device), - m_blk1(*this, "blk1"), - m_blk2(*this, "blk2"), - m_blk3(*this, "blk3"), - m_blk5(*this, "blk5"), - m_nvram(*this, "nvram") + : device_interface(device, "vic20exp") + , m_slot(dynamic_cast<vic20_expansion_slot_device *>(device.owner())) { - m_slot = dynamic_cast<vic20_expansion_slot_device *>(device.owner()); } @@ -59,8 +58,8 @@ 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_slot_interface(mconfig, *this), - device_image_interface(mconfig, *this), + device_single_card_slot_interface<device_vic20_expansion_card_interface>(mconfig, *this), + device_cartrom_image_interface(mconfig, *this), m_write_irq(*this), m_write_nmi(*this), m_write_res(*this), @@ -70,32 +69,12 @@ vic20_expansion_slot_device::vic20_expansion_slot_device(const machine_config &m //------------------------------------------------- -// device_validity_check - -//------------------------------------------------- - -void vic20_expansion_slot_device::device_validity_check(validity_checker &valid) const -{ - device_t *const carddev = get_card_device(); - if (carddev && !dynamic_cast<device_vic20_expansion_card_interface *>(carddev)) - osd_printf_error("Card device %s (%s) does not implement device_vic20_expansion_card_interface\n", carddev->tag(), carddev->name()); -} - - -//------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void vic20_expansion_slot_device::device_start() { - device_t *const carddev = get_card_device(); - m_card = dynamic_cast<device_vic20_expansion_card_interface *>(carddev); - if (carddev && !m_card) - fatalerror("Card device %s (%s) does not implement device_vic20_expansion_card_interface\n", carddev->tag(), carddev->name()); - - // resolve callbacks - m_write_irq.resolve_safe(); - m_write_nmi.resolve_safe(); - m_write_res.resolve_safe(); + m_card = get_card_device(); } @@ -112,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 { @@ -152,7 +241,7 @@ image_init_result vic20_expansion_slot_device::call_load() } } - return image_init_result::PASS; + return std::make_pair(err, std::string()); } |