summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/source/techspecs/layout_script.rst4
-rw-r--r--hash/tvochken.xml202
-rw-r--r--plugins/layout/init.lua6
-rw-r--r--src/devices/machine/w83977tf.cpp21
-rw-r--r--src/devices/machine/w83977tf.h26
-rw-r--r--src/emu/diimage.cpp13
-rw-r--r--src/mame/layout/tvochken.lay47
-rw-r--r--src/mame/sega/sega_beena.cpp111
-rw-r--r--src/mame/sega/tvochken_card.cpp158
-rw-r--r--src/mame/sega/tvochken_card.h54
10 files changed, 467 insertions, 175 deletions
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:
<luascript-ref-renderlayview>` (indexed by name).
* ``machine`` giving MAME’s current :ref:`running machine
<luascript-ref-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 <luascript-ref-attotime>`, :ref:`bounds
<luascript-ref-renderbounds>` and :ref:`colour <luascript-ref-rendercolor>`
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
-->
<softwarelist name="tvochken" description="TV Ocha-Ken barcode cards">
- <software name="tvochken" supported="no">
+ <software name="tvochken" supported="yes">
<description>TV to Ocha-Card: Ocha-Ken 'Ho' to Seikatsu</description>
<year>2005</year>
<publisher>Sega Toys</publisher>
<info name="alt_title" value="テレビとお茶札 お茶犬『ほっ』と生活"/>
- <part name="card1" interface="sega_beena_cart">
+ <part name="card1" interface="tvochken_card">
<feature name="part_id" value="Card 1"/>
<feature name="barcode" value="0x900a"/>
- <dataarea name="card1" size="0x4f1749">
+ <dataarea name="card" size="0x4f1749">
<rom name="0 - 0001.png" size="0x4f1749" crc="c5432bb7" sha1="375fb553245e88d37977f6a831ede72cf7c94eb8"/>
</dataarea>
</part>
- <part name="card2" interface="sega_beena_cart">
+ <part name="card2" interface="tvochken_card">
<feature name="part_id" value="Card 2"/>
<feature name="barcode" value="0xa05a"/>
- <dataarea name="card2" size="0x4df6f0">
+ <dataarea name="card" size="0x4df6f0">
<rom name="0 - 0002.png" size="0x4df6f0" crc="6c83c38a" sha1="616a796615423e1eaa05a2637cd606d5816c7f01"/>
</dataarea>
</part>
- <part name="card3" interface="sega_beena_cart">
+ <part name="card3" interface="tvochken_card">
<feature name="part_id" value="Card 3"/>
<feature name="barcode" value="0xb0aa"/>
- <dataarea name="card3" size="0x4f220b">
+ <dataarea name="card" size="0x4f220b">
<rom name="0 - 0003.png" size="0x4f220b" crc="a14f9d50" sha1="a3bce401fe3c70bef046addb4cbc31c5e0f04f0f"/>
</dataarea>
</part>
- <part name="card4" interface="sega_beena_cart">
+ <part name="card4" interface="tvochken_card">
<feature name="part_id" value="Card 4"/>
<feature name="barcode" value="0x90ca"/>
- <dataarea name="card4" size="0x4f1602">
+ <dataarea name="card" size="0x4f1602">
<rom name="0 - 0004.png" size="0x4f1602" crc="1c124ccf" sha1="840a3ee78ae0995b9b9fa9428da18d0ecd293f88"/>
</dataarea>
</part>
- <part name="card5" interface="sega_beena_cart">
+ <part name="card5" interface="tvochken_card">
<feature name="part_id" value="Card 5"/>
<feature name="barcode" value="0x910a"/>
- <dataarea name="card5" size="0x505a3a">
+ <dataarea name="card" size="0x505a3a">
<rom name="0 - 0005.png" size="0x505a3a" crc="c7190bb3" sha1="e4d1307971c053fc7ad98b6b8bea19a639c88084"/>
</dataarea>
</part>
- <part name="card6" interface="sega_beena_cart">
+ <part name="card6" interface="tvochken_card">
<feature name="part_id" value="Card 6"/>
<feature name="barcode" value="0x914a"/>
- <dataarea name="card6" size="0x50cbd4">
+ <dataarea name="card" size="0x50cbd4">
<rom name="0 - 0006.png" size="0x50cbd4" crc="0ef3b099" sha1="b736179f3b34b8301b32f2f6ded732634c9c0f76"/>
</dataarea>
</part>
- <part name="card7" interface="sega_beena_cart">
+ <part name="card7" interface="tvochken_card">
<feature name="part_id" value="Card 7"/>
<feature name="barcode" value="0x918a"/>
- <dataarea name="card7" size="0x4da934">
+ <dataarea name="card" size="0x4da934">
<rom name="0 - 0007.png" size="0x4da934" crc="66e119c6" sha1="d3ddc0bc4bea354e767ff6cc9cf152ce84bd2b24"/>
</dataarea>
</part>
- <part name="card8" interface="sega_beena_cart">
+ <part name="card8" interface="tvochken_card">
<feature name="part_id" value="Card 8"/>
<feature name="barcode" value="0x91ca"/>
- <dataarea name="card8" size="0x4eff47">
+ <dataarea name="card" size="0x4eff47">
<rom name="0 - 0008.png" size="0x4eff47" crc="df475cf6" sha1="26ed60fb032b41464cc93582ab51b05ec61abf5c"/>
</dataarea>
</part>
- <part name="card9" interface="sega_beena_cart">
+ <part name="card9" interface="tvochken_card">
<feature name="part_id" value="Card 9"/>
<feature name="barcode" value="0x920a"/>
- <dataarea name="card9" size="0x4f423e">
+ <dataarea name="card" size="0x4f423e">
<rom name="0 - 0009.png" size="0x4f423e" crc="d3f5b52c" sha1="157ec2a13e90381c5348352aafeffeb63f453f9c"/>
</dataarea>
</part>
- <part name="card10" interface="sega_beena_cart">
+ <part name="card10" interface="tvochken_card">
<feature name="part_id" value="Card 10"/>
<feature name="barcode" value="0xa25a"/>
- <dataarea name="card10" size="0x58a781">
+ <dataarea name="card" size="0x58a781">
<rom name="0 - 0010.png" size="0x58a781" crc="dfae4f5e" sha1="515cd302381d9dcbefa69adaaa4c8bc13b661877"/>
</dataarea>
</part>
- <part name="card11" interface="sega_beena_cart">
+ <part name="card11" interface="tvochken_card">
<feature name="part_id" value="Card 11"/>
<feature name="barcode" value="0x928a"/>
- <dataarea name="card11" size="0x5b058b">
+ <dataarea name="card" size="0x5b058b">
<rom name="0 - 0011.png" size="0x5b058b" crc="5bb62726" sha1="6199c01eb5fcc7de7fe90e89f3ee7140705caeba"/>
</dataarea>
</part>
- <part name="card12" interface="sega_beena_cart">
+ <part name="card12" interface="tvochken_card">
<feature name="part_id" value="Card 12"/>
<feature name="barcode" value="0x92ca"/>
- <dataarea name="card12" size="0x5a279b">
+ <dataarea name="card" size="0x5a279b">
<rom name="0 - 0012.png" size="0x5a279b" crc="b5d1111e" sha1="8b05ce9c1f74563ab9735645a5eb89a3cada74a5"/>
</dataarea>
</part>
- <part name="card13" interface="sega_beena_cart">
+ <part name="card13" interface="tvochken_card">
<feature name="part_id" value="Card 13"/>
<feature name="barcode" value="0xa312"/>
- <dataarea name="card13" size="0x4dc9ad">
+ <dataarea name="card" size="0x4dc9ad">
<rom name="0 - 0013.png" size="0x4dc9ad" crc="707edf49" sha1="e7deac18147217e8128b5d8c440fc605c530da81"/>
</dataarea>
</part>
- <part name="card14" interface="sega_beena_cart">
+ <part name="card14" interface="tvochken_card">
<feature name="part_id" value="Card 14"/>
<feature name="barcode" value="0x934a"/>
- <dataarea name="card14" size="0x4ce76b">
+ <dataarea name="card" size="0x4ce76b">
<rom name="0 - 0014.png" size="0x4ce76b" crc="5c3ec4c2" sha1="a4954ed1710a87ee673d3a15b6dfdf5af46e80d6"/>
</dataarea>
</part>
- <part name="card15" interface="sega_beena_cart">
+ <part name="card15" interface="tvochken_card">
<feature name="part_id" value="Card 15"/>
<feature name="barcode" value="0x938a"/>
- <dataarea name="card15" size="0x531c9f">
+ <dataarea name="card" size="0x531c9f">
<rom name="0 - 0015.png" size="0x531c9f" crc="3507b23e" sha1="ea12fa59718cdbbef6d7728e555176b76692c89b"/>
</dataarea>
</part>
- <part name="card16" interface="sega_beena_cart">
+ <part name="card16" interface="tvochken_card">
<feature name="part_id" value="Card 16"/>
<feature name="barcode" value="0x93ca"/>
- <dataarea name="card16" size="0x5506d3">
+ <dataarea name="card" size="0x5506d3">
<rom name="0 - 0016.png" size="0x5506d3" crc="6c3b995c" sha1="9f63ffa5ffec951af65dfb5ce432f13b0e1bd92b"/>
</dataarea>
</part>
- <part name="card17" interface="sega_beena_cart">
+ <part name="card17" interface="tvochken_card">
<feature name="part_id" value="Card 17"/>
<feature name="barcode" value="0xa41a"/>
- <dataarea name="card17" size="0x50cfbd">
+ <dataarea name="card" size="0x50cfbd">
<rom name="0 - 0017.png" size="0x50cfbd" crc="a3cdf730" sha1="89035eeb714f45cac2ef0c9e8ee86d5ba50d04bb"/>
</dataarea>
</part>
- <part name="card18" interface="sega_beena_cart">
+ <part name="card18" interface="tvochken_card">
<feature name="part_id" value="Card 18"/>
<feature name="barcode" value="0x944a"/>
- <dataarea name="card18" size="0x4c9ed3">
+ <dataarea name="card" size="0x4c9ed3">
<rom name="0 - 0018.png" size="0x4c9ed3" crc="8a0eaeb4" sha1="27131d1a642a27cea5ae1bb0c57fcd20d7e46f28"/>
</dataarea>
</part>
- <part name="card19" interface="sega_beena_cart">
+ <part name="card19" interface="tvochken_card">
<feature name="part_id" value="Card 19"/>
<feature name="barcode" value="0x948a"/>
- <dataarea name="card19" size="0x4e43a3">
+ <dataarea name="card" size="0x4e43a3">
<rom name="0 - 0019.png" size="0x4e43a3" crc="425cfb05" sha1="e62e0ae7da3aa45afc5d7744277288df32925b96"/>
</dataarea>
</part>
- <part name="card20" interface="sega_beena_cart">
+ <part name="card20" interface="tvochken_card">
<feature name="part_id" value="Card 20"/>
<feature name="barcode" value="0xb4da"/>
- <dataarea name="card20" size="0x4a67a5">
+ <dataarea name="card" size="0x4a67a5">
<rom name="0 - 0020.png" size="0x4a67a5" crc="1b3ddf36" sha1="f89981193f4a0f5438a8a4d05b29bba5832712f2"/>
</dataarea>
</part>
- <part name="card21" interface="sega_beena_cart">
+ <part name="card21" interface="tvochken_card">
<feature name="part_id" value="Card 21"/>
<feature name="barcode" value="0xb512"/>
- <dataarea name="card21" size="0x595884">
+ <dataarea name="card" size="0x595884">
<rom name="0 - 0021.png" size="0x595884" crc="812535ac" sha1="0e88309e4629e352542e0f77c282add67d9e0eff"/>
</dataarea>
</part>
- <part name="card22" interface="sega_beena_cart">
+ <part name="card22" interface="tvochken_card">
<feature name="part_id" value="Card 22"/>
<feature name="barcode" value="0xa55a"/>
- <dataarea name="card22" size="0x59e757">
+ <dataarea name="card" size="0x59e757">
<rom name="0 - 0022.png" size="0x59e757" crc="a3af7a1e" sha1="2ce48f5948d2b4aed80cff97e4443fb377a0dc75"/>
</dataarea>
</part>
- <part name="card23" interface="sega_beena_cart">
+ <part name="card23" interface="tvochken_card">
<feature name="part_id" value="Card 23"/>
<feature name="barcode" value="0x958a"/>
- <dataarea name="card23" size="0x5845cc">
+ <dataarea name="card" size="0x5845cc">
<rom name="0 - 0023.png" size="0x5845cc" crc="7962f20b" sha1="1cdb601803881b6161818902253d3e2d5c0676ca"/>
</dataarea>
</part>
- <part name="card24" interface="sega_beena_cart">
+ <part name="card24" interface="tvochken_card">
<feature name="part_id" value="Card 24"/>
<feature name="barcode" value="0x95ca"/>
- <dataarea name="card24" size="0x4cbaec">
+ <dataarea name="card" size="0x4cbaec">
<rom name="0 - 0024.png" size="0x4cbaec" crc="3fb7395c" sha1="2e9631bc27edc15e5be25c22a81f6f51fc1c6f20"/>
</dataarea>
</part>
- <part name="card25" interface="sega_beena_cart">
+ <part name="card25" interface="tvochken_card">
<feature name="part_id" value="Card 25"/>
<feature name="barcode" value="0x960a"/>
- <dataarea name="card25" size="0x57375d">
+ <dataarea name="card" size="0x57375d">
<rom name="0 - 0025.png" size="0x57375d" crc="b6dc9acd" sha1="fff3ebbea33f7261ae8ae4d4c7c3847b9cf3f88a"/>
</dataarea>
</part>
- <part name="card26" interface="sega_beena_cart">
+ <part name="card26" interface="tvochken_card">
<feature name="part_id" value="Card 26"/>
<feature name="barcode" value="0x964a"/>
- <dataarea name="card26" size="0x583f9c">
+ <dataarea name="card" size="0x583f9c">
<rom name="0 - 0026.png" size="0x583f9c" crc="46033178" sha1="ef265ce7fafa88cebe4d8c199687e58b0a1375a3"/>
</dataarea>
</part>
- <part name="card27" interface="sega_beena_cart">
+ <part name="card27" interface="tvochken_card">
<feature name="part_id" value="Card 27"/>
<feature name="barcode" value="0xb69a"/>
- <dataarea name="card27" size="0x586407">
+ <dataarea name="card" size="0x586407">
<rom name="0 - 0027.png" size="0x586407" crc="2278b79b" sha1="911200fd9b2662e60849ad8d0d818ffc77166815"/>
</dataarea>
</part>
- <part name="card28" interface="sega_beena_cart">
+ <part name="card28" interface="tvochken_card">
<feature name="part_id" value="Card 28"/>
<feature name="barcode" value="0x96ca"/>
- <dataarea name="card28" size="0x4e0094">
+ <dataarea name="card" size="0x4e0094">
<rom name="0 - 0028.png" size="0x4e0094" crc="4ecefa48" sha1="8bb7c0e2a1f117e7c1c205fb6f68dd3b79d3608f"/>
</dataarea>
</part>
- <part name="card29" interface="sega_beena_cart">
+ <part name="card29" interface="tvochken_card">
<feature name="part_id" value="Card 29"/>
<feature name="barcode" value="0x970a"/>
- <dataarea name="card29" size="0x58ee04">
+ <dataarea name="card" size="0x58ee04">
<rom name="0 - 0029.png" size="0x58ee04" crc="52cadc27" sha1="820a47efb41e1e52e3a0e75b8550983e2890fe23"/>
</dataarea>
</part>
- <part name="card30" interface="sega_beena_cart">
+ <part name="card30" interface="tvochken_card">
<feature name="part_id" value="Card 30"/>
<feature name="barcode" value="0x974a"/>
- <dataarea name="card30" size="0x59ffec">
+ <dataarea name="card" size="0x59ffec">
<rom name="0 - 0030.png" size="0x59ffec" crc="0bedfd6a" sha1="781cd0be18c3a29015317ace95e3749182a9c5e5"/>
</dataarea>
</part>
- <part name="card31" interface="sega_beena_cart">
+ <part name="card31" interface="tvochken_card">
<feature name="part_id" value="Card 31"/>
<feature name="barcode" value="0x978a"/>
- <dataarea name="card31" size="0x52a465">
+ <dataarea name="card" size="0x52a465">
<rom name="0 - 0031.png" size="0x52a465" crc="6f1fb6df" sha1="430c170759010daa72318bd6bac07637fb03ac66"/>
</dataarea>
</part>
- <part name="card32" interface="sega_beena_cart">
+ <part name="card32" interface="tvochken_card">
<feature name="part_id" value="Card 32"/>
<feature name="barcode" value="0x97ca"/>
- <dataarea name="card32" size="0x5794b4">
+ <dataarea name="card" size="0x5794b4">
<rom name="0 - 0032.png" size="0x5794b4" crc="0bd168a3" sha1="63eb11961046c3c382e695f0cf8292f2dbba0861"/>
</dataarea>
</part>
- <part name="card33" interface="sega_beena_cart">
+ <part name="card33" interface="tvochken_card">
<feature name="part_id" value="Card 33"/>
<feature name="barcode" value="0x980a"/>
- <dataarea name="card33" size="0x4b665e">
+ <dataarea name="card" size="0x4b665e">
<rom name="0 - 0033.png" size="0x4b665e" crc="03cf3ac0" sha1="55d58cb97d5f464982d3cba4915a78e50110dc28"/>
</dataarea>
</part>
- <part name="card34" interface="sega_beena_cart">
+ <part name="card34" interface="tvochken_card">
<feature name="part_id" value="Card 34"/>
<feature name="barcode" value="0x984a"/>
- <dataarea name="card34" size="0x5992ff">
+ <dataarea name="card" size="0x5992ff">
<rom name="0 - 0034.png" size="0x5992ff" crc="4c1c285c" sha1="cde5d284ffa9a9a44c88529692e5bc9f6fffb0c7"/>
</dataarea>
</part>
- <part name="card35" interface="sega_beena_cart">
+ <part name="card35" interface="tvochken_card">
<feature name="part_id" value="Card 35"/>
<feature name="barcode" value="0xa892"/>
- <dataarea name="card35" size="0x523acd">
+ <dataarea name="card" size="0x523acd">
<rom name="0 - 0035.png" size="0x523acd" crc="612aa0c0" sha1="b302fbad590fb8db3624884614c9a8bd8108acac"/>
</dataarea>
</part>
- <part name="card36" interface="sega_beena_cart">
+ <part name="card36" interface="tvochken_card">
<feature name="part_id" value="Card 36"/>
<feature name="barcode" value="0xa8da"/>
- <dataarea name="card36" size="0x5213b6">
+ <dataarea name="card" size="0x5213b6">
<rom name="0 - 0036.png" size="0x5213b6" crc="befc985e" sha1="d1caa434da81b2d1e0773d5edc147800c6d48b7a"/>
</dataarea>
</part>
- <part name="card37" interface="sega_beena_cart">
+ <part name="card37" interface="tvochken_card">
<feature name="part_id" value="Card 37"/>
<feature name="barcode" value="0xa91a"/>
- <dataarea name="card37" size="0x4ff7ee">
+ <dataarea name="card" size="0x4ff7ee">
<rom name="0 - 0037.png" size="0x4ff7ee" crc="eb1b4883" sha1="b5a36c627f224dd7d1d6953ac68dcd3ec055950c"/>
</dataarea>
</part>
- <part name="card38" interface="sega_beena_cart">
+ <part name="card38" interface="tvochken_card">
<feature name="part_id" value="Card 38"/>
<feature name="barcode" value="0xa952"/>
- <dataarea name="card38" size="0x519ced">
+ <dataarea name="card" size="0x519ced">
<rom name="0 - 0038.png" size="0x519ced" crc="ccc3807c" sha1="1834dea6b2246452b54b0f0136539e9b87cc85d1"/>
</dataarea>
</part>
- <part name="card39" interface="sega_beena_cart">
+ <part name="card39" interface="tvochken_card">
<feature name="part_id" value="Card 39"/>
<feature name="barcode" value="0x998a"/>
- <dataarea name="card39" size="0x5322d6">
+ <dataarea name="card" size="0x5322d6">
<rom name="0 - 0039.png" size="0x5322d6" crc="e38dba54" sha1="e42c4a29a384f177bbf3658a8f28306985d5cb78"/>
</dataarea>
</part>
- <part name="card40" interface="sega_beena_cart">
+ <part name="card40" interface="tvochken_card">
<feature name="part_id" value="Card 40"/>
<feature name="barcode" value="0xb9da"/>
- <dataarea name="card40" size="0x4e717c">
+ <dataarea name="card" size="0x4e717c">
<rom name="0 - 0040.png" size="0x4e717c" crc="d5222fa8" sha1="32f55c769f00e44beff9539241ab974bb94ebe98"/>
</dataarea>
</part>
- <part name="card41" interface="sega_beena_cart">
+ <part name="card41" interface="tvochken_card">
<feature name="part_id" value="Card 41"/>
<feature name="barcode" value="0xaa1a"/>
- <dataarea name="card41" size="0x512de5">
+ <dataarea name="card" size="0x512de5">
<rom name="0 - 0041.png" size="0x512de5" crc="5d763c3c" sha1="eb7e09b68e77bfe92fe2699c8c2010f9e7ea0dfb"/>
</dataarea>
</part>
- <part name="card42" interface="sega_beena_cart">
+ <part name="card42" interface="tvochken_card">
<feature name="part_id" value="Card 42"/>
<feature name="barcode" value="0x9a4a"/>
- <dataarea name="card42" size="0x500827">
+ <dataarea name="card" size="0x500827">
<rom name="0 - 0042.png" size="0x500827" crc="b4413674" sha1="f2255d47156f7fb45043517928b1afa86cc2c8b8"/>
</dataarea>
</part>
- <part name="card43" interface="sega_beena_cart">
+ <part name="card43" interface="tvochken_card">
<feature name="part_id" value="Card 43"/>
<feature name="barcode" value="0x9a8a"/>
- <dataarea name="card43" size="0x516bd5">
+ <dataarea name="card" size="0x516bd5">
<rom name="0 - 0043.png" size="0x516bd5" crc="04c35610" sha1="e7867e16ad3acdb5459059381880aceb11935475"/>
</dataarea>
</part>
- <part name="card44" interface="sega_beena_cart">
+ <part name="card44" interface="tvochken_card">
<feature name="part_id" value="Card 44"/>
<feature name="barcode" value="0x9aca"/>
- <dataarea name="card44" size="0x51e8b7">
+ <dataarea name="card" size="0x51e8b7">
<rom name="0 - 0044.png" size="0x51e8b7" crc="5e5cde23" sha1="67161d59ae158286c86f0800366206daa8ff080e"/>
</dataarea>
</part>
- <part name="card45" interface="sega_beena_cart">
+ <part name="card45" interface="tvochken_card">
<feature name="part_id" value="Card 45"/>
<feature name="barcode" value="0xab12"/>
- <dataarea name="card45" size="0x51a367">
+ <dataarea name="card" size="0x51a367">
<rom name="0 - 0045.png" size="0x51a367" crc="2d06e5d6" sha1="7d82cbbb0cff2ad1710dfb025ff5517dd3fb6321"/>
</dataarea>
</part>
- <part name="card46" interface="sega_beena_cart">
+ <part name="card46" interface="tvochken_card">
<feature name="part_id" value="Card 46"/>
<feature name="barcode" value="0xab52"/>
- <dataarea name="card46" size="0x509b6a">
+ <dataarea name="card" size="0x509b6a">
<rom name="0 - 0046.png" size="0x509b6a" crc="91b3cf44" sha1="7be818e4dbfa9ea8bad46270edb71fa899be6aa6"/>
</dataarea>
</part>
- <part name="card47" interface="sega_beena_cart">
+ <part name="card47" interface="tvochken_card">
<feature name="part_id" value="Card 47"/>
<feature name="barcode" value="0xbba2"/>
- <dataarea name="card47" size="0x50b36f">
+ <dataarea name="card" size="0x50b36f">
<rom name="0 - 0047.png" size="0x50b36f" crc="106f037e" sha1="eb2a5d056b5f19c53233765c813cdfb53746f30b"/>
</dataarea>
</part>
- <part name="card48" interface="sega_beena_cart">
+ <part name="card48" interface="tvochken_card">
<feature name="part_id" value="Card 48"/>
<feature name="barcode" value="0xabd2"/>
- <dataarea name="card48" size="0x5073bd">
+ <dataarea name="card" size="0x5073bd">
<rom name="0 - 0048.png" size="0x5073bd" crc="f4f2efeb" sha1="07774d7bde672d5b40142448691689edafe63421"/>
</dataarea>
</part>
- <part name="card49" interface="sega_beena_cart">
+ <part name="card49" interface="tvochken_card">
<feature name="part_id" value="Card 49"/>
<feature name="barcode" value="0x9c0a"/>
- <dataarea name="card49" size="0x521ed6">
+ <dataarea name="card" size="0x521ed6">
<rom name="0 - 0049.png" size="0x521ed6" crc="0cf9a850" sha1="b92be28de3c8284d75045b161a37e8eb52c16e83"/>
</dataarea>
</part>
- <part name="card50" interface="sega_beena_cart">
+ <part name="card50" interface="tvochken_card">
<feature name="part_id" value="Card 50"/>
<feature name="barcode" value="0x9c4a"/>
- <dataarea name="card50" size="0x4f7f34">
+ <dataarea name="card" size="0x4f7f34">
<rom name="0 - 0050.png" size="0x4f7f34" crc="a918012a" sha1="a5a96c2c0a2ec76a3ec1784faaade33e0b8743e2"/>
</dataarea>
</part>
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 <algorithm>
+
#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 <unsigned N> u8 activate_r(offs_t offset);
template <unsigned N> 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 @@
+<?xml version="1.0"?>
+<!--
+license:CC0-1.0
+-->
+<mamelayout version="2">
+ <element name="card" />
+
+ <view name="Default View">
+ <screen index="0">
+ <bounds x="0" y="0" width="12" height="9" />
+ </screen>
+
+ <element ref="card">
+ <bounds x="0" y="9.25" width="12" height="8" />
+ </element>
+ </view>
+
+ <script><![CDATA[
+ local sub -- keep this here to avoid it being garbage collected prematurely
+
+ file:set_resolve_tags_callback(
+ function ()
+ -- get card slot device and card display element
+ local card_device = emu.image_enumerator(file.device)['card']
+ local card_element = file.elements['card']
+
+ -- invalidate the card display on media change
+ local card_data = card_device.device:memregion('card')
+ sub = card_device:add_media_change_notifier(
+ function (event)
+ card_data = card_device.device:memregion('card')
+ card_element:invalidate()
+ end)
+
+ -- draw the card image
+ card_element:set_draw_callback(
+ function (state, bitmap)
+ if card_data ~= nil then
+ -- TODO: reduce temporary memory usage when I/O classes are exposed to Lua
+ local data = card_data:read(0, card_data.size)
+ local image = emu.bitmap_argb32.load(data)
+ image:resample(bitmap)
+ end
+ end)
+ end)
+ ]]></script>
+</mamelayout>
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<generic_slot_device> m_cart;
- memory_region *m_cart_region;
-
required_device<screen_device> m_screen_main;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_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<generic_slot_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<tvochken_card_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 <locale>
+#include <sstream>
+
+
+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<std::error_condition, std::string> 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 <string>
+#include <system_error>
+#include <utility>
+
+
+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<std::error_condition, std::string> 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