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 )