New not working system & software list: Sega AI (#11747)

* bus/segaai: Rename device_segaai_card_interface to segaai_card_interface
* bus/segaai: Rename device_segaai_exp_interface to segaai_exp_interface

* hash/segaai.xml: Add barcode for several titles.
* hash/segaai.xml: Merge eigooha1 and eigooha2 into eigoohan, and eigogam1 and eigogam2 into eigogame.
* hash/segaai.xml: Update description for Eigo de Ohanashi and Eigo de Game.
* hash/segaai.xml: Add notes to Pinpon Music Rhythm and Melody.
* hash/segaai.xml: Merge Okeiko Aiueo and Hanamaru Aiueo into a single software item.
* hash/segaai.xml: Swapped checksums for Okeiko Aiueo and Hanamaru Aiueo and updated some notes.
* hash/segaai.xml: Added and replaced some overlays. Added placeholders for some older revisions released on cassette.
* hash/segaai.xml: Add cassette dumps of Alice World, Robinson Land, and Cosmis Train.
* hash/segaai.xml: Add dumps of several older cassette versions.
* hash/segaai.xml: Add/update serial, alt_title, and barcodes for cassette releases.
* hash/segaai.xml: Use improved overlay scans.

* layout/segaai.lay: Display clickable area when no overlay is present.
* layout/segaai.lay: Make cursor square.

* sega/segaai.cpp: Update old driver.
* sega/segaai.cpp: Let cards and expansions install themselves.
* sega/segaai.cpp: Adjust upd7759 sound level.
* sega/segaai.cpp: Mark cassette as stereo.
* sega/segaai.cpp: Only output the left channel from the cassette player.
* sega/segaai.cpp: Set the cassette channel to use for data input.
* sega/segaai.cpp: Add upd7759 busy signal to input port 4.
This commit is contained in:
wilbertpol 2024-01-23 21:23:49 +00:00 committed by GitHub
parent 9ca1b442a0
commit 245b399d0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 2308 additions and 0 deletions

740
hash/segaai.xml Normal file
View File

@ -0,0 +1,740 @@
<?xml version="1.0"?>
<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
<!--
license:CC0-1.0
-->
<!--
The following software titles are known for the Sega AI:
Cassettes "Kumon Wonder School" 1986-8-1 - 1987-9-1
===================================================
1 Alice World
2 Robinson Land
3 Cosmic Train
4 Cinderella Labyrinth
5 Gulliver Pocket
6 Mozart Academy
7 Arabian Night
8 Andersen Dream
9 Ocean Fantasy
10 Columbus Map
1st Set: MyCards "Wonder School" 1988-7-1
=========================================
AI-4051 Alice World
AI-4052 Robinson Land
AI-4053 Cosmic Train
AI-4054 Cinderella Labyrinth
AI-4055 Gulliver Pocket
AI-4056 Mozart Academy
AI-4057 Arabian Night
AI-4058 Andersen Dream
AI-4059 Ocean Fantasy
AI-4060 Columbus Map
2nd Set: "Ongaku Wonder School" 1988-10-1
=========================================
AI-4114 Runrun Music
AI-4115 Tantan Rhythm
AI-4116 Ranran Melody
3rd Set: "English Wonder School" / えいごわんだーすくーるー 1989-5-1
================================================================
C-9532 Eigo de Ohanashi 1
C-9533 Eigo de Game 1: Popo no Yume
C-9535 Eigo de Ohanashi 2
C-9536 Eigo de Game 2: Popoland no Himitsu
AI-4201 Hanamaru Aiueo & Okeiko Aiueo
AI-4202 Waku Waku ABC to 123
AI-4203 Henshin Kanji
AI-8001 Pinpon Numbers
AI-8002 Pinpon Music Rhythm
AI-8003 Pinpon Music Melody
AI E-nikki (1986)
AI E-nikki (1989)
-->
<softwarelist name="segaai" description="Sega AI Software">
<software name="alicewor">
<description>Alice World</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4051"/>
<info name="alt_title" value="ありす・わーるど"/>
<info name="barcode" value="4974365240615"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="alice world.bin" size="0x20000" crc="1647d3a6" sha1="680033fb5d0e4b91cd0078d4ab12e5f4fe122119"/>
</dataarea>
<dataarea name="overlay" size="453649">
<rom name="alice world.jpg" size="453649" crc="9c44ccdb" sha1="4b3e8aa25a868f154630cfe166ad89376f9e5917"/>
</dataarea>
</part>
</software>
<software name="alicewort" cloneof="alicewor" supported="no">
<description>Alice World (tape, older)</description>
<year>1986</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="1"/>
<info name="alt_title" value="アリス ワールド"/>
<info name="barcode" value="4974365240011"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="357096">
<rom name="alice world (1986).jpg" size="357096" crc="64b2482d" sha1="e756a4054d2b0f45a02620a581134d86d1496737"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<!-- Side A, side B is empty -->
<dataarea name="cass" size="70982226">
<rom name="alice world (1986).flac" size="70982226" crc="d49d9a74" sha1="40e7c48217dd44156de6126521ea6fd25056a4f1"/>
</dataarea>
</part>
</software>
<software name="robinson">
<description>Robinson Land</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4052"/>
<info name="alt_title" value="ろびんそん・らんど"/>
<info name="barcode" value="4974365240622"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="robinson land.bin" size="0x20000" crc="60d22b3d" sha1="fa17ec899c8ed87681c110c3ef0e05d46fc9cdf3"/>
</dataarea>
<dataarea name="overlay" size="348822">
<rom name="robinson land.jpg" size="348822" crc="f5170856" sha1="97dd3264326232ab320753fd8228195b67f727b8"/>
</dataarea>
</part>
</software>
<software name="robinsont" cloneof="robinson" supported="no">
<description>Robinson Land (tape, older)</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="2"/>
<info name="alt_title" value="ロビンソン・ランド"/>
<info name="barcode" value="4974365240028"/>
<!-- No overlay. -->
<part name="cass" interface="cass">
<!-- Side A, side B is empty -->
<dataarea name="cass" size="61534605">
<rom name="robinson land (1987).flac" size="61534605" crc="9c7b099d" sha1="e196aafd6b3d4ec90c234205e0a9a6a1696ed38b"/>
</dataarea>
</part>
</software>
<software name="cosmictr">
<description>Cosmic Train</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4053"/>
<info name="alt_title" value="こずみっく・とれいん"/>
<info name="barcode" value="4974365240639"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="cosmic train.bin" size="0x20000" crc="cc70a670" sha1="38b8d458540ede5d91f2e1ea8e6dc9a7ed475d82"/>
</dataarea>
<dataarea name="overlay" size="475288">
<rom name="cosmic train.jpg" size="475288" crc="f0aa8f0e" sha1="e37165b44aa05c0191b6dac73ed8dfd07e647896"/>
</dataarea>
</part>
</software>
<software name="cosmictrt" cloneof="cosmictr" supported="no">
<description>Cosmic Train (tape, older)</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="3"/>
<info name="alt_title" value="コスミック・トレイン"/>
<info name="barcode" value="4974365240127"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="440521">
<rom name="cosmic train (1987).jpg" size="440521" crc="735e7ced" sha1="41d2547b802c296620c67ea12866e116fa80d399"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<!-- Side A, side B is empty -->
<dataarea name="cass" size="120000310">
<rom name="cosmic train (1987).flac" size="120000310" crc="144f9204" sha1="3d8a0ec86c6e4515857853fedd34588a2545249e"/>
</dataarea>
</part>
</software>
<software name="cinderel">
<description>Cinderella Labyrinth</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4054"/>
<info name="alt_title" value="しんでれら・らびりんす"/>
<info name="barcode" value="4974365240646"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="cinderella labyrinth.bin" size="0x20000" crc="cc865679" sha1="49a4cdb6f775786285271f7ea07334a8fad7a7f9"/>
</dataarea>
<dataarea name="overlay" size="601568">
<rom name="cinderella labyrinth.jpg" size="601568" crc="9d8f9786" sha1="761355f3fd4dfb0a75ca48b6be8833b6f9e8e141"/>
</dataarea>
</part>
</software>
<software name="cinderelt" cloneof="cinderel" supported="no">
<description>Cinderella Labyrinth (tape, older)</description>
<year>1986</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="4"/>
<info name="alt_title" value="シンデレラ・ラビリンス"/>
<info name="barcode" value="4974365240042"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="512880">
<rom name="cinderella labyrinth (1986).jpg" size="512880" crc="4aee47fc" sha1="9b5be6597b1f77ce770d423686109d57cba7395e"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="63843667">
<rom name="cinderella labyrinth (1986).flac" size="63843667" crc="f0f89f0e" sha1="800c0cc4924551ba99a4379a85508ac91cfb453b"/>
</dataarea>
</part>
</software>
<software name="gulliver">
<description>Gulliver Pocket</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4055"/>
<info name="alt_title" value="がりばー・ぽけっと"/>
<info name="barcode" value="4974365240653"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="gulliver pocket.bin" size="0x20000" crc="766b1630" sha1="d186bbd6f6e1d4577efc820c80b2e492ac979c4c"/>
</dataarea>
<dataarea name="overlay" size="486686">
<rom name="gulliver pocket.jpg" size="486686" crc="34a25d62" sha1="33624aa0b6c73cd5c7d0454df6f9a0858c02c28f"/>
</dataarea>
</part>
</software>
<software name="gullivert" cloneof="gulliver" supported="no">
<description>Gulliver Pocket (tape, older)</description>
<year>1986</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="5"/>
<info name="alt_title" value="ガリバー・ポケット"/>
<info name="barcode" value="4974365240059"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="424585">
<rom name="gulliver pocket (1986).jpg" size="424585" crc="ad13e8e7" sha1="a79e725c5cafdf9ddd1afa6f38510db390ab3dc5"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="62076328">
<rom name="gulliver pocket (1986).flac" size="62076328" crc="12fd6a59" sha1="c0523cad2656df42ce83465540d6637ca956f176"/>
</dataarea>
</part>
</software>
<software name="mozartac">
<description>Mozart Academy</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4056"/>
<info name="alt_title" value="もーつぁると・あかでみー"/>
<info name="barcode" value="4974365240660"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="mozart academy.bin" size="0x20000" crc="09bbee0f" sha1="16df750fd7f1f1882768e0e6cee89b92863cf79e"/>
</dataarea>
<dataarea name="overlay" size="364362">
<rom name="mozart academy.jpg" size="364362" crc="9e8818ad" sha1="8bd614c0df29b6a897a7776212952b7c3bb6b409"/>
</dataarea>
</part>
</software>
<software name="mozartact" cloneof="mozartac" supported="no">
<description>Mozart Academy (tape, older)</description>
<year>1986</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="6"/>
<info name="alt_title" value="モーツァルト・アカデミー"/>
<info name="barcode" value="4974365240066"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="249080">
<rom name="mozart academy (1986).jpg" size="249080" crc="92368896" sha1="b64db5d24a1509c2970ac35864426078083c89d1"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="63942538">
<rom name="mozart academy (1986).flac" size="63942538" crc="165597f8" sha1="5f7e1036e56a361ae89532cdd9996d4c3f8d624c"/>
</dataarea>
</part>
</software>
<software name="arabiann">
<description>Arabian Night</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4057"/>
<info name="alt_title" value="あらびあん・ないと"/>
<info name="barcode" value="4974365240677"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<dataarea name="rom" size="0x40000">
<rom name="arabian night.bin" size="0x40000" crc="c47ca594" sha1="347d525de9a00da557b684caae7d75680aae50fd"/>
</dataarea>
<dataarea name="overlay" size="539768">
<rom name="arabian night.jpg" size="539768" crc="c880f203" sha1="1c1327e16f1a73e40555882fc7065b772434f861"/>
</dataarea>
</part>
</software>
<software name="arabiannt" cloneof="arabiann" supported="no">
<description>Arabian Night (tape, older)</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="7"/>
<info name="alt_title" value="アラビアン・ナイト"/>
<info name="barcode" value="4974365240073"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="414478">
<rom name="arabian night (1987).jpg" size="414478" crc="e4080789" sha1="d40660a456535df962f806a9d6447fb1233ba2ea"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="130947422">
<rom name="arabian night (1987).flac" size="130947422" crc="f750ca29" sha1="f8e46123f3c7172bbf64ab032cac7b8419f9c5b1"/>
</dataarea>
</part>
</software>
<software name="andersen">
<description>Andersen Dream</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4058"/>
<info name="alt_title" value="あんでるせん・どりーむ"/>
<info name="barcode" value="4974365240684"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="andersen dream.bin" size="0x20000" crc="ef23c880" sha1="9f78bd9c2e583fa258451a98db13ec2428cef242"/>
</dataarea>
<dataarea name="overlay" size="466888">
<rom name="andersen dream.jpg" size="466888" crc="0793000a" sha1="62027ae7fd5af95bfbdecdabc1b60dc6fdbac58f"/>
</dataarea>
</part>
</software>
<software name="andersent" cloneof="andersen" supported="no">
<description>Andersen Dream (tape, older)</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="8"/>
<info name="alt_title" value="アンデルセン・ドリーム"/>
<info name="barcode" value="4974365240080"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="411831">
<rom name="andersen dream (1987).jpg" size="411831" crc="2f03ae8a" sha1="7d16493baec1fdf5e9ba5d284f421be362a39951"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="112724313">
<rom name="andersen dream (1987).flac" size="112724313" crc="884806f2" sha1="439b4bd107f3d0d59bba32c43d1486e0763e4ac4"/>
</dataarea>
</part>
</software>
<software name="oceanfan">
<description>Ocean Fantasy</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4059"/>
<info name="alt_title" value="おーしゃん・ふぁんたじー"/>
<info name="barcode" value="4974365240691"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<dataarea name="rom" size="0x40000">
<rom name="ocean fantasy.bin" size="0x40000" crc="2fe2d406" sha1="eab433b27725b3ef884c66f2ec1ba04af9a61dc1"/>
</dataarea>
<dataarea name="overlay" size="470555">
<rom name="ocean fantasy.jpg" size="470555" crc="fd1f318d" sha1="4ecf38dafbd5f117511835b0ea7faaac171dce29"/>
</dataarea>
</part>
</software>
<software name="oceanfant" cloneof="oceanfan" supported="no">
<description>Ocean Fantasy (tape, older)</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="9"/>
<info name="alt_title" value="オーシャン・ファンタジー"/>
<info name="barcode" value="4974365240103"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="304726">
<rom name="ocean fantasy (1987).jpg" size="304726" crc="b927f8c1" sha1="4b59e3bdb7c4ed160cb678f24b5a4e07508a6e43"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="146922567">
<rom name="ocean fantasy (1987).flac" size="146922567" crc="0e67892c" sha1="8d9a1474c87a2e2f147e528b51f9903cf7f08c11"/>
</dataarea>
</part>
</software>
<software name="columbus">
<description>Columbus Map</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4060"/>
<info name="alt_title" value="ころんぶす・まっぷ"/>
<info name="barcode" value="4974365240707"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="columbus map.bin" size="0x20000" crc="c95cd4e3" sha1="7aafc37b81d524f046e62dd2e289d142b3c639a6"/>
</dataarea>
<dataarea name="overlay" size="459268">
<rom name="columbus map.jpg" size="459268" crc="c5f6477a" sha1="336b89fa073d6a1303c932d604118a7518582b42"/>
</dataarea>
</part>
</software>
<software name="columbust" cloneof="columbus" supported="no">
<description>Columbus Map (tape, older)</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="serial" value="10"/>
<info name="alt_title" value="コロンブス・マップ"/>
<info name="barcode" value="4974365240110"/>
<part name="card" interface="segaai_card">
<!-- Hack to get the overlay to display; no mycard included in this release. -->
<feature name="part_id" value="Overlay"/>
<dataarea name="rom" size="0x20000"/>
<dataarea name="overlay" size="662612">
<rom name="columbus map (1987).jpg" size="662612" crc="631b58cb" sha1="8dff423f00d17cde01b62bce03f46ed922e50a9c"/>
</dataarea>
</part>
<part name="cass" interface="cass">
<dataarea name="cass" size="64783507">
<rom name="columbus map (1987).flac" size="64783507" crc="4478e9cc" sha1="615f3bb0a3d4be28ce6f7faf5cb165386475c90d"/>
</dataarea>
</part>
</software>
<software name="runrunmu">
<description>Runrun Music</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4114"/>
<info name="alt_title" value="るんるん・みゅーじっく"/>
<info name="barcode" value="4974365241148"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="runrun music.bin" size="0x20000" crc="9e8f5233" sha1="f0396cb16b6b5295eef71a4acda5c45d492313e1"/>
</dataarea>
<dataarea name="overlay" size="455482">
<rom name="runrun music.jpg" size="455482" crc="aff199c2" sha1="2bf73ee463808f6f4b5b1b7434b94f04ca5d1a40"/>
</dataarea>
</part>
</software>
<software name="tantanrh">
<description>Tantan Rhythm</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4115"/>
<info name="alt_title" value="たんたん・りずむ"/>
<info name="barcode" value="4974365241155"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="tantan rhythm.bin" size="0x20000" crc="33059c56" sha1="8ee471bc616cd476b64dcd63eb493c980e0dd888"/>
</dataarea>
<dataarea name="overlay" size="426500">
<rom name="tantan rhythm.jpg" size="426500" crc="6306408a" sha1="e9332fbeee99cc502ae3ee6fc9b55f98bf4d44ce"/>
</dataarea>
</part>
</software>
<software name="ranranme">
<description>Ranran Melody</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4116"/>
<info name="alt_title" value="らんらん・めろでぃー"/>
<info name="barcode" value="4974365241162"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="ranran melody.bin" size="0x20000" crc="6e7b1b27" sha1="d66eee759ac03bf877005d699e50af264f0f475b"/>
</dataarea>
<dataarea name="overlay" size="342453">
<rom name="ranran melody.jpg" size="342453" crc="a8961042" sha1="69040f152ddacf87cd6801b017fb1326271434f3"/>
</dataarea>
</part>
</software>
<software name="okeihana">
<description>Okeiko Hanamaru Aiueo</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4201"/>
<info name="alt_title" value="おけいこ・はなまる あいえうお"/>
<part name="card1" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<feature name="part_id" value="Okeiko Aiueo"/>
<dataarea name="rom" size="0x20000">
<rom name="okeiko aiueo.bin" size="0x20000" crc="252a0490" sha1="ab9d00a575bf0fb12557315fcd7c7e16caa8d802"/>
</dataarea>
</part>
<part name="card2" interface="segaai_card">
<feature name="slot" value="rom_128" />
<feature name="part_id" value="Hanamaru Aiueo"/>
<dataarea name="rom" size="0x20000">
<rom name="hanamaru aiueo.bin" size="0x20000" crc="60bfd7c3" sha1="44fc802e66f086a3cb49e4fcde22ce6f704b405f"/>
</dataarea>
</part>
</software>
<software name="wakuwaku">
<description>Waku Waku ABC to 123</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4202"/>
<info name="alt_title" value="わくわく ABCと123"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<dataarea name="rom" size="0x40000">
<rom name="waku waku abc to 123.bin" size="0x40000" crc="de094c16" sha1="57e6c027004b2a4086d2a061c1373ee71c5f6faa"/>
</dataarea>
</part>
</software>
<software name="henshin">
<description>Henshin Kanji</description>
<year>1988</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-4203"/>
<info name="alt_title" value="へんしんかんじ"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<dataarea name="rom" size="0x40000">
<rom name="henshin kanji.bin" size="0x40000" crc="1248035d" sha1="920386cd72482a389217de9387a7ee39fc226be1"/>
</dataarea>
</part>
</software>
<software name="pinponnm">
<description>Pinpon Numbers</description>
<year>1987</year>
<publisher>Sega</publisher>
<info name="serial" value="AI-8001"/>
<info name="alt_title" value="ピンポン ナンバーズ"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="pinpon numbers.bin" size="0x20000" crc="8103d3b0" sha1="93ba9244bf6e07789617b2d182043da28aea0999"/>
</dataarea>
<dataarea name="overlay" size="408197">
<rom name="pinpon numbers.jpg" size="408197" crc="525fe509" sha1="8f7c2f44a0948a306444432a9d6be7ea536590c1"/>
</dataarea>
</part>
</software>
<software name="pinponmr" supported="no">
<description>Pinpon Music Rhythm</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>No sound and cannot start a game.</notes>
<info name="serial" value="AI-8002"/>
<info name="alt_title" value="ピンポン ミュージック リズム"/>
<info name="usage" value="Requires Soundbox."/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="pinpon music rhythm.bin" size="0x20000" crc="376195cb" sha1="709d53959082a3e5477fb15c187612c98b0baac5"/>
</dataarea>
<dataarea name="overlay" size="363366">
<rom name="pinpon music rhythm.jpg" size="363366" crc="4a66fef5" sha1="f4c5626e06f1d032a153c73c45139bb87a8e8d72"/>
</dataarea>
</part>
</software>
<software name="pinponmm" supported="no">
<description>Pinpon Music Melody</description>
<year>1987</year>
<publisher>Sega</publisher>
<notes>No sound and cannot start a game.</notes>
<info name="serial" value="AI-8003"/>
<info name="alt_title" value="ピンポン ミュージック メロディー"/>
<info name="usage" value="Requires Soundbox."/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="pinpon music melody.bin" size="0x20000" crc="2deecb0c" sha1="3bddf3950921d09cf34e6def23cf491c8fa670c2"/>
</dataarea>
<dataarea name="overlay" size="336083">
<rom name="pinpon music melody.jpg" size="336083" crc="8b3ef04f" sha1="1b73747727c1d9febb5fb1e8f7164c17d66f7873"/>
</dataarea>
</part>
</software>
<software name="eigoohan" supported="no">
<description>Eigo de Ohanashi - English Wonder School: Folk &amp; Fairy Tales</description>
<year>1989</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet.</notes>
<info name="alt_title" value="えいごでおはなし"/>
<info name="barcode" value="4974365242060"/>
<part name="card1" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<feature name="part_id" value="C-9532 - えいごでおはなし1"/>
<dataarea name="rom" size="0x40000">
<rom name="eigo de ohanashi 1.bin" size="0x40000" crc="a43c79ba" sha1="2f69ea2b126803463f512c4b95c5586961214eaa"/>
</dataarea>
</part>
<part name="cass1a" interface="flac_cass">
<feature name="part_id" value="えいごでおはなし1 - Side A"/>
<dataarea name="cass" size="58086526">
<rom name="eigo de ohanashi 1 (side a).flac" size="58086526" crc="7a57c841" sha1="701013bcce40110e13ec3c2adfd2f65f6dfcf06b"/>
</dataarea>
</part>
<part name="cass1b" interface="flac_cass">
<feature name="part_id" value="えいごでおはなし1 - Side B"/>
<dataarea name="cass" size="55647160">
<rom name="eigo de ohanashi 1 (side b).flac" size="55647160" crc="bb1debfd" sha1="622b23180a21f55743a4864d446bc31007e287b5"/>
</dataarea>
</part>
<part name="card2" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<feature name="part_id" value="C-9535 - えいごでおはなし2"/>
<dataarea name="rom" size="0x40000">
<rom name="eigo de ohanashi 2.bin" size="0x40000" crc="ce241ffb" sha1="6d903af3c7f7f98090228f011936132ddd4f2cc6"/>
</dataarea>
</part>
<part name="cass2a" interface="flac_cass">
<feature name="part_id" value="えいごでおはなし2 - Side A"/>
<dataarea name="cass" size="60913103">
<rom name="eigo de ohanashi 2 (side a).flac" size="60913103" crc="2b3c496f" sha1="4d826c54b30c9e6df2f4275666cb932405a6cd1f"/>
</dataarea>
</part>
<part name="cass2b" interface="flac_cass">
<feature name="part_id" value="えいごでおはなし2 - Side B"/>
<dataarea name="cass" size="58812097">
<rom name="eigo de ohanashi 2 (side b).flac" size="58812097" crc="2cca36eb" sha1="393d1b6ed5318d07a9407644ed921e2b76569ffd"/>
</dataarea>
</part>
</software>
<software name="eigogame" supported="no">
<description>Eigo de Game - English Wonder School: Popo's Adventure</description>
<year>1989</year>
<publisher>Sega</publisher>
<notes>Cassette is not supported yet. Eigo de Game 2: Only the first entry from the menu works, the color names and 'big' are spoken. The other menu entries hang waiting for the cassette.</notes>
<info name="alt_title" value="えいごでげーむ"/>
<info name="barcode" value="4974365242053"/>
<part name="card1" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<feature name="part_id" value="C-9533 - えいごでげーむ1 Popoのゆめ"/>
<dataarea name="rom" size="0x40000">
<rom name="eigo de game 1 - popo no yume.bin" size="0x40000" crc="096ed76a" sha1="c9ad9479b72c7b58c596feaab984697b6cc1aa9e"/>
</dataarea>
</part>
<part name="cass1" interface="flac_cass">
<feature name="part_id" value="えいごでげーむ1 Popoのゆめ"/>
<dataarea name="cass" size="62294686">
<rom name="eigo de game 1 - popo no yume.flac" size="62294686" crc="2a89cd04" sha1="7207aae9543744a198dafaa969a812ddaa667160"/>
</dataarea>
</part>
<part name="card2" interface="segaai_card">
<feature name="slot" value="rom_256"/>
<feature name="part_id" value="C-9536 - えいごでげーむ2 Popolandのひみつ"/>
<dataarea name="rom" size="0x40000">
<rom name="eigo de game 2 - popoland no himitsu.bin" size="0x40000" crc="bd55f48c" sha1="8d25a2cbbf53844df94fc1becf461adc8b3f0190"/>
</dataarea>
</part>
<part name="cass2" interface="flac_cass">
<feature name="part_id" value="えいごでげーむ2 Popolandのひみつ"/>
<dataarea name="cass" size="71325328">
<rom name="eigo de game 2 - popoland no himitsu.flac" size="71325328" crc="f6bbee6c" sha1="c967cf013e7fc02aed7ad5d0979c05cf280fd30e"/>
</dataarea>
</part>
</software>
<software name="aienikki">
<description>AI Enikki</description>
<year>1989</year>
<publisher>Sega?</publisher>
<info name="alt_title" value="AIえにっき"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="ai enikki.bin" size="0x20000" crc="79bcc160" sha1="6a4280af6d668b0047629ad64e2b85626805913a"/>
</dataarea>
<dataarea name="overlay" size="210681">
<rom name="ai enikki.jpg" size="210681" crc="1d218dab" sha1="8d351acd7a6808ebc2d889caa016d85501c19cca"/>
</dataarea>
</part>
</software>
<!-- Note from smspower: The 1986 version of AI Enikki uses less data, I have trimmed the file to 96 KB as when reading the last 32KB it was returning the same data as the 64KB-96KB range -->
<software name="aienikkia" cloneof="aienikki">
<description>AI Enikki (1986)</description>
<year>1986</year>
<publisher>Sega?</publisher>
<info name="alt_title" value="AIえにっき"/>
<part name="card" interface="segaai_card">
<feature name="slot" value="rom_128"/>
<dataarea name="rom" size="0x20000">
<rom name="ai enikki (1986).bin" size="0x18000" crc="1849119c" sha1="2b04fe1ba0196ef24f2e1ea0270785cbbbf29c40"/>
</dataarea>
<dataarea name="overlay" size="415344">
<rom name="ai enikki (1986).jpg" size="415344" crc="8bb40fa4" sha1="801316456a800e6bc19fb840adacb09d328a450b"/>
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -2395,6 +2395,25 @@ if (BUSES["S100"]~=null) then
end
---------------------------------------------------
--
--@src/devices/bus/segaai/segaai_exp.h,BUSES["SEGAAI"] = true
---------------------------------------------------
if (BUSES["SEGAAI"]~=null) then
files {
MAME_DIR .. "src/devices/bus/segaai/rom.cpp",
MAME_DIR .. "src/devices/bus/segaai/rom.h",
MAME_DIR .. "src/devices/bus/segaai/segaai_exp.cpp",
MAME_DIR .. "src/devices/bus/segaai/segaai_exp.h",
MAME_DIR .. "src/devices/bus/segaai/segaai_slot.cpp",
MAME_DIR .. "src/devices/bus/segaai/segaai_slot.h",
MAME_DIR .. "src/devices/bus/segaai/soundbox.cpp",
MAME_DIR .. "src/devices/bus/segaai/soundbox.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/spc1000/exp.h,BUSES["SPC1000"] = true

View File

@ -0,0 +1,93 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
/***********************************************************************************************************
Sega AI card emulation
***********************************************************************************************************/
#include "emu.h"
#include "rom.h"
namespace {
class segaai_rom_128_device : public device_t,
public segaai_card_interface
{
public:
segaai_rom_128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: segaai_rom_128_device(mconfig, SEGAAI_ROM_128, tag, owner, clock)
{ }
virtual void install_memory_handlers(address_space *space) override;
protected:
segaai_rom_128_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, segaai_card_interface(mconfig, *this)
{ }
virtual void device_start() override { }
};
void segaai_rom_128_device::install_memory_handlers(address_space *space)
{
space->install_rom(0xa0000, 0xbffff, cart_rom_region()->base());
}
class segaai_rom_256_device : public segaai_rom_128_device
{
public:
segaai_rom_256_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: segaai_rom_128_device(mconfig, SEGAAI_ROM_256, tag, owner, clock)
, m_rom_bank(*this, "rombank%u", 0U)
{ }
virtual void install_memory_handlers(address_space *space) override;
private:
template <int Bank> void bank_w(u8 data);
void unknown0_w(u8 data);
void unknown1_w(u8 data);
memory_bank_array_creator<2> m_rom_bank;
};
void segaai_rom_256_device::install_memory_handlers(address_space *space)
{
for (int i = 0; i < 2; i++)
m_rom_bank[i]->configure_entries(0, cart_rom_region()->bytes() / 0x4000, cart_rom_region()->base(), 0x4000);
space->install_rom(0xa0000, 0xa3fff, 0x10000, cart_rom_region()->base());
space->install_read_bank(0xa4000, 0xa7fff, 0x10000, m_rom_bank[0]);
space->install_read_bank(0xa8000, 0xabfff, 0x10000, m_rom_bank[1]);
space->install_write_handler(0xafffc, 0xafffc, 0, 0x10000, 0, emu::rw_delegate(*this, FUNC(segaai_rom_256_device::unknown0_w)));
space->install_write_handler(0xafffd, 0xafffd, 0, 0x10000, 0, emu::rw_delegate(*this, FUNC(segaai_rom_256_device::unknown1_w)));
space->install_write_handler(0xafffe, 0xafffe, 0, 0x10000, 0, emu::rw_delegate(*this, FUNC(segaai_rom_256_device::bank_w<0>)));
space->install_write_handler(0xaffff, 0xaffff, 0, 0x10000, 0, emu::rw_delegate(*this, FUNC(segaai_rom_256_device::bank_w<1>)));
}
template <int Bank>
void segaai_rom_256_device::bank_w(u8 data)
{
m_rom_bank[Bank]->set_entry(data & 0x0f);
}
void segaai_rom_256_device::unknown0_w(u8 data)
{
// Unknown, upon start $00 is written and sometimes $80 after that
}
void segaai_rom_256_device::unknown1_w(u8 data)
{
// Unknown, upon start $00 is written
}
} // anonymous namespace
DEFINE_DEVICE_TYPE_PRIVATE(SEGAAI_ROM_128, segaai_card_interface, segaai_rom_128_device, "segaai_rom_128", "Sega AI Card - 128KB")
DEFINE_DEVICE_TYPE_PRIVATE(SEGAAI_ROM_256, segaai_card_interface, segaai_rom_256_device, "segaai_rom_256", "Sega AI Card - 256KB")

View File

@ -0,0 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
#ifndef MAME_BUS_SEGAAI_ROM_H
#define MAME_BUS_SEGAAI_ROM_H
#pragma once
#include "segaai_slot.h"
DECLARE_DEVICE_TYPE(SEGAAI_ROM_128, segaai_card_interface);
DECLARE_DEVICE_TYPE(SEGAAI_ROM_256, segaai_card_interface);
#endif

View File

@ -0,0 +1,48 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
/***********************************************************************************************************
Sega AI Expansion slot emulation
***********************************************************************************************************/
#include "emu.h"
#include "segaai_exp.h"
DEFINE_DEVICE_TYPE(SEGAAI_EXP_SLOT, segaai_exp_slot_device, "segaai_exp_slot", "Sega AI Expansion Slot")
segaai_exp_interface::segaai_exp_interface(const machine_config &mconfig, device_t &device)
: device_interface(device, "segaai_exp")
, m_slot(dynamic_cast<segaai_exp_slot_device *>(device.owner()))
{
}
segaai_exp_interface::~segaai_exp_interface()
{
}
segaai_exp_slot_device::segaai_exp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SEGAAI_EXP_SLOT, tag, owner, clock)
, device_single_card_slot_interface<segaai_exp_interface>(mconfig, *this)
, m_mem_space(*this, finder_base::DUMMY_TAG, -1)
, m_io_space(*this, finder_base::DUMMY_TAG, -1)
{
}
segaai_exp_slot_device::~segaai_exp_slot_device()
{
}
// slot interfaces
#include "soundbox.h"
void segaai_exp(device_slot_interface &device)
{
device.option_add("soundbox", SEGAAI_SOUNDBOX);
}

View File

@ -0,0 +1,63 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
#ifndef MAME_BUS_SEGAAI_EXP_H
#define MAME_BUS_SEGAAI_EXP_H
#pragma once
DECLARE_DEVICE_TYPE(SEGAAI_EXP_SLOT, segaai_exp_slot_device);
class segaai_exp_interface;
class segaai_exp_slot_device : public device_t,
public device_single_card_slot_interface<segaai_exp_interface>
{
public:
template <typename T>
segaai_exp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&opts, const char *dflt)
: segaai_exp_slot_device(mconfig, tag, owner, clock)
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
}
segaai_exp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual ~segaai_exp_slot_device();
template <typename T> void set_mem_space(T &&tag, int no) { m_mem_space.set_tag(std::forward<T>(tag), no); }
template <typename T> void set_io_space(T &&tag, int no) { m_io_space.set_tag(std::forward<T>(tag), no); }
address_space& mem_space() { return *m_mem_space; }
address_space& io_space() { return *m_io_space; }
protected:
virtual void device_start() override { }
private:
optional_address_space m_mem_space;
optional_address_space m_io_space;
};
class segaai_exp_interface : public device_interface
{
public:
segaai_exp_interface(const machine_config &mconfig, device_t &device);
virtual ~segaai_exp_interface();
protected:
address_space& mem_space() { return m_slot->mem_space(); }
address_space& io_space() { return m_slot->io_space(); }
private:
segaai_exp_slot_device *const m_slot;
};
// slot interfaces
void segaai_exp(device_slot_interface &device);
#endif

View File

@ -0,0 +1,99 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
/***********************************************************************************************************
Sega AI card emulation
***********************************************************************************************************/
#include "emu.h"
#include "segaai_slot.h"
DEFINE_DEVICE_TYPE(SEGAAI_CARD_SLOT, segaai_card_slot_device, "segaai_card_slot", "Sega AI Card Slot")
static char const *const ROM_128 = "rom_128";
static char const *const ROM_256 = "rom_256";
segaai_card_interface::segaai_card_interface(const machine_config &mconfig, device_t &device)
: device_interface(device, "segaai_card")
, m_slot(dynamic_cast<segaai_card_slot_device *>(device.owner()))
{
}
segaai_card_interface::~segaai_card_interface()
{
}
segaai_card_slot_device::segaai_card_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SEGAAI_CARD_SLOT, tag, owner, clock)
, device_cartrom_image_interface(mconfig, *this)
, device_single_card_slot_interface<segaai_card_interface>(mconfig, *this)
, m_address_space(*this, finder_base::DUMMY_TAG, -1, 8)
{
}
segaai_card_slot_device::~segaai_card_slot_device()
{
}
void segaai_card_slot_device::device_start()
{
m_cart = get_card_device();
}
std::pair<std::error_condition, std::string> segaai_card_slot_device::call_load()
{
if (m_cart)
{
const u32 length = !loaded_through_softlist() ? this->length() : get_software_region_length("rom");
if (length != 0x20000 && length != 0x40000)
{
return std::make_pair(image_error::INVALIDIMAGE, "Invalid card size. Supported sizes are: 128KB, 256KB");
}
if (!loaded_through_softlist())
{
memory_region *const romregion = machine().memory().region_alloc(subtag("rom"), length, 1, ENDIANNESS_LITTLE);
if (fread(romregion->base(), length) != length)
return std::make_pair(image_error::UNSPECIFIED, "Unable to fully read file");
}
m_cart->install_memory_handlers(m_address_space.target());
return std::make_pair(std::error_condition(), std::string());
}
return std::make_pair(std::error_condition(), std::string());
}
std::string segaai_card_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
if (hook.image_file())
{
uint64_t length;
hook.image_file()->length(length);
return std::string(length == 0x40000 ? ROM_256 : ROM_128);
}
return software_get_default_slot(ROM_128);
}
// slot interfaces
#include "rom.h"
void segaai_cards(device_slot_interface &device)
{
device.option_add_internal(ROM_128, SEGAAI_ROM_128);
device.option_add_internal(ROM_256, SEGAAI_ROM_256);
}

View File

@ -0,0 +1,73 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
#ifndef MAME_BUS_SEGAAI_SLOT_H
#define MAME_BUS_SEGAAI_SLOT_H
#pragma once
#include "imagedev/cartrom.h"
DECLARE_DEVICE_TYPE(SEGAAI_CARD_SLOT, segaai_card_slot_device);
class segaai_card_interface;
class segaai_card_slot_device : public device_t,
public device_cartrom_image_interface,
public device_single_card_slot_interface<segaai_card_interface>
{
public:
template <typename T>
segaai_card_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt)
: segaai_card_slot_device(mconfig, tag, owner, u32(0))
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
}
segaai_card_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual ~segaai_card_slot_device();
template <typename T> void set_address_space(T &&tag, int no) { m_address_space.set_tag(std::forward<T>(tag), no); }
virtual std::pair<std::error_condition, std::string> call_load() override;
virtual void call_unload() override {}
virtual const char *image_type_name() const noexcept override { return "card"; }
virtual const char *image_brief_type_name() const noexcept override { return "card"; }
virtual bool is_reset_on_load() const noexcept override { return true; }
virtual const char *image_interface() const noexcept override { return "segaai_card"; }
virtual const char *file_extensions() const noexcept override { return "aic,bin"; }
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
protected:
virtual void device_start() override;
private:
optional_address_space m_address_space;
segaai_card_interface* m_cart;
};
class segaai_card_interface : public device_interface
{
public:
segaai_card_interface(const machine_config &mconfig, device_t &device);
virtual ~segaai_card_interface();
virtual void install_memory_handlers(address_space *space) { }
protected:
memory_region *cart_rom_region() { return m_slot ? m_slot->memregion("rom") : nullptr; }
private:
segaai_card_slot_device *const m_slot;
};
void segaai_cards(device_slot_interface &device);
#endif

View File

@ -0,0 +1,320 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol, Fabio Priuli
// thanks-to:Chris Covell
/***********************************************************************************************************
Sega AI Soundbox expansion emulation
Sega AI Computer Sound Box, Model "AI-2002" quick PCB overview by Chris Covell
ICs on board:
IC 2 TMP82C53F-2 (91/09) Toshiba (Peripheral Timer)
IC 3 HN27512G-25 (87/12) Hitachi 64K EPROM
IC 6 YM2151 (91/10) Yamaha FM chip
IC 7 TMP82C55AF-10 (88/15) Toshiba (Peripheral Interface)
IC 8 YM3012 (91/10) Yamaha Stereo DAC
IC 9 HA17358 Hitachi Dual Op-Amp
IC 10 LC7537N Sanyo (Volume Control IC)
IC 11 C324C (90/42) NEC Quad Op-Amp
IC 12 LA4520 (Sanyo Power Audio Amp?)
IC 16-19 MB81464-12 (91/12) Fujitsu 32K DRAMs
Misc Flat DIPs
IC ?? LS125A Hitachi (near C41)
IC ?? 74HC04 TI (near C38)
IC ?? 74HC157A x2 Toshiba (near C37)
IC ?? 74HC138 TI (near C44, furthest)
IC ?? 74HC139 TI (near C44, closest)
TODO:
- Connections of the 8253
- Keyboard matrix is scanned on a timer irq (#FC) from 8253??
- LC7537N
HC04
pin 1 A1 - PB7
pin 2 Y1 -> HC04 pin 3 A2
pin 3 A2 <- HC04 pin 2 Y1
pin 4 Y2 -> 4th point, 1st row below HC04?
pin 5 A3 -
pin 6 Y3 -
pin 7 GND -
pin 8 Y4 - 1st point, 2nd row below HC04
pin 9 A4 - 1st point, 1st row below HC04
pin 10 Y5 -
pin 11 A5 <- HC04 pin 12 Y6
pin 12 Y6 -> HC04 pin 11 A5
pin 13 A6 - point just below C38 then continues to DRAMs
pin 14 VCC -
8255 PB7 - connected to HC04 pin 1?, pulled low
TMP8253
pin 9 CLK0 - seems to be tied to pin 24 in ym2151
pin 14 OUT0 - --> 2nd point, 2nd row below HC04
pin 15 GATE0 - NC
pin 18 OUT1 - 7th point, 1st row below HC04 -> 8th point, 1st row below HC04 -> LS125 pin 2?
pin 19 GATE1 - 6th point, 1st row below HC04 -> 4th point, 1st row below HC04
pin 20 CLK1 - 5th point, 1st row below HC04 -> 2nd point, 1st row below HC04 -> left point above C37 -> pin 1 2 lc157s to the right of IC16 (can't be right)
timer 0 - mode 3 - square wave (000A), gate not involved
timer 1 - mode 2 - rate generator (0E90), gate involved
0e90 = 3818
***********************************************************************************************************/
#include "emu.h"
#include "soundbox.h"
#include "machine/i8255.h"
#include "machine/pit8253.h"
#include "sound/ymopm.h"
#include "speaker.h"
//#define VERBOSE (LOG_GENERAL)
#include "logmacro.h"
namespace {
class segaai_soundbox_device : public device_t,
public segaai_exp_interface
{
public:
segaai_soundbox_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SEGAAI_SOUNDBOX, tag, owner, clock)
, segaai_exp_interface(mconfig, *this)
, m_tmp8253(*this, "tmp8253")
, m_tmp8255(*this, "tmp8255")
, m_ym2151(*this, "ym2151")
, m_rom(*this, "soundbox")
, m_rows(*this, "ROW%u", 0U)
, m_row(0)
{ }
static constexpr feature_type unemulated_features() { return feature::KEYBOARD; }
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_start() override;
private:
static constexpr u32 EXPANSION_RAM_SIZE = 0x20000;
u8 tmp8255_porta_r();
void tmp8255_portb_w(u8 data);
void tmp8255_portc_w(u8 data);
void ym2151_irq_w(int state);
void tmp8253_out0_w(int state);
void tmp8253_out1_w(int state);
required_device<pit8253_device> m_tmp8253;
required_device<i8255_device> m_tmp8255;
required_device<ym2151_device> m_ym2151;
required_region_ptr<u8> m_rom;
required_ioport_array<8> m_rows;
std::unique_ptr<u8[]> m_ram;
u8 m_row;
};
void segaai_soundbox_device::device_add_mconfig(machine_config &config)
{
PIT8253(config, m_tmp8253);
m_tmp8253->set_clk<0>(clock()); // ~3.58 MHz, seems to be tied to pin 24 in ym2151
m_tmp8253->out_handler<0>().set(FUNC(segaai_soundbox_device::tmp8253_out0_w));
// gate0 not connected
m_tmp8253->set_clk<1>(clock()); // 3.58 MHz?
m_tmp8253->out_handler<1>().set(FUNC(segaai_soundbox_device::tmp8253_out1_w));
// timer 2 is not connected, also not set up by the code
I8255(config, m_tmp8255);
m_tmp8255->in_pa_callback().set(FUNC(segaai_soundbox_device::tmp8255_porta_r));
m_tmp8255->in_pb_callback().set_constant(0xff);
m_tmp8255->out_pb_callback().set(FUNC(segaai_soundbox_device::tmp8255_portb_w));
m_tmp8255->out_pc_callback().set(FUNC(segaai_soundbox_device::tmp8255_portc_w));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
YM2151(config, m_ym2151, DERIVED_CLOCK(1,1)); // ~3.58MHz
m_ym2151->irq_handler().set(FUNC(segaai_soundbox_device::ym2151_irq_w));
m_ym2151->add_route(0, "lspeaker", 1.00);
m_ym2151->add_route(1, "rspeaker", 1.00);
}
ROM_START(soundbox)
ROM_REGION(0x10000, "soundbox", 0)
ROM_LOAD("ai-snd-2002-cecb.bin", 0x0000, 0x10000, CRC(ef2dabc0) SHA1(b60cd9f6f46b6c77dba8610df6fd83368569e713))
ROM_END
const tiny_rom_entry *segaai_soundbox_device::device_rom_region() const
{
return ROM_NAME(soundbox);
}
static INPUT_PORTS_START(soundbox)
PORT_START("ROW0")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW1")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW2")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW3")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW4")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW5")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW6")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("ROW7")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
INPUT_PORTS_END
ioport_constructor segaai_soundbox_device::device_input_ports() const
{
return INPUT_PORTS_NAME(soundbox);
}
void segaai_soundbox_device::device_start()
{
m_row = 0;
m_ram = std::make_unique<u8[]>(EXPANSION_RAM_SIZE);
save_pointer(NAME(m_ram), EXPANSION_RAM_SIZE);
save_item(NAME(m_row));
mem_space().install_ram(0x20000, 0x3ffff, &m_ram[0]);
mem_space().install_rom(0x80000, 0x8ffff, m_rom);
io_space().install_read_handler(0x20, 0x23, emu::rw_delegate(*m_ym2151, FUNC(ym2151_device::read)));
io_space().install_write_handler(0x20, 0x23, emu::rw_delegate(*m_ym2151, FUNC(ym2151_device::write)));
io_space().install_read_handler(0x24, 0x27, emu::rw_delegate(*m_tmp8253, FUNC(pit8253_device::read)));
io_space().install_write_handler(0x24, 0x27, emu::rw_delegate(*m_tmp8253, FUNC(pit8253_device::write)));
io_space().install_read_handler(0x28, 0x2b, emu::rw_delegate(*m_tmp8255, FUNC(i8255_device::read)));
io_space().install_write_handler(0x28, 0x2b, emu::rw_delegate(*m_tmp8255, FUNC(i8255_device::write)));
}
u8 segaai_soundbox_device::tmp8255_porta_r()
{
// Read pressed keys on music keyboard row (see routine @0x82399)
u8 result = 0xff;
for (int i = 0; i < 8; i++)
if (BIT(m_row, i)) result &= m_rows[i]->read();
return result;
}
/*
8255 port B
76543210
+-------- 8253 GATE1
+-------
+------
+-----
+----
+--- LC7537N pin22 DI
+-- LC7537N pin21 CLK
+- LC7537N pin20 DI
*/
void segaai_soundbox_device::tmp8255_portb_w(u8 data)
{
LOG("soundbox 8255 port B write $%02X\n", data);
m_tmp8253->write_gate1(BIT(data, 7));
}
void segaai_soundbox_device::tmp8255_portc_w(u8 data)
{
// Selects music keyboard row to scan (see routine @0x82399)
LOG("soundbox m_row = $%02X\n", data);
m_row = data;
}
void segaai_soundbox_device::ym2151_irq_w(int state)
{
LOG("Soundbox: IRQ from ym2151 is '%s'\n", state ? "ASSERT" : "CLEAR");
}
void segaai_soundbox_device::tmp8253_out0_w(int state)
{
// LOG("Soundbox: OUT0 from tmp8253 is '%s'\n", state ? "ASSERT" : "CLEAR");
}
void segaai_soundbox_device::tmp8253_out1_w(int state)
{
// LOG("Soundbox: OUT1 from tmp8253 is '%s'\n", state ? "ASSERT" : "CLEAR");
}
} // anonymous namespace
DEFINE_DEVICE_TYPE_PRIVATE(SEGAAI_SOUNDBOX, segaai_exp_interface, segaai_soundbox_device, "segaai_soundbox", "Sega AI Expansion - Soundbox")

View File

@ -0,0 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol, Fabio Priuli
// thanks-to:Chris Covell
#ifndef MAME_BUS_SEGAAI_SOUNDBOX_H
#define MAME_BUS_SEGAAI_SOUNDBOX_H
#pragma once
#include "segaai_exp.h"
DECLARE_DEVICE_TYPE(SEGAAI_SOUNDBOX, segaai_exp_interface);
#endif

View File

@ -0,0 +1,94 @@
<?xml version="1.0"?>
<!--
license:CC0-1.0
-->
<mamelayout version="2">
<element name="touchpadcursor">
<image>
<data><![CDATA[
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1" height="1" viewBox="0 0 1 1">
<g fill="none" stroke="#2222cc" stroke-width="0.06" stroke-opacity="1">
<circle cx="0.5" cy="0.5" r="0.1" />
<circle cx="0.5" cy="0.5" r="0.47" />
<line x1="0.03" y1="0.5" x2="0.4" y2="0.5" />
<line x1="0.6" y1="0.5" x2="0.97" y2="0.5" />
<line x1="0.5" y1="0.03" x2="0.5" y2="0.4" />
<line x1="0.5" y1="0.6" x2="0.5" y2="0.97" />
<line />
</g>
</svg>
]]></data>
</image>
</element>
<element name="touchpad_area">
<rect><color red="0.1" green="0.1" blue="0.1" /></rect>
</element>
<element name="overlay">
<rect><color alpha="0" /></rect>
</element>
<element name="touchpad">
<rect><color alpha="0" /></rect>
</element>
<view name="default">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
<element id="touchpad_area" ref="touchpad_area">
<bounds x="0.094" y="3.25" width="3.8" height="2.75" />
</element>
<element id="overlay" ref="overlay">
<bounds x="0" y="3.1" width="4" height="3" />
</element>
<element id="touchpad" ref="touchpad">
<bounds x="0.094" y="3.25" width="3.8" height="2.75" />
</element>
<element id="touchpadcursor" ref="touchpadcursor">
<!-- will be positioned by script -->
<bounds x="0" y="3.1" width="0.2" height="0.2" />
<color alpha="0.7" />
</element>
</view>
<script><![CDATA[
file:set_resolve_tags_callback(
function ()
-- get overlay, if any
local overlay_image = file.device:memregion('cardslot:overlay')
file.elements['overlay']:set_draw_callback(
function (state, bitmap)
if overlay_image ~= nil then
-- TODO: reduce temporary memory usage when I/O classes are exposed to Lua
local data = overlay_image:read(0, overlay_image.size)
local image = emu.bitmap_argb32.load(data)
image:resample(bitmap)
end
end)
local touchpad = file.views['default'].items['touchpad']
-- recompute target touchpad cursor size and area when necessary
local curxoffs, curyoffs, curxscale, curyscale, curwidth, curheight
file.views['default']:set_recomputed_callback(
function ()
local lbounds = touchpad.bounds
curwidth = lbounds.width / 16
curheight = (lbounds.height / 16) * (3.8 / 2.75)
curxoffs = lbounds.x0 - (curwidth * 0.5)
curyoffs = lbounds.y0 - (curheight * 0.5)
curxscale = lbounds.width / 255
curyscale = lbounds.height / 255
end)
-- animate the position of the touchpad cursor
local touchpadx = file.device:ioport('TOUCHPADX')
local touchpady = file.device:ioport('TOUCHPADY')
file.views['default'].items['touchpadcursor']:set_bounds_callback(
function ()
local x = curxoffs + (touchpadx:read() * curxscale)
local y = curyoffs + (touchpady:read() * curyscale)
return emu.render_bounds(x, y, x + curwidth, y + curheight)
end)
end)
]]></script>
</mamelayout>

View File

@ -39461,6 +39461,9 @@ tvochken //
@source:sega/sega_sawatte.cpp
sawatte //
@source:sega/segaai.cpp
segaai // (c) 1986 Sega
@source:sega/segaatom.cpp
spongbob // (c) 200? Sega

728
src/mame/sega/segaai.cpp Normal file
View File

@ -0,0 +1,728 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol, Fabio Priuli
// thanks-to:Chris Covell
/*
Sega AI driver
Not much is known at this stage, except that the system was intended to be
used for educational purposes in schools. Yet the audio chips seem much more
powerful than what an educational computer requires...
CPU : 16bit V20 @ 5MHz
ROM : 128KB OS.with SEGA PROLOG
RAM : 128KB
VRAM : 64KB
Video : V9938 Resolution 256x212
Sound : SN76489
Cassette Drive : 9600bps
TV Output : RGB, Video, RF
Keyboard : new JIS arrangement (Japanese input mapping)
TODO:
- Cassette, playback is controlled by the computer. Games with cassette
spin up the cassette for about 2 seconds
- The tape sometimes seeks back and forth for 5-15 seconds for the right
voice clip, while the game and player (kids) wait
"In these tapes, by the way, the left audio channel is the narration,
and the right channel the data bursts right before each one."
- Keyboard?
- SEGA Prolog? How to enter?
- Sound box:
Note from ccovell:
"With the Sound Box attached, I connected the output line of the Sound
Box's keyboard pins to one or more input pins, and it suddenly played an
FM instrument and printed "piano" on the screen! From this, pressing U/D
on the pad cycled through the various instruments, and the PL/PR buttons
lowered and raised the volume."
===========================================================================
Sega AI Computer quick PCB overview by Chris Covell
Major ICs
IC 1 D701080-5 (86/09?) NEC V20 CPU DIP40
IC 2 315-5200 (86/25) SEGA QFP100
IC 3 27C512-25 (86/15) 64K EPROM "E000 8/24"
IC 4 27C512-25 (86/06) 64K EPROM "F000 7/21"
IC 5 MPR-7689 (86/22) SEGA "264 AA E79" (ROM) DIP28
IC 10 V9938 Yamaha MSX2 VDP
IC 13 D7759C (86/12) NEC Speech Synthesizer DIP40
IC 14 MPR-7619 (86/23) SEGA (ROM) DIP28
IC 15 MPR-7620 (86/23) SEGA (ROM) DIP28
IC 16 SN76489AN TI PSG DIP16
IC 17 D8251AFC (86/09) NEC Communications Interface DIP28
IC 18 315-5201 (86/25) SEGA (bodge wire on pins 9,10) DIP20
IC 19 M5204A (87?/01) OKI
IC 20 D8255AC-2 (86/08) NEC Peripheral Interface DIP40
IC 6,7,8,9,11,12 D41464C-12 NEC 32K DRAMs - 128K RAM, 64K VRAM
Crystals, etc
X1 20.000 "KDS 6D"
X2 21.47727 "KDS"
X3 640kHz "CSB 640 P"
Connectors
CN1 6-pin DIN Power connector
CN2 8-pin DIN "AUX" connector
CN3 Video phono jack
CN4 Audio phono jack
CN5 35-pin Sega MyCard connector
CN6 60-pin expansion connector A1..A30 Bottom, B1..B30 Top
CN7 9-pin header connector to "Joy, Button, LED" unit
CN8 13(?) pin flat flex connector to pressure pad
CN9 9-pin header connector to tape drive motor, etc.
CN10 13-pin header connector to tape heads
JP2 2-wire header to SW2 button board
PJ1 7-wire header to Keyboard / Mic connector board
MIC 2-wire header to mic on KB/Mic board
SW1 Reset Switch
Power switch is on the AC Adaptor
Joypad unit (by Mitsumi) has U/D/L/R, "PL" and "PR" buttons, and a power LED.
Power Connector Pinout (Seen from AC Adaptor plug):
1 5 1 12V COM 5 5V COM
6 2 12V OUT 6 5V OUT
2 4 3 5V COM
3 4 5V OUT
AUX Connector Pinout:
7 6 1 +5V(?) 5 csync
3 8 1 2 GND 6 green
5 4 3 blue 7 Audio out
2 4 +5V(?) 8 red
New JIS Keyboard Connector Pinout:
1 2 1,2,3 data lines
3 4 5 4 ?? 5,8 data lines
6 7 8 6 GND 7 +5V
*/
#include "emu.h"
#include "bus/segaai/segaai_exp.h"
#include "bus/segaai/segaai_slot.h"
#include "cpu/nec/nec.h"
#include "imagedev/cassette.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
#include "sound/sn76496.h"
#include "sound/upd7759.h"
#include "video/v9938.h"
#include "crsshair.h"
#include "softlist.h"
#include "softlist_dev.h"
#include "speaker.h"
#include "segaai.lh"
//#define VERBOSE (LOG_GENERAL)
#include "logmacro.h"
namespace {
class segaai_state : public driver_device
{
public:
segaai_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_sound(*this, "sn76489a")
, m_v9938(*this, "v9938")
, m_upd7759(*this, "upd7759")
, m_i8251(*this, "i8251")
, m_i8255(*this, "i8255")
, m_cassette(*this, "cassette")
, m_cardslot(*this, "cardslot")
, m_expslot(*this, "exp")
, m_port4(*this, "PORT4")
, m_port5(*this, "PORT5")
, m_touch(*this, "TOUCH")
, m_touchpadx(*this, "TOUCHPADX")
, m_touchpady(*this, "TOUCHPADY")
, m_vector(0)
{ }
void segaai(machine_config &config);
protected:
virtual void machine_start() override;
private:
static constexpr u8 VECTOR_V9938 = 0xf8;
static constexpr u8 VECTOR_I8251_SEND = 0xf9;
static constexpr u8 VECTOR_I8251_RECEIVE = 0xfa;
static constexpr u8 VECTOR_UPD7759 = 0xfb;
static constexpr u8 IRQ_V9938 = 0x01;
static constexpr u8 IRQ_UPD7759 = 0x08;
// 8255 Port B bits
static constexpr u8 TOUCH_PAD_PRESSED = 0x02;
static constexpr u8 TOUCH_PAD_DATA_AVAILABLE = 0x04;
static constexpr u8 UPD7759_MODE = 0x01;
static constexpr u8 UPD7759_BANK = 0x02;
void mem_map(address_map &map);
void io_map(address_map &map);
void update_irq_state();
u32 get_vector() { return m_vector; }
void vdp_interrupt(int state);
void upd7759_drq_w(int state);
IRQ_CALLBACK_MEMBER(irq_callback);
u8 i8255_portb_r();
u8 i8255_portc_r();
void i8255_portc_w(u8 data);
void upd7759_ctrl_w(u8 data);
void upd7759_data_w(u8 data);
void port1c_w(u8 data);
void port1d_w(u8 data);
void port1e_w(u8 data);
u8 port1e_r();
u8 irq_enable_r();
void irq_enable_w(u8 data);
void irq_select_w(u8 data);
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
required_device<sn76489a_device> m_sound;
required_device<v9938_device> m_v9938;
required_device<upd7759_device> m_upd7759;
required_device<i8251_device> m_i8251;
required_device<i8255_device> m_i8255;
required_device<cassette_image_device> m_cassette;
required_device<segaai_card_slot_device> m_cardslot;
required_device<segaai_exp_slot_device> m_expslot;
required_ioport m_port4;
required_ioport m_port5;
required_ioport m_touch;
required_ioport m_touchpadx;
required_ioport m_touchpady;
u8 m_i8255_portb;
u8 m_upd7759_ctrl;
u8 m_port_1c;
u8 m_port_1d;
u8 m_port_1e;
u32 m_prev_v9938_irq;
u32 m_prev_upd7759_irq;
u8 m_touchpad_x;
u8 m_touchpad_y;
u8 m_irq_active;
u8 m_irq_enabled;
u32 m_vector;
};
void segaai_state::mem_map(address_map &map)
{
map(0x00000, 0x1ffff).ram();
// 0x20000-0x3ffff - Dynamically mapped by expansion slot
// 0x80000-0x8ffff - Dynamically mapped by expansion slot
// 0xa0000-0xbffff - Dynamically mapped by cardslot
map(0xc0000, 0xdffff).rom();
map(0xe0000, 0xeffff).rom();
map(0xf0000, 0xfffff).rom();
}
/*
Interesting combination of I/O actions from the BIOS:
EC267: B0 03 mov al,3h
EC269: E6 17 out 17h,al
EC26B: B0 FC mov al,0FCh ; 11111100
EC26D: E6 0F out 0Fh,al
EC26F: B0 FF mov al,0FFh
EC271: E6 08 out 8h,al
same code at ECDBE, ED2FC
EC2D6: B0 05 mov al,5h
EC2D8: E6 17 out 17h,al
EC2DA: B0 FA mov al,0FAh ; 11111010
EC2DC: E6 0F out 0Fh,al
EC2DE: B0 00 mov al,0h
EC2E0: E4 08 in al,8h
same code at ECE08, ECE1D, ED282, EDBA8, EDD78
EC319: B0 04 mov al,4h
EC31B: E6 17 out 17h,al
EC31D: B0 FE mov al,0FEh ; 11111110
EC31F: E6 0F out 0Fh,al
ECB45: 80 FA 03 cmp dl,3h
ECB48: 74 05 be 0ECB4Fh
ECB4A: B0 09 mov al,9h
ECB4C: E9 02 00 br 0ECB51h
ECB4F: B0 08 mov al,8h
ECB51: E6 17 out 17h,al
same code at ED02A, ED17E, ED1DC
ECEE5: B0 03 mov al,3h
ECEE7: E6 17 out 17h,al
ECEE9: B0 FC mov al,0FCh ; 11111100
ECEEB: E6 0F out 0Fh,al
ECEED: B0 00 mov al,0h
ECEEF: E6 08 out 8h,al
same code at ED0D9, ED120, EDB04, EDC8F
ECF0D: B0 02 mov al,2h
ECF0F: E6 17 out 17h,al
ECF11: B0 FE mov al,0FEh ; 11111110
ECF13: E6 0F out 0Fh,al
*/
void segaai_state::io_map(address_map &map)
{
map(0x00, 0x03).rw(m_v9938, FUNC(v9938_device::read), FUNC(v9938_device::write));
map(0x04, 0x07).rw(m_i8255, FUNC(i8255_device::read), FUNC(i8255_device::write));
// port 7, bit 7, engages tape?
map(0x08, 0x08).rw(m_i8251, FUNC(i8251_device::data_r), FUNC(i8251_device::data_w));
map(0x09, 0x09).rw(m_i8251, FUNC(i8251_device::status_r), FUNC(i8251_device::control_w));
// 0x0a (w) - ??
// 0a: 00 written during boot
map(0x0b, 0x0b).w(FUNC(segaai_state::upd7759_ctrl_w));
map(0x0c, 0x0c).w(m_sound, FUNC(sn76489a_device::write));
// 0x0e (w) - ??
// 0x0f (w) - ??
// during boot:
// 0e <- 13
// 0f <- ff
// 0f <- 07
// 0e <- 07
// 0e <- 08
// 0f <- fe
map(0x14, 0x14).mirror(0x01).w(FUNC(segaai_state::upd7759_data_w));
// IRQ Enable
map(0x16, 0x16).rw(FUNC(segaai_state::irq_enable_r), FUNC(segaai_state::irq_enable_w));
// IRQ Enable (per IRQ source selection) Why 2 registers for IRQ enable?
map(0x17, 0x17).w(FUNC(segaai_state::irq_select_w));
// Touchpad
map(0x1c, 0x1c).w(FUNC(segaai_state::port1c_w));
map(0x1d, 0x1d).w(FUNC(segaai_state::port1d_w));
map(0x1e, 0x1e).rw(FUNC(segaai_state::port1e_r), FUNC(segaai_state::port1e_w));
// 0x1f (w) - ??
// Expansion I/O
// 0x20-0x3f - Dynamically mapped by expansion slot
}
static INPUT_PORTS_START(ai_kbd)
PORT_START("PORT4")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("PL")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("RL")
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_READ_LINE_DEVICE_MEMBER("upd7759", upd7759_device, busy_r)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) // Microphone sensor
PORT_START("PORT5")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Grey Button")
PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("TOUCH")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Press touchpad")
PORT_START("TOUCHPADX")
PORT_BIT(0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_MINMAX(0, 255) PORT_PLAYER(1) PORT_NAME("Touchpad X")
PORT_START("TOUCHPADY")
PORT_BIT(0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_MINMAX(0, 255) PORT_PLAYER(1) PORT_NAME("Touchpad Y")
INPUT_PORTS_END
void segaai_state::update_irq_state()
{
int state = CLEAR_LINE;
if (m_irq_active & m_irq_enabled)
{
state = ASSERT_LINE;
}
m_maincpu->set_input_line(0, state);
}
// Based on edge triggers level triggers are created
void segaai_state::vdp_interrupt(int state)
{
if (state != CLEAR_LINE)
{
if (m_prev_v9938_irq == CLEAR_LINE)
{
m_irq_active |= IRQ_V9938;
}
}
m_prev_v9938_irq = state;
update_irq_state();
}
// Based on edge triggers level triggers are created
void segaai_state::upd7759_drq_w(int state)
{
int upd7759_irq = state ? CLEAR_LINE : ASSERT_LINE;
if (upd7759_irq != CLEAR_LINE)
{
if (m_prev_upd7759_irq == CLEAR_LINE)
{
m_irq_active |= IRQ_UPD7759;
}
}
m_prev_upd7759_irq = upd7759_irq;
update_irq_state();
}
IRQ_CALLBACK_MEMBER(segaai_state::irq_callback)
{
if (m_irq_active & m_irq_enabled & IRQ_V9938)
{
m_vector = VECTOR_V9938;
m_irq_active &= ~IRQ_V9938;
}
else if (m_irq_active & m_irq_enabled & IRQ_UPD7759)
{
m_vector = VECTOR_UPD7759;
m_irq_active &= ~IRQ_UPD7759;
}
else
{
if (m_irq_active & m_irq_enabled)
{
fatalerror("Unknown irq triggered: $%02X active, $%02X enabled\n", m_irq_active, m_irq_enabled);
}
fatalerror("irq_callback called but no irq active and enabled: $%02X active, $%02X enabled\n", m_irq_active, m_irq_enabled);
}
update_irq_state();
return m_vector;
}
/*
Mainboard 8255 port B
76543210
+-------- Tape input (right channel?), unknown if input is signal level or bit
+------- Tape head engaged
+------ Tape insertion sensor (0 - tape is inserted, 1 - no tape inserted)
+----- Tape write enable sensor
+---- keyboard connector pin 3
+--- 0 = Touch pad data available
+-- 0 = Touch pad pressed
+- Trigger button near touch panel (active low)
*/
u8 segaai_state::i8255_portb_r()
{
m_i8255_portb = (m_i8255_portb & 0xf8) | (m_port5->read() & 0x01);
if (BIT(m_port_1d, 0))
{
if (!BIT(m_touch->read(), 0))
{
m_i8255_portb |= TOUCH_PAD_PRESSED;
}
m_i8255_portb |= TOUCH_PAD_DATA_AVAILABLE;
}
else
{
m_i8255_portb |= TOUCH_PAD_PRESSED;
}
if (m_cassette->get_image() != nullptr)
{
m_i8255_portb &= ~0x20;
}
else
{
m_i8255_portb |= 0x20;
}
// when checking whether the tape is running Popoland wants to see bit7 set and bit5 reset
// toggling this stops eigogam2 from booting normally into a game.
// For tape reading eigogam2 routines at A11EA and A120C
// There is a whistle tone on the cassette before normal speech starts, the code there likely
// checks for this whistle tone.
//m_i8255_portb ^= 0x80;
return m_i8255_portb;
}
/*
Mainboard 8255 port C
76543210
+-------- keyboard connector pin 5
+------- keyboard connector pin 8
+------ keyboard connector pin 2
+----- keyboard connector pin 1
+---- Output
+--- Output
+-- Output
+- Output
*/
u8 segaai_state::i8255_portc_r()
{
u8 data = 0xf0;
return data;
}
/*
pin 10-13 - PC0-PC3 -> RA41
PC0-PC3 continue on underside of pcb
pin 14-17 - PC4-PC7 -> RA42
PC3 continues on underside of pcb
PC2 - pin 6 upa2003c, drives upa2003c pin 11
PC1 - pin 4 upa2003c, drives upa2003c pin 13
PC0 - pin 2 upd2003c, drives upa2003c pin 15
these go to 3 dots to the left of resistors below upa2003c?
which end up on the 9 pin flat connector on the lower left side of the pcb
PC4 - to pin 1 of 7 pin connector bottom right side of pcb -> jis keyboard connector ?
CN9 - 9 pin connector goes to cassette interface
pin 1 - red
pin 2 - black
pin 3 - blue
pin 4 - yellow
pin 5 - white
pin 6 - black/grey
pin 7 - blue
pin 8 - grey
pin 9 - brown
*/
void segaai_state::i8255_portc_w(u8 data)
{
// Writes to bits 6,5,4, unknown what they mean
// Bit 0 written by cosmictr
LOG("i8255 port c write: %02x\n", data);
}
void segaai_state::upd7759_data_w(u8 data)
{
m_upd7759->start_w(ASSERT_LINE);
m_upd7759->port_w(data);
m_upd7759->start_w(CLEAR_LINE);
}
void segaai_state::upd7759_ctrl_w(u8 data)
{
LOG("I/O Port $0b write: $%02x\n", data);
m_upd7759_ctrl = data;
// bit0 is connected to /md line of the uPD7759
m_upd7759->md_w((m_upd7759_ctrl & UPD7759_MODE) ? 0 : 1);
// bit1 selects which ROM should be used?
m_upd7759->set_rom_bank((m_upd7759_ctrl & UPD7759_BANK) >> 1);
}
// I/O Port 16 - IRQ Enable
u8 segaai_state::irq_enable_r()
{
return m_irq_enabled;
}
// IRQ Enable
// 76543210
// +-------- ???
// +------- ???
// +------ ???
// +----- ???
// +---- D7759 IRQ enable
// +--- ???
// +-- ??? 8251 receive?
// +- V9938 IRQ enable
void segaai_state::irq_enable_w(u8 data)
{
m_irq_enabled = data;
m_irq_active &= data;
update_irq_state();
}
// I/O Port 17 - IRQ Enable selection
// This port seems to be used to set or reset specific bits in the IRQ enable register.
// Why 2 ways of setting/clearing irq enable bits?
void segaai_state::irq_select_w(u8 data)
{
int pin = (data >> 1) & 0x07;
if (BIT(data, 0))
{
m_irq_enabled |= (1 << pin);
}
else
{
m_irq_enabled &= ~(1 << pin);
m_irq_active &= m_irq_enabled;
}
update_irq_state();
}
void segaai_state::port1c_w(u8 data)
{
m_port_1c = data;
}
void segaai_state::port1d_w(u8 data)
{
m_port_1d = data;
}
void segaai_state::port1e_w(u8 data)
{
m_port_1e = data;
}
u8 segaai_state::port1e_r()
{
if (BIT(m_port_1c, 0))
{
return m_touchpady->read();
}
else
{
return m_touchpadx->read();
}
}
void segaai_state::machine_start()
{
m_i8255_portb = 0x7f;
m_upd7759_ctrl = 0;
m_port_1c = 0;
m_port_1d = 0;
m_port_1e = 0;
m_prev_v9938_irq = CLEAR_LINE;
m_prev_upd7759_irq = CLEAR_LINE;
m_touchpad_x = 0;
m_touchpad_y = 0;
m_vector = 0;
m_irq_enabled = 0;
m_irq_active = 0;
save_item(NAME(m_i8255_portb));
save_item(NAME(m_upd7759_ctrl));
save_item(NAME(m_port_1c));
save_item(NAME(m_port_1d));
save_item(NAME(m_port_1e));
save_item(NAME(m_prev_v9938_irq));
save_item(NAME(m_prev_upd7759_irq));
save_item(NAME(m_touchpad_x));
save_item(NAME(m_touchpad_y));
save_item(NAME(m_irq_active));
save_item(NAME(m_irq_enabled));
save_item(NAME(m_vector));
machine().crosshair().get_crosshair(0).set_screen(CROSSHAIR_SCREEN_NONE);
}
void segaai_state::segaai(machine_config &config)
{
V20(config, m_maincpu, 20_MHz_XTAL/4);
m_maincpu->set_addrmap(AS_PROGRAM, &segaai_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &segaai_state::io_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(segaai_state::irq_callback));
V9938(config, m_v9938, 21.477272_MHz_XTAL);
m_v9938->set_screen_ntsc(m_screen);
m_v9938->set_vram_size(0x10000);
m_v9938->int_cb().set(FUNC(segaai_state::vdp_interrupt));
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
I8255(config, m_i8255);
m_i8255->in_pa_callback().set_ioport(m_port4);
m_i8255->in_pb_callback().set(FUNC(segaai_state::i8255_portb_r));
m_i8255->in_pc_callback().set(FUNC(segaai_state::i8255_portc_r));
m_i8255->out_pc_callback().set(FUNC(segaai_state::i8255_portc_w));
I8251(config, m_i8251, 0);
SPEAKER(config, "mono").front_center();
SN76489A(config, m_sound, 21.477272_MHz_XTAL/6); // not verified, but sounds close to real hw recordings
m_sound->add_route(ALL_OUTPUTS, "mono", 1.00);
UPD7759(config, m_upd7759);
m_upd7759->add_route(ALL_OUTPUTS, "mono", 0.70);
m_upd7759->drq().set(FUNC(segaai_state::upd7759_drq_w));
// Card slot
SEGAAI_CARD_SLOT(config, m_cardslot, segaai_cards, nullptr);
m_cardslot->set_address_space(m_maincpu, AS_PROGRAM);
SOFTWARE_LIST(config, "software").set_original("segaai");
// Expansion slot
SEGAAI_EXP_SLOT(config, m_expslot, 21'477'272/6, segaai_exp, nullptr); // not verified, assuming 3.58MHz
m_expslot->set_mem_space(m_maincpu, AS_PROGRAM);
m_expslot->set_io_space(m_maincpu, AS_IO);
// Built-in cassette
CASSETTE(config, m_cassette).set_stereo();
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED);
m_cassette->set_interface("cass");
m_cassette->add_route(0, "mono", 0.70); // Channel 0 contains regular recorded sound
m_cassette->set_channel(1); // Channel 1 contains data
config.set_default_layout(layout_segaai);
}
ROM_START(segaai)
ROM_REGION(0x100000, "maincpu", 0)
ROM_LOAD("mpr-7689.ic5", 0xc0000, 0x20000, CRC(62402ac9) SHA1(bf52d22b119d54410dad4949b0687bb0edf3e143))
ROM_LOAD("e000 8_24.ic3", 0xe0000, 0x10000, CRC(c8b6a539) SHA1(cbf8473d1e3d8037ea98e9ca8b9aafdc8d16ff23)) // actual label is "e000 8/24"
ROM_LOAD("f000 7_21.ic4", 0xf0000, 0x10000, CRC(64d6cd8c) SHA1(68c130048f16d6a0abe1978e84440931470222d9)) // actual label is "f000 7/21"
ROM_REGION(0x40000, "upd7759", 0)
ROM_LOAD("mpr-7619.ic14", 0x00000, 0x20000, CRC(d1aea002) SHA1(c8d5408bba65b17301f19cf9ebd2b635d642525a))
ROM_LOAD("mpr-7620.ic15", 0x20000, 0x20000, CRC(e042754b) SHA1(02aede7a3e2fda9cbca621b530afa4520cf16610))
ROM_END
} // anonymous namespace
COMP(1986, segaai, 0, 0, segaai, ai_kbd, segaai_state, empty_init, "Sega", "AI", MACHINE_NOT_WORKING)