// license:BSD-3-Clause // copyright-holders:Sandro Ronco /********************************************************************* z88.c Z88 cartridge slots emulation *********************************************************************/ #include "emu.h" #include "z88.h" /*************************************************************************** PARAMETERS ***************************************************************************/ #define CLOSE_FLAP_TIME attotime::from_msec(200) //************************************************************************** // GLOBAL VARIABLES //************************************************************************** DEFINE_DEVICE_TYPE(Z88CART_SLOT, z88cart_slot_device, "z88cart_slot", "Z88 Cartridge Slot") //************************************************************************** // Z88 Cartridge Interface //************************************************************************** //------------------------------------------------- // device_z88cart_interface - constructor //------------------------------------------------- device_z88cart_interface::device_z88cart_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "z88cart") { } //------------------------------------------------- // ~device_z88cart_interface - destructor //------------------------------------------------- device_z88cart_interface::~device_z88cart_interface() { } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // z88cart_slot_device - constructor //------------------------------------------------- z88cart_slot_device::z88cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, Z88CART_SLOT, tag, owner, clock) , device_cartrom_image_interface(mconfig, *this) , device_single_card_slot_interface(mconfig, *this) , m_out_flp_cb(*this) , m_cart(nullptr) , m_flp_timer(nullptr) { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void z88cart_slot_device::device_start() { m_cart = get_card_device(); m_flp_timer = timer_alloc(FUNC(z88cart_slot_device::close_flap), this); m_flp_timer->reset(); } //------------------------------------------------- // close_flap //------------------------------------------------- TIMER_CALLBACK_MEMBER(z88cart_slot_device::close_flap) { // close the flap m_out_flp_cb(CLEAR_LINE); } /*------------------------------------------------- call load -------------------------------------------------*/ std::pair z88cart_slot_device::call_load() { if (m_cart) { uint8_t *const cart_base = m_cart->get_cart_base(); if (!cart_base) return std::make_pair(image_error::INTERNAL, std::string()); if (!loaded_through_softlist()) { offs_t read_length = length(); fread(cart_base + (m_cart->get_cart_size() - read_length), read_length); } else { offs_t read_length = get_software_region_length("rom"); memcpy(cart_base + (m_cart->get_cart_size() - read_length), get_software_region("rom"), read_length); } } // open the flap m_out_flp_cb(ASSERT_LINE); // setup the timer to close the flap m_flp_timer->adjust(CLOSE_FLAP_TIME); return std::make_pair(std::error_condition(), std::string()); } /*------------------------------------------------- call_unload -------------------------------------------------*/ void z88cart_slot_device::call_unload() { if (m_cart) { size_t cart_size = m_cart->get_cart_size(); if (cart_size > 0) { memset(m_cart->get_cart_base(), 0xff, cart_size); } } // open the flap m_out_flp_cb(ASSERT_LINE); // setup the timer to close the flap m_flp_timer->adjust(CLOSE_FLAP_TIME); } /*------------------------------------------------- get default card software -------------------------------------------------*/ std::string z88cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const { // select the correct slot device for the ROM size if (hook.image_file()) { uint64_t size; std::error_condition err = hook.image_file()->length(size); if (!err) { if (size <= 0x8000) return std::string("32krom"); if (size <= 0x20000) return std::string("128krom"); if (size <= 0x40000) return std::string("256krom"); if (size <= 0x100000) return std::string("1024kflash"); fatalerror("%s: unsupported ROM size 0x%06x", tag(), size); } else fatalerror("%s: %s:%d %s\n", tag(), err.category().name(), err.value(), err.message()); } return software_get_default_slot("128krom"); } /*------------------------------------------------- read -------------------------------------------------*/ uint8_t z88cart_slot_device::read(offs_t offset) { if (m_cart) return m_cart->read(offset); else return 0xff; } /*------------------------------------------------- write -------------------------------------------------*/ void z88cart_slot_device::write(offs_t offset, uint8_t data) { if (m_cart) m_cart->write(offset, data); } /*------------------------------------------------- set EPROM programming voltage to slot 3 -------------------------------------------------*/ void z88cart_slot_device::vpp_w(int state) { if (m_cart) m_cart->vpp_w(state); } /*------------------------------------------------- get_cart_base -------------------------------------------------*/ uint8_t* z88cart_slot_device::get_cart_base() { if (m_cart) return m_cart->get_cart_base(); else return nullptr; }