diff --git a/hash/sega_beena_cart.xml b/hash/sega_beena_cart.xml index e1641611ec100..fc6986dc96902 100644 --- a/hash/sega_beena_cart.xml +++ b/hash/sega_beena_cart.xml @@ -138,6 +138,48 @@ license:CC0-1.0 + + Go! Go! Advance Drive: 6-tsu no Machine ni Chousen da! (Rev. S-100004-1100) + 2005 + Sega Toys + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Go! Go! Advance Drive: 6-tsu no Machine ni Chousen da! 2005 @@ -180,7 +222,7 @@ license:CC0-1.0 - + Soreike! Anpanman Card de Tanoshiku ABC 2006 Sega Toys @@ -189,35 +231,392 @@ license:CC0-1.0 - - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -639,6 +1038,406 @@ license:CC0-1.0 + + Densha Daishuugou! Card de Asobou + 2006 + Sega Toys + Missing card 16 artwork + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Doraemon Tanoshiku O-Keiko Hiragana Katakana 2005 diff --git a/hash/tvochken.xml b/hash/tvochken.xml index 6651e460d8b0f..208dc6223bad6 100644 --- a/hash/tvochken.xml +++ b/hash/tvochken.xml @@ -10,350 +10,350 @@ license:CC0-1.0 2005 Sega Toys - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/mame/layout/beena.lay b/src/mame/layout/beena.lay index a525446f04b7b..30663849b16b6 100644 --- a/src/mame/layout/beena.lay +++ b/src/mame/layout/beena.lay @@ -3,6 +3,8 @@ license:CC0-1.0 --> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/sega/tvochken_card.cpp b/src/mame/sega/9h0-0008_card.cpp similarity index 76% rename from src/mame/sega/tvochken_card.cpp rename to src/mame/sega/9h0-0008_card.cpp index 4895055ec9b8e..2800c89add1c5 100644 --- a/src/mame/sega/tvochken_card.cpp +++ b/src/mame/sega/9h0-0008_card.cpp @@ -2,9 +2,9 @@ // copyright-holders:Vas Crabb /****************************************************************************** - tvochken_card.cpp + 9h0-0008_card.cpp - Sega TV Ocha-ken barcode card loader + Sega Toys 9H0-0008 barcode card loader TODO: * Decode barcode from the scan so it doesn't need to be in a software @@ -13,7 +13,8 @@ *******************************************************************************/ #include "emu.h" -#include "tvochken_card.h" + +#include "9h0-0008_card.h" #include "rendutil.h" #include "softlist_dev.h" @@ -24,27 +25,33 @@ #include -DEFINE_DEVICE_TYPE(TVOCHKEN_CARD, tvochken_card_device, "tvochken_card", "Sega TV Ocha-Ken barcode card") +DEFINE_DEVICE_TYPE(SEGA_9H0_0008_CARD, sega_9h0_0008_card_device, "sega_9h0_0008_card", "Sega Toys 9H0-0008 barcode card") -tvochken_card_device::tvochken_card_device( +sega_9h0_0008_card_device::sega_9h0_0008_card_device( machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) - : device_t(mconfig, TVOCHKEN_CARD, tag, owner, clock) + : sega_9h0_0008_card_device(mconfig, SEGA_9H0_0008_CARD, tag, owner, clock) +{ +} + + +sega_9h0_0008_card_device::sega_9h0_0008_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : sega_9h0_0008_iox_slot_device(mconfig, type, tag, owner, clock) , device_image_interface(mconfig, *this) , m_barcode(0) { } -tvochken_card_device::~tvochken_card_device() +sega_9h0_0008_card_device::~sega_9h0_0008_card_device() { } -std::pair tvochken_card_device::call_load() +std::pair sega_9h0_0008_card_device::call_load() { memory_region *cardrgn; if (loaded_through_softlist()) @@ -106,7 +113,7 @@ std::pair tvochken_card_device::call_load() // TODO: support reading barcode from image m_barcode = 0; osd_printf_warning( - "%s: TV Ocha-Ken barcodes are only supported for software list items.\n", + "%s: Sega Toys 9H0-0008 barcodes are only supported for software list items.\n", tag()); } @@ -137,7 +144,7 @@ std::pair tvochken_card_device::call_load() } -void tvochken_card_device::call_unload() +void sega_9h0_0008_card_device::call_unload() { memory_region *const cardrgn = memregion("card"); if (cardrgn) @@ -147,11 +154,12 @@ void tvochken_card_device::call_unload() } -void tvochken_card_device::device_start() +void sega_9h0_0008_card_device::device_start() { } -software_list_loader const &tvochken_card_device::get_software_list_loader() const + +software_list_loader const &sega_9h0_0008_card_device::get_software_list_loader() const { return rom_software_list_loader::instance(); } diff --git a/src/mame/sega/tvochken_card.h b/src/mame/sega/9h0-0008_card.h similarity index 56% rename from src/mame/sega/tvochken_card.h rename to src/mame/sega/9h0-0008_card.h index 67d548e28f02f..2c459e6a05618 100644 --- a/src/mame/sega/tvochken_card.h +++ b/src/mame/sega/9h0-0008_card.h @@ -2,13 +2,13 @@ // copyright-holders:Vas Crabb /****************************************************************************** - tvochken_card.h + 9h0-0008_card.h - Sega TV Ocha-ken barcode card loader + Sega Toys 9H0-0008 barcode card loader *******************************************************************************/ -#ifndef MAME_SEGA_TVOCHKEN_CARD_H -#define MAME_SEGA_TVOCHKEN_CARD_H +#ifndef MAME_SEGA_9H0_0008_CARD_H +#define MAME_SEGA_9H0_0008_CARD_H #pragma once @@ -16,12 +16,23 @@ #include #include +#include "9h0-0008_iox.h" -class tvochken_card_device : public device_t, public device_image_interface +class sega_9h0_0008_card_device : public sega_9h0_0008_iox_slot_device, public device_image_interface { public: - tvochken_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); - virtual ~tvochken_card_device(); + // construction/destruction + template + sega_9h0_0008_card_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt, bool const fixed) + : sega_9h0_0008_card_device(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + sega_9h0_0008_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + virtual ~sega_9h0_0008_card_device(); // device_image_interface implementation virtual std::pair call_load() override ATTR_COLD; @@ -30,14 +41,16 @@ class tvochken_card_device : public device_t, public device_image_interface virtual bool is_writeable() const noexcept override { return false; } virtual bool is_creatable() const noexcept override { return false; } virtual bool is_reset_on_load() const noexcept override { return false; } - virtual char const *image_interface() const noexcept override { return "tvochken_card"; } + virtual char const *image_interface() const noexcept override { return "sega_9h0_0008_card"; } virtual char const *file_extensions() const noexcept override { return "png,jpg,bmp"; } // loose media not supported yet virtual char const *image_type_name() const noexcept override { return "card"; } virtual char const *image_brief_type_name() const noexcept override { return "crd"; } - u16 barcode() const noexcept { return m_barcode; } + virtual u16 data() const noexcept override { return m_barcode; } protected: + sega_9h0_0008_card_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); + // device_t implementation virtual void device_start() override ATTR_COLD; @@ -49,6 +62,6 @@ class tvochken_card_device : public device_t, public device_image_interface }; -DECLARE_DEVICE_TYPE(TVOCHKEN_CARD, tvochken_card_device) +DECLARE_DEVICE_TYPE(SEGA_9H0_0008_CARD, sega_9h0_0008_card_device) -#endif // MAME_SEGA_TVOCHKEN_CARD_H +#endif // MAME_SEGA_9H0_0008_CARD_H diff --git a/src/mame/sega/9h0-0008_card_reader.cpp b/src/mame/sega/9h0-0008_card_reader.cpp new file mode 100644 index 0000000000000..3beee5be7f4bd --- /dev/null +++ b/src/mame/sega/9h0-0008_card_reader.cpp @@ -0,0 +1,150 @@ +// license:BSD-3-Clause +// copyright-holders:QUFB +/****************************************************************************** + + 9h0-0008_card_reader.cpp + + Sega Toys 9H0-0008 barcode card reader + +*******************************************************************************/ + +#include "emu.h" + +#include "9h0-0008_card_reader.h" +#include "9h0-0008_iox.h" + +#define VERBOSE (0) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(BEENA_CARD_READER, sega_beena_card_reader_device, "sega_beena_card_reader", "Sega Beena Card Reader") +DEFINE_DEVICE_TYPE(BEENA_CARD_READER_2061, sega_beena_card_reader_2061_device, "sega_beena_card_reader_2061", "Sega Beena Card Reader RD2061") +DEFINE_DEVICE_TYPE(TVOCHKEN_CARD_READER, sega_tvochken_card_reader_device, "sega_tvochken_card_reader", "Sega TV Ocha-ken Card Reader") + + +static INPUT_PORTS_START( sega_beena_card_reader ) + PORT_START("IO") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_PLAYER(1) PORT_NAME("Scan Card") PORT_WRITE_LINE_MEMBER(FUNC(sega_beena_card_reader_device::scan_card)) +INPUT_PORTS_END + +ioport_constructor sega_beena_card_reader_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( sega_beena_card_reader ); +} + + +sega_beena_card_reader_device::sega_beena_card_reader_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sega_beena_card_reader_device(mconfig, BEENA_CARD_READER, tag, owner, clock, true, 12, 32) +{ +} + +sega_beena_card_reader_device::sega_beena_card_reader_device( + const machine_config &mconfig, + device_type type, + const char *tag, + device_t *owner, + u32 clock, + bool is_sync_cycle, + u8 num_bits, + u8 num_hold) + : device_t(mconfig, type, tag, owner, clock) + , device_sega_9h0_0008_iox_slot_interface(mconfig, *this) + , m_io(*this, "IO") + , m_is_sync_cycle(is_sync_cycle) + , m_num_bits(num_bits) + , m_num_hold(num_hold) +{ +} + +void sega_beena_card_reader_device::device_start() +{ + save_item(NAME(m_card_data)); + save_item(NAME(m_card_data_i)); + save_item(NAME(m_card_hold_i)); + save_item(NAME(m_card_state)); + save_item(NAME(m_card_status)); + + save_item(NAME(m_is_sync_cycle)); + save_item(NAME(m_num_bits)); + save_item(NAME(m_num_hold)); +} + +void sega_beena_card_reader_device::device_reset() +{ + m_card_data = 0; + m_card_data_i = 0; + m_card_hold_i = 0; + m_card_state = IDLE; + m_card_status = 0; +} + +u32 sega_beena_card_reader_device::read(bool is_enabled) +{ + if (machine().side_effects_disabled() || !is_enabled) { + return 0x18; + } + + if (m_card_state == START_WRITE_DATA) { + LOG("start write card: hold %d\n", m_card_hold_i); + m_card_hold_i--; + if (m_card_hold_i == 0) { + m_card_hold_i = m_num_hold; + m_card_data_i = 0; + m_card_status = 0; + m_card_state = WRITE_DATA; + } + + return 0x18 | (1 << 5); + } + + if (m_card_state == WRITE_DATA) { + u8 data_bit = (m_card_data >> (m_num_bits - 1 - m_card_data_i)) & 1; + LOG("write card: bit %d -> %d (sync %d)\n", m_card_data_i, data_bit, m_card_status); + + m_card_hold_i--; + if (m_card_hold_i == 0) { + m_card_hold_i = m_num_hold; + m_card_status ^= 1; + + // If barcodes stripes have spacing between them, each read bit takes 2 sync bits to be parsed. + if (m_is_sync_cycle) { + if (m_card_status == 0) { + m_card_data_i++; + } + } else { + m_card_data_i++; + } + + if (m_card_data_i == m_num_bits) { + m_card_data_i = 0; + m_card_status = 0; + m_card_state = IDLE; + } + } + + return 0x18 | (m_card_status << 6) | (data_bit << 5); + } + + return 0x18; +} + +void sega_beena_card_reader_device::scan_card(int state) +{ + if (state && (m_card_state == IDLE)) { + m_card_data = m_port->data(); + m_card_hold_i = 10; + m_card_state = START_WRITE_DATA; + LOG("scanning card: %04x\n", m_card_data); + } +} + + +sega_beena_card_reader_2061_device::sega_beena_card_reader_2061_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sega_beena_card_reader_device(mconfig, BEENA_CARD_READER_2061, tag, owner, clock, true, 12, 5) +{ +} + + +sega_tvochken_card_reader_device::sega_tvochken_card_reader_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sega_beena_card_reader_device(mconfig, TVOCHKEN_CARD_READER, tag, owner, clock, false, 16, 32) +{ +} diff --git a/src/mame/sega/9h0-0008_card_reader.h b/src/mame/sega/9h0-0008_card_reader.h new file mode 100644 index 0000000000000..1d5c0225ae25f --- /dev/null +++ b/src/mame/sega/9h0-0008_card_reader.h @@ -0,0 +1,91 @@ +// license:BSD-3-Clause +// copyright-holders:QUFB +/****************************************************************************** + + 9h0-0008_card_reader.h + + Sega Toys 9H0-0008 barcode card reader + +*******************************************************************************/ +#ifndef MAME_SEGA_9H0_0008_CARD_READER_H +#define MAME_SEGA_9H0_0008_CARD_READER_H + +#pragma once + +#include "softlist_dev.h" + +#include "9h0-0008_iox.h" + + /* + * Each card encodes a number N as `(N << 2) | 0xc01` in exactly 12 bits. + * Stripes for each bit have spacing between them. + * + * Bundled with denshaca, where barcode values are compared against a table at ROM address 0x80051240. + */ +class sega_beena_card_reader_device : public device_t, public device_sega_9h0_0008_iox_slot_interface +{ +public: + sega_beena_card_reader_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + virtual u32 read(bool is_ready) override; + void scan_card(int state); + +protected: + enum card_state : u8 + { + IDLE = 0, + START_WRITE_DATA, + WRITE_DATA, + }; + + sega_beena_card_reader_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool is_sync_cycle, u8 num_bits, u8 num_hold); + + // device_t implementation + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + required_ioport m_io; + + u16 m_card_data; + u8 m_card_data_i; + u8 m_card_state; + u8 m_card_hold_i; + u8 m_card_status; + + bool m_is_sync_cycle; + u8 m_num_bits; + u8 m_num_hold; +}; + + + /* + * Bundled with anpaabc, where barcode values are compared against a table at ROM address 0x8039e97c. + */ +class sega_beena_card_reader_2061_device : public sega_beena_card_reader_device +{ +public: + sega_beena_card_reader_2061_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); +}; + + + /* + * Each card encodes a number in exactly 16 bits. Valid barcodes always have the last bit set. + * Stripes for each bit are contiguous. + * + * Values are compared against an in-memory table for tvochken at 0xc00d0f9c, taken from ROM address 0xa00579b4. + */ +class sega_tvochken_card_reader_device : public sega_beena_card_reader_device +{ +public: + sega_tvochken_card_reader_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); +}; + + +DECLARE_DEVICE_TYPE(BEENA_CARD_READER, sega_beena_card_reader_device) +DECLARE_DEVICE_TYPE(BEENA_CARD_READER_2061, sega_beena_card_reader_2061_device) +DECLARE_DEVICE_TYPE(TVOCHKEN_CARD_READER, sega_tvochken_card_reader_device) + +#endif // MAME_SEGA_9H0_0008_CARD_READER_H diff --git a/src/mame/sega/9h0-0008_iox.cpp b/src/mame/sega/9h0-0008_iox.cpp new file mode 100644 index 0000000000000..9d2147cc726eb --- /dev/null +++ b/src/mame/sega/9h0-0008_iox.cpp @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:QUFB +/****************************************************************************** + + 9h0-0008_iox.cpp + + Sega Toys 9H0-0008 I/O expansion slot + +*******************************************************************************/ + +#include "emu.h" + +#include "9h0-0008_iox.h" + +#include "rendutil.h" +#include "softlist_dev.h" + + +device_sega_9h0_0008_iox_slot_interface::device_sega_9h0_0008_iox_slot_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "sega_9h0_0008_iox") +{ + m_port = dynamic_cast(device.owner()); +} + +device_sega_9h0_0008_iox_slot_interface::~device_sega_9h0_0008_iox_slot_interface() +{ +} + + +DEFINE_DEVICE_TYPE(SEGA_9H0_0008_IOX_SLOT, sega_9h0_0008_iox_slot_device, "sega_9h0_0008_iox_slot", "Sega Toys 9H0-0008 I/O expansion slot") + + +sega_9h0_0008_iox_slot_device::sega_9h0_0008_iox_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : sega_9h0_0008_iox_slot_device(mconfig, SEGA_9H0_0008_IOX_SLOT, tag, owner, clock) +{ +} + +sega_9h0_0008_iox_slot_device::sega_9h0_0008_iox_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_single_card_slot_interface(mconfig, *this) + , m_device(nullptr) +{ +} + +sega_9h0_0008_iox_slot_device::~sega_9h0_0008_iox_slot_device() +{ +} + +void sega_9h0_0008_iox_slot_device::device_start() +{ + m_device = get_card_device(); +} diff --git a/src/mame/sega/9h0-0008_iox.h b/src/mame/sega/9h0-0008_iox.h new file mode 100644 index 0000000000000..212ade14a2009 --- /dev/null +++ b/src/mame/sega/9h0-0008_iox.h @@ -0,0 +1,66 @@ +// license:BSD-3-Clause +// copyright-holders:QUFB +/****************************************************************************** + + 9h0-0008_iox.h + + Sega Toys 9H0-0008 I/O expansion slot + +*******************************************************************************/ + +#ifndef MAME_SEGA_9H0_0008_IOX_H +#define MAME_SEGA_9H0_0008_IOX_H + +#pragma once + +class device_sega_9h0_0008_iox_slot_interface; + +class sega_9h0_0008_iox_slot_device : public device_t, public device_single_card_slot_interface +{ +public: + // construction/destruction + template + sega_9h0_0008_iox_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt, bool const fixed) + : sega_9h0_0008_iox_slot_device(mconfig, tag, owner, 0) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(fixed); + } + sega_9h0_0008_iox_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + virtual ~sega_9h0_0008_iox_slot_device(); + + virtual u16 data() const noexcept { return 0; } + +protected: + sega_9h0_0008_iox_slot_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); + + // device_t implementation + virtual void device_start() override ATTR_COLD; + +private: + device_sega_9h0_0008_iox_slot_interface *m_device; +}; + + +// class representing interface-specific live I/O expansion peripheral +class device_sega_9h0_0008_iox_slot_interface : public device_interface +{ +public: + // construction/destruction + virtual ~device_sega_9h0_0008_iox_slot_interface(); + + virtual u32 read(bool is_enabled) { return 0; } + +protected: + device_sega_9h0_0008_iox_slot_interface(const machine_config &mconfig, device_t &device); + + sega_9h0_0008_iox_slot_device *m_port; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(SEGA_9H0_0008_IOX_SLOT, sega_9h0_0008_iox_slot_device) + +#endif // MAME_SEGA_9H0_0008_IOX_H diff --git a/src/mame/sega/sega_beena.cpp b/src/mame/sega/sega_beena.cpp index e80b578014c21..e676210233491 100644 --- a/src/mame/sega/sega_beena.cpp +++ b/src/mame/sega/sega_beena.cpp @@ -135,7 +135,8 @@ #include "emu.h" -#include "tvochken_card.h" +#include "9h0-0008_card.h" +#include "9h0-0008_card_reader.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" @@ -853,7 +854,7 @@ void sega_9h0_0008_state::memcache_parse_data_bit(uint32_t &status) uint32_t sega_9h0_0008_state::io_expansion_r() { - return 0; // TODO + return 0; // FIXME: Confirm with hardware tests. } uint32_t sega_9h0_0008_state::io_memcache_r() @@ -1775,6 +1776,7 @@ class sega_beena_state : public sega_9h0_0008_cart_state public: sega_beena_state(const machine_config &mconfig, device_type type, const char *tag) : sega_9h0_0008_cart_state(mconfig, type, tag) + , m_card(*this, "card") , m_io_page_config(*this, "PAGE_CONFIG") , m_io_page(*this, "PAGE") , m_io_pad_left(*this, "PAD_LEFT") @@ -1789,11 +1791,16 @@ class sega_beena_state : public sega_9h0_0008_cart_state virtual DECLARE_CROSSHAIR_MAPPER_MEMBER(pen_y_mapper); +protected: + virtual void video_start() override ATTR_COLD; + private: virtual void install_game_rom() override; + virtual uint32_t io_expansion_r() override; virtual void update_crosshair(screen_device &screen) override; virtual void update_sensors(offs_t offset) override; + required_device m_card; required_ioport m_io_page_config; required_ioport m_io_page; required_ioport m_io_pad_left; @@ -1804,6 +1811,12 @@ class sega_beena_state : public sega_9h0_0008_cart_state required_ioport m_io_pen_y; }; +static void beena_iox_devices(device_slot_interface &device) +{ + device.option_add("rd", BEENA_CARD_READER); + device.option_add("rd2061", BEENA_CARD_READER_2061); +} + void sega_beena_state::sega_beena(machine_config &config) { sega_9h0_0008(config); @@ -1816,9 +1829,21 @@ void sega_beena_state::sega_beena(machine_config &config) SOFTWARE_LIST(config, "cart_list").set_original("sega_beena_cart"); + SEGA_9H0_0008_CARD(config, m_card, beena_iox_devices, nullptr, false); + + SOFTWARE_LIST(config, "card_list").set_original("sega_beena_cart"); + config.set_default_layout(layout_beena); } +void sega_beena_state::video_start() +{ + const int view = m_card->get_card_device() ? 1 : 0; + machine().render().first_target()->set_view(view); + + sega_9h0_0008_state::video_start(); +} + void sega_beena_state::install_game_rom() { if (m_cart->exists()) { @@ -1849,6 +1874,23 @@ void sega_beena_state::install_game_rom() } } +/** + * Combines: + * - Scanned card barcode + * - bit 5: current data bit to read from 16-bit value; + * - bit 6: status for advancing data bit position; + * - Peripheral status + * - bit 7 == 0: peripheral is ready; + */ +uint32_t sega_beena_state::io_expansion_r() +{ + if (m_card->get_card_device()) { + return m_card->get_card_device()->read(true); + } + + return 0; // FIXME: Confirm with hardware tests. +} + void sega_beena_state::update_crosshair(screen_device &screen) { // Show crosshair on single screen with storyware pen target @@ -1999,68 +2041,31 @@ class tvochken_state : public sega_9h0_0008_state virtual uint32_t io_expansion_r() override; - void scan_card(int state); - private: - enum card_state : uint8_t - { - IDLE = 0, - START_WRITE_DATA, - WRITE_DATA, - }; - - virtual void machine_start() override ATTR_COLD; - virtual void machine_reset() override ATTR_COLD; - virtual void install_game_rom() override; - required_device m_card; - + required_device m_card; required_ioport m_io_buttons; - uint8_t m_card_previous_input; - - uint16_t m_card_data; - uint8_t m_card_data_i; - uint8_t m_card_state; - uint8_t m_card_hold_i; - uint8_t m_card_status; }; +static void tvochken_iox_devices(device_slot_interface &device) +{ + device.option_add("rd1831", TVOCHKEN_CARD_READER); + device.set_default_option("rd1831"); + device.set_fixed(true); +} + void tvochken_state::tvochken(machine_config &config) { sega_9h0_0008(config); - TVOCHKEN_CARD(config, m_card); + SEGA_9H0_0008_CARD(config, m_card, tvochken_iox_devices, nullptr, false); SOFTWARE_LIST(config, "card_list").set_original("tvochken"); config.set_default_layout(layout_tvochken); } -void tvochken_state::machine_start() -{ - sega_9h0_0008_state::machine_start(); - - save_item(NAME(m_card_data)); - save_item(NAME(m_card_data_i)); - save_item(NAME(m_card_hold_i)); - save_item(NAME(m_card_state)); - save_item(NAME(m_card_status)); -} - -void tvochken_state::machine_reset() -{ - sega_9h0_0008_state::machine_reset(); - - m_card_previous_input = 0; - - m_card_data = 0; - m_card_data_i = 0; - m_card_hold_i = 0; - m_card_state = IDLE; - m_card_status = 0; -} - /** * Combines all inputs: * - Pressed buttons @@ -2071,7 +2076,7 @@ void tvochken_state::machine_reset() * - bit 5: current data bit to read from 16-bit value; * - bit 6: status for advancing data bit position; * - * Parsing protocol at function 0xa0001240 doesn't seem to use any + * Parsing protocol for tvochken at function 0xa0001240 doesn't seem to use any * control commands to start parsing either input. It expects each parsed barcode * to take several reads before advancing to the next data bit. We handle this * by holding the value for a few reads, which also covers reads unrelated @@ -2079,69 +2084,10 @@ void tvochken_state::machine_reset() */ uint32_t tvochken_state::io_expansion_r() { - if (machine().side_effects_disabled() || (m_io_auxiliary_regs[0x8/4] & 0xff) != 0) { - return 0x98 | m_io_buttons->read(); - } - - /** - * Each scanned barcode is compared against these values taken from - * an in-memory table at 0xc00d0f9c. Valid barcodes always have the - * last bit set. - * - * 0x900a, 0xa05a, 0xb0aa, 0x90ca, 0x910a, - * 0x914a, 0x918a, 0x91ca, 0x920a, 0xa25a, - * 0x928a, 0x92ca, 0xa312, 0x934a, 0x938a, - * 0x93ca, 0xa41a, 0x944a, 0x948a, 0xb4da, - * 0xb512, 0xa55a, 0x958a, 0x95ca, 0x960a, - * 0x964a, 0xb69a, 0x96ca, 0x970a, 0x974a, - * 0x978a, 0x97ca, 0x980a, 0x984a, 0xa892, - * 0xa8da, 0xa91a, 0xa952, 0x998a, 0xb9da, - * 0xaa1a, 0x9a4a, 0x9a8a, 0x9aca, 0xab12, - * 0xab52, 0xbba2, 0xabd2, 0x9c0a, 0x9c4a - */ - - if (m_card_state == START_WRITE_DATA) { - m_card_hold_i--; - if (m_card_hold_i == 0) { - m_card_hold_i = 10; - m_card_data_i = 0; - m_card_status = 0; - m_card_state = WRITE_DATA; - } - - return 0x98 | (1 << 5) | m_io_buttons->read(); - } - - if (m_card_state == WRITE_DATA) { - uint8_t data_bit = (m_card_data >> (15 - m_card_data_i)) & 1; - LOG("write card: bit %d -> %d (sync %d)\n", m_card_data_i, data_bit, m_card_status); - - m_card_hold_i--; - if (m_card_hold_i == 0) { - m_card_hold_i = 10; - m_card_status ^= 1; - m_card_data_i++; - if (m_card_data_i == 16) { - m_card_data_i = 0; - m_card_status = 0; - m_card_state = IDLE; - } - } - - return 0x98 | (m_card_status << 6) | (data_bit << 5) | m_io_buttons->read(); - } - - return 0x98 | m_io_buttons->read(); -} - -void tvochken_state::scan_card(int state) -{ - if (m_card->exists() && state && (m_card_state == IDLE)) { - m_card_data = m_card->barcode(); - m_card_hold_i = 10; - m_card_state = START_WRITE_DATA; - LOG("scanning card: %04x\n", m_card_data); - } + const uint32_t card_data = m_card->get_card_device() + ? m_card->get_card_device()->read((m_io_auxiliary_regs[0x8/4] & 0xff) == 0) + : 0; + return card_data | m_io_buttons->read(); } void tvochken_state::install_game_rom() @@ -2203,6 +2149,7 @@ void carbeena_state::install_game_rom() m_maincpu->space(AS_PROGRAM).install_rom(ROM_MASK_BASE, ROM_MASK_BASE + 0x7fffff, 0x800000, rom->base()); } + static INPUT_PORTS_START( sega_9h0_0008 ) PORT_START("VIDEO_CONFIG") PORT_CONFNAME( 0x80, 0x00, "Video Output" ) @@ -2271,9 +2218,6 @@ static INPUT_PORTS_START( tvochken ) PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("A") PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("B") PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("C") - - PORT_START("CARDS") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("Scan Card") PORT_WRITE_LINE_MEMBER(FUNC(tvochken_state::scan_card)) INPUT_PORTS_END static INPUT_PORTS_START( carbeena )