From 59cbd883f8196ec7d3582f5e9f1e0f93233aae78 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 14 Dec 2023 13:14:26 +1100 Subject: sega/sega_beena.cpp: Hooked up barcode cards. Systems promoted to working --------------------------- Sega TV Ocha-Ken [QUFB] Software list items promoted to working (tvochken.xml) ------------------------------------------------------ TV to Ocha-Card: Ocha-Ken 'Ho' to Seikatsu [Vas Crabb] --- docs/source/techspecs/layout_script.rst | 4 + hash/tvochken.xml | 202 ++++++++++++++++---------------- plugins/layout/init.lua | 6 + src/devices/machine/w83977tf.cpp | 21 +++- src/devices/machine/w83977tf.h | 26 ++-- src/emu/diimage.cpp | 13 +- src/mame/layout/tvochken.lay | 47 ++++++++ src/mame/sega/sega_beena.cpp | 111 +++++++++--------- src/mame/sega/tvochken_card.cpp | 158 +++++++++++++++++++++++++ src/mame/sega/tvochken_card.h | 54 +++++++++ 10 files changed, 467 insertions(+), 175 deletions(-) create mode 100644 src/mame/layout/tvochken.lay create mode 100644 src/mame/sega/tvochken_card.cpp create mode 100644 src/mame/sega/tvochken_card.h diff --git a/docs/source/techspecs/layout_script.rst b/docs/source/techspecs/layout_script.rst index d8949c65e7c..be6166a7146 100644 --- a/docs/source/techspecs/layout_script.rst +++ b/docs/source/techspecs/layout_script.rst @@ -480,6 +480,10 @@ providing what’s needed: ` (indexed by name). * ``machine`` giving MAME’s current :ref:`running machine `. +* ``emu.device_enumerator``, ``emu.palette_enumerator``, + ``emu.screen_enumerator``, ``emu.cassette_enumerator``, + ``emu.image_enumerator`` and ``emu.slot_enumerator`` functions for obtaining + specific device interfaces. * ``emu.attotime``, ``emu.render_bounds`` and ``emu.render_color`` functions for creating :ref:`attotime `, :ref:`bounds ` and :ref:`colour ` diff --git a/hash/tvochken.xml b/hash/tvochken.xml index ad2953126be..6651e460d8b 100644 --- a/hash/tvochken.xml +++ b/hash/tvochken.xml @@ -5,358 +5,358 @@ license:CC0-1.0 --> - + TV to Ocha-Card: Ocha-Ken 'Ho' to Seikatsu 2005 Sega Toys - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/plugins/layout/init.lua b/plugins/layout/init.lua index e2da4c196e4..e4466a15912 100644 --- a/plugins/layout/init.lua +++ b/plugins/layout/init.lua @@ -19,6 +19,12 @@ function layout.startplugin() local env = { machine = manager.machine, emu = { + device_enumerator = emu.device_enumerator, + palette_enumerator = emu.palette_enumerator, + screen_enumerator = emu.screen_enumerator, + cassette_enumerator = emu.cassette_enumerator, + image_enumerator = emu.image_enumerator, + slot_enumerator = emu.slot_enumerator, attotime = emu.attotime, render_bounds = emu.render_bounds, render_color = emu.render_color, diff --git a/src/devices/machine/w83977tf.cpp b/src/devices/machine/w83977tf.cpp index 23c070c50e0..c63368c0a68 100644 --- a/src/devices/machine/w83977tf.cpp +++ b/src/devices/machine/w83977tf.cpp @@ -14,14 +14,16 @@ TODO: #include "emu.h" #include "machine/w83977tf.h" -#include "bus/isa/isa.h" //#include "machine/ds128x.h" #include "machine/pckeybrd.h" +#include + #define VERBOSE (LOG_GENERAL) //#define LOG_OUTPUT_FUNC osd_printf_info #include "logmacro.h" + DEFINE_DEVICE_TYPE(W83977TF, w83977tf_device, "w83977tf", "Winbond W83977TF Super I/O") w83977tf_device::w83977tf_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -43,7 +45,22 @@ w83977tf_device::w83977tf_device(const machine_config &mconfig, const char *tag, // , m_txd2_callback(*this) // , m_ndtr2_callback(*this) // , m_nrts2_callback(*this) -{ } + , m_index(0) + , m_logical_index(0) + , m_hefras(0) + , m_lockreg(0) + , m_lock_sequence(0) + , m_keyb_irq_line(0) + , m_mouse_irq_line(0) + , m_rtc_irq_line(0) + , m_keyb_address{ 0, 0 } +{ + std::fill(std::begin(m_activate), std::end(m_activate), false); +} + +w83977tf_device::~w83977tf_device() +{ +} void w83977tf_device::device_start() { diff --git a/src/devices/machine/w83977tf.h b/src/devices/machine/w83977tf.h index 2fe165f3135..4893620c00e 100644 --- a/src/devices/machine/w83977tf.h +++ b/src/devices/machine/w83977tf.h @@ -1,6 +1,5 @@ // license:BSD-3-Clause // copyright-holders: Angelo Salese - #ifndef MAME_MACHINE_W83977TF_H #define MAME_MACHINE_W83977TF_H @@ -16,7 +15,7 @@ class w83977tf_device : public device_t, { public: w83977tf_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - ~w83977tf_device() {} + virtual ~w83977tf_device(); void remap(int space_id, offs_t start, offs_t end) override; @@ -58,6 +57,18 @@ private: // devcb_write_line m_ndtr2_callback; // devcb_write_line m_nrts2_callback; + u8 m_index; + u8 m_logical_index; + bool m_activate[0xb]; + + u8 m_hefras; + u8 m_lockreg; + u8 m_lock_sequence; + u8 m_keyb_irq_line; + u8 m_mouse_irq_line; + u8 m_rtc_irq_line; + u16 m_keyb_address[2]; + uint8_t read(offs_t offset); void write(offs_t offset, u8 data); u8 cr26_r(); @@ -65,9 +76,6 @@ private: void config_map(address_map &map); - u8 m_index = 0; - u8 m_logical_index = 0; - bool m_activate[0xb]{}; void logical_device_select_w(offs_t offset, u8 data); template u8 activate_r(offs_t offset); template void activate_w(offs_t offset, u8 data); @@ -98,14 +106,6 @@ private: void irq_rtc_w(int state); void request_irq(int irq, int state); - - u8 m_hefras = 0; - u8 m_lockreg = 0; - u8 m_lock_sequence = 0; - u8 m_keyb_irq_line = 0; - u8 m_mouse_irq_line = 0; - u8 m_rtc_irq_line = 0; - u16 m_keyb_address[2]{}; }; DECLARE_DEVICE_TYPE(W83977TF, w83977tf_device); diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index f0e4172314e..59d1523a6b1 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -407,9 +407,8 @@ u8 *device_image_interface::get_software_region(std::string_view tag) if (!loaded_through_softlist()) return nullptr; - std::string full_tag = util::string_format("%s:%s", device().tag(), tag); - memory_region *region = device().machine().root_device().memregion(full_tag); - return region != nullptr ? region->base() : nullptr; + memory_region *const region = device().memregion(tag); + return region ? region->base() : nullptr; } @@ -419,9 +418,11 @@ u8 *device_image_interface::get_software_region(std::string_view tag) u32 device_image_interface::get_software_region_length(std::string_view tag) { - std::string full_tag = util::string_format("%s:%s", device().tag(), tag); - memory_region *region = device().machine().root_device().memregion(full_tag); - return region != nullptr ? region->bytes() : 0; + if (!loaded_through_softlist()) + return 0; + + memory_region *const region = device().memregion(tag); + return region ? region->bytes() : 0; } diff --git a/src/mame/layout/tvochken.lay b/src/mame/layout/tvochken.lay new file mode 100644 index 00000000000..f3f0b3c5225 --- /dev/null +++ b/src/mame/layout/tvochken.lay @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/src/mame/sega/sega_beena.cpp b/src/mame/sega/sega_beena.cpp index e08b00868e7..64cfbdf4cd1 100644 --- a/src/mame/sega/sega_beena.cpp +++ b/src/mame/sega/sega_beena.cpp @@ -8,7 +8,6 @@ TODO: - Storyware layout MIDI audio Peripherals (including the SD-Card adapter) Component list / PCB diagram @@ -111,8 +110,7 @@ Storyware --------- - Although no booklet artwork is rendered, toggling input port 'Pen Target' - switches between mapping pen coordinates to the tablet or the Storyware. + Toggling 'Pen Target' input switches between mapping pen coordinates to the tablet or the book. Test Mode --------- @@ -131,6 +129,8 @@ #include "emu.h" +#include "tvochken_card.h" + #include "bus/generic/slot.h" #include "bus/generic/carts.h" #include "cpu/arm7/ap2010cpu.h" @@ -147,10 +147,12 @@ #include "screen.h" #include "beena.lh" +#include "tvochken.lh" #define VERBOSE (0) #include "logmacro.h" + namespace { class sega_9h0_0008_state : public driver_device @@ -161,8 +163,6 @@ public: , m_maincpu(*this, "maincpu") , m_workram(*this, "workram") , m_pcm(*this, "pcm") - , m_cart(*this, "cartslot") - , m_cart_region(nullptr) , m_screen_main(*this, "screen") , m_gfxdecode(*this, "gfxdecode") , m_palette(*this, "palette") @@ -179,12 +179,12 @@ public: , m_io_video_config(*this, "VIDEO_CONFIG") { } - void sega_9h0_0008(machine_config &config); - protected: static inline constexpr uint32_t ROM_MASK_BASE = 0x80000000; static inline constexpr uint32_t ROM_FLASH_BASE = 0xa0000000; + void sega_9h0_0008(machine_config &config); + virtual void device_post_load() override; virtual void machine_start() override; virtual void machine_reset() override; @@ -258,9 +258,6 @@ protected: bool m_requested_fiq; uint32_t m_irq_wait_start_addr; - optional_device m_cart; - memory_region *m_cart_region; - required_device m_screen_main; required_device m_gfxdecode; required_device m_palette; @@ -1721,13 +1718,9 @@ void sega_9h0_0008_state::sega_9h0_0008(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfxdecode_device::empty); - config.set_default_layout(layout_beena); - SPEAKER(config, "speaker").front_center(); AP2010PCM(config, m_pcm); // Unknown clock m_pcm->add_route(ALL_OUTPUTS, "speaker", 1.0); - - SOFTWARE_LIST(config, "cart_list").set_original("sega_beena_cart"); } @@ -1736,6 +1729,7 @@ class sega_beena_state : public sega_9h0_0008_state public: sega_beena_state(const machine_config &mconfig, device_type type, const char *tag) : sega_9h0_0008_state(mconfig, type, tag) + , m_cart(*this, "cartslot") , m_io_page_config(*this, "PAGE_CONFIG") , m_io_page(*this, "PAGE") , m_io_pad_left(*this, "PAD_LEFT") @@ -1756,6 +1750,8 @@ private: virtual void update_crosshair(screen_device &screen) override; virtual void update_sensors(offs_t offset) override; + required_device m_cart; + required_ioport m_io_page_config; required_ioport m_io_page; required_ioport m_io_pad_left; @@ -1775,6 +1771,10 @@ void sega_beena_state::sega_beena(machine_config &config) m_cart->set_width(GENERIC_ROM32_WIDTH); m_cart->set_device_load(FUNC(sega_beena_state::cart_load)); m_cart->set_must_be_loaded(false); + + SOFTWARE_LIST(config, "cart_list").set_original("sega_beena_cart"); + + config.set_default_layout(layout_beena); } void sega_beena_state::install_game_rom() @@ -1974,12 +1974,16 @@ class tvochken_state : public sega_9h0_0008_state public: tvochken_state(const machine_config &mconfig, device_type type, const char *tag) : sega_9h0_0008_state(mconfig, type, tag) + , m_card(*this, "card") , m_io_buttons(*this, "BUTTONS") - , m_io_cards(*this, "CARDS") { } + void tvochken(machine_config &config); + virtual uint32_t io_expansion_r() override; + void scan_card(int state); + private: enum card_state : uint8_t { @@ -1993,11 +1997,11 @@ private: virtual void install_game_rom() override; + required_device m_card; + required_ioport m_io_buttons; - required_ioport m_io_cards; uint8_t m_card_previous_input; - uint8_t m_card_i; uint16_t m_card_data; uint8_t m_card_data_i; uint8_t m_card_state; @@ -2005,11 +2009,21 @@ private: uint8_t m_card_status; }; +void tvochken_state::tvochken(machine_config &config) +{ + sega_9h0_0008(config); + + TVOCHKEN_CARD(config, m_card); + + 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_i)); save_item(NAME(m_card_data)); save_item(NAME(m_card_data_i)); save_item(NAME(m_card_hold_i)); @@ -2023,7 +2037,6 @@ void tvochken_state::machine_reset() m_card_previous_input = 0; - m_card_i = 0; m_card_data = 0; m_card_data_i = 0; m_card_hold_i = 0; @@ -2057,35 +2070,18 @@ uint32_t tvochken_state::io_expansion_r() * Each scanned barcode is compared against these values taken from * an in-memory table at 0xc00d0f9c. Valid barcodes always have the * last bit set. - */ - const uint16_t CARD_BARCODES[] = { - 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 - }; - - const uint8_t data = m_io_cards->read(); - if (m_card_previous_input != data) { - m_card_previous_input = data; - if ((data & 0x80) == 0) { - m_card_i = data; - LOG("selected card: %d\n", m_card_i + 1); - } else { - if (m_card_state == IDLE) { - m_card_data = CARD_BARCODES[m_card_i]; - m_card_hold_i = 10; - m_card_state = START_WRITE_DATA; - LOG("scanning card: %d -> %04x\n", m_card_i + 1, m_card_data); - } - } - } + * + * 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--; @@ -2121,6 +2117,16 @@ uint32_t tvochken_state::io_expansion_r() return 0x98 | m_io_buttons->read(); } +void tvochken_state::scan_card(int state) +{ + if (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); + } +} + void tvochken_state::install_game_rom() { memory_region *rom = memregion("flash_rom"); @@ -2198,8 +2204,7 @@ static INPUT_PORTS_START( tvochken ) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("C") PORT_START("CARDS") - PORT_BIT( 0x7f, 0x00, IPT_POSITIONAL ) PORT_POSITIONS(50) PORT_WRAPS PORT_SENSITIVITY(10) PORT_KEYDELTA(1) PORT_CODE(JOYCODE_X) PORT_CODE_DEC(KEYCODE_HOME) PORT_CODE_INC(KEYCODE_END) PORT_FULL_TURN_COUNT(50) PORT_NAME("Selected Card") - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("Scan Card") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("Scan Card") PORT_WRITE_LINE_MEMBER(tvochken_state, scan_card) INPUT_PORTS_END @@ -2227,6 +2232,6 @@ ROM_END } // anonymous namespace -// year, name, parent, compat, machine, input, class, init, company, fullname, flags -CONS( 2005, beena, 0, 0, sega_beena, sega_beena, sega_beena_state, empty_init, "Sega", "Advanced Pico BEENA", MACHINE_IMPERFECT_GRAPHICS|MACHINE_IMPERFECT_TIMING|MACHINE_IMPERFECT_SOUND ) -CONS( 2005, tvochken, 0, 0, sega_9h0_0008, tvochken, tvochken_state, empty_init, "Sega", "TV Ocha-Ken", MACHINE_NOT_WORKING|MACHINE_REQUIRES_ARTWORK|MACHINE_IMPERFECT_GRAPHICS|MACHINE_IMPERFECT_TIMING|MACHINE_IMPERFECT_SOUND ) +// year, name, parent, compat, machine, input, class, init, company, fullname, flags +CONS( 2005, beena, 0, 0, sega_beena, sega_beena, sega_beena_state, empty_init, "Sega", "Advanced Pico BEENA", MACHINE_IMPERFECT_GRAPHICS|MACHINE_IMPERFECT_TIMING|MACHINE_IMPERFECT_SOUND ) +CONS( 2005, tvochken, 0, 0, tvochken, tvochken, tvochken_state, empty_init, "Sega", "TV Ocha-Ken", MACHINE_IMPERFECT_GRAPHICS|MACHINE_IMPERFECT_TIMING|MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/sega/tvochken_card.cpp b/src/mame/sega/tvochken_card.cpp new file mode 100644 index 00000000000..b0393690586 --- /dev/null +++ b/src/mame/sega/tvochken_card.cpp @@ -0,0 +1,158 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/****************************************************************************** + + tvochken_card.cpp + + Sega TV Ocha-ken barcode card loader + + TODO: + * Decode barcode from the scan so it doesn't need to be in a software + part feature and loose files can be supported. + * Determine correct barcode value to return when no card is inserted. + +*******************************************************************************/ + +#include "emu.h" +#include "tvochken_card.h" + +#include "rendutil.h" +#include "softlist_dev.h" + +#include "ioprocs.h" + +#include +#include + + +DEFINE_DEVICE_TYPE(TVOCHKEN_CARD, tvochken_card_device, "tvochken_card", "Sega TV Ocha-Ken barcode card") + + +tvochken_card_device::tvochken_card_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + u32 clock) + : device_t(mconfig, TVOCHKEN_CARD, tag, owner, clock) + , device_image_interface(mconfig, *this) + , m_barcode(0) +{ +} + + +tvochken_card_device::~tvochken_card_device() +{ +} + + +std::pair tvochken_card_device::call_load() +{ + memory_region *cardrgn; + if (loaded_through_softlist()) + { + // ensure card region is present + cardrgn = memregion("card"); + if (!cardrgn) + { + return std::make_pair( + image_error::BADSOFTWARE, + "Software list item has no 'card' data area"); + } + + // try to parse the barcode number + char const *const barcodestr = get_feature("barcode"); + if (!barcodestr) + { + machine().memory().region_free(cardrgn->name()); + return std::make_pair( + image_error::BADSOFTWARE, + "Software list item has no 'barcode' feature"); + } + std::istringstream stream; + stream.imbue(std::locale::classic()); + if (('0' == barcodestr[0]) && (('x' == barcodestr[1]) || ('X' == barcodestr[1]))) + { + stream.str(barcodestr + 2); + stream >> std::hex; + } + else + { + stream.str(barcodestr); + } + stream >> m_barcode; + if (!stream) + { + machine().memory().region_free(cardrgn->name()); + m_barcode = 0; + return std::make_pair( + image_error::BADSOFTWARE, + util::string_format("Software list item has invalid 'barcode' feature '%s'", barcodestr)); + } + } + else + { + // attempt to read the file into memory + auto const len = length(); + cardrgn = machine().memory().region_alloc(subtag("card"), len, 1, ENDIANNESS_LITTLE); + if (!cardrgn) + return std::make_pair(std::errc::not_enough_memory, std::string()); + if (fread(cardrgn->base(), len) != len) + { + machine().memory().region_free(cardrgn->name()); + return std::make_pair( + std::errc::io_error, + "Error reading card scan file"); + } + + // 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", + tag()); + } + + // sanity check that the card scan looks like a supported bitmap + auto io = util::ram_read(cardrgn->base(), cardrgn->bytes()); + if (!io) + { + machine().memory().region_free(cardrgn->name()); + m_barcode = 0; + return std::make_pair(std::errc::not_enough_memory, std::string()); + } + switch (render_detect_image(*io)) + { + case RENDUTIL_IMGFORMAT_PNG: + case RENDUTIL_IMGFORMAT_JPEG: + case RENDUTIL_IMGFORMAT_MSDIB: + break; + default: + machine().memory().region_free(cardrgn->name()); + m_barcode = 0; + return std::make_pair( + image_error::INVALIDIMAGE, + "Card scan does not appear to be a PNG, JPEG or Microsoft DIB (BMP) bitmap"); + } + io.reset(); + + return std::make_pair(std::error_condition(), std::string()); +} + + +void tvochken_card_device::call_unload() +{ + memory_region *const cardrgn = memregion("card"); + if (cardrgn) + machine().memory().region_free(cardrgn->name()); + + m_barcode = 0; +} + + +void tvochken_card_device::device_start() +{ +} + +software_list_loader const &tvochken_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/tvochken_card.h new file mode 100644 index 00000000000..67d548e28f0 --- /dev/null +++ b/src/mame/sega/tvochken_card.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/****************************************************************************** + + tvochken_card.h + + Sega TV Ocha-ken barcode card loader + +*******************************************************************************/ +#ifndef MAME_SEGA_TVOCHKEN_CARD_H +#define MAME_SEGA_TVOCHKEN_CARD_H + +#pragma once + +#include +#include +#include + + +class tvochken_card_device : public device_t, 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(); + + // device_image_interface implementation + virtual std::pair call_load() override ATTR_COLD; + virtual void call_unload() override ATTR_COLD; + virtual bool is_readable() const noexcept override { return true; } + 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 *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; } + +protected: + // device_t implementation + virtual void device_start() override ATTR_COLD; + + // device_image_interface implementation + virtual software_list_loader const &get_software_list_loader() const override ATTR_COLD; + +private: + u16 m_barcode; +}; + + +DECLARE_DEVICE_TYPE(TVOCHKEN_CARD, tvochken_card_device) + +#endif // MAME_SEGA_TVOCHKEN_CARD_H -- cgit v1.2.3