summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/odyssey2/slot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/odyssey2/slot.cpp')
-rw-r--r--src/devices/bus/odyssey2/slot.cpp210
1 files changed, 125 insertions, 85 deletions
diff --git a/src/devices/bus/odyssey2/slot.cpp b/src/devices/bus/odyssey2/slot.cpp
index 574b93ec01b..dba3fa09ff3 100644
--- a/src/devices/bus/odyssey2/slot.cpp
+++ b/src/devices/bus/odyssey2/slot.cpp
@@ -5,12 +5,14 @@
Magnavox Odyssey 2 cart emulation
(through slot devices)
- ***********************************************************************************************************/
-
+***********************************************************************************************************/
#include "emu.h"
#include "slot.h"
+#include <tuple>
+
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -27,8 +29,9 @@ DEFINE_DEVICE_TYPE(O2_CART_SLOT, o2_cart_slot_device, "o2_cart_slot", "Odyssey 2
device_o2_cart_interface::device_o2_cart_interface(const machine_config &mconfig, device_t &device)
: device_interface(device, "odyssey2cart")
- , m_rom(nullptr)
, m_rom_size(0)
+ , m_exrom_size(0)
+ , m_voice_size(0)
{
}
@@ -41,29 +44,6 @@ device_o2_cart_interface::~device_o2_cart_interface()
{
}
-//-------------------------------------------------
-// rom_alloc - alloc the space for the cart
-//-------------------------------------------------
-
-void device_o2_cart_interface::rom_alloc(uint32_t size, const char *tag)
-{
- if (m_rom == nullptr)
- {
- m_rom = device().machine().memory().region_alloc(std::string(tag).append(O2SLOT_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base();
- m_rom_size = size;
- }
-}
-
-
-//-------------------------------------------------
-// ram_alloc - alloc the space for the ram
-//-------------------------------------------------
-
-void device_o2_cart_interface::ram_alloc(uint32_t size)
-{
- m_ram.resize(size);
-}
-
//**************************************************************************
// LIVE DEVICE
@@ -72,12 +52,14 @@ void device_o2_cart_interface::ram_alloc(uint32_t size)
//-------------------------------------------------
// o2_cart_slot_device - constructor
//-------------------------------------------------
-o2_cart_slot_device::o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+
+o2_cart_slot_device::o2_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, O2_CART_SLOT, tag, owner, clock)
- , device_image_interface(mconfig, *this)
+ , device_cartrom_image_interface(mconfig, *this)
, device_single_card_slot_interface<device_o2_cart_interface>(mconfig, *this)
, m_type(O2_STD)
, m_cart(nullptr)
+ , m_b(0)
{
}
@@ -114,19 +96,23 @@ struct o2_slot
static const o2_slot slot_list[] =
{
{ O2_STD, "o2_rom" },
- { O2_ROM12, "o2_rom12" },
- { O2_ROM16, "o2_rom16" },
+ { O2_4IN1, "o2_4in1" },
+ { O2_RALLY, "o2_rally" },
+ { O2_KTAA, "o2_ktaa" },
{ O2_CHESS, "o2_chess" },
+ { O2_HOMECOMP, "o2_homecomp" },
+ { O2_TEST, "o2_test" },
{ O2_VOICE, "o2_voice" }
};
static int o2_get_pcb_id(const char *slot)
{
- for (auto & elem : slot_list)
- {
- if (!core_stricmp(elem.slot_option, slot))
- return elem.pcb_id;
- }
+ if (slot)
+ for (auto & elem : slot_list)
+ {
+ if (!strcmp(elem.slot_option, slot))
+ return elem.pcb_id;
+ }
return 0;
}
@@ -145,64 +131,75 @@ static const char *o2_get_slot(int type)
/*-------------------------------------------------
call load
- -------------------------------------------------*/
+-------------------------------------------------*/
-image_init_result o2_cart_slot_device::call_load()
+std::pair<std::error_condition, std::string> o2_cart_slot_device::call_load()
{
+ std::error_condition err;
+
if (m_cart)
{
- uint32_t size = !loaded_through_softlist() ? length() : get_software_region_length("rom");
- m_cart->rom_alloc(size, tag());
-
- if (!loaded_through_softlist())
- fread(m_cart->get_rom_base(), size);
- else
- memcpy(m_cart->get_rom_base(), get_software_region("rom"), size);
-
- if (!loaded_through_softlist())
+ if (loaded_through_softlist())
{
- m_type = O2_STD;
- if (size == 12288)
- m_type = O2_ROM12;
- if (size == 16384)
- m_type = O2_ROM16;
+ load_software_region("rom", m_cart->m_rom);
+ load_software_region("exrom", m_cart->m_exrom);
+ load_software_region("voice", m_cart->m_voice);
+ m_cart->m_rom_size = get_software_region_length("rom");
+ m_cart->m_exrom_size = get_software_region_length("exrom");
+ m_cart->m_voice_size = get_software_region_length("voice");
+
+ m_type = o2_get_pcb_id(get_feature("slot"));
+
+ // Videopac+ determines whether the screen should have a border, with a gate connected
+ // to the cartridge B pin. This way, old Videopac games can still run in full screen.
+ const char *b_pin = get_feature("b_pin");
+ m_b = b_pin && strtoul(b_pin, nullptr, 0) ? 1 : 0;
}
else
{
- const char *pcb_name = get_feature("slot");
- if (pcb_name)
- m_type = o2_get_pcb_id(pcb_name);
+ u32 const size = length();
+ 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;
+ }
}
- //printf("Type: %s\n", o2_get_slot(m_type));
-
- return image_init_result::PASS;
+ if (m_cart->get_rom_size() > 0)
+ m_cart->cart_init();
+ else if (!err)
+ err = image_error::UNSPECIFIED;
+ }
+ else
+ {
+ err = image_error::UNSPECIFIED;
}
- return image_init_result::PASS;
+ return std::make_pair(err, std::string());
}
/*-------------------------------------------------
get default card software
- -------------------------------------------------*/
+-------------------------------------------------*/
std::string o2_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
if (hook.image_file())
{
- const char *slot_string;
- uint32_t size = hook.image_file()->size();
- int type = O2_STD;
-
- if (size == 12288)
- type = O2_ROM12;
- if (size == 16384)
- type = O2_ROM16;
-
- slot_string = o2_get_slot(type);
-
- //printf("type: %s\n", slot_string);
+ uint64_t size;
+ hook.image_file()->length(size); // FIXME: check error return
+ int const type = (size == 0x4000) ? O2_RALLY : O2_STD;
+ char const *const slot_string = o2_get_slot(type);
return std::string(slot_string);
}
@@ -210,46 +207,89 @@ std::string o2_cart_slot_device::get_default_card_software(get_default_card_soft
return software_get_default_slot("o2_rom");
}
+
/*-------------------------------------------------
read_rom**
- -------------------------------------------------*/
+-------------------------------------------------*/
-READ8_MEMBER(o2_cart_slot_device::read_rom04)
+u8 o2_cart_slot_device::read_rom04(offs_t offset)
{
if (m_cart)
- return m_cart->read_rom04(space, offset);
+ return m_cart->read_rom04(offset);
else
return 0xff;
}
-READ8_MEMBER(o2_cart_slot_device::read_rom0c)
+u8 o2_cart_slot_device::read_rom0c(offs_t offset)
{
if (m_cart)
- return m_cart->read_rom0c(space, offset);
+ return m_cart->read_rom0c(offset);
else
return 0xff;
}
+
/*-------------------------------------------------
- io_write
- -------------------------------------------------*/
+ io
+-------------------------------------------------*/
+
+void o2_cart_slot_device::io_write(offs_t offset, u8 data)
+{
+ if (m_cart)
+ m_cart->io_write(offset, data);
+}
+
+u8 o2_cart_slot_device::io_read(offs_t offset)
+{
+ return (m_cart) ? m_cart->io_read(offset) : 0xff;
+}
+
+void o2_cart_slot_device::bus_write(u8 data)
+{
+ if (m_cart)
+ m_cart->bus_write(data);
+}
+
+u8 o2_cart_slot_device::bus_read()
+{
+ return (m_cart) ? m_cart->bus_read() : 0xff;
+}
+
+int o2_cart_slot_device::t0_read()
+{
+ return (m_cart) ? m_cart->t0_read() : 0;
+}
-WRITE8_MEMBER(o2_cart_slot_device::io_write)
+int o2_cart_slot_device::b_read()
{
if (m_cart)
- m_cart->io_write(space, offset, data);
+ {
+ int b = m_cart->b_read();
+ const bool override = b != -1;
+ return override ? b : m_b;
+ }
+ else
+ return 0;
}
#include "bus/odyssey2/rom.h"
+#include "bus/odyssey2/4in1.h"
+#include "bus/odyssey2/rally.h"
+#include "bus/odyssey2/ktaa.h"
#include "bus/odyssey2/chess.h"
+#include "bus/odyssey2/homecomp.h"
+#include "bus/odyssey2/test.h"
#include "bus/odyssey2/voice.h"
void o2_cart(device_slot_interface &device)
{
- device.option_add_internal("o2_rom", O2_ROM_STD);
- device.option_add_internal("o2_rom12", O2_ROM_12K);
- device.option_add_internal("o2_rom16", O2_ROM_16K);
- device.option_add_internal("o2_chess", O2_ROM_CHESS);
- device.option_add_internal("o2_voice", O2_ROM_VOICE);
+ device.option_add_internal("o2_rom", O2_ROM_STD);
+ device.option_add_internal("o2_4in1", O2_ROM_4IN1);
+ device.option_add_internal("o2_rally", O2_ROM_RALLY);
+ device.option_add_internal("o2_ktaa", O2_ROM_KTAA);
+ device.option_add_internal("o2_chess", O2_ROM_CHESS);
+ device.option_add_internal("o2_homecomp", O2_ROM_HOMECOMP);
+ device.option_add_internal("o2_test", O2_ROM_TEST);
+ device.option_add_internal("o2_voice", O2_ROM_VOICE);
}