This commit is contained in:
angelosa 2020-05-09 20:25:04 +02:00
commit b868f3115f
324 changed files with 14846 additions and 8174 deletions

View File

@ -1643,7 +1643,7 @@ Screen-Printer (standalone)
<info name="usage" value="Type SYSTEM and load with POLEPO, enter / to start" />
<part name="cass1" interface="cgenie_cass">
<dataarea name="cass" size="14362">
<rom name="polepo.cas" size="14362" crc="cfd0d6ce" sha1="35658b20373f4ec0673a6aa81f161101dd916cea" />
<rom name="polepo.cas" size="14362" crc="cfd0d6ce" sha1="bfced1e2d8128d38b4657c330ff67037759de832" />
</dataarea>
</part>
</software>

View File

@ -157,7 +157,7 @@ Systemskiva för hårdskiveenhet [version 7242]
<software name="stvaratt">
<description>Stava rätt på nytt sätt (version 8481)</description>
<year>19??</year>
<publisher>Esselte Stadium</publisher>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-34298-X" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2178838">
@ -169,7 +169,7 @@ Systemskiva för hårdskiveenhet [version 7242]
<software name="mattev1">
<description>Matematikverkstad I (beta, nät/skollicens)</description>
<year>1987</year>
<publisher>Esselte Stadium</publisher>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-33777" />
<info name="release" value="19870806" />
<part name="flop1" interface="floppy_5_25">
@ -182,7 +182,7 @@ Systemskiva för hårdskiveenhet [version 7242]
<software name="video">
<description>Video-butiken (enanvändare)</description>
<year>1986</year>
<publisher>Esselte Stadium</publisher>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-33070" />
<info name="release" value="19860916" />
<part name="flop1" interface="floppy_5_25">
@ -202,7 +202,7 @@ Systemskiva för hårdskiveenhet [version 7242]
<software name="statett">
<description>StatEtt - Analys</description>
<year>1990</year>
<publisher>Esselte Stadium</publisher>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-35831" />
<info name="release" value="19900101" />
<part name="flop1" interface="floppy_5_25">
@ -216,7 +216,7 @@ Systemskiva för hårdskiveenhet [version 7242]
<software name="raknrattd" cloneof="raknratt">
<description>Räkna lätt, räkna rätt (demo, version 6175)</description>
<year>19??</year>
<publisher>Esselte Stadium</publisher>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-4408-7" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209405">
@ -224,4 +224,110 @@ Systemskiva för hårdskiveenhet [version 7242]
</dataarea>
</part>
</software>
<software name="stilplus">
<description>Stil-Plus (alfa 1.0, nät/skollicens)</description>
<year>1989</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-35456" />
<info name="release" value="19890530" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2217678">
<rom name="StilPlus.mfm" size="2217678" crc="b16bb821" sha1="d965a865e3f97d7d256c89176948ef371d65254b"/>
</dataarea>
</part>
</software>
<software name="action1">
<description>Action1 Glosprogram (nät/skollicens)</description>
<year>1987</year>
<publisher>Almqvist &amp; Wiksell Läromedel AB</publisher>
<info name="serial" value="24-33584" />
<info name="release" value="19870114" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209365">
<rom name="Action1 Glosprogram.mfm" size="2209365" crc="1e2a96a1" sha1="098842f0571c0b9beb64295bef5ded29e5ce6add"/>
</dataarea>
</part>
</software>
<software name="coulomb">
<description>Coulombs lag (nät/skollicens)</description>
<year>1987</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-33772" />
<info name="release" value="19870731" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209453">
<rom name="Coulombs lag.mfm" size="2209453" crc="16e9749c" sha1="adc4658eaa24cdaf4f261f2a1848b98435155d0a"/>
</dataarea>
</part>
</software>
<software name="kinetik">
<description>Kinetik (nät/skollicens)</description>
<year>1987</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-34652" />
<info name="release" value="19870823" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209459">
<rom name="Kinetik.mfm" size="2209459" crc="c906fa1d" sha1="a6e9411dcc1935cb17a65c7eb162fc127eb1f9a1"/>
</dataarea>
</part>
</software>
<software name="jordskift">
<description>Jorden skiftas, folket skingras (nät/skollicens)</description>
<year>1987</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-33799" />
<info name="release" value="19871105" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209529">
<rom name="Jorden skiftas, folket skingras.mfm" size="2209529" crc="b1df76ea" sha1="6d6e2fd20ccc4cec2999932168f8a82221f16c47"/>
</dataarea>
</part>
</software>
<!-- Requires a hardware key which isn't dumped -->
<software name="skvallra">
<description>Får dataregister skvallra? (enanvändare)</description>
<year>1985</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-34112" />
<info name="release" value="19851029" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209468">
<rom name="Far dataregister skvallra.mfm" size="2209468" crc="06fc17bc" sha1="7de8a56025058f2a5298ee0dfa1db32c7f335643"/>
</dataarea>
</part>
</software>
<software name="skvallrak" cloneof="skvallra">
<description>Får dataregister skvallra? (komplement)</description>
<year>1986</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-34820" />
<info name="release" value="19860904" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2152177">
<rom name="Far dataregister skvallra (Komplement).mfm" size="2152177" crc="9fa1f31a" sha1="8e0eb4e26d4167193f2b4504f014cf14a8ab8c65"/>
</dataarea>
</part>
</software>
<!-- Requires a hardware key which isn't dumped -->
<software name="kommunik">
<description>Datorn i kommunikation (enanvändare)</description>
<year>1986</year>
<publisher>Esselte Studium</publisher>
<info name="serial" value="24-33828" />
<info name="release" value="19861006" />
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="2209396">
<rom name="Datorn i kommunikation.mfm" size="2209396" crc="780900ce" sha1="923cbefe3ac449d64f1a5ef50f69f59f3a33e438"/>
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -1366,7 +1366,7 @@ Re-releases (probably the same as the original release, but listed while waiting
<software name="meikyujd">
<description>Meikyuu Jiin Dababa</description>
<year>1986</year>
<year>1987</year>
<publisher>Konami</publisher>
<info name="serial" value="KDS-MIK"/>
<info name="release" value="19870529"/>

View File

@ -11042,7 +11042,7 @@ but dumps still have to be confirmed.
<software name="babyboom">
<description>Baby Boom (Prototype, 19940811)</description>
<year>199?</year>
<year>1994</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="2097152">
@ -11053,7 +11053,7 @@ but dumps still have to be confirmed.
<software name="babyboom1" cloneof="babyboom">
<description>Baby Boom (Prototype, 19940603)</description>
<year>199?</year>
<year>1994</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="2097152">
@ -11064,7 +11064,7 @@ but dumps still have to be confirmed.
<software name="babyboom2" cloneof="babyboom">
<description>Baby Boom (Prototype, 19940606)</description>
<year>199?</year>
<year>1994</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="2097152">

View File

@ -5312,7 +5312,7 @@ kept for now until finding out what those bytes affect...
</part>
</software>
<software name="gw126a">
<software name="gw126a" cloneof="gw126">
<description>Game World - 126 Games (Kor, Hacked?)</description>
<year>19??</year>
<publisher>Zemina</publisher>

View File

@ -15269,7 +15269,7 @@ license:CC0
</part>
</software>
<software name="guardlgnu" cloneof="guardlgn">
<software name="guardlgnu" cloneof="guardlgn" supported="no">
<description>The Guardian Legend (USA)</description>
<year>1989</year>
<publisher>Brøderbund</publisher>
@ -15288,7 +15288,7 @@ license:CC0
</part>
</software>
<software name="guardlgn">
<software name="guardlgn" supported="no">
<description>The Guardian Legend (Euro)</description>
<year>1992</year>
<publisher>Nintendo</publisher>
@ -15307,7 +15307,7 @@ license:CC0
</part>
</software>
<software name="guardic" cloneof="guardlgn">
<software name="guardic" cloneof="guardlgn" supported="no">
<description>Guardic Gaiden (Jpn)</description>
<year>1987</year>
<publisher>Irem</publisher>
@ -25010,7 +25010,7 @@ license:CC0
<publisher>Jaleco</publisher>
<info name="serial" value="JF-28"/>
<info name="release" value="19900629"/>
<info name="alt_title" value="燃えろ!! 柔道うぉり・ーず"/>
<info name="alt_title" value="燃えろ!! 柔道うおりあ〜ず"/>
<part name="cart" interface="nes_cart">
<feature name="slot" value="jf17" />
<feature name="pcb" value="JALECO-JF-17" />
@ -75764,7 +75764,7 @@ be better to redump them properly. -->
</part>
</software>
<software name="sf3_9">
<software name="sf3_9" cloneof="sf3">
<description>Street Fighter III (Asia, 9 characters)</description>
<year>19??</year>
<publisher>&lt;unknown&gt;</publisher>

View File

@ -7,7 +7,7 @@ license:CC0
<software name="cpm22">
<description>CP/M-80 R2.2 for QX-10 &amp; QX-16</description>
<year>198?</year>
<year>1984</year>
<publisher>Epson</publisher>
<part name="flop1" interface="floppy_5_25">
@ -17,6 +17,18 @@ license:CC0
</part>
</software>
<software name="cpm22_83">
<description>CP/M-80 R2.2 for QX-10 &amp; QX-16 1983</description>
<year>1983</year>
<publisher>Epson</publisher>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="273195">
<rom name="qx10_cpm.imd" size="273195" crc="47d0c8cc" sha1="f6a10a280925d26d4c74cdf17e01ace13ead4773" />
</dataarea>
</part>
</software>
<software name="tmp2">
<description>TMP-II for QX-10 256K (v2.44)</description>
<year>1983</year>

File diff suppressed because it is too large Load Diff

53
hash/super80_flop.xml Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
<!--
license:CC0
Procedure: Mount the floppy into the first drive.
Select the TwinBoot software, and start the emulation.
When the TwinBoot starts up, it will auto-detect CP/M or DOS, and boot it.
Super-80 DOS is incredibly primitive. There is no directory as such. DIR lists the contents of each "track".
You must load all the tracks needed into memory before running the program.
More information will be added when I find it.
-->
<softwarelist name="super80_flop" description="Dick Smith Super-80 floppies">
<software name="cpm">
<description>CP/M boot disk</description>
<year>198?</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="470469">
<rom name="cpm.imd" size="470469" crc="5f244055" sha1="1fd601efba719d2ee2fb58671f8584aca0e473b0"/>
</dataarea>
</part>
</software>
<software name="dos">
<description>Super-80 DOS disk</description>
<year>198?</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="69347">
<rom name="s80dos.imd" size="69347" crc="42b3b094" sha1="52ae93b07b9c6a8492bdcf56cbb13685fff47ec5"/>
</dataarea>
</part>
</software>
<software name="dosgames">
<description>Super-80 DOS disk with games</description>
<year>198?</year>
<publisher>&lt;unknown&gt;</publisher>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="558331">
<rom name="s80dosb0.imd" size="558331" crc="2a437bd3" sha1="be2125fee65d4b3f4da59f9ad76598e2bd7d95af"/>
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -313074,9 +313074,6 @@ license:CC0
</part>
</software>
<!-- Project 2612 VGM Archives located at http://project2612.org/list.php
Update April 7, 2020 - 13 new entries -->
@ -314209,6 +314206,440 @@ license:CC0
</part>
</software>
<!-- Project 2612 VGM Archives located at http://project2612.org/list.php
Update May 2, 2020 - 5 new entries -->
<software name="joemont2_md">
<description>Joe Montana II - Sports Talk Football (GEN/MD)</description>
<year>1991</year>
<publisher>Sega</publisher>
<info name="cores" value="SN76496, YM2612"/>
<part name="001" interface="vgm_quik">
<feature name="part_id" value="01 - main theme.vgz" />
<dataarea name="quik" size="1572973">
<rom name="01 - main theme.vgz" size="1572973" crc="b3572679" sha1="3c63848bc10e1f344d64905f5d14753d6c14b63a" offset="0" />
</dataarea>
</part>
</software>
<software name="lotust_md">
<description>Lotus Turbo Challenge (GEN/MD)</description>
<year>1992</year>
<publisher>Gremlin Graphics Software Ltd.</publisher>
<info name="cores" value="SN76496, YM2612"/>
<part name="001" interface="vgm_quik">
<feature name="part_id" value="01 - title theme.vgz" />
<dataarea name="quik" size="719245">
<rom name="01 - title theme.vgz" size="719245" crc="c53d07ef" sha1="044371167bd48c5ff94f60848eec7364e28cf890" offset="0" />
</dataarea>
</part>
<part name="002" interface="vgm_quik">
<feature name="part_id" value="02 - forest.vgz" />
<dataarea name="quik" size="87473">
<rom name="02 - forest.vgz" size="87473" crc="40565839" sha1="ca8e57471b99d0636da1b416efd0bae462800f81" offset="0" />
</dataarea>
</part>
<part name="003" interface="vgm_quik">
<feature name="part_id" value="03 - night.vgz" />
<dataarea name="quik" size="127484">
<rom name="03 - night.vgz" size="127484" crc="7c07ef2f" sha1="dd9f080f21296bb583e50dfc9702916d1794165a" offset="0" />
</dataarea>
</part>
<part name="004" interface="vgm_quik">
<feature name="part_id" value="04 - fog.vgz" />
<dataarea name="quik" size="18374">
<rom name="04 - fog.vgz" size="18374" crc="1b11cac4" sha1="9b6d0fa2f0f29d17a1ce798d4fac59fdc38a8fb9" offset="0" />
</dataarea>
</part>
<part name="005" interface="vgm_quik">
<feature name="part_id" value="05 - snow.vgz" />
<dataarea name="quik" size="6512">
<rom name="05 - snow.vgz" size="6512" crc="851ff91c" sha1="37050143b22ccaa6de9a2963ce59c711cf6ab400" offset="0" />
</dataarea>
</part>
<part name="006" interface="vgm_quik">
<feature name="part_id" value="06 - desert.vgz" />
<dataarea name="quik" size="56566">
<rom name="06 - desert.vgz" size="56566" crc="090d3910" sha1="614436c539e89922f9276f0ed80e9b961a8e9593" offset="0" />
</dataarea>
</part>
<part name="007" interface="vgm_quik">
<feature name="part_id" value="07 - interstate.vgz" />
<dataarea name="quik" size="6490">
<rom name="07 - interstate.vgz" size="6490" crc="23bf85b4" sha1="e71dd11b0499d1ceff1eb650b62c738bc6c29501" offset="0" />
</dataarea>
</part>
<part name="008" interface="vgm_quik">
<feature name="part_id" value="08 - marsh.vgz" />
<dataarea name="quik" size="69098">
<rom name="08 - marsh.vgz" size="69098" crc="54e2e2fb" sha1="222d4567add14996a2fe33ba796cbd5885408d8c" offset="0" />
</dataarea>
</part>
<part name="009" interface="vgm_quik">
<feature name="part_id" value="09 - storm.vgz" />
<dataarea name="quik" size="68157">
<rom name="09 - storm.vgz" size="68157" crc="3257c4fd" sha1="68e287840435d30a711b7698b1343095b72eaaa2" offset="0" />
</dataarea>
</part>
<part name="010" interface="vgm_quik">
<feature name="part_id" value="10 - ending.vgz" />
<dataarea name="quik" size="664924">
<rom name="10 - ending.vgz" size="664924" crc="09841b94" sha1="e33b52a3a214972bb216cf768887245dce93a9d8" offset="0" />
</dataarea>
</part>
</software>
<software name="madden95_md">
<description>Madden NFL '95 (GEN/MD)</description>
<year>1994</year>
<publisher>Electronic Arts</publisher>
<info name="cores" value="SN76496, YM2612"/>
<part name="001" interface="vgm_quik">
<feature name="part_id" value="01 - ea sports.vgz" />
<dataarea name="quik" size="70299">
<rom name="01 - ea sports.vgz" size="70299" crc="5ae906c3" sha1="1a331babeff7fc732a746a884ea649a03577966c" offset="0" />
</dataarea>
</part>
<part name="002" interface="vgm_quik">
<feature name="part_id" value="02 - welcome.vgz" />
<dataarea name="quik" size="52680">
<rom name="02 - welcome.vgz" size="52680" crc="e267a10f" sha1="25401c69be28a1964b7968140d4cee285172f480" offset="0" />
</dataarea>
</part>
<part name="003" interface="vgm_quik">
<feature name="part_id" value="03 - nfl on fox (game setup).vgz" />
<dataarea name="quik" size="1633451">
<rom name="03 - nfl on fox (game setup).vgz" size="1633451" crc="e6bb5c3d" sha1="d281f0953956e2a2e5367b1e8e24f9e798f258eb" offset="0" />
</dataarea>
</part>
<part name="004" interface="vgm_quik">
<feature name="part_id" value="04 - game start.vgz" />
<dataarea name="quik" size="2285567">
<rom name="04 - game start.vgz" size="2285567" crc="74c25daf" sha1="6c40dcf2d5b1b6b82c279d6600775ad5e1a61bd2" offset="0" />
</dataarea>
</part>
<part name="005" interface="vgm_quik">
<feature name="part_id" value="05 - pause menu.vgz" />
<dataarea name="quik" size="1128631">
<rom name="05 - pause menu.vgz" size="1128631" crc="d74bf85a" sha1="38be59a3c9dc04076474270bacb18cb022c6016a" offset="0" />
</dataarea>
</part>
<part name="006" interface="vgm_quik">
<feature name="part_id" value="06 - playoff tree.vgz" />
<dataarea name="quik" size="1599500">
<rom name="06 - playoff tree.vgz" size="1599500" crc="0a37d690" sha1="abcad460c51f8f8e6bec8a8fe78b56d224281ddd" offset="0" />
</dataarea>
</part>
<part name="007" interface="vgm_quik">
<feature name="part_id" value="07 - you won.vgz" />
<dataarea name="quik" size="588879">
<rom name="07 - you won.vgz" size="588879" crc="8f2027d3" sha1="c763a0098b24841d174346b54f07ec02ab63ac63" offset="0" />
</dataarea>
</part>
</software>
<software name="teddyboy_md">
<description>Teddy Boy Blues (GEN/MD)</description>
<year>1992</year>
<publisher>Sega</publisher>
<info name="cores" value="SN76496, YM2612"/>
<part name="001" interface="vgm_quik">
<feature name="part_id" value="01 - title theme.vgz" />
<dataarea name="quik" size="7649">
<rom name="01 - title theme.vgz" size="7649" crc="fd01f50a" sha1="e77cc1e94a143700af1eee3604d5766501099a26" offset="0" />
</dataarea>
</part>
<part name="002" interface="vgm_quik">
<feature name="part_id" value="02 - bgm 1.vgz" />
<dataarea name="quik" size="17868">
<rom name="02 - bgm 1.vgz" size="17868" crc="75c872c0" sha1="5950fa5f41ccc78a42e8e53a3232e4580b973b9f" offset="0" />
</dataarea>
</part>
<part name="003" interface="vgm_quik">
<feature name="part_id" value="03 - bgm 2.vgz" />
<dataarea name="quik" size="20856">
<rom name="03 - bgm 2.vgz" size="20856" crc="a6c24a7d" sha1="1283064246fbad8e1a9c516b66e0b50fed290453" offset="0" />
</dataarea>
</part>
<part name="004" interface="vgm_quik">
<feature name="part_id" value="04 - round clear.vgz" />
<dataarea name="quik" size="2953">
<rom name="04 - round clear.vgz" size="2953" crc="97d32b54" sha1="ff33193d1f58cdc75b84a51eeec2052950abfe7a" offset="0" />
</dataarea>
</part>
<part name="005" interface="vgm_quik">
<feature name="part_id" value="05 - bonus round.vgz" />
<dataarea name="quik" size="10779">
<rom name="05 - bonus round.vgz" size="10779" crc="9792d536" sha1="ebec8506f6445d1b042ad6e55f3d260ac1dcfe87" offset="0" />
</dataarea>
</part>
<part name="006" interface="vgm_quik">
<feature name="part_id" value="06 - bonus clear.vgz" />
<dataarea name="quik" size="2421">
<rom name="06 - bonus clear.vgz" size="2421" crc="2c147774" sha1="60cec9be8ce176b06a368e90b7850c400fb6ab9c" offset="0" />
</dataarea>
</part>
<part name="007" interface="vgm_quik">
<feature name="part_id" value="07 - game over.vgz" />
<dataarea name="quik" size="2732">
<rom name="07 - game over.vgz" size="2732" crc="e796d745" sha1="5fcd75243bb3c10f7cef4af0f5595e4d89d640c3" offset="0" />
</dataarea>
</part>
<part name="008" interface="vgm_quik">
<feature name="part_id" value="08 - ranking.vgz" />
<dataarea name="quik" size="7519">
<rom name="08 - ranking.vgz" size="7519" crc="a14bd81e" sha1="2ab52b6e95ad13c1e44ec669f5efa526a0b20d4e" offset="0" />
</dataarea>
</part>
</software>
<software name="uruseiya_md">
<description>Urusei Yatsura - Dear My Friends (Sega CD) (GEN/MD)</description>
<year>1994</year>
<publisher>Game Arts Co., Ltd.</publisher>
<info name="cores" value="SN76496, YM2612"/>
<part name="001" interface="vgm_quik">
<feature name="part_id" value="01 - title.vgz" />
<dataarea name="quik" size="69366">
<rom name="01 - title.vgz" size="69366" crc="02c5f7f7" sha1="a1a7c4822ba03394e2d6f4d6870c164fc80488ff" offset="0" />
</dataarea>
</part>
<part name="002" interface="vgm_quik">
<feature name="part_id" value="02 - intro 1.vgz" />
<dataarea name="quik" size="89092">
<rom name="02 - intro 1.vgz" size="89092" crc="89354535" sha1="88d1f733582a80e8bba38d5cd004421abca91bc6" offset="0" />
</dataarea>
</part>
<part name="003" interface="vgm_quik">
<feature name="part_id" value="03 - ataru.vgz" />
<dataarea name="quik" size="81237">
<rom name="03 - ataru.vgz" size="81237" crc="4c5c16d0" sha1="3f788d9f06bee41fdc666c359dd1921adecc4ed5" offset="0" />
</dataarea>
</part>
<part name="004" interface="vgm_quik">
<feature name="part_id" value="04 - tomobiki.vgz" />
<dataarea name="quik" size="116057">
<rom name="04 - tomobiki.vgz" size="116057" crc="25328acf" sha1="16a6be97f8f238d9d6ca889ef32858c9810fcd99" offset="0" />
</dataarea>
</part>
<part name="005" interface="vgm_quik">
<feature name="part_id" value="05 - ran.vgz" />
<dataarea name="quik" size="111691">
<rom name="05 - ran.vgz" size="111691" crc="2cb86244" sha1="526273098e800dc94d8d64c5283776882f037cd2" offset="0" />
</dataarea>
</part>
<part name="006" interface="vgm_quik">
<feature name="part_id" value="06 - school.vgz" />
<dataarea name="quik" size="139602">
<rom name="06 - school.vgz" size="139602" crc="3e520ebd" sha1="80b6443add96de1a02c05fe89ffa0f027e2fe872" offset="0" />
</dataarea>
</part>
<part name="007" interface="vgm_quik">
<feature name="part_id" value="07 - ryu.vgz" />
<dataarea name="quik" size="65098">
<rom name="07 - ryu.vgz" size="65098" crc="e31176a9" sha1="ae74f112023af1d9c62a290b13f76645f9d41890" offset="0" />
</dataarea>
</part>
<part name="008" interface="vgm_quik">
<feature name="part_id" value="08 - mendou.vgz" />
<dataarea name="quik" size="95557">
<rom name="08 - mendou.vgz" size="95557" crc="496eeb61" sha1="bd6809b30e97668406b800e5aa59d3b883bec8b6" offset="0" />
</dataarea>
</part>
<part name="009" interface="vgm_quik">
<feature name="part_id" value="09 - calamity.vgz" />
<dataarea name="quik" size="57610">
<rom name="09 - calamity.vgz" size="57610" crc="d24d73db" sha1="9f0873345aa5bbbf217a4cbc14ea0e26c4c935f5" offset="0" />
</dataarea>
</part>
<part name="010" interface="vgm_quik">
<feature name="part_id" value="10 - mendou 2.vgz" />
<dataarea name="quik" size="80842">
<rom name="10 - mendou 2.vgz" size="80842" crc="1cb16579" sha1="9ccd6af831f82e1446d2211d79976c0a07144c3f" offset="0" />
</dataarea>
</part>
<part name="011" interface="vgm_quik">
<feature name="part_id" value="11 - park.vgz" />
<dataarea name="quik" size="151110">
<rom name="11 - park.vgz" size="151110" crc="230c0595" sha1="8a437a4bd23a30149bbee3fe84e2942b482bc853" offset="0" />
</dataarea>
</part>
<part name="012" interface="vgm_quik">
<feature name="part_id" value="12 - temple.vgz" />
<dataarea name="quik" size="138891">
<rom name="12 - temple.vgz" size="138891" crc="c6d2e759" sha1="ebbb8adc38ad0a1b233181ec48d91d70461a2676" offset="0" />
</dataarea>
</part>
<part name="013" interface="vgm_quik">
<feature name="part_id" value="13 - funfair.vgz" />
<dataarea name="quik" size="83274">
<rom name="13 - funfair.vgz" size="83274" crc="1d8ed67c" sha1="75824a39f43e0abc7aed07047a7066fbba136150" offset="0" />
</dataarea>
</part>
<part name="014" interface="vgm_quik">
<feature name="part_id" value="14 - destruction.vgz" />
<dataarea name="quik" size="75749">
<rom name="14 - destruction.vgz" size="75749" crc="35b68552" sha1="2d98bbcd215ff70fe7b540e90099acea9a0871a4" offset="0" />
</dataarea>
</part>
<part name="015" interface="vgm_quik">
<feature name="part_id" value="15 - mendou slow.vgz" />
<dataarea name="quik" size="68245">
<rom name="15 - mendou slow.vgz" size="68245" crc="7ad2c10c" sha1="a6512eabfc480ae389c81486dab41096617b7d5b" offset="0" />
</dataarea>
</part>
<part name="016" interface="vgm_quik">
<feature name="part_id" value="16 - subspace2.vgz" />
<dataarea name="quik" size="101027">
<rom name="16 - subspace2.vgz" size="101027" crc="3cf0f706" sha1="1fcf955102691f4a89b8edbb6b0f5be7d718587f" offset="0" />
</dataarea>
</part>
<part name="017" interface="vgm_quik">
<feature name="part_id" value="17 - subspace4.vgz" />
<dataarea name="quik" size="134001">
<rom name="17 - subspace4.vgz" size="134001" crc="b2f9343d" sha1="7df9df6f9441f10a2dd560fc7bc570b5df954e45" offset="0" />
</dataarea>
</part>
<part name="018" interface="vgm_quik">
<feature name="part_id" value="18 - danger.vgz" />
<dataarea name="quik" size="72784">
<rom name="18 - danger.vgz" size="72784" crc="37c39fd9" sha1="11b1d327f39538a9b440caaf977c118d8bd2e941" offset="0" />
</dataarea>
</part>
<part name="019" interface="vgm_quik">
<feature name="part_id" value="19 - cutscene 1a.vgz" />
<dataarea name="quik" size="68017">
<rom name="19 - cutscene 1a.vgz" size="68017" crc="65640428" sha1="3f7234e2e88c8190b5123741bd81d9ab5a9dc461" offset="0" />
</dataarea>
</part>
<part name="020" interface="vgm_quik">
<feature name="part_id" value="20 - cutscene 4.vgz" />
<dataarea name="quik" size="109993">
<rom name="20 - cutscene 4.vgz" size="109993" crc="d14ff10b" sha1="ca687de3a0a5bfddc24a1f5cff8d2e3f58450da8" offset="0" />
</dataarea>
</part>
<part name="021" interface="vgm_quik">
<feature name="part_id" value="21 - cutscene 7a.vgz" />
<dataarea name="quik" size="54081">
<rom name="21 - cutscene 7a.vgz" size="54081" crc="b71f2709" sha1="6b6df178d9730c49bc620ca815c1c13eea428038" offset="0" />
</dataarea>
</part>
<part name="022" interface="vgm_quik">
<feature name="part_id" value="22 - cutscene 7b.vgz" />
<dataarea name="quik" size="117350">
<rom name="22 - cutscene 7b.vgz" size="117350" crc="14e62acf" sha1="0f733b5604b2001fc7f179a8becb840ade6dd360" offset="0" />
</dataarea>
</part>
<part name="023" interface="vgm_quik">
<feature name="part_id" value="23 - cutscene 7c.vgz" />
<dataarea name="quik" size="75096">
<rom name="23 - cutscene 7c.vgz" size="75096" crc="f8639ff7" sha1="6692d457107bca6802be5ee4922e2dba54c503ae" offset="0" />
</dataarea>
</part>
<part name="024" interface="vgm_quik">
<feature name="part_id" value="24 - cutscene 8b.vgz" />
<dataarea name="quik" size="77382">
<rom name="24 - cutscene 8b.vgz" size="77382" crc="73d888de" sha1="78e9dbe51e5088efb932a169788d3abb3deb56c6" offset="0" />
</dataarea>
</part>
<part name="025" interface="vgm_quik">
<feature name="part_id" value="25 - cutscene 8c.vgz" />
<dataarea name="quik" size="33654">
<rom name="25 - cutscene 8c.vgz" size="33654" crc="ff16102a" sha1="48bfe597b6df4e521f409d17e307d6632cc510d5" offset="0" />
</dataarea>
</part>
<part name="026" interface="vgm_quik">
<feature name="part_id" value="26 - cutscene 11.vgz" />
<dataarea name="quik" size="72651">
<rom name="26 - cutscene 11.vgz" size="72651" crc="0a09c972" sha1="9c492ac7ee0ab3ca534d83b240bc26e6e14fdfc9" offset="0" />
</dataarea>
</part>
<part name="027" interface="vgm_quik">
<feature name="part_id" value="27 - cutscene 15 (alternate loop).vgz" />
<dataarea name="quik" size="174156">
<rom name="27 - cutscene 15 (alternate loop).vgz" size="174156" crc="cdaf950e" sha1="16ae31fb1c186cda4e524f07a4b5763cd6185cfd" offset="0" />
</dataarea>
</part>
<part name="028" interface="vgm_quik">
<feature name="part_id" value="27 - cutscene 15.vgz" />
<dataarea name="quik" size="68007">
<rom name="27 - cutscene 15.vgz" size="68007" crc="226bdaad" sha1="7cbe38c7c413eaa5628a9c507e32629347cbd6fe" offset="0" />
</dataarea>
</part>
<part name="029" interface="vgm_quik">
<feature name="part_id" value="28 - cutscene 16a.vgz" />
<dataarea name="quik" size="69652">
<rom name="28 - cutscene 16a.vgz" size="69652" crc="1a2034bd" sha1="25140168bb103b77450fb147d794f6dfeab56332" offset="0" />
</dataarea>
</part>
<part name="030" interface="vgm_quik">
<feature name="part_id" value="29 - cutscene 16b.vgz" />
<dataarea name="quik" size="100208">
<rom name="29 - cutscene 16b.vgz" size="100208" crc="e9614a99" sha1="fd6d09077510ce3de25b7a1442f6793a9b5e1577" offset="0" />
</dataarea>
</part>
<part name="031" interface="vgm_quik">
<feature name="part_id" value="30 - slideshow.vgz" />
<dataarea name="quik" size="48301">
<rom name="30 - slideshow.vgz" size="48301" crc="adcdaa2a" sha1="8bb6a5e1412574aa123c6c52564c1ef57afeb213" offset="0" />
</dataarea>
</part>
<part name="032" interface="vgm_quik">
<feature name="part_id" value="31 - subspace fighter infinity nitro (menu).vgz" />
<dataarea name="quik" size="74709">
<rom name="31 - subspace fighter infinity nitro (menu).vgz" size="74709" crc="a4f02550" sha1="3f74fa1123fc8c4fabfe8e90dbade0a08b809203" offset="0" />
</dataarea>
</part>
<part name="033" interface="vgm_quik">
<feature name="part_id" value="32 - subspace fighter infinity nitro (arena).vgz" />
<dataarea name="quik" size="89431">
<rom name="32 - subspace fighter infinity nitro (arena).vgz" size="89431" crc="c09ec976" sha1="1d2558e207defbbd01947adad23135e8dc8ec020" offset="0" />
</dataarea>
</part>
<part name="034" interface="vgm_quik">
<feature name="part_id" value="33 - subspace fighter infinity nitro (end).vgz" />
<dataarea name="quik" size="33473">
<rom name="33 - subspace fighter infinity nitro (end).vgz" size="33473" crc="b147fd88" sha1="6d50d69bc22fb326171f8e58e537502e02023f54" offset="0" />
</dataarea>
</part>
<part name="035" interface="vgm_quik">
<feature name="part_id" value="34 - maximum speed (menu).vgz" />
<dataarea name="quik" size="86681">
<rom name="34 - maximum speed (menu).vgz" size="86681" crc="ab55c3d7" sha1="7a13e8a823cbc82e9a8cfaf6b6c602eef83fa9ed" offset="0" />
</dataarea>
</part>
<part name="036" interface="vgm_quik">
<feature name="part_id" value="35 - maximum speed (level).vgz" />
<dataarea name="quik" size="76688">
<rom name="35 - maximum speed (level).vgz" size="76688" crc="91bbec09" sha1="5f8b753628523443c157923d0987b4e7d223d43c" offset="0" />
</dataarea>
</part>
<part name="037" interface="vgm_quik">
<feature name="part_id" value="36 - maximum speed (end).vgz" />
<dataarea name="quik" size="47101">
<rom name="36 - maximum speed (end).vgz" size="47101" crc="842690ea" sha1="0fedeb6f6565b01e84c626c8685fabb13130116e" offset="0" />
</dataarea>
</part>
<part name="038" interface="vgm_quik">
<feature name="part_id" value="37 - happy kotatsuneko episode 2 (menu).vgz" />
<dataarea name="quik" size="80263">
<rom name="37 - happy kotatsuneko episode 2 (menu).vgz" size="80263" crc="6006f24f" sha1="0dffdfe9b4d4bea1dd1e1739ed03c6a39b2f5abe" offset="0" />
</dataarea>
</part>
<part name="039" interface="vgm_quik">
<feature name="part_id" value="38 - happy kotatsuneko episode 2 (level).vgz" />
<dataarea name="quik" size="178449">
<rom name="38 - happy kotatsuneko episode 2 (level).vgz" size="178449" crc="2de6c0f7" sha1="b7b82960f631256a9f08a873167f9d121d7f241e" offset="0" />
</dataarea>
</part>
<part name="040" interface="vgm_quik">
<feature name="part_id" value="39 - happy kotatsuneko episode 2 (end).vgz" />
<dataarea name="quik" size="74699">
<rom name="39 - happy kotatsuneko episode 2 (end).vgz" size="74699" crc="8d7f2ddf" sha1="b07298ba43b96add6754d239028ac24f1810fb5a" offset="0" />
</dataarea>
</part>
</software>
<!-- SMS Power! VGM Archives located at http://www.smspower.org/Music/VGMs
Later installments of vgmplay.xml may include other non-game OST content -->

View File

@ -107,7 +107,7 @@ Regular game cartridges
| | 80-090160(US) | <unknown> (Should be Monsters vs. Aliens #80-084440, exists in VTech V.Link database) |
| | 80-090163(UK) | Monsters vs. Aliens |
| XX | 80-090164(GE) | Monsters vs. Aliens |
| | 80-090165(FR) | Monsters Contre Aliens |
| XX | 80-090165(FR) | Monsters Contre Aliens |
| XX | 80-090167(SP) | Monstruos contra Alienígenas (52-090167(SP) on back label) |
+========+===================+================================================================================================+
| | 80-090180(US) | <Unknown> |
@ -421,7 +421,7 @@ Regular game cartridges
| | 80-092503(UK) | Whiz Kid Wheels |
| | 80-092504(GE) | Flitzers Schlaue Staedtetour (diff color) |
| XX | 80-092504(GE) | Flitzers Schlaue Staedtetour (purple, 52-092504(GER) on back label) |
| | 80-092505(FR) | Mission Pilote |
| XX | 80-092505(FR) | Mission Pilote |
| | 80-092506(PT) | Conducao Diverrido (Cart# 92516) |
| XX | 80-092507(SP) | Conducción Divertida (52-92507(SP) on back label) |
| | 80-092510(KOR) | Whiz Kid Wheels - 꼬마 자동차 트러클 (50-92510(KOR) on back label) |
@ -510,6 +510,7 @@ Regular game cartridges
| XX | 80-092854(SE) | Wall-E |
| | (NO) | Wall-E |
| | (FI) | Wall-E |
| | (CN) | 瓦力 |
+========+===================+================================================================================================+
| XX | 80-092860(US) | Shrek the Third: Arthur's School Day Adventure |
| XX | 80-092860(US) | Shrek the Third: Arthur's School Day Adventure (alt) |
@ -1998,8 +1999,6 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<dataarea name="rom" size="0x800000">
<rom name="52-91327 - V.Smile Gimnasio Interactivo (Spain).bin" size="0x800000" crc="a203eaf7" sha1="bb7c7ecf6b208cd8b81daba58748345d3109268a" />
</dataarea>
<dataarea name="nvram" size="131072">
</dataarea>
</part>
</software>
@ -2512,6 +2511,22 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
</part>
</software>
<!-- No inputs -->
<software name="monstalnf" cloneof="monstalng" supported="no">
<description>DreamWorks Monstres contre Aliens (France)</description>
<year>2009?</year>
<publisher>VTech</publisher>
<info name="serial" value="80-090165(FR)" />
<part name="cart" interface="vsmile_cart">
<feature name="slot" value="vsmile_rom" />
<feature name="cart_type" value="lilac" />
<feature name="u1" value="" />
<dataarea name="rom" size="8388608">
<rom name="090165 - MonstresContreAliens (FR).bin" size="8388608" crc="eb7b16b2" sha1="45d32470b2283ea47032e007e4f803f8b5ea6dfa" />
</dataarea>
</part>
</software>
<!-- No inputs -->
<software name="monstalns" cloneof="monstalng" supported="no">
<description>DreamWorks Monstruos contra Alienígenas (Spain)</description>
@ -4563,7 +4578,7 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<publisher>VTech</publisher>
<info name="serial" value="80-092504(GER)" />
<part name="cart" interface="vsmile_cart">
<feature name="slot" value="vsmile_nvram" />
<feature name="slot" value="vsmile_rom" />
<feature name="pcb" value="708201" />
<feature name="pcb_model" value="708201-4" />
<feature name="cart_type" value="lilac" />
@ -4571,7 +4586,20 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<dataarea name="rom" size="8388608">
<rom name="80-092504 - Flitzers Schlaue Stadtetour (GER).bin" size="8388608" crc="1bdd6066" sha1="1e2a9090c0bfe08c31e750e263bad4a4a1fb2e73" />
</dataarea>
<dataarea name="nvram" size="131072">
</part>
</software>
<software name="wkwheelf" cloneof="wkwheelg"> <!-- Will be clone of "wkwheel" once found and dumped. -->
<description>Mission Pilote (France)</description>
<year>200?</year>
<publisher>VTech</publisher>
<info name="serial" value="80-092505(FR)" />
<part name="cart" interface="vsmile_cart">
<feature name="slot" value="vsmile_rom" />
<feature name="cart_type" value="lilac" />
<feature name="u1" value="" />
<dataarea name="rom" size="8388608">
<rom name="092505 - MissionPilote (FR).bin" size="8388608" crc="81531074" sha1="11631a6e837d3aa7a7bd6c0bcefa8289440a60b8" />
</dataarea>
</part>
</software>
@ -4582,7 +4610,7 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<publisher>VTech</publisher>
<info name="serial" value="80-092507(SP)" />
<part name="cart" interface="vsmile_cart">
<feature name="slot" value="vsmile_nvram" />
<feature name="slot" value="vsmile_rom" />
<feature name="pcb" value="706714" />
<feature name="pcb_model" value="706714-1" />
<feature name="cart_type" value="lilac" />
@ -4590,8 +4618,6 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<dataarea name="rom" size="8388608">
<rom name="80-092507 - Conduccion Divertida (SP).bin" size="8388608" crc="c52ff5d8" sha1="ce48bb9ea53cbdfa243170217908cc1f4352e4f0" />
</dataarea>
<dataarea name="nvram" size="131072">
</dataarea>
</part>
</software>
@ -4602,7 +4628,7 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<publisher>VTech</publisher>
<info name="serial" value="80-090224(GE)" />
<part name="cart" interface="vsmile_cart">
<feature name="slot" value="vsmile_nvram" />
<feature name="slot" value="vsmile_rom" />
<feature name="pcb" value="708106" />
<feature name="pcb_model" value="708106-3" />
<feature name="cart_type" value="lilac" />
@ -4610,8 +4636,6 @@ V.Smile Smartbook Smartidges (need a Smartbook touch tablet connected to a regul
<dataarea name="rom" size="8388608">
<rom name="80-090224 - Dolphis Wasserabenteuer (GE).bin" size="8388608" crc="3fd78b1b" sha1="eadbc8b2a9bf09f623f27d3b94a1b19643685629" />
</dataarea>
<dataarea name="nvram" size="131072">
</dataarea>
</part>
</software>

View File

@ -141,7 +141,7 @@ Language:
| | 80-084362(NL) | Handy Manny |
| | 80-084363(UK) | Handy Manny |
| | 80-084364(GE) | Meister Manny's Werkzeugkiste |
| | 80-084365(FR) | Manny Et Ses Outils |
| XX | 80-084365(FR) | Manny et ses outils |
| | 80-084366(PT) | Manny Maozinhas (84376 on cart) |
| | 80-084367(SP) | Manny Manitas |
+========+===================+===========================================================================================+
@ -187,20 +187,20 @@ Language:
| | 80-084482(NL) | Prinses en de Kikker (label in english) |
| XX | 80-084483(UK) | The Princess and the Frog |
| XX | 80-084484(GE) | Kuess den Frosch |
| | 80-084485(FR) | La Princesse Et La Grenouille |
| XX | 80-084485(FR) | La Princesse Et La Grenouille - Le grand rêve de Tiana |
| | 80-084487(SP) | Tiana y el Sapo - El gran sueño de Tiana |
+========+===================+===========================================================================================+
| XX | 80-084500(US) | Shrek Forever After |
| | 80-084502(NL) | Sjrek voor eeuwig en altijd |
| | 80-084503(UK) | Shrek Forever After |
| XX | 80-084504(GE) | Fuer immer Shrek |
| | 80-084505(FR) | Shrek 4 - Il Etait une Fin |
| XX | 80-084505(FR) | Shrek 4 - Il était une fin |
| | 80-084507(SP) | Shrek Felices para siempre |
+========+===================+===========================================================================================+
| | 80-084520(US) | <Unknown> |
+========+===================+===========================================================================================+
| | 80-084540(US) | Super Why to the Rescue! The Beach Day Mystery |
| | 80-084541(US) | Super Why to the Rescue! The Beach Day Mystery (pocket version) |
| | 80-084541(US) | Super Why to the Rescue! The Beach Day Mystery (pocket version) |
+========+===================+===========================================================================================+
| | 80-084560(US) | <Unknown> |
+========+===================+===========================================================================================+
@ -473,7 +473,7 @@ Language:
</part>
</software>
<software name="hmannym" cloneof="doram" supported="no">
<software name="hmannym" supported="no">
<description>Disney Handy Manny (USA, Rev. 2?)</description>
<year>2009</year>
<publisher>VTech</publisher>
@ -486,6 +486,19 @@ Language:
</part>
</software>
<software name="hmannymf" cloneof="hmannym" supported="no">
<description>Disney Manny et ses outils (France)</description>
<year>2009</year>
<publisher>VTech</publisher>
<info name="serial" value="80-084365(FR)" />
<part name="cart" interface="vsmile_cart">
<feature name="u1" value="" />
<dataarea name="rom" size="8388608">
<rom name="084365 - MannyEtSesOutils (MOTION) (FR).bin" size="8388608" crc="a664071e" sha1="6900419492aa7424290b3db4b37c47b14a17ab61" />
</dataarea>
</part>
</software>
<software name="kfpandamg" supported="no">
<description>DreamWorks Kung Fu Panda - Der Weg des Panda (Germany)</description>
<year>2008?</year>
@ -826,6 +839,18 @@ Language:
</part>
</software>
<software name="prinfrogmf" cloneof="prinfrogm" supported="no">
<description>Disney La Princesse Et La Grenouille - Le grand rêve de Tiana (France)</description>
<year>2010</year>
<publisher>VTech</publisher>
<info name="serial" value="80-084485(FR)" />
<part name="cart" interface="vsmile_cart">
<dataarea name="rom" size="8388608">
<rom name="084485 - LaPrincesseEtLaGrenouille (MOTION) (FR).bin" size="8388608" crc="1e1e84a2" sha1="01543d05122809e6bb5e8bdac213eedc22f442bd" />
</dataarea>
</part>
</software>
<software name="scoobyffmf" supported="no">
<description>Scooby-Doo! - Panique à Funland (France)</description>
<year>2008</year> <!-- (s08) -->
@ -886,6 +911,20 @@ Language:
</part>
</software>
<!-- Does not boot, just loops on the intro -->
<software name="shrekfamf" cloneof="shrekfam" supported="no">
<description>Shrek 4 - Il était une fin (France)</description>
<year>2010?</year>
<publisher>VTech</publisher>
<info name="serial" value="80-084505(FR)" />
<part name="cart" interface="vsmile_cart">
<dataarea name="rom" size="0x1000000">
<rom name="084505 - Shrek 4 (MOTION) (FR)_blob1.bin" size="0x0800000" crc="bb3d3e09" sha1="539f0948ec1dad3b2465990fcf053f2cacc7e766" offset="0x0000000" />
<rom name="084505 - Shrek 4 (MOTION) (FR)_blob2.bin" size="0x0800000" crc="7c633e07" sha1="a07b2439473be97bc1a785ae4050297ae0e5244a" offset="0x0800000" />
</dataarea>
</part>
</software>
<!-- Soccer Challenge -->
<software name="soccerchmg" supported="no">
<description>Fussball Meisterschaft (Germany)</description>

View File

@ -3306,6 +3306,8 @@ if (BUSES["COCO"]~=null) then
MAME_DIR .. "src/devices/bus/coco/coco_dcmodem.h",
MAME_DIR .. "src/devices/bus/coco/coco_orch90.cpp",
MAME_DIR .. "src/devices/bus/coco/coco_orch90.h",
MAME_DIR .. "src/devices/bus/coco/coco_ram.cpp",
MAME_DIR .. "src/devices/bus/coco/coco_ram.h",
MAME_DIR .. "src/devices/bus/coco/coco_ssc.cpp",
MAME_DIR .. "src/devices/bus/coco/coco_ssc.h",
MAME_DIR .. "src/devices/bus/coco/coco_pak.cpp",

View File

@ -2781,7 +2781,7 @@ end
---------------------------------------------------
--
--@src/devices/machine/scnxx562.h,MACHINES["SCN_PCI"] = true
--@src/devices/machine/scn_pci.h,MACHINES["SCN_PCI"] = true
---------------------------------------------------
if (MACHINES["SCN_PCI"]~=null) then

View File

@ -850,6 +850,17 @@ if (VIDEOS["SED1330"]~=null) then
}
end
--------------------------------------------------
--
--@src/devices/video/sed1500.h,VIDEOS["SED1500"] = true
--------------------------------------------------
if (VIDEOS["SED1500"]~=null) then
files {
MAME_DIR .. "src/devices/video/sed1500.cpp",
MAME_DIR .. "src/devices/video/sed1500.h",
}
end
--------------------------------------------------
--
--@src/devices/video/sed1520.h,VIDEOS["SED1520"] = true

View File

@ -354,6 +354,7 @@ VIDEOS["SCN2674"] = true
VIDEOS["PWM_DISPLAY"] = true
--VIDEOS["SED1200"] = true
--VIDEOS["SED1330"] = true
--VIDEOS["SED1500"] = true
--VIDEOS["SED1520"] = true
VIDEOS["SNES_PPU"] = true
VIDEOS["STVVDP"] = true
@ -1521,8 +1522,6 @@ files {
MAME_DIR .. "src/mame/includes/mitchell.h",
MAME_DIR .. "src/mame/video/mitchell.cpp",
MAME_DIR .. "src/mame/drivers/sf.cpp",
MAME_DIR .. "src/mame/includes/sf.h",
MAME_DIR .. "src/mame/video/sf.cpp",
MAME_DIR .. "src/mame/drivers/sidearms.cpp",
MAME_DIR .. "src/mame/includes/sidearms.h",
MAME_DIR .. "src/mame/video/sidearms.cpp",

View File

@ -382,6 +382,7 @@ VIDEOS["PWM_DISPLAY"] = true
VIDEOS["SDA5708"] = true
VIDEOS["SED1200"] = true
VIDEOS["SED1330"] = true
VIDEOS["SED1500"] = true
VIDEOS["SED1520"] = true
VIDEOS["SNES_PPU"] = true
VIDEOS["STVVDP"] = true
@ -1901,6 +1902,8 @@ files {
MAME_DIR .. "src/mame/drivers/fp200.cpp",
MAME_DIR .. "src/mame/drivers/fp1100.cpp",
MAME_DIR .. "src/mame/drivers/fp6000.cpp",
MAME_DIR .. "src/mame/machine/fp6000_kbd.cpp",
MAME_DIR .. "src/mame/machine/fp6000_kbd.h",
MAME_DIR .. "src/mame/drivers/ht6000.cpp",
MAME_DIR .. "src/mame/drivers/pb1000.cpp",
MAME_DIR .. "src/mame/drivers/pv1000.cpp",
@ -2003,6 +2006,8 @@ files {
MAME_DIR .. "src/mame/machine/cit101_kbd.cpp",
MAME_DIR .. "src/mame/machine/cit101_kbd.h",
MAME_DIR .. "src/mame/drivers/cit220.cpp",
MAME_DIR .. "src/mame/machine/cit220_kbd.cpp",
MAME_DIR .. "src/mame/machine/cit220_kbd.h",
}
createMESSProjects(_target, _subtarget, "coleco")
@ -4279,6 +4284,7 @@ files {
MAME_DIR .. "src/mame/drivers/elwro800.cpp",
MAME_DIR .. "src/mame/drivers/emate.cpp",
MAME_DIR .. "src/mame/drivers/epic14e.cpp",
MAME_DIR .. "src/mame/drivers/ergo201.cpp",
MAME_DIR .. "src/mame/drivers/esprit.cpp",
MAME_DIR .. "src/mame/drivers/eti660.cpp",
MAME_DIR .. "src/mame/includes/eti660.h",
@ -4460,6 +4466,10 @@ files {
MAME_DIR .. "src/mame/drivers/palestra.cpp",
MAME_DIR .. "src/mame/machine/nl_palestra.cpp",
MAME_DIR .. "src/mame/drivers/mindset.cpp",
MAME_DIR .. "src/mame/drivers/gs6502.cpp",
MAME_DIR .. "src/mame/drivers/gs6809.cpp",
MAME_DIR .. "src/mame/drivers/gscpm.cpp",
MAME_DIR .. "src/mame/drivers/gsz80.cpp",
}
end

View File

@ -661,7 +661,6 @@ INPUT_PORTS_START(matrix_dk)
INPUT_PORTS_END
INPUT_PORTS_START(matrix_ch)
// FIXME: natural keyboard doesn't play nicely with PORT_CONDITION, but it's an issue with natural keyboard itself
PORT_INCLUDE(matrix_common)
PORT_START("CFG")

View File

@ -82,8 +82,7 @@ void bbc_datacentre_device::device_add_mconfig(machine_config &config)
ATA_INTERFACE(config, m_ide).options(ata_devices, "hdd", "hdd", false);
m_ide->irq_handler().set(FUNC(bbc_datacentre_device::irq_w));
/* 24LC512 - 512Kb I2C Serial EEPROM */
I2CMEM(config, m_nvram).set_page_size(128).set_data_size(0x10000);
I2C_24C512(config, m_nvram); // 24LC512
/* import floppy images - delayed to allow RAMFS to initialise before import */
QUICKLOAD(config, "import0", "ssd,dsd,img", attotime::from_seconds(1)).set_load_callback(FUNC(bbc_datacentre_device::quickload_cb<0>));

View File

@ -40,6 +40,32 @@
Reading from $FF48-$FF4F clears bit 7 of DSKREG ($FF40)
---------------------------------------------------------------------------
Disto No Halt Extension
The Disto Super Controller II includes "no halt" circuitry. Implemented
by using a read and write cache.
CachDat - Cache Data Register
$FF74 & $FF75: Read/Write cache data.
CachCtrl - Cache Controller
$FF76: Read
Bit 7 low indicates an interrupt request from the disk controller
$FF76: Write:
00000000 = Caching off
00001000 = Tell cache controller to send interrupt when device is
ready to send/receive a buffer (seek done, etc.)
00000111 = Read cache on - Get next 256 data bytes from controller
to cache
00000100 = Write cache on - Next 256 bytes stored in cache are
sector
00000110 = Copy Write cache to controller
*********************************************************************/
#include "emu.h"
@ -49,18 +75,20 @@
#include "machine/msm6242.h"
#include "machine/ds1315.h"
#include "machine/wd_fdc.h"
#include "machine/ram.h"
#include "formats/dmk_dsk.h"
#include "formats/jvc_dsk.h"
#include "formats/vdk_dsk.h"
#include "formats/sdf_dsk.h"
#include "formats/os9_dsk.h"
// #define VERBOSE (LOG_GENERAL )
#include "logmacro.h"
/***************************************************************************
PARAMETERS
***************************************************************************/
#define LOG_FDC 0
#define WD_TAG "wd17xx"
#define WD2797_TAG "wd2797"
#define DISTO_TAG "disto"
@ -88,6 +116,10 @@ protected:
NONE = 0xFF
};
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// device-level overrides
virtual DECLARE_READ8_MEMBER(cts_read) override;
virtual DECLARE_READ8_MEMBER(scs_read) override;
@ -108,6 +140,16 @@ protected:
required_device<msm6242_device> m_disto_msm6242; // 6242 RTC on Disto interface
offs_t m_msm6242_rtc_address;
optional_ioport m_rtc;
// Protected
virtual DECLARE_READ8_MEMBER(ff74_read);
virtual DECLARE_WRITE8_MEMBER(ff74_write);
private:
// registers
uint8_t m_cache_controler;
uint8_t m_cache_pointer;
required_device<ram_device> m_cache_buffer;
};
@ -143,6 +185,8 @@ void coco_fdc_device_base::device_add_mconfig(machine_config &config)
MSM6242(config, m_disto_msm6242, 32.768_kHz_XTAL);
DS1315(config, CLOUD9_TAG, 0);
RAM(config, "cachebuffer").set_default_size("256").set_default_value(0);
}
@ -183,6 +227,7 @@ uint8_t* coco_family_fdc_device_base::get_cart_base()
return memregion("eprom")->base();
}
//-------------------------------------------------
// coco_family_fdc_device_base::get_cart_memregion
//-------------------------------------------------
@ -209,9 +254,100 @@ coco_fdc_device_base::coco_fdc_device_base(const machine_config &mconfig, device
, m_disto_msm6242(*this, DISTO_TAG)
, m_msm6242_rtc_address(0)
, m_rtc(*this, ":real_time_clock")
, m_cache_buffer(*this, "cachebuffer")
{
}
//-------------------------------------------------
// device_start - device-specific start
//-------------------------------------------------
void coco_fdc_device_base::device_start()
{
install_readwrite_handler(0xFF74, 0xFF76,
read8_delegate(*this, FUNC(coco_fdc_device_base::ff74_read)),
write8_delegate(*this, FUNC(coco_fdc_device_base::ff74_write)));
save_item(NAME(m_cache_controler));
save_item(NAME(m_cache_pointer));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void coco_fdc_device_base::device_reset()
{
m_cache_controler = 0x80;
m_cache_pointer = 0;
}
//-------------------------------------------------
// ff74_read - no halt registers
//-------------------------------------------------
READ8_MEMBER(coco_fdc_device_base::ff74_read)
{
uint8_t data = 0x0;
switch(offset)
{
case 0x0:
data = m_cache_buffer->read(m_cache_pointer++);
LOG( "CachDat_A read: %2.2x\n", data );
break;
case 0x1:
data = m_cache_buffer->read(m_cache_pointer++);
LOG( "CachDat_B read: %2.2x\n", data );
break;
case 0x2:
data = m_cache_controler;
LOG( "CachCtrl read: %2.2x\n", data );
break;
}
return data;
}
//-------------------------------------------------
// ff74_write - no halt registers
//-------------------------------------------------
WRITE8_MEMBER(coco_fdc_device_base::ff74_write)
{
switch(offset)
{
case 0x0:
LOG( "CachDat_A write: %2.2x\n", data );
m_cache_buffer->write(m_cache_pointer++, data);
break;
case 0x1:
LOG( "CachDat_B write: %2.2x\n", data );
m_cache_buffer->write(m_cache_pointer++, data);
break;
case 0x2:
LOG( "CachCtrl write: %2.2x\n", data );
// reset static ram buffer pointer on any write
m_cache_pointer = 0;
if(data == 0)
{
// Clear interrupt when caching is turned off
set_line_value(line::CART, CLEAR_LINE);
m_cache_controler |= 0x80;
}
m_cache_controler = (m_cache_controler & 0x80) | (data & 0x7f);
break;
}
}
//-------------------------------------------------
// real_time_clock
//-------------------------------------------------
@ -238,15 +374,60 @@ coco_fdc_device_base::rtc_type coco_fdc_device_base::real_time_clock()
void coco_fdc_device_base::update_lines()
{
// clear HALT enable under certain circumstances
if (intrq() && (dskreg() & 0x20))
set_dskreg(dskreg() & ~0x80); // clear halt enable
if( (m_cache_controler & 0x7f) == 0) /* cache disabled */
{
// clear HALT enable under certain circumstances
if (intrq() && (dskreg() & 0x20))
set_dskreg(dskreg() & ~0x80); // clear halt enable
// set the NMI line
set_line_value(line::NMI, intrq() && (dskreg() & 0x20));
// set the NMI line
set_line_value(line::NMI, intrq() && (dskreg() & 0x20));
// set the HALT line
set_line_value(line::HALT, !drq() && (dskreg() & 0x80));
// set the HALT line
set_line_value(line::HALT, !drq() && (dskreg() & 0x80));
}
else
{
if( drq() == ASSERT_LINE)
{
if( (m_cache_controler & 0x07) == 0x07) /* Read cache on */
{
uint8_t data = m_wd17xx->data_r();
LOG("Cached drq read: %2.2x\n", data );
m_cache_buffer->write(m_cache_pointer++, data);
}
else if( (m_cache_controler & 0x07) == 0x04 ) /* Write cache on */
{
uint8_t data = m_cache_buffer->read(m_cache_pointer++);
LOG("Cached drq write: %2.2x\n", data );
m_wd17xx->data_w(data);
}
else if( (m_cache_controler & 0x07) == 0x06 ) /* Copy Write cache to controller */
{
uint8_t data = m_cache_buffer->read(m_cache_pointer++);
LOG("Cached drq write: %2.2x\n", data );
m_wd17xx->data_w(data);
}
else
{
LOG("illegal DRQ cached assert mode\n" );
}
}
if( (m_cache_controler & 0x08) == 0x08)
{
set_line_value(line::CART, intrq());
}
if( intrq() == ASSERT_LINE)
{
m_cache_controler &= 0x7f;
}
else
{
m_cache_controler |= 0x80;
}
}
}
@ -259,19 +440,16 @@ void coco_fdc_device_base::dskreg_w(uint8_t data)
uint8_t drive = 0;
uint8_t head;
if (LOG_FDC)
{
logerror("fdc_coco_dskreg_w(): %c%c%c%c%c%c%c%c ($%02x)\n",
data & 0x80 ? 'H' : 'h',
data & 0x40 ? '3' : '.',
data & 0x20 ? 'D' : 'S',
data & 0x10 ? 'P' : 'p',
data & 0x08 ? 'M' : 'm',
data & 0x04 ? '2' : '.',
data & 0x02 ? '1' : '.',
data & 0x01 ? '0' : '.',
data);
}
LOG("fdc_coco_dskreg_w(): %c%c%c%c%c%c%c%c ($%02x)\n",
data & 0x80 ? 'H' : 'h',
data & 0x40 ? '3' : '.',
data & 0x20 ? 'D' : 'S',
data & 0x10 ? 'P' : 'p',
data & 0x08 ? 'M' : 'm',
data & 0x04 ? '2' : '.',
data & 0x02 ? '1' : '.',
data & 0x01 ? '0' : '.',
data);
// An email from John Kowalski informed me that if the DS3 is
// high, and one of the other drive bits is selected (DS0-DS2), then the
@ -334,41 +512,46 @@ READ8_MEMBER(coco_fdc_device_base::scs_read)
{
case 8:
result = m_wd17xx->status_r();
LOG("m_wd17xx->status_r: %2.2x\n", result );
break;
case 9:
result = m_wd17xx->track_r();
LOG("m_wd17xx->track_r: %2.2x\n", result );
break;
case 10:
result = m_wd17xx->sector_r();
LOG("m_wd17xx->sector_r: %2.2x\n", result );
break;
case 11:
result = m_wd17xx->data_r();
LOG("m_wd17xx->data_r: %2.2x\n", result );
break;
}
/* other stuff for RTCs */
switch (offset)
{
case 0x10: /* FF50 */
if (real_time_clock() == rtc_type::DISTO)
result = m_disto_msm6242->read(m_msm6242_rtc_address);
break;
case 0x10: /* FF50 */
if (real_time_clock() == rtc_type::DISTO)
result = m_disto_msm6242->read(m_msm6242_rtc_address);
break;
case 0x38: /* FF78 */
if (real_time_clock() == rtc_type::CLOUD9)
m_ds1315->read_0();
break;
case 0x38: /* FF78 */
if (real_time_clock() == rtc_type::CLOUD9)
m_ds1315->read_0();
break;
case 0x39: /* FF79 */
if (real_time_clock() == rtc_type::CLOUD9)
m_ds1315->read_1();
break;
case 0x39: /* FF79 */
if (real_time_clock() == rtc_type::CLOUD9)
m_ds1315->read_1();
break;
case 0x3C: /* FF7C */
if (real_time_clock() == rtc_type::CLOUD9)
result = m_ds1315->read_data();
break;
case 0x3C: /* FF7C */
if (real_time_clock() == rtc_type::CLOUD9)
result = m_ds1315->read_data();
break;
}
return result;
}
@ -386,15 +569,19 @@ WRITE8_MEMBER(coco_fdc_device_base::scs_write)
dskreg_w(data);
break;
case 8:
LOG("m_wd17xx->cmd_w: %2.2x\n", data );
m_wd17xx->cmd_w(data);
break;
case 9:
LOG("m_wd17xx->track_w: %2.2x\n", data );
m_wd17xx->track_w(data);
break;
case 10:
LOG("m_wd17xx->sector_w: %2.2x\n", data );
m_wd17xx->sector_w(data);
break;
case 11:
LOG("m_wd17xx->data_w: %2.2x\n", data );
m_wd17xx->data_w(data);
break;
};

View File

@ -64,6 +64,7 @@
#include "coco_pak.h"
#include "coco_rs232.h"
#include "coco_ssc.h"
#include "coco_ram.h"
#define SLOT1_TAG "slot1"
#define SLOT2_TAG "slot2"
@ -164,6 +165,7 @@ static void coco_cart_slot1_3(device_slot_interface &device)
device.option_add("dcmodem", COCO_DCMODEM);
device.option_add("orch90", COCO_ORCH90);
device.option_add("ssc", COCO_SSC);
device.option_add("ram", COCO_PAK_RAM);
device.option_add("games_master", COCO_PAK_GMC);
device.option_add("banked_16k", COCO_PAK_BANKED);
device.option_add("pak", COCO_PAK);
@ -177,6 +179,7 @@ static void coco_cart_slot4(device_slot_interface &device)
device.option_add("dcmodem", COCO_DCMODEM);
device.option_add("orch90", COCO_ORCH90);
device.option_add("ssc", COCO_SSC);
device.option_add("ram", COCO_PAK_RAM);
device.option_add("games_master", COCO_PAK_GMC);
device.option_add("banked_16k", COCO_PAK_BANKED);
device.option_add("pak", COCO_PAK);

View File

@ -0,0 +1,183 @@
// license:BSD-3-Clause
// copyright-holders:tim lindner
/***************************************************************************
coco_ram.cpp
Code for emulating the Disto RAM cartridge
This cartridge came in several forms: 256K, 512K, 768K, and 1024K.
***************************************************************************/
#include "emu.h"
#include "coco_ram.h"
#include "cococart.h"
#include "machine/ram.h"
#define STATICRAM_TAG "static_ram"
// #define VERBOSE (LOG_GENERAL )
#include "logmacro.h"
#define RAM_SIZE_IN_K 1024
#define BUFFER_SIZE (RAM_SIZE_IN_K * 1024)
#define STRINGIZE_HELPER(expr) #expr
#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
//**************************************************************************
// TYPE DECLARATIONS
//**************************************************************************
namespace
{
// ======================> coco_pak_device
class coco_pak_ram_device :
public device_t,
public device_cococart_interface
{
public:
// construction/destruction
coco_pak_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void device_add_mconfig(machine_config &config) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual DECLARE_WRITE8_MEMBER(scs_write) override;
virtual DECLARE_READ8_MEMBER(scs_read) override;
private:
required_device<ram_device> m_staticram;
int m_offset;
};
};
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE_PRIVATE(COCO_PAK_RAM, device_cococart_interface, coco_pak_ram_device, "cocopakram", "Disto " STRINGIZE(RAM_SIZE_IN_K) "K RAM Cartridge")
//-------------------------------------------------
// coco_pak_device - constructor
//-------------------------------------------------
coco_pak_ram_device::coco_pak_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, COCO_PAK_RAM, tag, owner, clock)
, device_cococart_interface(mconfig, *this)
, m_staticram(*this, STATICRAM_TAG)
, m_offset(0)
{
}
//**************************************************************************
// MACHINE FRAGMENTS AND ADDRESS MAPS
//**************************************************************************
void coco_pak_ram_device::device_add_mconfig(machine_config &config)
{
RAM(config, STATICRAM_TAG).set_default_size(STRINGIZE(RAM_SIZE_IN_K) "K").set_default_value(0);
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void coco_pak_ram_device::device_start()
{
// initial state
m_offset = 0;
// save state
save_item(NAME(m_offset));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void coco_pak_ram_device::device_reset()
{
m_offset = 0;
}
//-------------------------------------------------
// scs_write
//-------------------------------------------------
WRITE8_MEMBER(coco_pak_ram_device::scs_write)
{
// int idata = data;
switch(offset)
{
case 0:
m_offset = ((m_offset & 0xffff00) + data);
break;
case 1:
m_offset = ((m_offset & 0xff00ff) + (data << 8));
break;
case 2:
m_offset = ((m_offset & 0x00ffff) + (data << 16));
break;
case 3:
if( m_offset < BUFFER_SIZE )
{
m_staticram->write(m_offset, data);
}
break;
}
LOG("scs_write: %s: %06x, %02x, %02x\n", machine().describe_context(), m_offset, offset, data);
}
//-------------------------------------------------
// scs_read
//-------------------------------------------------
READ8_MEMBER(coco_pak_ram_device::scs_read)
{
uint8_t data = 0x00;
switch (offset)
{
case 0:
data = (m_offset) & 0xff;
break;
case 1:
data = (m_offset & 0xff00ff) >> 8;
break;
case 2:
data = (m_offset & 0xff0000) >> 16;
break;
case 3:
if( m_offset < BUFFER_SIZE )
{
data = m_staticram->read(m_offset);
}
break;
}
LOG("scs_read: %s: %06x, %02x, %02x\n", machine().describe_context(), m_offset, offset, data);
return data;
}

View File

@ -0,0 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:tim lindner
#ifndef MAME_BUS_COCO_COCO_RAM_H
#define MAME_BUS_COCO_COCO_RAM_H
#pragma once
#include "cococart.h"
// device type definition
DECLARE_DEVICE_TYPE(COCO_PAK_RAM, device_cococart_interface)
#endif // MAME_BUS_COCO_COCO_RAM_H

View File

@ -148,21 +148,21 @@ bool ekara_rom_i2c_24c08_epitch_device::is_write_access_not_rom(void)
void ekara_rom_i2c_24c08_epitch_device::device_add_mconfig(machine_config &config)
{
I2CMEM(config, "i2cmem", 0).set_page_size(16).set_data_size(0x400); // 24C08
I2C_24C08(config, "i2cmem", 0);
}
// i2c 24lc04
void ekara_rom_i2c_24lc04_device::device_add_mconfig(machine_config &config)
{
I2CMEM(config, "i2cmem", 0).set_page_size(16).set_data_size(0x200); // 24LC04
I2C_24C04(config, "i2cmem", 0); // 24LC04
}
// i2c 24lc02
void ekara_rom_i2c_24lc02_device::device_add_mconfig(machine_config &config)
{
I2CMEM(config, "i2cmem", 0).set_page_size(16).set_data_size(0x100); // 24LC02
I2C_24C02(config, "i2cmem", 0); // 24LC02
}
// i2c 24lc02 with direct IO port access
@ -206,7 +206,7 @@ READ_LINE_MEMBER(ekara_rom_i2c_24lc02_gc0010_device::read_sda )
void ekara_rom_i2c_24lc02_gc0010_device::device_add_mconfig(machine_config &config)
{
I2CMEM(config, "i2cmem", 0)/*.set_page_size(16)*/.set_data_size(0x100); // 24LC02
I2C_24C02(config, "i2cmem", 0); // 24LC02
}

View File

@ -9,6 +9,7 @@
**********************************************************************/
#include "emu.h"
#include "grid2102.h"
// device type definition

View File

@ -70,13 +70,30 @@ TIMER_CALLBACK_MEMBER(mc1502_fdc_device::motor_callback)
motor_on = 0;
}
void mc1502_fdc_device::motors_onoff()
{
floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
floppy_image_device *floppy1 = m_fdc->subdevice<floppy_connector>("1")->get_device();
if (motor_on)
{
// bits 2, 3 -- motor on (drive 0, 1)
floppy0->mon_w(!(m_control & 4));
floppy1->mon_w(!(m_control & 8));
}
else
{
floppy0->mon_w(ASSERT_LINE);
floppy1->mon_w(ASSERT_LINE);
}
}
uint8_t mc1502_fdc_device::mc1502_wd17xx_aux_r()
{
uint8_t data;
data = 0;
return data;
motor_timer->adjust(attotime::from_msec(3000));
motor_on = 1;
motors_onoff();
return 0;
}
void mc1502_fdc_device::mc1502_wd17xx_aux_w(uint8_t data)
@ -86,24 +103,15 @@ void mc1502_fdc_device::mc1502_wd17xx_aux_w(uint8_t data)
floppy_image_device *floppy = ((data & 0x10) ? floppy1 : floppy0);
// master reset
if ((data & 1) == 0)
m_fdc->reset();
m_fdc->mr_w(data & 1);
m_fdc->set_floppy(floppy);
// SIDE ONE
floppy->ss_w((data & 2) ? 1 : 0);
// bits 2, 3 -- motor on (drive 0, 1)
// the schematic appears to show the motor lines connected, if they aren't then motor_on doesn't work correctly
floppy0->mon_w(!(data & 12));
floppy1->mon_w(!(data & 12));
if (data & 12)
{
motor_timer->adjust(attotime::from_msec(3000));
motor_on = 1;
}
m_control = data;
motors_onoff();
}
/*
@ -191,6 +199,7 @@ mc1502_fdc_device::mc1502_fdc_device(const machine_config &mconfig, const char *
, device_isa8_card_interface(mconfig, *this)
, m_fdc(*this, "fdc")
, motor_on(0)
, m_control(0)
, motor_timer(nullptr)
, m_cpu(*this, finder_base::DUMMY_TAG)
{
@ -214,4 +223,5 @@ void mc1502_fdc_device::device_start()
motor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc1502_fdc_device::motor_callback),this));
motor_on = 0;
m_control = 0;
}

View File

@ -51,9 +51,10 @@ private:
required_device<fd1793_device> m_fdc;
int motor_on;
u8 m_control;
emu_timer *motor_timer;
required_device<cpu_device> m_cpu;
void motors_onoff();
public:
void mc1502_wd17xx_aux_w(uint8_t data);
uint8_t mc1502_wd17xx_aux_r();

View File

@ -96,7 +96,7 @@ WRITE16_MEMBER(jakks_gamekey_rom_i2c_base_device::write_cart_seeprom)
void jakks_gamekey_rom_i2c_24lc04_device::device_add_mconfig(machine_config &config)
{
I2CMEM(config, "i2cmem", 0)/*.set_page_size(16)*/.set_data_size(0x200); // 24LC04
I2C_24C04(config, "i2cmem", 0); // 24LC04
}

View File

@ -88,7 +88,7 @@ void md_seprom_codemast_device::device_add_mconfig(machine_config &config)
void md_seprom_mm96_device::device_add_mconfig(machine_config &config)
{
I2C_24C16A(config, m_i2cmem);
I2C_24C16(config, m_i2cmem); // 24C16A
}

View File

@ -212,6 +212,7 @@ i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type
, m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0)
, m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0)
, m_opcode_config("opcodes", ENDIANNESS_LITTLE, 8, 16, 0)
, m_in_inta_func(*this)
, m_out_status_func(*this)
, m_out_inte_func(*this)
, m_in_sid_func(*this)
@ -308,6 +309,7 @@ void i8085a_cpu_device::device_start()
m_trap_pending = 0;
m_trap_im_copy = 0;
m_sod_state = 0;
m_in_acknowledge = false;
m_ietemp = false;
init_tables();
@ -351,6 +353,7 @@ void i8085a_cpu_device::device_start()
m_io = &space(AS_IO);
/* resolve callbacks */
m_in_inta_func.resolve();
m_out_status_func.resolve_safe();
m_out_inte_func.resolve_safe();
m_in_sid_func.resolve_safe(0);
@ -372,6 +375,7 @@ void i8085a_cpu_device::device_start()
save_item(NAME(m_trap_pending));
save_item(NAME(m_trap_im_copy));
save_item(NAME(m_sod_state));
save_item(NAME(m_in_acknowledge));
set_icountptr(m_icount);
}
@ -479,11 +483,13 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state)
{
int newstate = (state != CLEAR_LINE);
/* NMI is edge-triggered */
if (irqline == INPUT_LINE_NMI)
/* TRAP is level and edge-triggered NMI */
if (irqline == I8085_TRAP_LINE)
{
if (!m_nmi_state && newstate)
m_trap_pending = true;
else if (!newstate)
m_trap_pending = false;
m_nmi_state = newstate;
}
@ -511,6 +517,8 @@ void i8085a_cpu_device::break_halt_for_interrupt()
}
else
set_status(0x23); /* int ack */
m_in_acknowledge = true;
}
void i8085a_cpu_device::check_for_interrupts()
@ -527,7 +535,7 @@ void i8085a_cpu_device::check_for_interrupts()
/* break out of HALT state and call the IRQ ack callback */
break_halt_for_interrupt();
standard_irq_callback(INPUT_LINE_NMI);
standard_irq_callback(I8085_TRAP_LINE);
/* push the PC and jump to $0024 */
op_push(m_PC);
@ -584,29 +592,17 @@ void i8085a_cpu_device::check_for_interrupts()
/* followed by classic INTR */
else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE))
{
u32 vector;
/* break out of HALT state and call the IRQ ack callback */
if (!m_in_inta_func.isnull())
standard_irq_callback(I8085_INTR_LINE);
break_halt_for_interrupt();
vector = standard_irq_callback(I8085_INTR_LINE);
u8 vector = read_inta();
/* use the resulting vector as an opcode to execute */
set_inte(0);
switch (vector & 0xff0000)
{
case 0xcd0000: /* CALL nnnn */
m_icount -= 7;
op_push(m_PC);
case 0xc30000: /* JMP nnnn */
m_icount -= 10;
m_PC.d = vector & 0xffff;
break;
default:
LOG("i8085 take int $%02x\n", vector);
execute_one(vector & 0xff);
break;
}
LOG("i8085 take int $%02x\n", vector);
execute_one(vector);
}
}
@ -670,14 +666,27 @@ u8 i8085a_cpu_device::get_rim_value()
// memory access
u8 i8085a_cpu_device::read_arg()
{
return m_cache->read_byte(m_PC.w.l++);
set_status(0x82); // memory read
if (m_in_acknowledge)
return read_inta();
else
return m_cache->read_byte(m_PC.w.l++);
}
PAIR i8085a_cpu_device::read_arg16()
{
PAIR p;
p.b.l = m_cache->read_byte(m_PC.w.l++);
p.b.h = m_cache->read_byte(m_PC.w.l++);
set_status(0x82); // memory read
if (m_in_acknowledge)
{
p.b.l = read_inta();
p.b.h = read_inta();
}
else
{
p.b.l = m_cache->read_byte(m_PC.w.l++);
p.b.h = m_cache->read_byte(m_PC.w.l++);
}
return p;
}
@ -687,6 +696,14 @@ u8 i8085a_cpu_device::read_op()
return m_opcode_cache->read_byte(m_PC.w.l++);
}
u8 i8085a_cpu_device::read_inta()
{
if (m_in_inta_func.isnull())
return standard_irq_callback(I8085_INTR_LINE);
else
return m_in_inta_func(m_PC.w.l);
}
u8 i8085a_cpu_device::read_mem(u32 a)
{
set_status(0x82); // memory read
@ -855,13 +872,15 @@ void i8085a_cpu_device::execute_run()
do
{
debugger_instruction_hook(m_PC.d);
/* the instruction after an EI does not take an interrupt, so
we cannot check immediately; handle post-EI behavior here */
if (m_after_ei != 0 && --m_after_ei == 0)
check_for_interrupts();
m_in_acknowledge = false;
logerror("PC=%04X\n", m_PC.d);
debugger_instruction_hook(m_PC.d);
/* here we go... */
execute_one(read_op());

View File

@ -45,6 +45,9 @@ public:
// CLK rate callback (8085A only)
template <typename... T> void set_clk_out(T &&... args) { m_clk_out_func.set(std::forward<T>(args)...); }
// INTA vector fetch callback
auto in_inta_func() { return m_in_inta_func.bind(); }
// STATUS changed callback
auto out_status_func() { return m_out_status_func.bind(); }
@ -100,6 +103,7 @@ private:
address_space_config m_io_config;
address_space_config m_opcode_config;
devcb_read8 m_in_inta_func;
devcb_write8 m_out_status_func;
devcb_write_line m_out_inte_func;
devcb_read_line m_in_sid_func;
@ -121,6 +125,7 @@ private:
u8 m_trap_pending; /* TRAP interrupt latched? */
u8 m_trap_im_copy; /* copy of IM register when TRAP was taken */
u8 m_sod_state; /* state of the SOD line */
bool m_in_acknowledge;
bool m_ietemp; /* import/export temp space */
@ -144,6 +149,7 @@ private:
u8 get_rim_value();
void break_halt_for_interrupt();
u8 read_op();
u8 read_inta();
u8 read_arg();
PAIR read_arg16();
u8 read_mem(u32 a);

View File

@ -586,7 +586,7 @@ void i80186_cpu_device::device_start()
state_add( I8086_VECTOR, "V", m_int_vector).formatstr("%02X");
state_add( I8086_PC, "PC", m_pc ).callimport().formatstr("%05X");
state_add( STATE_GENPCBASE, "CURPC", m_pc ).callimport().formatstr("%05X").noshow();
state_add<uint32_t>( STATE_GENPCBASE, "CURPC", [this] { return (m_sregs[CS] << 4) + m_prev_ip; }).mask(0xfffff).noshow();
state_add( I8086_HALT, "HALT", m_halt ).mask(1);
// Most of these mnemonics are borrowed from the Intel 80C186EA/80C188EA User's Manual.

View File

@ -275,7 +275,7 @@ void i80286_cpu_device::device_start()
state_add( I286_VECTOR, "V", m_int_vector).formatstr("%02X");
state_add( I286_PC, "PC", m_pc).callimport().formatstr("%06X");
state_add( STATE_GENPCBASE, "CURPC", m_pc ).callimport().formatstr("%06X").noshow();
state_add<uint32_t>( STATE_GENPCBASE, "CURPC", [this] { return m_base[CS] + m_prev_ip; }).mask(0xffffff).noshow();
state_add( I8086_HALT, "HALT", m_halt ).mask(1);
m_out_shutdown_func.resolve_safe();
@ -316,7 +316,6 @@ void i80286_cpu_device::state_import(const device_state_entry &entry)
break;
case STATE_GENPC:
case STATE_GENPCBASE:
if (m_pc - m_base[CS] > m_limit[CS])
{
// TODO: should this call data_descriptor instead of ignoring jumps outside the current segment?
@ -331,6 +330,7 @@ void i80286_cpu_device::state_import(const device_state_entry &entry)
}
}
m_ip = m_pc - m_base[CS];
m_prev_ip = m_ip;
break;
}
}
@ -769,7 +769,7 @@ void i80286_cpu_device::code_descriptor(uint16_t selector, uint16_t offset, int
m_limit[CS] = LIMIT(desc);
m_base[CS] = BASE(desc);
m_rights[CS] = RIGHTS(desc);
m_ip = offset;
m_prev_ip = m_ip = offset;
}
else
{ // systemdescriptor
@ -862,7 +862,7 @@ void i80286_cpu_device::code_descriptor(uint16_t selector, uint16_t offset, int
}
else
{
m_ip = offset;
m_prev_ip = m_ip = offset;
m_sregs[CS]=selector;
m_base[CS]=selector<<4;
m_rights[CS]=0x93;
@ -880,11 +880,11 @@ void i80286_cpu_device::interrupt_descriptor(int number, int hwint, int error)
{
number = standard_irq_callback(0);
m_irq_state = CLEAR_LINE;
m_pending_irq &= ~INT_IRQ;
hwint = 1;
}
debugger_exception_hook(number);
if(!PM)
{
PUSH(flags & ~0xf000);
@ -979,7 +979,7 @@ void i80286_cpu_device::interrupt_descriptor(int number, int hwint, int error)
m_limit[CS] = LIMIT(gatedesc);
m_base[CS] = BASE(gatedesc);
m_rights[CS] = RIGHTS(gatedesc);
m_ip = GATEOFF(desc);
m_prev_ip = m_ip = GATEOFF(desc);
m_TF = 0;
m_NT = 0;
if(GATE(RIGHTS(desc)) == INTGATE)

View File

@ -23,6 +23,16 @@ enum
I286_BP,
I286_SI,
I286_DI,
I286_AL,
I286_AH,
I286_CL,
I286_CH,
I286_DL,
I286_DH,
I286_BL,
I286_BH,
I286_FLAGS,
I286_ES,

View File

@ -359,7 +359,7 @@ void i8086_cpu_device::device_start()
state_add( I8086_VECTOR, "V", m_int_vector).formatstr("%02X");
state_add( I8086_PC, "PC", m_pc ).callimport().formatstr("%05X");
state_add( STATE_GENPCBASE, "CURPC", m_pc ).callimport().formatstr("%05X").noshow();
state_add<uint32_t>( STATE_GENPCBASE, "CURPC", [this] { return (m_sregs[CS] << 4) + m_prev_ip; }).mask(0xfffff).noshow();
state_add( I8086_HALT, "HALT", m_halt ).mask(1);
}
@ -421,10 +421,10 @@ void i8086_common_cpu_device::state_import(const device_state_entry &entry)
break;
case STATE_GENPC:
case STATE_GENPCBASE:
if (m_pc - (m_sregs[CS] << 4) > 0xffff)
m_sregs[CS] = m_pc >> 4;
m_ip = m_pc - (m_sregs[CS] << 4);
m_prev_ip = m_ip;
break;
}
}
@ -506,7 +506,7 @@ void i8086_common_cpu_device::device_start()
// Register state for debugger
state_add( I8086_IP, "IP", m_ip ).callimport().formatstr("%04X");
state_add( I8086_AX, "AX", m_regs.w[AX] ).formatstr("%04X");
state_add( I8086_CX, "CX", m_regs.w[CS] ).formatstr("%04X");
state_add( I8086_CX, "CX", m_regs.w[CX] ).formatstr("%04X");
state_add( I8086_DX, "DX", m_regs.w[DX] ).formatstr("%04X");
state_add( I8086_BX, "BX", m_regs.w[BX] ).formatstr("%04X");
state_add( I8086_SP, "SP", m_regs.w[SP] ).formatstr("%04X");
@ -514,6 +514,15 @@ void i8086_common_cpu_device::device_start()
state_add( I8086_SI, "SI", m_regs.w[SI] ).formatstr("%04X");
state_add( I8086_DI, "DI", m_regs.w[DI] ).formatstr("%04X");
state_add( I8086_AL, "AL", m_regs.b[AL] ).noshow();
state_add( I8086_AH, "AH", m_regs.b[AH] ).noshow();
state_add( I8086_CL, "CL", m_regs.b[CL] ).noshow();
state_add( I8086_CH, "CH", m_regs.b[CH] ).noshow();
state_add( I8086_DL, "DL", m_regs.b[DL] ).noshow();
state_add( I8086_DH, "DH", m_regs.b[DH] ).noshow();
state_add( I8086_BL, "BL", m_regs.b[BL] ).noshow();
state_add( I8086_BH, "BH", m_regs.b[BH] ).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_TF).formatstr("%16s").noshow();
set_icountptr(m_icount);
@ -586,7 +595,7 @@ void i8086_common_cpu_device::interrupt(int int_num, int trap)
PUSH(m_sregs[CS]);
PUSH(m_ip);
m_ip = dest_off;
m_prev_ip = m_ip = dest_off;
m_sregs[CS] = dest_seg;
}

View File

@ -20,6 +20,7 @@ enum
{
I8086_PC = STATE_GENPC,
I8086_IP = 1, I8086_AX, I8086_CX, I8086_DX, I8086_BX, I8086_SP, I8086_BP, I8086_SI, I8086_DI,
I8086_AL, I8086_AH, I8086_CL, I8086_CH, I8086_DL, I8086_DH, I8086_BL, I8086_BH,
I8086_FLAGS, I8086_ES, I8086_CS, I8086_SS, I8086_DS,
I8086_VECTOR, I8086_HALT
};

View File

@ -91,6 +91,27 @@ void i960_cpu_device::send_iac(uint32_t adr)
iac[3] = m_program->read_dword(adr+12);
switch(iac[0]>>24) {
case 0x40: // generate irq
break;
case 0x41: // test for pending interrupts
// check_irqs() seems to take care of this
// though it may not be entirely accurate
check_irqs();
break;
case 0x80: // store SAT & PRCB in memory
m_program->write_dword(iac[1], m_SAT);
m_program->write_dword(iac[1]+4, m_PRCB);
break;
case 0x89: // invalidate internal instruction cache
// we do not emulate the instruction cache, so this is safe to ignore
break;
case 0x8F: // enable/disable breakpoints
// processor breakpoints are not emulated, safe to ignore
break;
case 0x91: // stop processor
break;
case 0x92: // continue initialization
break;
case 0x93: // reinit
m_SAT = iac[1];
m_PRCB = iac[2];

View File

@ -9,90 +9,169 @@
#include "emu.h"
#include "i960dis.h"
/*
Based on documents:
270567-001 80960KB Programmer's Reference Manual (March 1988)
270710-003 i960 CA/CF Microprocessor User's Manual (March 1994)
271081-001 80960MC Programmer's Reference Manual (July 1988)
272483-001 i960 Jx Microprocessor User's Manual (September 1994)
272484-002 i960 Hx Microprocessor Developer's Manual (September 1998)
272736-002 i960 Rx I/O Microprocessor Developer's Manual (April 1997)
273353-001 Intel 80303 I/O Processor Developer's Manual (May 2000)
*/
const i960_disassembler::mnemonic_t i960_disassembler::mnemonic[256] = {
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 00
{ "b", 8 }, { "call", 8 }, { "ret", 9 }, { "bal", 8 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 00
{ "b", 1, 1 }, { "call", 1, 1 }, { "ret", 1, 0 }, { "bal", 1, 1 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "bno", 8 }, { "bg", 8 }, { "be", 8 }, { "bge", 8 }, { "bl", 8 }, { "bne", 8 }, { "ble", 8 }, { "bo", 8 }, // 10
{ "faultno", 0 }, { "faultg", 0 }, { "faulte", 0 }, { "faultge", 0 }, { "faultl", 0 }, { "faultne", 0 }, { "faultle", 0 }, { "faulto", 0 },
{ "bno", 1, 1 }, { "bg", 1, 1 }, { "be", 1, 1 }, { "bge", 1, 1 }, { "bl", 1, 1 }, { "bne", 1, 1 }, { "ble", 1, 1 }, { "bo", 1, 1 }, // 10
{ "faultno", 1, 0 }, { "faultg", 1, 0 }, { "faulte", 1, 0 }, { "faultge", 1, 0 }, { "faultl", 1, 0 }, { "faultne", 1, 0 }, { "faultle", 1, 0 }, { "faulto", 1, 0 },
{ "testno", 10 }, { "testg", 10 }, { "teste", 10 }, { "testge", 10 }, { "testl", 10 }, { "testne", 10 }, { "testle", 10 }, { "testo", 10 }, // 20
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "testno", 2, 1 }, { "testg", 2, 1 }, { "teste", 2, 1 }, { "testge", 2, 1 }, { "testl", 2, 1 }, { "testne", 2, 1 }, { "testle", 2, 1 }, { "testo", 2, 1 }, // 20
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "bbc", 6 }, { "cmpobg", 7 }, { "cmpobe", 7 }, { "cmpobge", 7 }, { "cmpobl", 7 }, { "cmpobne", 7 }, { "cmpoble", 7 }, { "bbs", 6 }, // 30
{ "cmpibno", 7 }, { "cmpibg", 7 }, { "cmpibe", 7 }, { "cmpibge", 7 }, { "cmpibl", 7 }, { "cmpibne", 7 }, { "cmpible", 7 }, { "cmpibo", 7 },
{ "bbc", 2, 3 }, { "cmpobg", 2, 3 }, { "cmpobe", 2, 3 }, { "cmpobge", 2, 3 }, { "cmpobl", 2, 3 }, { "cmpobne", 2, 3 }, { "cmpoble", 2, 3 }, { "bbs", 2, 3 }, // 30
{ "cmpibno", 2, 3 }, { "cmpibg", 2, 3 }, { "cmpibe", 2, 3 }, { "cmpibge", 2, 3 }, { "cmpibl", 2, 3 }, { "cmpibne", 2, 3 }, { "cmpible", 2, 3 }, { "cmpibo", 2, 3 },
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 40
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 40
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 50
{ "58", 3 }, { "59", 3 }, { "5A", 3 }, { "5B", 3 }, { "5C", 2 }, { "5D", 2 }, { "?", 0 }, { "5F", 2 },
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 50
{ "58", 4, 0 }, { "59", 4, 0 }, { "5A", 4, 0 }, { "5B", 4, 0 }, { "5C", 4, 0 }, { "5D", 4, 0 }, { "?", 0, 0 }, { "5F", 4, 0 },
{ "60", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "64", 3 }, { "65", 3 }, { "calls", 0 }, { "67", 3 }, // 60
{ "68", 3 }, { "69", 3 }, { "?", 0 }, { "?", 0 }, { "6C", 3 }, { "6D", 3 }, { "6E", 3 }, { "?", 0 },
{ "60", 4, 0 }, { "61", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "64", 4, 0 }, { "65", 4, 0 }, { "66", 4, 0 }, { "67", 4, 0 }, // 60
{ "68", 4, 0 }, { "69", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "6C", 4, 0 }, { "6D", 4, 0 }, { "6E", 4, 0 }, { "?", 0, 0 },
{ "70", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "74", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 70
{ "78", 3 }, { "79", 3 }, { "7A", 3 }, { "7B", 3 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "70", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "74", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 70
{ "78", 4, 0 }, { "79", 4, 0 }, { "7A", 4, 0 }, { "7B", 4, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "ldob", 4 }, { "?", 0 }, { "stob", 1 }, { "?", 0 }, { "bx", 11 }, { "balx", 1 }, { "callx", 11 }, { "?", 0 }, // 80
{ "ldos", 4 }, { "?", 0 }, { "stos", 1 }, { "?", 0 }, { "lda", 4 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "ldob", 3, 2 }, { "?", 0, 0 }, { "stob", 3, -2 }, { "?", 0, 0 }, { "bx", 3, 1 }, { "balx", 3, 2 }, { "callx", 3, 1 }, { "?", 0, 0 }, // 80
{ "ldos", 3, 2 }, { "?", 0, 0 }, { "stos", 3, -2 }, { "?", 0, 0 }, { "lda", 3, 2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "ld", 4 }, { "?", 0 }, { "st", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 90
{ "ldl", 4 }, { "?", 0 }, { "stl", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "ld", 3, 2 }, { "?", 0, 0 }, { "st", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // 90
{ "ldl", 3, 2 }, { "?", 0, 0 }, { "stl", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "ldt", 4 }, { "?", 0 }, { "stt", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // a0
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "ldt", 3, 2 }, { "?", 0, 0 }, { "stt", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // a0
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "dcinva", 3, 1 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "ldq", 4 }, { "?", 0 }, { "stq", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // b0
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "ldq", 3, 2 }, { "?", 0, 0 }, { "stq", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // b0
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "ldib", 4 }, { "?", 0 }, { "stib", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // c0
{ "ldis", 4 }, { "?", 0 }, { "stis", 1 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "ldib", 3, 2 }, { "?", 0, 0 }, { "stib", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // c0
{ "ldis", 3, 2 }, { "?", 0, 0 }, { "stis", 3, -2 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // d0
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // d0
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // e0
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 },
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // e0
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 },
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // f0
{ "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, // f0
{ "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }, { "?", 0, 0 }
};
const i960_disassembler::mnemonic_t i960_disassembler::mnem_reg[111] =
const i960_disassembler::mnemonic_t i960_disassembler::mnem_reg[197] =
{
{ "notbit", 0x580 }, { "and", 0x581 }, { "andnot", 0x582 }, { "setbit", 0x583 }, { "notand",0x584 },
{ "xor", 0x586 }, { "or", 0x587 }, { "nor", 0x588 }, { "xnor",0x589 }, { "not",0x58a },
{ "clrbit", 0x58c }, { "alterbit", 0x58f },
{ "addo", 0x590 }, { "addi",0x591 }, { "subo",0x592 }, { "subi",0x593 }, { "cmpob",0x594 }, { "shro",0x598 }, { "shrdi",0x59a }, { "shri",0x59b }, { "shlo",0x59c }, { "rotate",0x59d }, { "shli",0x59e },
{ "cmpo",0x5a0 }, { "cmpi",0x5a1 }, { "concmpo",0x5a2 }, { "concmpi",0x5a3 }, { "cmpinco",0x5a4 }, { "cmpinci",0x5a5 }, { "cmpdeco",0x5a6 }, { "cmpdeci",0x5a7 }, { "scanbyte",0x5ac }, { "bswap",0x5ad }, { "chkbit",0x5ae },
{ "addc",0x5b0 }, { "subc",0x5b2 },
{ "mov", 0x5cc },
{ "movl",0x5dc },
{ "movq",0x5fc },
{ "synmov",0x600 }, { "synmovq",0x602 },
{ "scanbit", 0x641 }, { "daddc", 0x642 }, { "dsubc", 0x643 }, { "dmovt", 0x644 }, { "modac",0x645 },
{ "modify",0x650 }, { "extract",0x651 }, { "modtc",0x654 }, { "modpc",0x655 },
{ "emul",0x670 }, { "ediv",0x671 }, { "cvtir", 0x674 }, { "cvtilr", 0x675 }, { "scalerl", 0x676 }, { "scaler", 0x677 },
{ "atanr",0x680 }, { "logepr", 0x681 }, { "logr", 0x682 }, { "remr", 0x683 }, { "cmpor", 0x684 }, { "cmpr", 0x685 }, { "sqrtr", 0x688 },
{ "expr", 0x689 }, { "logbnr", 0x68a }, { "roundr", 0x68b }, { "sinr", 0x68c }, { "cosr", 0x68d }, { "tanr", 0x68e }, { "classr", 0x68f },
{ "atanrl",0x690 }, { "logeprl", 0x691 }, { "logrl", 0x692 }, { "remrl", 0x693 }, { "cmporl", 0x694 }, { "cmprl", 0x695 }, { "sqrtrl", 0x698 },
{ "exprl", 0x699 }, { "logbnrl", 0x69a }, { "roundrl", 0x69b }, { "sinrl", 0x69c }, { "cosrl", 0x69d }, { "tanrl", 0x69e }, { "classrl", 0x69f },
{ "cvtri", 0x6c0 }, { "cvtril", 0x6c1 }, { "cvtzri", 0x6c2 }, { "cvtzril", 0x6c3 }, { "movr", 0x6c9 },
{ "movrl", 0x6d9 },
{ "movre", 0x6e1 }, { "cpysre", 0x6e2 }, { "cpyrsre", 0x6e3 },
{ "mulo", 0x701 }, { "remo",0x708 }, { "divo",0x70b },
{ "muli",0x741 }, { "remi",0x748 }, { "modi",0x749 }, { "divi",0x74b },
{ "divr",0x78b }, { "mulr",0x78c }, { "subr",0x78d }, { "addr",0x78f },
{ "divrl",0x79b }, { "mulrl",0x79c }, { "subrl",0x79d }, { "addrl",0x79f },
{ "ending_code",0 }
};
{ "notbit", 0x580, -3 }, { "and", 0x581, -3 }, { "andnot", 0x582, -3 }, { "setbit", 0x583, -3 }, // 58
{ "notand", 0x584, -3 }, { "xor", 0x586, -3 }, { "or", 0x587, -3 },
{ "nor", 0x588, -3 }, { "xnor", 0x589, -3 }, { "not", 0x58a, -2 }, { "ornot", 0x58b, -3 },
{ "clrbit", 0x58c, -3 }, { "notor", 0x58d, -3 }, { "nand", 0x58e, -3 }, { "alterbit", 0x58f, -3 },
const char *const i960_disassembler::constnames[32] =
{
"0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf",
"0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f"
{ "addo", 0x590, -3 }, { "addi", 0x591, -3 }, { "subo", 0x592, -3 }, { "subi", 0x593, -3 }, // 59
{ "cmpob", 0x594, 2 }, { "cmpib", 0x595, 2 }, { "cmpos", 0x596, 2 }, { "cmpis", 0x597, 2 },
{ "shro", 0x598, -3 }, { "shrdi", 0x59a, -3 }, { "shri", 0x59b, -3 },
{ "shlo", 0x59c, -3 }, { "rotate", 0x59d, -3 }, { "shli", 0x59e, -3 },
{ "cmpo", 0x5a0, 2 }, { "cmpi", 0x5a1, 2 }, { "concmpo", 0x5a2, 2 }, { "concmpi", 0x5a3, 2 }, // 5a
{ "cmpinco", 0x5a4, -3 }, { "cmpinci", 0x5a5, -3 }, { "cmpdeco", 0x5a6, -3 }, { "cmpdeci", 0x5a7, -3 },
{ "scanbyte", 0x5ac, 2 }, { "bswap", 0x5ad, -2 }, { "chkbit", 0x5ae, 2 },
{ "addc", 0x5b0, -3 }, { "subc", 0x5b2, -3 }, { "intdis", 0x5b4, 0 }, { "inten", 0x5b5, 0 }, // 5b
{ "mov", 0x5cc, -2 }, // 5c
{ "eshro", 0x5d8, -3 }, // 5d
{ "movl", 0x5dc, -2 },
{ "movt", 0x5ec, -2 }, // 5e
{ "movq", 0x5fc, -2 }, // 5f
{ "synmov", 0x600, 2 }, { "synmovl", 0x601, 2 }, { "synmovq", 0x602, 2 }, { "cmpstr", 0x603, 3 }, // 60
{ "movqstr", 0x604, -3 }, { "movstr", 0x605, -3 },
{ "atmod", 0x610, 33 }, { "atadd", 0x612, 33 }, { "inspacc", 0x613, -2 }, // 61
{ "ldphy", 0x614, -2 }, { "synld", 0x615, -2 }, { "fill", 0x617, 3 },
{ "sdma", 0x630, 3 }, { "udma", 0x631, 0 }, // 63
{ "spanbit", 0x640, -2 }, { "scanbit", 0x641, -2 }, { "daddc", 0x642, -3 }, { "dsubc", 0x643, -3 }, // 64
{ "dmovt", 0x644, -2 }, { "modac", 0x645, 3 },
{ "modify", 0x650, 33 }, { "extract", 0x651, 33 }, // 65
{ "modtc", 0x654, 33 }, { "modpc", 0x655, 33 }, { "receive", 0x656, -2 },
{ "intctl", 0x658, -2 }, { "sysctl", 0x659, 33 }, { "icctl", 0x65b, 33 },
{ "dcctl", 0x65c, 33 }, { "halt", 0x65d, 0 },
{ "calls", 0x660, 1 }, { "send", 0x662, -3 }, { "sendserv", 0x663, 1 }, // 66
{ "resumprcs", 0x664, 1 }, { "schedprcs", 0x665, 1 }, { "saveprcs", 0x666, 0 },
{ "condwait", 0x668, 1 }, { "wait", 0x669, 1 }, { "signal", 0x66a, 1 }, { "mark", 0x66b, 0 },
{ "fmark", 0x66c, 0 }, { "flushreg", 0x66d, 0 }, { "syncf", 0x66f, 0 },
{ "emul", 0x670, -3 }, { "ediv", 0x671, -3 }, { "ldtime", 0x671, -1 }, // 67
{ "cvtir", 0x674, -20 }, { "cvtilr", 0x675, -20 }, { "scalerl", 0x676, -30 }, { "scaler", 0x677, -30 },
{ "atanr", 0x680, -30 }, { "logepr", 0x681, -30 }, { "logr", 0x682, -30 }, { "remr", 0x683, -30 }, // 68
{ "cmpor", 0x684, 20 }, { "cmpr", 0x685, 20 },
{ "sqrtr", 0x688, -20 }, { "expr", 0x689, -20 }, { "logbnr", 0x68a, -20 }, { "roundr", 0x68b, -20 },
{ "sinr", 0x68c, -20 }, { "cosr", 0x68d, -20 }, { "tanr", 0x68e, -20 }, { "classr", 0x68f, 10 },
{ "atanrl", 0x690, -30 }, { "logeprl", 0x691, -30 }, { "logrl", 0x692, -30 }, { "remrl", 0x693, -30 }, // 69
{ "cmporl", 0x694, 20 }, { "cmprl", 0x695, 20 },
{ "sqrtrl", 0x698, -20 }, { "exprl", 0x699, -20 }, { "logbnrl", 0x69a, -20 }, { "roundrl", 0x69b, -20 },
{ "sinrl", 0x69c, -20 }, { "cosrl", 0x69d, -20 }, { "tanrl", 0x69e, -20 }, { "classrl", 0x69f, 10 },
{ "cvtri", 0x6c0, -20 }, { "cvtril", 0x6c1, -20 }, { "cvtzri", 0x6c2, -20 }, { "cvtzril", 0x6c3, -20 }, // 6c
{ "movr", 0x6c9, -20 },
{ "movrl", 0x6d9, -20 }, // 6d
{ "movre", 0x6e1, -20 }, { "cpysre", 0x6e2, -30 }, { "cpyrsre", 0x6e3, -30 }, // 6e
{ "movre", 0x6e9, -20 },
{ "mulo", 0x701, -3 }, // 70
{ "remo", 0x708, -3 }, { "divo", 0x70b, -3 },
{ "muli", 0x741, -3 }, // 74
{ "remi", 0x748, -3 }, { "modi", 0x749, -3 }, { "divi", 0x74b, -3 },
{ "addono", 0x780, -3 }, { "addino", 0x781, -3 }, { "subono", 0x782, -3 }, { "subino", 0x783, -3 }, // 78
{ "selno", 0x784, -3 },
{ "divr", 0x78b, -30 }, { "mulr", 0x78c, -30 }, { "subr", 0x78d, -30 }, { "addr", 0x78f, -30 },
{ "addog", 0x790, -3 }, { "addig", 0x791, -3 }, { "subog", 0x792, -3 }, { "subig", 0x793, -3 }, // 79
{ "selg", 0x794, -3 },
{ "divrl", 0x79b, -30 }, { "mulrl", 0x79c, -30 }, { "subrl", 0x79d, -30 }, { "addrl", 0x79f, -30 },
{ "addoe", 0x7a0, -3 }, { "addie", 0x7a1, -3 }, { "suboe", 0x7a2, -3 }, { "subie", 0x7a3, -3 }, // 7a
{ "sele", 0x7a4, -3 },
{ "addoge", 0x7b0, -3 }, { "addige", 0x7b1, -3 }, { "suboge", 0x7b2, -3 }, { "subige", 0x7b3, -3 }, // 7b
{ "selge", 0x7b4, -3 },
{ "addol", 0x7c0, -3 }, { "addil", 0x7c1, -3 }, { "subol", 0x7c2, -3 }, { "subil", 0x7c3, -3 }, // 7c
{ "sell", 0x7c4, -3 },
{ "addone", 0x7d0, -3 }, { "addine", 0x7d1, -3 }, { "subone", 0x7d2, -3 }, { "subine", 0x7d3, -3 }, // 7d
{ "selne", 0x7d4, -3 },
{ "addole", 0x7e0, -3 }, { "addile", 0x7e1, -3 }, { "subole", 0x7e2, -3 }, { "subile", 0x7e3, -3 }, // 7e
{ "selle", 0x7e4, -3 },
{ "addoo", 0x7f0, -3 }, { "addio", 0x7f1, -3 }, { "suboo", 0x7f2, -3 }, { "subio", 0x7f3, -3 }, // 7f
{ "selo", 0x7f4, -3 },
{ "ending_code", 0, 0 }
};
const char *const i960_disassembler::regnames[32] =
@ -101,80 +180,355 @@ const char *const i960_disassembler::regnames[32] =
"g0","g1","g2","g3", "g4","g5","g6","g7", "g8","g9","g10","g11", "g12","g13","g14","fp",
};
#define REG_DST regnames[dst]
#define REG_ABASE regnames[abase]
#define REG_REG2 regnames[reg2]
#define REG_COBR_SRC1 ((iCode & 0x2000) ? constnames[COBRSRC1] : regnames[COBRSRC1])
#define REG_COBR_SRC2 regnames[COBRSRC2]
#define NEM mnemonic[op].mnem
// REG format
#define SRC1 (iCode & 0x1f)
#define S1 ((iCode >> 5) & 0x1)
#define S2 ((iCode >> 6) & 0x1)
#define OP2 ((iCode >> 7) & 0xf)
#define M1 ((iCode >> 11) & 0x1)
#define M2 ((iCode >> 12) & 0x1)
#define M3 ((iCode >> 13) & 0x1)
#define SRC2 ((iCode >> 14) & 0x1f)
#define DST ((iCode >> 19) & 0x1f)
#define OP ((iCode >> 24) & 0xff)
// COBR format
#define COBRSRC1 ((iCode >> 19) & 0x1f)
#define COBRSRC2 ((iCode >> 14) & 0x1f)
std::string i960_disassembler::dis_decode_reg(u32 iCode, unsigned char cnt)
const char *const i960_disassembler::fprnames[32] =
{
std::string src1, src2, dst;
"fp0","fp1","fp2","fp3", "?","?","?","?", "?","?","?","?", "?","?","?","?",
"+0.0","?","?","?", "?","?","+1.0","?", "?","?","?","?", "?","?","?","?",
};
if (S1)
src1 = "";
else
offs_t i960_disassembler::dis_decode_invalid(std::ostream &stream, u32 iCode)
{
/*
u8 op = (unsigned char) (iCode >> 24);
u8 op2 = (unsigned char) (iCode >> 7)&0xf;
u8 model = (unsigned char) (iCode >> 10) &0x3;
u8 modeh = (unsigned char) (iCode >> 12) &0x3;
return util::stream_format(stream, "%s %08lx %02x:%01x %1x %1x", mnemonic[op].mnem, iCode, op, op2, modeh, model);
*/
//util::stream_format(stream, ".word\t0x%08x", iCode);
util::stream_format(stream, "? %08x", iCode);
return 4;
}
offs_t i960_disassembler::dis_decode_ctrl(std::ostream &stream, u32 iCode, u32 ip, signed char cnt)
{
u8 op = (unsigned char) (iCode >> 24);
//u8 t = (unsigned char) (iCode >> 1 & 1); // Cx, Hx, Rx - branch prediction (ignored for now)
u32 disp = iCode & 0x00fffffc;
// check bit 0
if ((iCode & 1) != 0x0) return dis_decode_invalid(stream, iCode);
switch(cnt)
{
if(M1)
src1 = util::string_format("0x%lx", SRC1);
else
src1 = util::string_format("%s", regnames[SRC1]);
case 0: // no operand
util::stream_format(stream, "%s", mnemonic[op].mnem);
break;
case 1: // 1 operand
util::stream_format(stream, "%-8s%08lx", mnemonic[op].mnem, ((((s32)disp) << 8) >> 8) + (ip));
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
if (S2)
src2 = ",reserved";
else
return 4;
}
offs_t i960_disassembler::dis_decode_cobr(std::ostream &stream, u32 iCode, u32 ip, signed char cnt)
{
u8 op = (unsigned char) (iCode >> 24);
u8 src1 = (unsigned char) (iCode >> 19) & 0x1f;
u8 src2 = (unsigned char) (iCode >> 14) & 0x1f;
u8 m1 = (unsigned char) (iCode >> 13 & 1);
//u8 t = (unsigned char) (iCode >> 1 & 1); // Cx, Hx, Rx - branch prediction
u8 s2 = (unsigned char) iCode & 1; // Cx, Hx, Rx - src2 = special function register
u32 disp = iCode & 0x1ffc;
std::string op1, op2, op3;
switch(cnt)
{
if(M2)
src2 = util::string_format(",0x%lx", SRC2);
else
src2 = util::string_format(",%s", regnames[SRC2]);
case 1: // 1 operand (test*)
// For the test-if instructions, only the srcl field is used. Here, this field specifies a destination global or local register (ml is ignored).
util::stream_format(stream, "%-8s%s", mnemonic[op].mnem, regnames[src1]);
break;
case 3: // 3 operands
// TODO m1 set differs on Mx, Kx, Jx, Rx references (literal) and Hx reference (sf-register)
if (m1) op1 = util::string_format("%d", src1);
else op1 = util::string_format("%s", regnames[src1]);
if (s2) op2 = util::string_format("sf%d", src2);
else op2 = util::string_format("%s", regnames[src2]);
op3 = util::string_format("0x%lx", ((((s32)disp) << 19) >> 19) + (ip));
util::stream_format(stream, "%-8s%s,%s,%s", mnemonic[op].mnem, op1, op2, op3);
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
if(M3)
dst = "";
else
dst = util::string_format(",%s", regnames[DST]);
return 4;
}
if (cnt == 1)
return util::string_format("%s%s", src1, dst);
else
return util::string_format("%s%s%s", src1, src2, dst);
offs_t i960_disassembler::dis_decode_mema(std::ostream &stream, u32 iCode, signed char cnt)
{
u8 op = (unsigned char) (iCode >> 24);
u8 srcdst = (unsigned char) (iCode >> 19) & 0x1f;
u8 abase = (unsigned char) (iCode >> 14) & 0x1f;
u8 mode = (unsigned char) (iCode >> 13) & 0x1;
u32 offset = iCode & 0xfff;
switch(mode)
{
case 0:
// offset
switch(cnt)
{
case 1: // bx/callx
util::stream_format(stream, "%-8s0x%lx", mnemonic[op].mnem, offset);
break;
case 2: // load
util::stream_format(stream, "%-8s0x%lx,%s", mnemonic[op].mnem, offset, regnames[srcdst]);
break;
case -2: // store
util::stream_format(stream, "%-8s%s,0x%lx", mnemonic[op].mnem, regnames[srcdst], offset);
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
break;
case 1:
// (abase) + offset
switch(cnt)
{
case 1: // bx/callx
util::stream_format(stream, "%-8s0x%lx(%s)", mnemonic[op].mnem, offset, regnames[abase]);
break;
case 2: // load
util::stream_format(stream, "%-8s0x%lx(%s),%s", mnemonic[op].mnem, offset, regnames[abase], regnames[srcdst]);
break;
case -2: // store
util::stream_format(stream, "%-8s%s,0x%lx(%s)", mnemonic[op].mnem, regnames[srcdst], offset, regnames[abase]);
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
return 4;
}
offs_t i960_disassembler::dis_decode_memb(std::ostream &stream, u32 iCode, u32 ip, u32 disp, signed char cnt)
{
u8 op = (unsigned char) (iCode >> 24);
u8 srcdst = (unsigned char) (iCode >> 19) & 0x1f;
u8 abase = (unsigned char) (iCode >> 14) & 0x1f;
u8 mode = (unsigned char) (iCode >> 10) & 0xf;
u8 scale = (unsigned char) (iCode >> 7) & 0x7;
u8 index = (unsigned char) iCode & 0x1f;
offs_t IPinc;
std::string efa;
// check bits 5 and 6
if ((iCode & 0x60) != 0x0) return dis_decode_invalid(stream, iCode);
// check scale
if (scale > 4) return dis_decode_invalid(stream, iCode);
if ((mode == 0x5) || (mode >= 0xc)) IPinc = 8;
else IPinc = 4;
switch(mode)
{
case 0x4: // (abase)
efa = util::string_format("(%s)", regnames[abase]);
break;
case 0x5: // (IP) + displacement + 8
efa = util::string_format("0x%x", ip + disp + 8);
break;
case 0x6: // reserved
return dis_decode_invalid(stream, iCode);
break;
case 0x7: // (abase) + (index) * 2^scale
if (scale == 0) efa = util::string_format("(%s)[%s]", regnames[abase], regnames[index]);
else efa = util::string_format("(%s)[%s*%ld]", regnames[abase], regnames[index], 1 << scale);
break;
case 0xc: // displacement
efa = util::string_format("0x%x", disp);
break;
case 0xd: // (abase) + displacement
efa = util::string_format("0x%x(%s)", disp, regnames[abase]);
break;
case 0xe: // (index) * 2^scale + displacement
if (scale == 0) efa = util::string_format("0x%x[%s]", disp, regnames[index]);
else efa = util::string_format("0x%x[%s*%ld]", disp, regnames[index], 1 << scale);
break;
case 0xf: // (abase) + (index) * 2^scale + displacement
if (scale == 0) efa = util::string_format("0x%x(%s)[%s]", disp, regnames[abase], regnames[index]);
else efa = util::string_format("0x%x(%s)[%s*%ld]", disp, regnames[abase], regnames[index], 1 << scale);
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
switch (cnt)
{
case 1: // bx/callx
util::stream_format(stream, "%-8s%s", mnemonic[op].mnem, efa);
break;
case 2: // load
util::stream_format(stream, "%-8s%s,%s", mnemonic[op].mnem, efa, regnames[srcdst]);
break;
case -2: // store
util::stream_format(stream, "%-8s%s,%s", mnemonic[op].mnem, regnames[srcdst], efa);
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
return IPinc;
}
offs_t i960_disassembler::dis_decode_reg(std::ostream &stream, u32 iCode)
{
u16 op = (unsigned short) ((iCode >> 20) & 0xff0) | ((iCode >> 7) & 0xf);
u8 srcdst = (unsigned char) (iCode >> 19) & 0x1f;
u8 src2 = (unsigned char) (iCode >> 14) & 0x1f;
u8 m3 = (unsigned char) (iCode >> 13) & 1;
u8 m2 = (unsigned char) (iCode >> 12) & 1;
u8 m1 = (unsigned char) (iCode >> 11) & 1;
u8 s2 = (unsigned char) (iCode >> 6) & 1;
u8 s1 = (unsigned char) (iCode >> 5) & 1;
u8 src1 = (unsigned char) iCode & 0x1f;
u8 sm1 = ((s1 << 1) | m1);
u8 sm2 = ((s2 << 1) | m2);
u32 i = 0;
std::string op1, op2, op3;
while(mnem_reg[i].type != 0)
{
if (mnem_reg[i].type == op) break;
i++;
}
if (mnem_reg[i].type != op) return dis_decode_invalid(stream, iCode);
switch (sm1)
{
case 0: // neither set
op1 = util::string_format("%s", regnames[src1]);
break;
case 1: // M1 set
op1 = util::string_format("%d", src1);
break;
case 2: // S1 set
op1 = util::string_format("sf%d", src1);
break;
case 3: // M1 and S1 set
default:
return dis_decode_invalid(stream, iCode);
break;
}
switch (sm2)
{
case 0: // neither set
op2 = util::string_format("%s", regnames[src2]);
break;
case 1: // M2 set
op2 = util::string_format("%d", src2);
break;
case 2: // S2 set
op2 = util::string_format("sf%d", src2);
break;
case 3: // M2 and S2 set
default:
return dis_decode_invalid(stream, iCode);
break;
}
switch (mnem_reg[i].flags)
{
case 0: // no operand
util::stream_format(stream, "%-8s", mnem_reg[i].mnem);
break;
case 1: // single operand, which is NOT a destination.
util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem, op1);
break;
case -1: // single operand, which IS a destination.
if (m3) op3 = util::string_format("sf%d", srcdst);
else op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem, op3);
break;
case 2: // 2 operands, the 2nd of which is NOT a destination.
util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op2);
break;
case -2: // 2 operands, the 2nd of which IS a destination.
if (m3) op3 = util::string_format("sf%d", srcdst);
else op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op3);
break;
case 3: // 3 operands, the 3rd of which is NOT a destination.
if (m3) op3 = util::string_format("%d", srcdst);
else op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3);
break;
case -3: // 3 operands, the 3rd of which IS a destination.
if (m3) op3 = util::string_format("sf%d", srcdst);
else op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3);
break;
case 33: // 3 operands, the 3rd of which is source and destination.
// m3 must NOT be set for src/dst type
if (m3) return dis_decode_invalid(stream, iCode);
op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3);
break;
// floating point opcodes
case 10: // single operand, which is NOT a destination.
if (m1) op1 = util::string_format("%s", fprnames[src1]);
else op1 = util::string_format("%s", regnames[src1]);
util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem, op1);
break;
case 20: // 2 operands, the 2nd of which is NOT a destination.
if (m1) op1 = util::string_format("%s", fprnames[src1]);
else op1 = util::string_format("%s", regnames[src1]);
if (m2) op2 = util::string_format("%s", fprnames[src2]);
else op2 = util::string_format("%s", regnames[src2]);
util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op2);
break;
case -20: // 2 operands, the 2nd of which IS a destination.
if (m1) op1 = util::string_format("%s", fprnames[src1]);
else op1 = util::string_format("%s", regnames[src1]);
if (m3) op3 = util::string_format("%s", fprnames[srcdst]);
else op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s,%s", mnem_reg[i].mnem, op1, op3);
break;
case -30: // 3 operands, the 3rd of which IS a destination.
if (m1) op1 = util::string_format("%s", fprnames[src1]);
else op1 = util::string_format("%s", regnames[src1]);
if (m2) op2 = util::string_format("%s", fprnames[src2]);
else op2 = util::string_format("%s", regnames[src2]);
if (m3) op3 = util::string_format("%s", fprnames[srcdst]);
else op3 = util::string_format("%s", regnames[srcdst]);
util::stream_format(stream, "%-8s%s,%s,%s", mnem_reg[i].mnem, op1, op2, op3);
break;
default:
return dis_decode_invalid(stream, iCode);
break;
}
return 4;
}
offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
u32 IP = pc;
u32 iCode = opcodes.r32(IP);
u8 op = (unsigned char) (iCode >> 24);
u8 op2 = (unsigned char) (iCode >> 7)&0xf;
u16 opc = 0;
u32 i = 0;
u8 model = (unsigned char) (iCode >> 10) &0x3;
u8 modeh = (unsigned char) (iCode >> 12) &0x3;
//mode = (unsigned char) (iCode >> 10) &0x7;
u8 dst = (unsigned char) (iCode >> 19) &0x1f;
u8 abase = (unsigned char) (iCode>>14)&0x1f;
u8 reg2 = (unsigned char) (iCode)&0x1f;
u8 op = (unsigned char) (iCode >> 24);
offs_t IPinc = 4;
offs_t disflags = 0;
@ -186,157 +540,25 @@ offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
switch(mnemonic[op].type)
{
case 0: // not yet implemented
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
case 0: // invalid / not yet implemented
IPinc = dis_decode_invalid(stream, iCode);
break;
case 1: // memory access (write)
switch(modeh)
{
case 0:
util::stream_format(stream, "%-8s%s,0x%lx",NEM,REG_DST, iCode&0xfff);
break;
case 1:
switch (model)
{
case 0:
util::stream_format(stream, "%-8s%s,(%s)",NEM,REG_DST, REG_ABASE);
break;
case 3:
util::stream_format(stream, "%-8s%s,(%s)[%s*%ld]",NEM,REG_DST, REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7));
break;
default:
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
break;
}
break;
case 2:
util::stream_format(stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE);
break;
case 3:
switch (model)
{
case 0:
util::stream_format(stream, "%-8s%s,0x%x",NEM,REG_DST, opcodes.r32(IP + 4));
IPinc = 8;
break;
case 1:
util::stream_format(stream, "%-8s%s,0x%x(%s)",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE);
IPinc = 8;
break;
case 2:
util::stream_format(stream, "%-8s%s,0x%x[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_REG2,1<<((iCode>>7)&0x7));
IPinc = 8;
break;
case 3:
util::stream_format(stream, "%-8s%s,0x%x(%s)[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7));
IPinc = 8;
break;
default:
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
break;
}
break;
default:
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
break;
}
case 1: // CTRL format
IPinc = dis_decode_ctrl(stream, iCode, IP, mnemonic[op].flags);
break;
case 2:
i = 0;
opc = op<<4|op2;
while(mnem_reg[i].type != 0)
{
if (mnem_reg[i].type == opc) break;
i++;
}
if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,1));
else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
case 2: // COBR compare and branch type
IPinc = dis_decode_cobr(stream, iCode, IP, mnemonic[op].flags);
break;
case 3:
i = 0;
opc = op<<4|op2;
while(mnem_reg[i].type != 0)
{
if (mnem_reg[i].type == opc) break;
i++;
}
if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,0));
else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
case 3: // MEM format
if ((iCode >> 12) & 0x1)
// MEMB format
IPinc = dis_decode_memb(stream, iCode, IP, opcodes.r32(IP + 4), mnemonic[op].flags);
else
// MEMA format
IPinc = dis_decode_mema(stream, iCode, mnemonic[op].flags);
break;
case 4: // memory access (read)
switch(modeh)
{
case 0:
util::stream_format(stream, "%-8s0x%lx,%s",NEM,iCode&0xfff,REG_DST);
break;
case 1:
switch (model)
{
case 0:
util::stream_format(stream, "%-8s(%s),%s",NEM,REG_ABASE,REG_DST);
break;
case 3:
util::stream_format(stream, "%-8s(%s)[%s*%ld],%s",NEM,REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7),REG_DST);
break;
default:
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
break;
}
break;
case 2:
util::stream_format(stream, "%-8s0x%lx(%s),%s",NEM,iCode&0xfff,REG_ABASE,REG_DST);
break;
case 3:
switch (model)
{
case 0:
util::stream_format(stream, "%-8s0x%x,%s",NEM,opcodes.r32(IP + 4),REG_DST);
IPinc = 8;
break;
case 1:
util::stream_format(stream, "%-8s0x%x(%s),%s",NEM,opcodes.r32(IP + 4),REG_ABASE,REG_DST);
IPinc = 8;
break;
case 2:
util::stream_format(stream, "%-8s0x%x[%s*%ld],%s",NEM,opcodes.r32(IP + 4),REG_REG2,1<<((iCode>>7)&0x7),REG_DST);
IPinc = 8;
break;
case 3:
util::stream_format(stream, "%-8s0x%x(%s)[%s*%ld],%s",NEM, opcodes.r32(IP + 4),REG_ABASE,REG_REG2,1<<((iCode>>7)&0x7),REG_DST);
IPinc = 8;
break;
default:
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
break;
}
break;
default:
util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model);
break;
}
break;
case 6: // bitpos and branch type
util::stream_format(stream, "%-8s%ld,%s,0x%lx",NEM, COBRSRC1, REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP));
break;
case 7: // compare and branch type
util::stream_format(stream, "%-8s%s,%s,0x%lx",NEM,REG_COBR_SRC1,REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP));
break;
case 8: // target type
util::stream_format(stream, "%-8s%08lx",NEM,((((s32)iCode&0x00fffffc)<<8)>>8) + (IP));
break;
case 9: // no operands
util::stream_format(stream, "%s",NEM);
break;
case 10: // TEST type: register only
util::stream_format(stream, "%s %s", NEM, REG_DST);
break;
case 11: // workaround to match users guide
util::stream_format(stream, "%-8s(%s)",NEM, REG_ABASE);
case 4: // REG format
IPinc = dis_decode_reg(stream, iCode);
break;
default:
stream << "???";

View File

@ -19,14 +19,20 @@ private:
{
const char *mnem;
unsigned short type;
signed char flags;
};
static const mnemonic_t mnemonic[256];
static const mnemonic_t mnem_reg[111];
static const char *const constnames[32];
static const mnemonic_t mnem_reg[197];
static const char *const regnames[32];
static const char *const fprnames[32];
std::string dis_decode_reg(u32 iCode, unsigned char cnt);
offs_t dis_decode_invalid(std::ostream &stream, u32 iCode);
offs_t dis_decode_ctrl(std::ostream &stream, u32 iCode, u32 ip, signed char cnt);
offs_t dis_decode_cobr(std::ostream &stream, u32 iCode, u32 ip, signed char cnt);
offs_t dis_decode_mema(std::ostream &stream, u32 iCode, signed char cnt);
offs_t dis_decode_memb(std::ostream &stream, u32 iCode, u32 ip, u32 disp, signed char cnt);
offs_t dis_decode_reg(std::ostream &stream, u32 iCode);
};

View File

@ -37,7 +37,7 @@
#define OC2 m_output_compare2.w.l
#define OC2H m_output_compare2.w.h
#define OC2D m_output_compare2.d
#define TOH m_timer_over.w.l
#define TOH m_timer_over.w.h
#define TOD m_timer_over.d
// serial I/O
@ -1352,10 +1352,10 @@ uint8_t hd6301x_cpu_device::p7_data_r()
void hd6301x_cpu_device::p7_data_w(uint8_t data)
{
LOGPORT("Port 7 Data Register: %02x\n", data);
data &= 0x1f;
LOGPORT("Port 7 Data Register: %02x\n", data);
m_portx_data[2] = data;
m_out_portx_func[2](0, m_portx_data[2], 0x1f);
}
@ -1369,9 +1369,11 @@ uint8_t m6801_cpu_device::tcsr_r()
void m6801_cpu_device::tcsr_w(uint8_t data)
{
data &= 0x1f;
LOGTIMER("Timer Control and Status Register: %02x\n", data);
m_tcsr = data;
m_tcsr = data | (m_tcsr & 0xe0);
m_pending_tcsr &= m_tcsr;
modified_tcsr();
if( !(m_cc & 0x10) )
@ -1390,11 +1392,7 @@ uint8_t m6801_cpu_device::ch_r()
uint8_t m6801_cpu_device::cl_r()
{
uint8_t data = m_counter.b.l;
// HACK there should be a break here, but Coleco Adam won't boot with it present, proper fix required to the free-running counter
(void)data;
return ocrh_r();
return m_counter.b.l;
}
void m6801_cpu_device::ch_w(uint8_t data)

View File

@ -91,10 +91,9 @@ protected:
uint8_t p4_data_r();
void p4_data_w(uint8_t data);
public: // FIXME: psion.cpp accesses this
protected:
uint8_t tcsr_r();
void tcsr_w(uint8_t data);
protected:
uint8_t ch_r();
uint8_t cl_r();
void ch_w(uint8_t data);

View File

@ -1480,6 +1480,16 @@ void fpgen_rm_reg(u16 w2)
m_icount -= 43;
break;
}
case 0x21: // FMOD
{
s8 const mode = float_rounding_mode;
float_rounding_mode = float_round_to_zero;
m_fpr[dst] = floatx80_rem(m_fpr[dst], source);
SET_CONDITION_CODES(m_fpr[dst]);
float_rounding_mode = mode;
m_icount -= 43; // guess
break;
}
case 0x22: // FADD
{
m_fpr[dst] = floatx80_add(m_fpr[dst], source);

View File

@ -50,7 +50,7 @@ MAIN:
case 0x1E: %EXG; return;
case 0x1F: %TFR; return;
case 0x20: set_cond(true); %BRANCH; return;
case 0x20: set_cond(true); %BRANCH; return;
case 0x21: set_cond(false); %BRANCH; return;
case 0x22: set_cond(cond_hi()); %BRANCH; return;
case 0x23: set_cond(!cond_hi()); %BRANCH; return;
@ -271,7 +271,7 @@ MAIN:
case 0xFD: set_regop16(m_q.p.d); %EXTENDED; %ST16; return;
case 0xFE: set_regop16(m_u); %EXTENDED; %LD16; return;
case 0xFF: set_regop16(m_u); %EXTENDED; %ST16; return;
default: %ILLEGAL; return;
default: %ILLEGAL; return;
}
return;
@ -279,7 +279,6 @@ DISPATCH10:
@m_opcode = read_opcode();
switch(m_opcode)
{
case 0x20: set_cond(true); %LBRANCH; return;
case 0x21: set_cond(false); %LBRANCH; return;
case 0x22: set_cond(cond_hi()); %LBRANCH; return;
case 0x23: set_cond(!cond_hi()); %LBRANCH; return;
@ -410,7 +409,7 @@ DISPATCH10:
case 0xFE: set_regop16(m_s); %EXTENDED; %LD16; return;
case 0xFF: set_regop16(m_s); %EXTENDED; %ST16; return;
default: %ILLEGAL; return;
default: %ILLEGAL; return;
}
return;
@ -512,7 +511,7 @@ DISPATCH11:
case 0xF7: set_regop8(m_q.r.f); %EXTENDED; %ST8; return;
case 0xFB: set_regop8(m_q.r.f); %EXTENDED; %ADD8; return;
default: %ILLEGAL; return;
default: %ILLEGAL; return;
}
return;
@ -891,7 +890,7 @@ TFM:
// operation that executed one transfer, and bumped the program
// counter back. However, some documentation suggests that TFM
// was abortable, so we now have a get_pending_interrupt() call
// here.
// here.
//
// Lastly, I have no information on the precise sub-instruction timing
// here; the timings of the reads and writes are really just a guess.

View File

@ -285,6 +285,7 @@ void nec_common_device::device_reset()
memset( &m_regs.w, 0, sizeof(m_regs.w));
m_ip = 0;
m_prev_ip = 0;
m_TF = 0;
m_IF = 0;
m_DF = 0;
@ -331,7 +332,7 @@ void nec_common_device::nec_interrupt(unsigned int_num, int/*INTSOURCES*/ source
PUSH(Sreg(PS));
PUSH(m_ip);
m_ip = (WORD)dest_off;
m_prev_ip = m_ip = (WORD)dest_off;
Sreg(PS) = (WORD)dest_seg;
CHANGE_PC;
}
@ -352,7 +353,7 @@ void nec_common_device::nec_brk(unsigned int_num)
PUSH(Sreg(PS));
PUSH(m_ip);
}
m_ip = read_mem_word(int_num*4);
m_prev_ip = m_ip = read_mem_word(int_num*4);
Sreg(PS) = read_mem_word(int_num*4+2);
CHANGE_PC;
}
@ -464,6 +465,7 @@ void nec_common_device::device_start()
m_E16 = 0;
m_debugger_temp = 0;
m_ip = 0;
m_prev_ip = 0;
memset(m_regs.w, 0x00, sizeof(m_regs.w));
memset(m_sregs, 0x00, sizeof(m_sregs));
@ -472,6 +474,7 @@ void nec_common_device::device_start()
save_item(NAME(m_sregs));
save_item(NAME(m_ip));
save_item(NAME(m_prev_ip));
save_item(NAME(m_TF));
save_item(NAME(m_IF));
save_item(NAME(m_DF));
@ -511,21 +514,29 @@ void nec_common_device::device_start()
m_io = &space(AS_IO);
state_add( NEC_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%05X");
state_add( NEC_IP, "IP", m_ip).formatstr("%04X");
state_add( NEC_SP, "SP", Wreg(SP)).formatstr("%04X");
state_add( NEC_FLAGS, "F", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( NEC_AW, "AW", Wreg(AW)).formatstr("%04X");
state_add( NEC_CW, "CW", Wreg(CW)).formatstr("%04X");
state_add( NEC_DW, "DW", Wreg(DW)).formatstr("%04X");
state_add( NEC_BW, "BW", Wreg(BW)).formatstr("%04X");
state_add( NEC_BP, "BP", Wreg(BP)).formatstr("%04X");
state_add( NEC_IX, "IX", Wreg(IX)).formatstr("%04X");
state_add( NEC_IY, "IY", Wreg(IY)).formatstr("%04X");
state_add( NEC_ES, "DS1", Sreg(DS1)).formatstr("%04X");
state_add( NEC_CS, "PS", Sreg(PS)).formatstr("%04X");
state_add( NEC_SS, "SS", Sreg(SS)).formatstr("%04X");
state_add( NEC_DS, "DS0", Sreg(DS0)).formatstr("%04X");
state_add( NEC_PC, "PC", m_ip).formatstr("%04X");
state_add( NEC_PSW, "PSW", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( NEC_AW, "AW", Wreg(AW)).formatstr("%04X");
state_add( NEC_CW, "CW", Wreg(CW)).formatstr("%04X");
state_add( NEC_DW, "DW", Wreg(DW)).formatstr("%04X");
state_add( NEC_BW, "BW", Wreg(BW)).formatstr("%04X");
state_add( NEC_SP, "SP", Wreg(SP)).formatstr("%04X");
state_add( NEC_BP, "BP", Wreg(BP)).formatstr("%04X");
state_add( NEC_IX, "IX", Wreg(IX)).formatstr("%04X");
state_add( NEC_IY, "IY", Wreg(IY)).formatstr("%04X");
state_add( NEC_DS1, "DS1", Sreg(DS1)).formatstr("%04X");
state_add( NEC_PS, "PS", Sreg(PS)).formatstr("%04X");
state_add( NEC_SS, "SS", Sreg(SS)).formatstr("%04X");
state_add( NEC_DS0, "DS0", Sreg(DS0)).formatstr("%04X");
state_add( NEC_AL, "AL", Breg(AL)).noshow();
state_add( NEC_AH, "AH", Breg(AH)).noshow();
state_add( NEC_CL, "CL", Breg(CL)).noshow();
state_add( NEC_CH, "CH", Breg(CH)).noshow();
state_add( NEC_DL, "DL", Breg(DL)).noshow();
state_add( NEC_DH, "DH", Breg(DH)).noshow();
state_add( NEC_BL, "BL", Breg(BL)).noshow();
state_add( NEC_BH, "BH", Breg(BH)).noshow();
if (m_chip_type == V33_TYPE)
state_add(NEC_XA, "XA", m_xa);
@ -570,7 +581,7 @@ void nec_common_device::state_import(const device_state_entry &entry)
{
switch (entry.index())
{
case NEC_PC:
case STATE_GENPC:
if (m_debugger_temp - (Sreg(PS)<<4) < 0x10000)
{
m_ip = m_debugger_temp - (Sreg(PS)<<4);
@ -580,9 +591,10 @@ void nec_common_device::state_import(const device_state_entry &entry)
Sreg(PS) = m_debugger_temp >> 4;
m_ip = m_debugger_temp & 0x0000f;
}
m_prev_ip = m_ip;
break;
case NEC_FLAGS:
case NEC_PSW:
ExpandFlags(m_debugger_temp);
break;
}
@ -594,16 +606,18 @@ void nec_common_device::state_export(const device_state_entry &entry)
switch (entry.index())
{
case STATE_GENPC:
case STATE_GENPCBASE:
case NEC_PC:
m_debugger_temp = (Sreg(PS)<<4) + m_ip;
break;
case STATE_GENPCBASE:
m_debugger_temp = (Sreg(PS)<<4) + m_prev_ip;
break;
case STATE_GENSP:
m_debugger_temp = (Sreg(SS)<<4) + Wreg(SP);
break;
case NEC_FLAGS:
case NEC_PSW:
m_debugger_temp = CompressFlags();
break;
}
@ -622,6 +636,8 @@ void nec_common_device::execute_run()
}
while(m_icount>0) {
m_prev_ip = m_ip;
/* Dispatch IRQ */
if (m_pending_irq && m_no_interrupt==0)
{

View File

@ -13,8 +13,10 @@
enum
{
NEC_PC=0,
NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
NEC_DS1, NEC_PS, NEC_SS, NEC_DS0,
NEC_AL, NEC_AH, NEC_CL, NEC_CH, NEC_DL, NEC_DH, NEC_BL, NEC_BH,
NEC_PSW,
NEC_XA,
NEC_PENDING
};
@ -77,6 +79,7 @@ private:
uint16_t m_sregs[4];
uint16_t m_ip;
uint16_t m_prev_ip;
/* PSW flags */
int32_t m_SignVal;

View File

@ -180,6 +180,7 @@ uint8_t v25_common_device::fetchop()
void v25_common_device::device_reset()
{
m_ip = 0;
m_prev_ip = 0;
m_IBRK = 1;
m_F0 = 0;
m_F1 = 0;
@ -270,7 +271,7 @@ void v25_common_device::nec_interrupt(unsigned int_num, int /*INTSOURCES*/ sourc
PUSH(Sreg(PS));
PUSH(m_ip);
m_ip = (WORD)dest_off;
m_prev_ip = m_ip = (WORD)dest_off;
Sreg(PS) = (WORD)dest_seg;
CHANGE_PC;
}
@ -286,7 +287,7 @@ void v25_common_device::nec_bankswitch(unsigned bank_num)
Wreg(PSW_SAVE) = tmp;
Wreg(PC_SAVE) = m_ip;
m_ip = Wreg(VECTOR_PC);
m_prev_ip = m_ip = Wreg(VECTOR_PC);
CHANGE_PC;
}
@ -565,6 +566,7 @@ void v25_common_device::device_start()
save_item(NAME(m_intp_state));
save_item(NAME(m_ip));
save_item(NAME(m_prev_ip));
save_item(NAME(m_IBRK));
save_item(NAME(m_F0));
save_item(NAME(m_F1));
@ -637,23 +639,32 @@ void v25_common_device::device_start()
m_p1_out.resolve_safe();
m_p2_out.resolve_safe();
state_add( V25_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%05X");
state_add( V25_IP, "IP", m_ip).formatstr("%04X");
state_add( V25_SP, "SP", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_FLAGS, "F", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_AW, "AW", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_CW, "CW", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_DW, "DW", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_BW, "BW", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_BP, "BP", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_IX, "IX", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_IY, "IY", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_ES, "DS1", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_CS, "PS", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_SS, "SS", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_DS, "DS0", m_debugger_temp).callimport().callexport().formatstr("%04X");
state_add( V25_PC, "PC", m_ip).formatstr("%04X");
state_add<uint16_t>( V25_PSW, "PSW", [this]() { return CompressFlags(); }, [this](uint16_t data) { ExpandFlags(data); });
state_add( V25_IDB, "IDB", m_IDB).mask(0xffe00).callimport();
state_add<uint16_t>( V25_AW, "AW", [this]() { return Wreg(AW); }, [this](uint16_t data) { Wreg(AW) = data; });
state_add<uint16_t>( V25_CW, "CW", [this]() { return Wreg(CW); }, [this](uint16_t data) { Wreg(CW) = data; });
state_add<uint16_t>( V25_DW, "DW", [this]() { return Wreg(DW); }, [this](uint16_t data) { Wreg(DW) = data; });
state_add<uint16_t>( V25_BW, "BW", [this]() { return Wreg(BW); }, [this](uint16_t data) { Wreg(BW) = data; });
state_add<uint16_t>( V25_SP, "SP", [this]() { return Wreg(SP); }, [this](uint16_t data) { Wreg(SP) = data; });
state_add<uint16_t>( V25_BP, "BP", [this]() { return Wreg(BP); }, [this](uint16_t data) { Wreg(BP) = data; });
state_add<uint16_t>( V25_IX, "IX", [this]() { return Wreg(IX); }, [this](uint16_t data) { Wreg(IX) = data; });
state_add<uint16_t>( V25_IY, "IY", [this]() { return Wreg(IY); }, [this](uint16_t data) { Wreg(IY) = data; });
state_add<uint16_t>( V25_DS1, "DS1", [this]() { return Sreg(DS1); }, [this](uint16_t data) { Sreg(DS1) = data; });
state_add<uint16_t>( V25_PS, "PS", [this]() { return Sreg(PS); }, [this](uint16_t data) { Sreg(PS) = data; });
state_add<uint16_t>( V25_SS, "SS", [this]() { return Sreg(SS); }, [this](uint16_t data) { Sreg(SS) = data; });
state_add<uint16_t>( V25_DS0, "DS0", [this]() { return Sreg(DS0); }, [this](uint16_t data) { Sreg(DS0) = data; });
state_add<uint8_t>( V25_AL, "AL", [this]() { return Breg(AL); }, [this](uint8_t data) { Breg(AL) = data; }).noshow();
state_add<uint8_t>( V25_AH, "AH", [this]() { return Breg(AH); }, [this](uint8_t data) { Breg(AH) = data; }).noshow();
state_add<uint8_t>( V25_CL, "CL", [this]() { return Breg(CL); }, [this](uint8_t data) { Breg(CL) = data; }).noshow();
state_add<uint8_t>( V25_CH, "CH", [this]() { return Breg(CH); }, [this](uint8_t data) { Breg(CH) = data; }).noshow();
state_add<uint8_t>( V25_DL, "DL", [this]() { return Breg(DL); }, [this](uint8_t data) { Breg(DL) = data; }).noshow();
state_add<uint8_t>( V25_DH, "DH", [this]() { return Breg(DH); }, [this](uint8_t data) { Breg(DH) = data; }).noshow();
state_add<uint8_t>( V25_BL, "BL", [this]() { return Breg(BL); }, [this](uint8_t data) { Breg(BL) = data; }).noshow();
state_add<uint8_t>( V25_BH, "BH", [this]() { return Breg(BH); }, [this](uint8_t data) { Breg(BH) = data; }).noshow();
state_add( V25_IDB, "IDB", m_IDB).mask(0xffe00).callimport();
state_add( STATE_GENPC, "GENPC", m_debugger_temp).callexport().noshow();
state_add( STATE_GENPCBASE, "CURPC", m_debugger_temp).callexport().noshow();
@ -694,7 +705,7 @@ void v25_common_device::state_import(const device_state_entry &entry)
{
switch (entry.index())
{
case V25_PC:
case STATE_GENPC:
if( m_debugger_temp - (Sreg(PS)<<4) < 0x10000 )
{
m_ip = m_debugger_temp - (Sreg(PS)<<4);
@ -704,58 +715,7 @@ void v25_common_device::state_import(const device_state_entry &entry)
Sreg(PS) = m_debugger_temp >> 4;
m_ip = m_debugger_temp & 0x0000f;
}
break;
case V25_SP:
Wreg(SP) = m_debugger_temp;
break;
case V25_FLAGS:
ExpandFlags(m_debugger_temp);
break;
case V25_AW:
Wreg(AW) = m_debugger_temp;
break;
case V25_CW:
Wreg(CW) = m_debugger_temp;
break;
case V25_DW:
Wreg(DW) = m_debugger_temp;
break;
case V25_BW:
Wreg(BW) = m_debugger_temp;
break;
case V25_BP:
Wreg(BP) = m_debugger_temp;
break;
case V25_IX:
Wreg(IX) = m_debugger_temp;
break;
case V25_IY:
Wreg(IY) = m_debugger_temp;
break;
case V25_ES:
Sreg(DS1) = m_debugger_temp;
break;
case V25_CS:
Sreg(PS) = m_debugger_temp;
break;
case V25_SS:
Sreg(SS) = m_debugger_temp;
break;
case V25_DS:
Sreg(DS0) = m_debugger_temp;
m_prev_ip = m_ip;
break;
case V25_IDB:
@ -770,66 +730,16 @@ void v25_common_device::state_export(const device_state_entry &entry)
switch (entry.index())
{
case STATE_GENPC:
case STATE_GENPCBASE:
case V25_PC:
m_debugger_temp = (Sreg(PS)<<4) + m_ip;
break;
case STATE_GENPCBASE:
m_debugger_temp = (Sreg(PS)<<4) + m_prev_ip;
break;
case STATE_GENSP:
m_debugger_temp = (Sreg(SS)<<4) + Wreg(SP);
break;
case V25_SP:
m_debugger_temp = Wreg(SP);
break;
case V25_FLAGS:
m_debugger_temp = CompressFlags();
break;
case V25_AW:
m_debugger_temp = Wreg(AW);
break;
case V25_CW:
m_debugger_temp = Wreg(CW);
break;
case V25_DW:
m_debugger_temp = Wreg(DW);
break;
case V25_BW:
m_debugger_temp = Wreg(BW);
break;
case V25_BP:
m_debugger_temp = Wreg(BP);
break;
case V25_IX:
m_debugger_temp = Wreg(IX);
break;
case V25_IY:
m_debugger_temp = Wreg(IY);
break;
case V25_ES:
m_debugger_temp = Sreg(DS1);
break;
case V25_CS:
m_debugger_temp = Sreg(PS);
break;
case V25_SS:
m_debugger_temp = Sreg(SS);
break;
case V25_DS:
m_debugger_temp = Sreg(DS0);
break;
}
}
@ -875,6 +785,7 @@ void v25_common_device::execute_run()
while(m_icount>0) {
/* Dispatch IRQ */
m_prev_ip = m_ip;
if (m_no_interrupt==0 && (m_pending_irq & m_unmasked_irq))
{
if (m_pending_irq & NMI_IRQ)

View File

@ -16,8 +16,10 @@
enum
{
V25_PC=0,
V25_IP, V25_AW, V25_CW, V25_DW, V25_BW, V25_SP, V25_BP, V25_IX, V25_IY,
V25_FLAGS, V25_ES, V25_CS, V25_SS, V25_DS,
V25_AW, V25_CW, V25_DW, V25_BW, V25_SP, V25_BP, V25_IX, V25_IY,
V25_DS1, V25_PS, V25_SS, V25_DS0,
V25_AL, V25_AH, V25_CL, V25_CH, V25_DL, V25_DH, V25_BL, V25_BH,
V25_PSW,
V25_IDB,
V25_PENDING
};
@ -80,6 +82,7 @@ private:
required_shared_ptr<uint16_t> m_internal_ram;
uint16_t m_ip;
uint16_t m_prev_ip;
/* PSW flags */
int32_t m_SignVal;

View File

@ -19,7 +19,7 @@
2017-Feb-15 Edstrom
Fixed shift registers to be more accurate, eg 50/50 duty cycle, latching
on correct flanks and leading and trailing flanks added + logging.
on correct edges and leading and trailing edges added + logging.
*/
#include "emu.h"
@ -386,7 +386,7 @@ void via6522_device::clear_int(int data)
void via6522_device::shift_out()
{
// Only shift out msb on falling flank
// Only shift out msb on falling edge
if (m_shift_counter & 1)
{
LOGSHIFT(" %s shift Out SR: %02x->", tag(), m_sr);
@ -399,26 +399,26 @@ void via6522_device::shift_out()
if (m_shift_counter == 1 && SO_EXT_CONTROL(m_acr))
{
LOGINT("SHIFT EXT out INT request ");
set_int(INT_SR); // IRQ on last falling flank for external clock (mode 7)
set_int(INT_SR); // IRQ on last falling edge for external clock (mode 7)
}
}
else // Check for INT condition, eg the last and raising flank of the 15-0 falling/raising flanks
else // Check for INT condition, eg the last and raising edge of the 15-0 falling/raising edges
{
if (!SO_T2_RATE(m_acr)) // The T2 continous shifter doesn't do interrupts (mode 4)
{
if (m_shift_counter == 0 && (SO_O2_CONTROL(m_acr) || SO_T2_CONTROL(m_acr)))
{
LOGINT("SHIFT O2/T2 out INT request ");
set_int(INT_SR); // IRQ on last raising flank for internal clock (mode 5-6)
set_int(INT_SR); // IRQ on last raising edge for internal clock (mode 5-6)
}
}
}
m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all flanks
m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all edges
}
void via6522_device::shift_in()
{
// Only shift in data on raising flank
// Only shift in data on raising edge
if ( !(m_shift_counter & 1) )
{
LOGSHIFT("%s shift In SR: %02x->", tag(), m_sr);
@ -429,10 +429,10 @@ void via6522_device::shift_in()
{
LOGINT("SHIFT in INT request ");
// set_int(INT_SR);// TODO: this interrupt is 1-2 clock cycles too early
m_shift_irq_timer->adjust(clocks_to_attotime(2)/2); // Delay IRQ 2 flanks for all shift INs (mode 1-3)
m_shift_irq_timer->adjust(clocks_to_attotime(2)/2); // Delay IRQ 2 edges for all shift INs (mode 1-3)
}
}
m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all flanks
m_shift_counter = (m_shift_counter - 1) & 0x0f; // Count all edges
}
void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@ -440,7 +440,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
switch (id)
{
case TIMER_SHIFT_IRQ: // This timer event is a delayed IRQ for improved cycle accuracy
set_int(INT_SR); // triggered from shift_in or shift_out on the last rising flank
set_int(INT_SR); // triggered from shift_in or shift_out on the last rising edge
m_shift_irq_timer->adjust(attotime::never); // Not needed really...
break;
case TIMER_SHIFT:
@ -448,7 +448,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
m_out_cb1 ^= 1;
m_cb1_handler(m_out_cb1);
// we call shift methods for all flanks
// we call shift methods for all edges
if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
{
shift_out();
@ -459,7 +459,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para
}
// If in continous mode or the shifter is still shifting we re-arm the timer
if (SO_T2_RATE(m_acr) || (m_shift_counter != 0x0f))
if (SO_T2_RATE(m_acr) || (m_shift_counter < 0x0f))
{
if (SI_O2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
{
@ -703,15 +703,20 @@ u8 via6522_device::read(offs_t offset)
val = m_sr;
if (!machine().side_effects_disabled())
{
m_out_cb1 = 1;
m_cb1_handler(m_out_cb1);
m_shift_counter = 0x0f;
if (!(SI_EXT_CONTROL(m_acr) || SO_EXT_CONTROL(m_acr))) {
m_out_cb1 = 1;
m_cb1_handler(m_out_cb1);
m_shift_counter = 0x0f;
}
else
m_shift_counter = m_in_cb1 ? 0x0f : 0x10;
LOGINT("SR INT ");
clear_int(INT_SR);
LOGSHIFT(" - ACR: %02x ", m_acr);
if (SI_O2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr))
{
m_shift_timer->adjust(clocks_to_attotime(8) / 2); // 8 flanks to start shifter from a read
m_shift_timer->adjust(clocks_to_attotime(8) / 2); // 8 edges to start shifter from a read
LOGSHIFT(" - read SR starts O2 timer ");
}
else if (SI_T2_CONTROL(m_acr) || SO_T2_CONTROL(m_acr))
@ -889,21 +894,20 @@ void via6522_device::write(offs_t offset, u8 data)
m_sr = data;
LOGSHIFT("Write SR: %02x\n", m_sr);
// make sure CB1 is high - this should not be needed though
if (m_out_cb1 != 1)
{
logerror("VIA: CB1 is low starting shifter\n");
if (!(SI_EXT_CONTROL(m_acr) || SO_EXT_CONTROL(m_acr))) {
m_out_cb1 = 1;
m_cb1_handler(m_out_cb1);
m_shift_counter = 0x0f;
}
else
m_shift_counter = m_in_cb1 ? 0x0f : 0x10;
m_shift_counter = 0x0f;
LOGINT("SR INT ");
clear_int(INT_SR);
LOGSHIFT(" - ACR is: %02x ", m_acr);
if (SO_O2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr))
{
m_shift_timer->adjust(clocks_to_attotime(8) / 2); // 8 flanks to start shifter from a write
m_shift_timer->adjust(clocks_to_attotime(8) / 2); // 8 edges to start shifter from a write
LOGSHIFT(" - write SR starts O2 timer");
}
else if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SI_T2_CONTROL(m_acr))
@ -966,6 +970,13 @@ void via6522_device::write(offs_t offset, u8 data)
m_t1->adjust(clocks_to_attotime(counter1 + IFR_DELAY));
m_t1_active = 1;
}
if (SI_T2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr) || SI_EXT_CONTROL(m_acr))
{
m_out_cb2 = 1;
m_cb2_handler(m_out_cb2);
}
LOGSHIFT("\n");
}
break;

View File

@ -4,8 +4,7 @@
I2C Memory
Generic ram/rom/eeprom/flash on an i2c bus. Supports specifying the slave address,
the data size & the page size for writing.
ram/rom/eeprom/flash on an i2c bus.
inputs:
e0,e1,e2 lower 3 bits of the slave address
@ -16,9 +15,11 @@ inputs:
outputs:
sda serial data
The memory address is only 8 bits, devices larger than this have multiple slave addresses.
The top five address bits are set at manufacture time, two values are standard.
The memory address is only 8 bits for devices up to 2048 bytes,
devices from 512 to 2048 bytes occupy multiple slave addresses.
The top five address bits are set at manufacture time,
there are two standard values.
***************************************************************************/
#include "emu.h"
@ -59,15 +60,16 @@ static inline void ATTR_PRINTF( 3, 4 ) verboselog( device_t *device, int n_level
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(I2CMEM, i2cmem_device, "i2cmem", "I2C Memory")
DEFINE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device, "x2404p", "X2404P I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C01, i2c_24c01_device, "24c01", "24C01 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_PCD8572, i2c_pcd8572_device, "pcd8572", "PCD8572 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C02, i2c_24c02_device, "24c02", "24C02 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_M24C02, i2c_m24c02_device, "m24c02", "M24C02 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C04, i2c_24c04_device, "24c04", "24C04 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device, "x2404p", "X2404P I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C08, i2c_24c08_device, "24c08", "24C08 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C16, i2c_24c16_device, "24c16", "24C16 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C16A, i2c_24c16a_device, "24c16a", "24C16A I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C64, i2c_24c64_device, "24c64", "24C64 I2C Memory")
DEFINE_DEVICE_TYPE(I2C_24C512, i2c_24c512_device, "24c512", "24C512 I2C Memory")
//**************************************************************************
// LIVE DEVICE
@ -83,13 +85,15 @@ i2cmem_device::i2cmem_device(
const char *tag,
device_t *owner,
uint32_t clock,
int page_size,
int read_page_size,
int write_page_size,
int data_size) :
device_t(mconfig, type, tag, owner, clock),
device_nvram_interface(mconfig, *this),
m_region(*this, DEVICE_SELF),
m_slave_address(I2CMEM_SLAVE_ADDRESS),
m_page_size(page_size),
m_read_page_size(read_page_size),
m_write_page_size(write_page_size),
m_data_size(data_size),
m_scl(0),
m_sdaw(0),
@ -110,48 +114,53 @@ i2cmem_device::i2cmem_device(
assert(!clock);
}
i2cmem_device::i2cmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2CMEM, tag, owner, clock, 0, 0)
{
}
i2c_x2404p_device::i2c_x2404p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_X2404P, tag, owner, clock, 8, 0x200)
{
}
i2c_24c01_device::i2c_24c01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C01, tag, owner, clock, 4, 0x80)
i2cmem_device(mconfig, I2C_24C01, tag, owner, clock, 0, 8, 0x80)
{
}
i2c_pcd8572_device::i2c_pcd8572_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_PCD8572, tag, owner, clock, 0, 0, 0x80)
{
}
i2c_24c02_device::i2c_24c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C02, tag, owner, clock, 4, 0x100)
i2cmem_device(mconfig, I2C_24C02, tag, owner, clock, 0, 8, 0x100)
{
}
i2c_m24c02_device::i2c_m24c02_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_M24C02, tag, owner, clock, 0, 16, 0x100)
{
}
i2c_24c04_device::i2c_24c04_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C04, tag, owner, clock, 8, 0x200)
i2cmem_device(mconfig, I2C_24C04, tag, owner, clock, 0, 16, 0x200)
{
}
i2c_x2404p_device::i2c_x2404p_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_X2404P, tag, owner, clock, 0x100, 8, 0x200)
{
}
i2c_24c08_device::i2c_24c08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C08, tag, owner, clock, 0, 0x400)
i2cmem_device(mconfig, I2C_24C08, tag, owner, clock, 0, 16, 0x400)
{
}
i2c_24c16_device::i2c_24c16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C16, tag, owner, clock, 8, 0x800)
{
}
i2c_24c16a_device::i2c_24c16a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C16A, tag, owner, clock, 0, 0x800)
i2cmem_device(mconfig, I2C_24C16, tag, owner, clock, 0, 16, 0x800)
{
}
i2c_24c64_device::i2c_24c64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C64, tag, owner, clock, 8, 0x2000)
i2cmem_device(mconfig, I2C_24C64, tag, owner, clock, 0, 32, 0x2000)
{
}
i2c_24c512_device::i2c_24c512_device(const machine_config& mconfig, const char* tag, device_t* owner, uint32_t clock) :
i2cmem_device(mconfig, I2C_24C512, tag, owner, clock, 0, 128, 0x10000)
{
}
@ -162,7 +171,7 @@ i2c_24c64_device::i2c_24c64_device(const machine_config &mconfig, const char *ta
void i2cmem_device::device_start()
{
m_data = std::make_unique<uint8_t []>(m_data_size);
m_page.resize( m_page_size );
m_page.resize( m_write_page_size );
save_item( NAME(m_scl) );
save_item( NAME(m_sdaw) );
@ -181,7 +190,7 @@ void i2cmem_device::device_start()
save_item( NAME(m_page_offset) );
save_item( NAME(m_page_written_size) );
save_pointer( &m_data[0], "m_data", m_data_size );
if ( m_page_size > 0 )
if ( m_write_page_size > 0 )
{
save_item( NAME(m_page) );
}
@ -286,13 +295,15 @@ WRITE_LINE_MEMBER( i2cmem_device::write_sda )
{
if( m_sdaw )
{
if( m_state == STATE_DATAIN && m_page_size > 0 )
if( m_page_written_size > 0 )
{
int base = data_offset();
int root = base & ~( m_page_size - 1);
for( int i=0; i < m_page_written_size; i++)
m_data[root | ((base + i) & (m_page_size - 1))] = m_page[i];
verboselog( this, 1, "data[ %04x to %04x ] = %x bytes\n", base, root | ((base + m_page_written_size - 1) & (m_page_size - 1)), m_page_written_size );
int root = base & ~( m_write_page_size - 1 );
for( int i = 0; i < m_page_written_size; i++ )
m_data[root | ((base + i) & (m_write_page_size - 1))] = m_page[i];
verboselog( this, 1, "data[ %04x to %04x ] = %x bytes\n", base, root | ((base + m_page_written_size - 1) & (m_write_page_size - 1)), m_page_written_size );
m_page_written_size = 0;
}
verboselog( this, 1, "stop\n" );
m_state = STATE_IDLE;
@ -373,7 +384,7 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
break;
case STATE_ADDRESSLOW:
m_byteaddr = m_shift | (skip_addresshigh() ? (m_devsel & DEVSEL_ADDRESS) << 7 : m_addresshigh << 8);
m_byteaddr = m_shift | (skip_addresshigh() ? ((m_devsel & DEVSEL_ADDRESS) << 7) & address_mask() : m_addresshigh << 8);
m_page_offset = 0;
m_page_written_size = 0;
@ -388,17 +399,17 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
verboselog( this, 0, "write not enabled\n" );
m_state = STATE_IDLE;
}
else if( m_page_size > 0 )
else if( m_write_page_size > 0 )
{
m_page[ m_page_offset ] = m_shift;
verboselog( this, 1, "page[ %04x ] <- %02x\n", m_page_offset, m_page[ m_page_offset ] );
m_page_offset++;
if( m_page_offset == m_page_size )
if( m_page_offset == m_write_page_size )
m_page_offset = 0;
m_page_written_size++;
if( m_page_written_size > m_page_size)
m_page_written_size = m_page_size;
if( m_page_written_size > m_write_page_size)
m_page_written_size = m_write_page_size;
}
else
{
@ -440,7 +451,7 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
m_shift = m_data[offset];
verboselog( this, 1, "data[ %04x ] -> %02x\n", offset, m_shift );
m_byteaddr++;
m_byteaddr = (m_byteaddr & ~(m_read_page_size - 1)) | ((m_byteaddr + 1) & (m_read_page_size - 1));
}
m_sdar = ( m_shift >> 7 ) & 1;

View File

@ -33,12 +33,7 @@ class i2cmem_device :
public device_nvram_interface
{
public:
// construction/destruction
i2cmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
i2cmem_device & set_address(int address) { m_slave_address = address; return *this; }
i2cmem_device & set_page_size(int page_size) { m_page_size = page_size; return *this; }
i2cmem_device & set_data_size(int data_size) { m_data_size = data_size; return *this; }
i2cmem_device & set_e0(int e0) { m_e0 = e0; return *this; }
i2cmem_device & set_e1(int e1) { m_e1 = e1; return *this; }
i2cmem_device & set_e2(int e2) { m_e2 = e2; return *this; }
@ -55,7 +50,7 @@ public:
protected:
// construction/destruction
i2cmem_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int page_size, int data_size);
i2cmem_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int read_page_size, int write_page_size, int data_size);
// device-level overrides
virtual void device_start() override;
@ -76,7 +71,8 @@ protected:
// internal state
std::unique_ptr<uint8_t[]> m_data;
int m_slave_address;
int m_page_size;
int m_read_page_size;
int m_write_page_size;
int m_data_size;
int m_scl;
int m_sdaw;
@ -103,24 +99,27 @@ protected:
i2c_##name##_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); \
};
DECLARE_I2C_DEVICE(x2404p)
DECLARE_I2C_DEVICE(24c01)
DECLARE_I2C_DEVICE(24c02)
DECLARE_I2C_DEVICE(24c04)
DECLARE_I2C_DEVICE(24c08)
DECLARE_I2C_DEVICE(24c01);
DECLARE_I2C_DEVICE(pcd8572);
DECLARE_I2C_DEVICE(24c02);
DECLARE_I2C_DEVICE(m24c02);
DECLARE_I2C_DEVICE(24c04);
DECLARE_I2C_DEVICE(x2404p);
DECLARE_I2C_DEVICE(24c08);
DECLARE_I2C_DEVICE(24c16);
DECLARE_I2C_DEVICE(24c16a);
DECLARE_I2C_DEVICE(24c64);
DECLARE_I2C_DEVICE(24c512);
// device type definition
DECLARE_DEVICE_TYPE(I2CMEM, i2cmem_device)
DECLARE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device)
DECLARE_DEVICE_TYPE(I2C_24C01, i2c_24c01_device)
DECLARE_DEVICE_TYPE(I2C_PCD8572, i2c_pcd8572_device)
DECLARE_DEVICE_TYPE(I2C_24C02, i2c_24c02_device)
DECLARE_DEVICE_TYPE(I2C_M24C02, i2c_m24c02_device)
DECLARE_DEVICE_TYPE(I2C_24C04, i2c_24c04_device)
DECLARE_DEVICE_TYPE(I2C_X2404P, i2c_x2404p_device)
DECLARE_DEVICE_TYPE(I2C_24C08, i2c_24c08_device)
DECLARE_DEVICE_TYPE(I2C_24C16, i2c_24c16_device)
DECLARE_DEVICE_TYPE(I2C_24C16A, i2c_24c16a_device)
DECLARE_DEVICE_TYPE(I2C_24C64, i2c_24c64_device)
DECLARE_DEVICE_TYPE(I2C_24C512, i2c_24c512_device)
#endif // MAME_MACHINE_I2CMEM_H

View File

@ -46,12 +46,12 @@ void i82357_device::device_add_mconfig(machine_config &config)
PIC8259(config, m_pic[0], 0);
m_pic[0]->in_sp_callback().set_constant(1);
m_pic[0]->read_slave_ack_callback().set(
[this](offs_t offset)
[this](offs_t offset) -> u8
{
if (offset == 2)
return m_pic[1]->acknowledge();
return u32(0);
return 0;
});
PIC8259(config, m_pic[1], 0);

View File

@ -158,7 +158,7 @@ INPUT_PORTS_START( generic_keyboard )
PORT_BIT( 0x0100U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x01) PORT_CHAR('8') PORT_CHAR('(')
PORT_BIT( 0x0200U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x00) PORT_CHAR('9') PORT_CHAR('(')
PORT_BIT( 0x0200U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x01) PORT_CHAR('9') PORT_CHAR(')')
PORT_BIT( 0x0400U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x00) PORT_CHAR('0') PORT_CHAR('(')
PORT_BIT( 0x0400U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x00) PORT_CHAR('0') PORT_CHAR(')')
PORT_BIT( 0x0400U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x01) PORT_CHAR('0')
PORT_BIT( 0x0800U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x00) PORT_CHAR('-') PORT_CHAR('_')
PORT_BIT( 0x0800U, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CONDITION("GENKBD_CFG", 0x01, EQUALS, 0x01) PORT_CHAR('-') PORT_CHAR('=')

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont, Olivier Galibert
/*********************************************************************
ncr5380n.c
Implementation of the NCR 5380
*********************************************************************/
// copyright-holders:Patrick Mackinlay
#ifndef MAME_MACHINE_NCR5380N_H
#define MAME_MACHINE_NCR5380N_H
@ -15,221 +8,179 @@
#include "machine/nscsi_bus.h"
class ncr5380n_device : public nscsi_device, public nscsi_slot_card_interface
class ncr5380n_device
: public nscsi_device
, public nscsi_slot_card_interface
{
public:
ncr5380n_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
ncr5380n_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
// configuration helpers
// device configuration
auto irq_handler() { return m_irq_handler.bind(); }
auto drq_handler() { return m_drq_handler.bind(); }
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
// register access
void map(address_map &map);
u8 read(offs_t offset);
void write(offs_t offset, u8 data);
uint8_t dma_r();
void dma_w(uint8_t val);
// dma access
void eop_w(int state);
u8 dma_r();
void dma_w(u8 val);
protected:
ncr5380n_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
ncr5380n_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock, bool has_lbs = false);
// device_t overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
// ncsci_device overrides
virtual void scsi_ctrl_changed() override;
// register read handlers
u8 csdata_r();
u8 icmd_r();
u8 mode_r();
u8 tcmd_r();
u8 csstat_r();
u8 bas_r();
u8 idata_r();
u8 rpi_r();
// register write handlers
void odata_w(u8 data);
void icmd_w(u8 data);
void mode_w(u8 data);
void tcmd_w(u8 data);
void selen_w(u8 data);
void sds_w(u8 data);
void sdtr_w(u8 data);
void sdir_w(u8 data);
// state machine
void state_timer(void *ptr, s32 param);
int state_step();
// other helpers
void scsi_data_w(u8 data);
void set_irq(bool irq_state);
void set_drq(bool drq_state);
private:
enum { MODE_D, MODE_T, MODE_I };
enum { IDLE };
enum icmd_mask : u8
{
IC_RST = 0x80, // assert R̅S̅T̅
IC_TEST = 0x40, // test mode (wo)
IC_AIP = 0x40, // arbitration in progress (ro)
IC_LA = 0x20, // lost arbitration (ro)
IC_ACK = 0x10, // assert A̅C̅K̅
IC_BSY = 0x08, // assert B̅S̅Y̅
IC_SEL = 0x04, // assert S̅E̅L̅
IC_ATN = 0x02, // assert A̅T̅N̅
IC_DBUS = 0x01, // assert data bus
enum {
// Bus initiated sequences
BUSINIT_SETTLE_DELAY = 1,
BUSINIT_ASSERT_BUS_SEL,
BUSINIT_MSG_OUT,
BUSINIT_RECV_BYTE,
BUSINIT_ASSERT_BUS_RESEL,
BUSINIT_WAIT_REQ,
BUSINIT_RECV_BYTE_NACK,
// Bus SCSI Reset
BUSRESET_WAIT_INT,
BUSRESET_RESET_BOARD,
// Disconnected state commands
DISC_SEL_ARBITRATION,
DISC_SEL_ATN_WAIT_REQ,
DISC_SEL_ATN_SEND_BYTE,
DISC_SEL_WAIT_REQ,
DISC_SEL_SEND_BYTE,
DISC_REC_ARBITRATION,
DISC_REC_MSG_IN,
DISC_REC_SEND_BYTE,
DISC_RESET,
// Command sequence
CMDSEQ_CMD_PHASE,
CMDSEQ_RECV_BYTE,
// Target commands
TARGET_SEND_BYTE,
TARGET_CMD_RECV_BYTE,
TARGET_MSG_RECV_BYTE,
TARGET_MSG_RECV_PAD,
TARGET_DISC_SEND_BYTE,
TARGET_DISC_MSG_IN,
TARGET_DISC_SEND_BYTE_2,
// Initiator commands
INIT_MSG_WAIT_REQ,
INIT_XFR,
INIT_XFR_SEND_BYTE,
INIT_XFR_SEND_PAD_WAIT_REQ,
INIT_XFR_SEND_PAD,
INIT_XFR_RECV_PAD_WAIT_REQ,
INIT_XFR_RECV_PAD,
INIT_XFR_RECV_BYTE_ACK,
INIT_XFR_RECV_BYTE_NACK,
INIT_XFR_WAIT_REQ,
INIT_CPT_RECV_BYTE_ACK,
INIT_CPT_RECV_WAIT_REQ,
INIT_CPT_RECV_BYTE_NACK
IC_PHASE = 0x9e,
IC_WRITE = 0x9f,
};
enum {
// Arbitration
ARB_WAIT_BUS_FREE = 1,
ARB_COMPLETE,
ARB_ASSERT_SEL,
ARB_SET_DEST,
ARB_RELEASE_BUSY,
ARB_TIMEOUT_BUSY,
ARB_TIMEOUT_ABORT,
ARB_DESKEW_WAIT,
// Send/receive byte
SEND_WAIT_SETTLE,
SEND_WAIT_REQ_0,
RECV_WAIT_REQ_1,
RECV_WAIT_SETTLE,
RECV_WAIT_REQ_0
enum mode_mask : u8
{
MODE_BLOCKDMA = 0x80,
MODE_TARGET = 0x40,
MODE_PARITYCHK = 0x20,
MODE_PARITYIRQ = 0x10,
MODE_EOPIRQ = 0x08,
MODE_BSYIRQ = 0x04,
MODE_DMA = 0x02,
MODE_ARBITRATE = 0x01,
};
enum tcmd_mask : u8
{
TC_LBS = 0x80, // last byte sent
TC_REQ = 0x08, // assert R̅E̅Q̅
TC_MSG = 0x04, // assert M̅S̅G̅
TC_CD = 0x02, // assert C̅/D
TC_IO = 0x01, // assert I̅/O
enum {
STATE_MASK = 0x00ff,
SUB_SHIFT = 8,
SUB_MASK = 0xff00
TC_PHASE = 0x07,
};
enum { BUS_BUSY, BUS_FREE_WAIT, BUS_FREE };
enum {
ST_RST = 0x80,
ST_BSY = 0x40,
ST_REQ = 0x20,
ST_MSG = 0x10,
ST_CD = 0x08,
ST_IO = 0x04,
ST_SEL = 0x02,
ST_DBP = 0x01,
BAS_ENDOFDMA = 0x80,
BAS_DMAREQUEST = 0x40,
BAS_PARITYERROR = 0x20,
BAS_IRQACTIVE = 0x10,
BAS_PHASEMATCH = 0x08,
BAS_BUSYERROR = 0x04,
BAS_ATN = 0x02,
BAS_ACK = 0x01,
IC_RST = 0x80,
IC_ARBITRATION = 0x40,
IC_ARBLOST = 0x20,
IC_ACK = 0x10,
IC_BSY = 0x08,
IC_SEL = 0x04,
IC_ATN = 0x02,
IC_DBUS = 0x01,
IC_PHASEMASK = 0x9e,
IC_WRITEMASK = 0x9f,
MODE_BLOCKDMA = 0x80,
MODE_TARGET = 0x40,
MODE_PARITYCHK = 0x20,
MODE_PARITYIRQ = 0x10,
MODE_EOPIRQ = 0x08,
MODE_BSYIRQ = 0x04,
MODE_DMA = 0x02,
MODE_ARBITRATE = 0x01
enum csstat_mask : u8
{
ST_RST = 0x80,
ST_BSY = 0x40,
ST_REQ = 0x20,
ST_MSG = 0x10,
ST_CD = 0x08,
ST_IO = 0x04,
ST_SEL = 0x02,
ST_DBP = 0x01,
};
enum bas_mask : u8
{
BAS_ENDOFDMA = 0x80,
BAS_DMAREQUEST = 0x40,
BAS_PARITYERROR = 0x20,
BAS_IRQACTIVE = 0x10,
BAS_PHASEMATCH = 0x08,
BAS_BUSYERROR = 0x04,
BAS_ATN = 0x02,
BAS_ACK = 0x01,
};
enum { DMA_NONE, DMA_IN, DMA_OUT };
uint32_t m_fake_clock;
emu_timer *tm;
uint8_t status, istatus, m_mode, m_outdata, m_busstatus, m_dmalatch;
uint8_t m_icommand, m_tcommand;
uint8_t clock_conv, sync_offset, sync_period, bus_id, select_timeout, seq;
uint16_t tcount;
int mode;
int state/*, xfr_phase*/;
bool irq, drq;
void drq_set();
void drq_clear();
void step(bool timeout);
void function_complete();
void function_bus_complete();
void bus_complete();
void arbitrate();
void check_irq();
void reset_soft();
void reset_disconnect();
void send_byte();
void recv_byte();
void delay(int cycles);
void delay_cycles(int cycles);
void map(address_map &map);
uint8_t scsidata_r();
void outdata_w(uint8_t data);
uint8_t icmd_r();
void icmd_w(uint8_t data);
uint8_t mode_r();
void mode_w(uint8_t data);
uint8_t command_r();
void command_w(uint8_t data);
uint8_t status_r();
void selenable_w(uint8_t data);
uint8_t busandstatus_r();
void startdmasend_w(uint8_t data);
uint8_t indata_r();
void startdmatargetrx_w(uint8_t data);
uint8_t resetparityirq_r();
void startdmainitrx_w(uint8_t data);
devcb_write_line m_irq_handler;
devcb_write_line m_drq_handler;
// state machine
emu_timer *m_state_timer;
enum state : unsigned
{
IDLE,
// arbitration
ARB_BUS_FREE,
ARB_START,
ARB_EVALUATE,
// dma transfer
DMA_IN_REQ,
DMA_IN_ACK,
DMA_OUT_REQ,
DMA_OUT_DRQ,
DMA_OUT_ACK,
}
m_state;
// registers
u8 m_odata;
u8 m_icmd;
u8 m_mode;
u8 m_tcmd;
u8 m_bas;
u8 m_idata;
// line state
u32 m_scsi_ctrl;
bool m_irq_state;
bool m_drq_state;
bool const m_has_lbs;
};
class ncr53c80_device : public ncr5380n_device
{
public:
ncr53c80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
ncr53c80_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
};
class cxd1180_device : public ncr5380n_device
{
public:
cxd1180_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
};
DECLARE_DEVICE_TYPE(NCR5380N, ncr5380n_device)
DECLARE_DEVICE_TYPE(NCR53C80, ncr53c80_device)
DECLARE_DEVICE_TYPE(CXD1180, cxd1180_device)
#endif // MAME_MACHINE_NCR5380N_H

View File

@ -288,6 +288,11 @@ void nscsi_full_device::step(bool timeout)
scsi_bus->ctrl_w(scsi_refid, 0, S_ALL);
scsi_state = IDLE;
LOG("scsi bus reset\n");
scsi_state = scsi_substate = IDLE;
buf_control_rpos = buf_control_wpos = 0;
scsi_identify = 0;
data_buffer_size = 0;
data_buffer_pos = 0;
return;
}

View File

@ -39,14 +39,15 @@ void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int para
/* is this IRQ in service and not cascading and sfnm? */
if ((m_isr & mask) && !(m_master && m_cascade && m_nested && (m_slave & mask)))
{
LOG("pic8259_timerproc(): PIC IRQ #%d still in service\n", irq);
LOG("pic8259_timerproc(): PIC IR%d still in service\n", irq);
break;
}
/* is this IRQ pending and enabled? */
if ((m_state == state_t::READY) && (m_irr & mask) && !(m_imr & mask))
{
LOG("pic8259_timerproc(): PIC triggering IRQ #%d\n", irq);
LOG("pic8259_timerproc(): PIC triggering IR%d\n", irq);
m_current_level = irq;
m_out_int_func(1);
return;
}
@ -54,6 +55,7 @@ void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int para
if((m_isr & mask) && m_master && m_cascade && m_nested && (m_slave & mask))
break;
}
m_current_level = -1;
m_out_int_func(0);
}
@ -64,7 +66,7 @@ void pic8259_device::set_irq_line(int irq, int state)
if (state)
{
/* setting IRQ line */
LOG("set_irq_line(): PIC set IRQ line #%d\n", irq);
LOG("set_irq_line(): PIC set IR%d line\n", irq);
if(m_level_trig_mode || (!m_level_trig_mode && !(m_irq_lines & mask)))
{
@ -75,26 +77,28 @@ void pic8259_device::set_irq_line(int irq, int state)
else
{
/* clearing IRQ line */
LOG("set_irq_line(): PIC cleared IRQ line #%d\n", irq);
LOG("set_irq_line(): PIC cleared IR%d line\n", irq);
m_irq_lines &= ~mask;
m_irr &= ~mask;
}
set_timer();
if (m_inta_sequence == 0)
set_timer();
}
uint32_t pic8259_device::acknowledge()
uint8_t pic8259_device::acknowledge()
{
for (int n = 0, irq = m_prio; n < 8; n++, irq = (irq + 1) & 7)
if (is_x86())
{
uint8_t mask = 1 << irq;
/* is this IRQ pending and enabled? */
if ((m_irr & mask) && !(m_imr & mask))
if (m_current_level != -1)
{
if (!machine().side_effects_disabled()) {
LOG("pic8259_acknowledge(): PIC acknowledge IRQ #%d\n", irq);
uint8_t mask = 1 << m_current_level;
if (!machine().side_effects_disabled())
{
LOG("pic8259_acknowledge(): PIC acknowledge IR%d\n", m_current_level);
if (!m_level_trig_mode)
m_irr &= ~mask;
@ -107,29 +111,70 @@ uint32_t pic8259_device::acknowledge()
if ((m_cascade!=0) && (m_master!=0) && (mask & m_slave))
{
// it's from slave device
return m_read_slave_ack_func(irq);
return m_read_slave_ack_func(m_current_level);
}
else
{
if (is_x86())
{
/* For x86 mode*/
return irq + m_base;
}
else
{
/* in case of 8080/85) */
return 0xcd0000 + (m_vector_addr_high << 8) + m_vector_addr_low + (irq << (3-m_vector_size));
}
/* For x86 mode*/
return m_current_level + m_base;
}
}
else
{
if (!machine().side_effects_disabled())
logerror("Spurious INTA\n");
return m_base + 7;
}
}
if (!machine().side_effects_disabled())
logerror("Spurious IRQ\n");
if (is_x86())
return m_base + 7;
else
return 0xcd0000 + (m_vector_addr_high << 8) + m_vector_addr_low + (7 << (3-m_vector_size));
{
/* in case of 8080/85 */
if (m_inta_sequence == 0)
{
if (!machine().side_effects_disabled())
{
if (m_current_level != -1)
{
LOG("pic8259_acknowledge(): PIC acknowledge IR%d\n", m_current_level);
uint8_t mask = 1 << m_current_level;
if (!m_level_trig_mode)
m_irr &= ~mask;
m_isr |= mask;
}
else
logerror("Spurious INTA\n");
m_inta_sequence = 1;
}
if (m_cascade && m_master && m_current_level != -1 && BIT(m_slave, m_current_level))
return m_read_slave_ack_func(m_current_level);
else
return 0xcd;
}
else if (m_inta_sequence == 1)
{
if (!machine().side_effects_disabled())
m_inta_sequence = 2;
if (m_cascade && m_master && m_current_level != -1 && BIT(m_slave, m_current_level))
return m_read_slave_ack_func(m_current_level);
else
return m_vector_addr_low + ((m_current_level & 7) << (3-m_vector_size));
}
else
{
if (!machine().side_effects_disabled())
{
m_inta_sequence = 0;
if (m_auto_eoi && m_current_level != -1)
m_isr &= ~(1 << m_current_level);
set_timer();
}
if (m_cascade && m_master && m_current_level != -1 && BIT(m_slave, m_current_level))
return m_read_slave_ack_func(m_current_level);
else
return m_vector_addr_high;
}
}
}
@ -150,18 +195,17 @@ uint8_t pic8259_device::read(offs_t offset)
if ( m_ocw3 & 0x04 )
{
/* Polling mode */
if ( m_irr & ~m_imr )
if (m_current_level != -1)
{
/* check the various IRQs */
for (int n = 0, irq = m_prio; n < 8; n++, irq = (irq + 1) & 7)
{
if ( ( 1 << irq ) & m_irr & ~m_imr )
{
data = 0x80 | irq;
break;
}
}
acknowledge();
data = 0x80 | m_current_level;
if (!m_level_trig_mode)
m_irr &= ~(1 << m_current_level);
if (!m_auto_eoi)
m_isr |= 1 << m_current_level;
set_timer();
}
}
else
@ -207,7 +251,9 @@ void pic8259_device::write(offs_t offset, uint8_t data)
m_cascade = (data & 0x02) ? 0 : 1;
m_icw4_needed = (data & 0x01) ? 1 : 0;
m_vector_addr_low = (data & 0xe0);
m_state = state_t::ICW2;
m_state = state_t::ICW2;
m_current_level = -1;
m_inta_sequence = 0;
m_out_int_func(0);
}
else if (m_state == state_t::READY)
@ -377,6 +423,8 @@ void pic8259_device::device_start()
save_item(NAME(m_mode));
save_item(NAME(m_auto_eoi));
save_item(NAME(m_is_x86));
save_item(NAME(m_current_level));
save_item(NAME(m_inta_sequence));
}
@ -406,6 +454,8 @@ void pic8259_device::device_reset()
m_is_x86 = 0;
m_vector_addr_low = 0;
m_vector_addr_high = 0;
m_current_level = -1;
m_inta_sequence = 0;
m_master = m_in_sp_func();
}

View File

@ -39,7 +39,7 @@ public:
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
uint32_t acknowledge();
uint8_t acknowledge();
DECLARE_WRITE_LINE_MEMBER( ir0_w ) { set_irq_line(0, state); }
DECLARE_WRITE_LINE_MEMBER( ir1_w ) { set_irq_line(1, state); }
@ -113,6 +113,9 @@ private:
uint8_t m_mode;
uint8_t m_auto_eoi;
uint8_t m_is_x86;
int8_t m_current_level;
uint8_t m_inta_sequence;
};
class v5x_icu_device : public pic8259_device

View File

@ -3,7 +3,7 @@
#ifndef MAME_MACHINE_RESCAP_H
#define MAME_MACHINE_RESCAP_H
/* Little helpers for magnitude conversions */
// Little helpers for magnitude conversions
#define RES_R(res) ((double)(res))
#define RES_K(res) ((double)(res) * 1e3)
#define RES_M(res) ((double)(res) * 1e6)
@ -15,7 +15,7 @@
#define IND_N(ind) ((double)(ind) * 1e-9)
#define IND_P(ind) ((double)(ind) * 1e-12)
/* vin --/\r1/\-- out --/\r2/\-- gnd */
// vin --/\r1/\-- out --/\r2/\-- gnd
#define RES_VOLTAGE_DIVIDER(r1, r2) ((double)(r2) / ((double)(r1) + (double)(r2)))
#define RES_2_PARALLEL(r1, r2) (((r1) * (r2)) / ((r1) + (r2)))
@ -26,4 +26,15 @@
#define RES_2_SERIAL(r1,r2) ((r1)+(r2))
// macro for the RC time constant on a 74LS123 with C > 1000pF
// R is in ohms, C is in farads
#define TIME_OF_74LS123(r,c) (0.45 * (double)(r) * (double)(c))
// macros for the RC time constant on a 555 timer IC
// R is in ohms, C is in farads
#define PERIOD_OF_555_MONOSTABLE_NSEC(r,c) ((attoseconds_t)(1100000000 * (double)(r) * (double)(c)))
#define PERIOD_OF_555_ASTABLE_NSEC(r1,r2,c) ((attoseconds_t)( 693000000 * ((double)(r1) + 2.0 * (double)(r2)) * (double)(c)))
#define PERIOD_OF_555_MONOSTABLE(r,c) attotime::from_nsec(PERIOD_OF_555_MONOSTABLE_NSEC(r,c))
#define PERIOD_OF_555_ASTABLE(r1,r2,c) attotime::from_nsec(PERIOD_OF_555_ASTABLE_NSEC(r1,r2,c))
#endif // MAME_MACHINE_RESCAP_H

View File

@ -85,7 +85,7 @@ public:
bool enabled() const { return m_timer->enabled(); }
// property setters
void set_param(int param) const { assert(m_type == TIMER_TYPE_GENERIC); m_timer->set_param(param); }
void set_param(int param) const { if(m_type != TIMER_TYPE_GENERIC) fatalerror("Cannot change parameter on a non-generic timer.\n"); m_timer->set_param(param); }
void set_ptr(void *ptr) { m_ptr = ptr; }
void enable(bool enable = true) const { m_timer->enable(enable); }
@ -93,7 +93,8 @@ public:
void reset() { adjust(attotime::never, 0, attotime::never); }
void adjust(const attotime &duration, s32 param = 0, const attotime &period = attotime::never) const
{
assert(m_type == TIMER_TYPE_GENERIC);
if(m_type != TIMER_TYPE_GENERIC)
fatalerror("Cannot adjust a non-generic timer.\n");
m_timer->adjust(duration, param, period);
}

View File

@ -68,6 +68,7 @@ public:
auto write_port5_callback() { return m_write_port[4].bind(); }
auto write_port6_callback() { return m_write_port[5].bind(); }
auto write_port7_callback() { return m_write_port[6].bind(); }
tms1024_device &set_ms(u8 i) { m_ms = i & 1; return *this; } // if hardwired, can just set MS pin state here
void write_h(u8 data);
u8 read_h();

View File

@ -1840,8 +1840,8 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data)
// loop over all interrupt sources
for (auto & elem : m_uart->m_int_state)
{
// find the first channel with an interrupt requested
if (elem & Z80_DAISY_INT)
// find the first interrupt under service
if (elem & Z80_DAISY_IEO)
{
LOGCMD("- %c found IUS bit to clear\n", 'A' + m_index);
elem = 0; // Clear IUS bit (called IEO in z80 daisy lingo)
@ -1858,7 +1858,8 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data)
of these modes is selected and this command is issued before the data has been read from the
Receive FIFO, the data is lost */
LOGCMD("%s: %c : WR0_ERROR_RESET - not implemented\n", owner()->tag(), 'A' + m_index);
m_rx_fifo_rp_step(); // Reset error state in fifo and unlock it. unlock == step to next slot in fifo.
if (m_rx_fifo_wp != m_rx_fifo_rp)
m_rx_fifo_rp_step(); // Reset error state in fifo and unlock it. unlock == step to next slot in fifo.
break;
case WR0_SEND_ABORT: // Flush transmitter and Send 8-13 bits of '1's, used with SDLC
LOGCMD("%s: %c : WR0_SEND_ABORT - not implemented\n", owner()->tag(), 'A' + m_index);

View File

@ -1,16 +1,21 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*
C140.c
c140.cpp
Simulator based on AMUSE sources.
The C140 sound chip is used by Namco System 2 and System 21
The 219 ASIC (which incorporates a modified C140) is used by Namco NA-1 and NA-2
This chip controls 24 channels (C140) or 16 (219) of PCM.
16 bytes are associated with each channel.
Channels can be 8 bit signed PCM, or 12 bit signed PCM.
Channels can be 8 bit compressed PCM, or 12 bit signed PCM.
TODO: What does the INT0 pin do? Normally Namco tied it to VOL0 (with VOL1 = VCC).
TODO:
- What does the INT0 pin do? Normally Namco tied it to VOL0 (with VOL1 = VCC).
- Acknowledge A9 bit (9th address bit) of host interface
- Verify data bus bits of C219
- Verify C219 LFSR algorithm (same as c352.cpp?)
- Verify unknown mode bits (0x40 for C140, 0x02 for C219)
--------------
@ -37,43 +42,44 @@ TODO: What does the INT0 pin do? Normally Namco tied it to VOL0 (with VOL1 = VCC
2000.06.26 CAB fixed compressed pcm playback
2002.07.20 R. Belmont added support for multiple banking types
2006.01.08 R. Belmont added support for NA-1/2 "219" derivative
2020.05.06 cam900 Implement some features from QuattroPlay sources, by superctr
*/
#include "emu.h"
#include "c140.h"
#include <algorithm>
struct voice_registers
{
uint8_t volume_right;
uint8_t volume_left;
uint8_t frequency_msb;
uint8_t frequency_lsb;
uint8_t bank;
uint8_t mode;
uint8_t start_msb;
uint8_t start_lsb;
uint8_t end_msb;
uint8_t end_lsb;
uint8_t loop_msb;
uint8_t loop_lsb;
uint8_t reserved[4];
u8 volume_right;
u8 volume_left;
u8 frequency_msb;
u8 frequency_lsb;
u8 bank;
u8 mode;
u8 start_msb;
u8 start_lsb;
u8 end_msb;
u8 end_lsb;
u8 loop_msb;
u8 loop_lsb;
u8 reserved[4];
};
// device type definition
DEFINE_DEVICE_TYPE(C140, c140_device, "c140", "Namco C140")
DEFINE_DEVICE_TYPE(C219, c219_device, "c219", "Namco C219")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
static inline int limit(int32_t in)
static inline int limit(s32 in)
{
if(in>0x7fff) return 0x7fff;
else if(in<-0x8000) return -0x8000;
return in;
return std::max(-0x7fff, std::min(0x8000, in));
}
@ -82,19 +88,29 @@ static inline int limit(int32_t in)
//-------------------------------------------------
c140_device::c140_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, C140, tag, owner, clock)
: c140_device(mconfig, C140, tag, owner, clock)
{
}
c140_device::c140_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, device_rom_interface(mconfig, *this, 21)
, device_rom_interface(mconfig, *this, 25, ENDIANNESS_BIG, 16) // Verified from schematics (24 bit address, 12(16? for C219) bit data)
, m_int1_callback(*this)
, m_sample_rate(0)
, m_stream(nullptr)
, m_banking_type(C140_TYPE::SYSTEM2)
, m_mixer_buffer_left(nullptr)
, m_mixer_buffer_right(nullptr)
, m_baserate(0)
{
memset(m_REG, 0, sizeof(uint8_t)*0x200);
memset(m_pcmtbl, 0, sizeof(int16_t)*8);
std::fill(std::begin(m_REG), std::end(m_REG), 0);
std::fill(std::begin(m_pcmtbl), std::end(m_pcmtbl), 0);
}
c219_device::c219_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: c140_device(mconfig, C219, tag, owner, clock)
{
// TODO: unknown address bus bits
}
@ -111,46 +127,76 @@ void c140_device::device_start()
m_stream = stream_alloc(0, 2, m_sample_rate);
/* make decompress pcm table */ //2000.06.26 CAB
int32_t segbase = 0;
for(int i = 0; i < 8; i++)
// make decompress pcm table (Verified from Wii Virtual Console Arcade Starblade)
for (int i = 0; i < 256; i++)
{
m_pcmtbl[i]=segbase; //segment base value
segbase += 16<<i;
int j = (s8)i;
s8 s1 = j & 7;
s8 s2 = abs(j >> 3) & 31;
m_pcmtbl[i] = 0x80 << s1 & 0xff00;
m_pcmtbl[i] += s2 << (s1 ? s1 + 3 : 4);
if (j < 0)
m_pcmtbl[i] = -m_pcmtbl[i];
}
memset(m_REG,0,sizeof(m_REG));
std::fill(std::begin(m_REG), std::end(m_REG), 0);
for(int i = 0; i < MAX_VOICE; i++)
for (int i = 0; i < MAX_VOICE; i++)
{
init_voice(&m_voi[i]);
}
/* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */
m_mixer_buffer_left = std::make_unique<int16_t[]>(m_sample_rate);
m_mixer_buffer_right = std::make_unique<int16_t[]>(m_sample_rate);
m_mixer_buffer_left = std::make_unique<s16[]>(m_sample_rate);
m_mixer_buffer_right = std::make_unique<s16[]>(m_sample_rate);
save_item(NAME(m_REG));
for (int i = 0; i < MAX_VOICE; i++)
{
save_item(NAME(m_voi[i].ptoffset), i);
save_item(NAME(m_voi[i].pos), i);
save_item(NAME(m_voi[i].key), i);
save_item(NAME(m_voi[i].lastdt), i);
save_item(NAME(m_voi[i].prevdt), i);
save_item(NAME(m_voi[i].dltdt), i);
save_item(NAME(m_voi[i].rvol), i);
save_item(NAME(m_voi[i].lvol), i);
save_item(NAME(m_voi[i].frequency), i);
save_item(NAME(m_voi[i].bank), i);
save_item(NAME(m_voi[i].mode), i);
save_item(NAME(m_voi[i].sample_start), i);
save_item(NAME(m_voi[i].sample_end), i);
save_item(NAME(m_voi[i].sample_loop), i);
}
save_item(STRUCT_MEMBER(m_voi, ptoffset));
save_item(STRUCT_MEMBER(m_voi, pos));
save_item(STRUCT_MEMBER(m_voi, key));
save_item(STRUCT_MEMBER(m_voi, lastdt));
save_item(STRUCT_MEMBER(m_voi, prevdt));
save_item(STRUCT_MEMBER(m_voi, dltdt));
save_item(STRUCT_MEMBER(m_voi, rvol));
save_item(STRUCT_MEMBER(m_voi, lvol));
save_item(STRUCT_MEMBER(m_voi, frequency));
save_item(STRUCT_MEMBER(m_voi, bank));
save_item(STRUCT_MEMBER(m_voi, mode));
save_item(STRUCT_MEMBER(m_voi, sample_start));
save_item(STRUCT_MEMBER(m_voi, sample_end));
save_item(STRUCT_MEMBER(m_voi, sample_loop));
}
void c219_device::device_start()
{
c140_device::device_start();
// generate mulaw table (Verified from Wii Virtual Console Arcade Knuckle Heads)
// same as c352.cpp
int j = 0;
for (int i = 0; i < 128; i++)
{
m_pcmtbl[i] = j << 5;
if (i < 16)
j += 1;
else if (i < 24)
j += 2;
else if (i < 48)
j += 4;
else if (i < 100)
j += 8;
else
j += 16;
}
for (int i = 0; i < 128; i++)
m_pcmtbl[i + 128] = (~m_pcmtbl[i]) & 0xffe0;
m_lfsr = 0x1234;
save_item(NAME(m_lfsr));
}
void c140_device::device_clock_changed()
{
@ -159,8 +205,8 @@ void c140_device::device_clock_changed()
m_stream->set_sample_rate(m_sample_rate);
/* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */
m_mixer_buffer_left = std::make_unique<int16_t[]>(m_sample_rate);
m_mixer_buffer_right = std::make_unique<int16_t[]>(m_sample_rate);;
m_mixer_buffer_left = std::make_unique<s16[]>(m_sample_rate);
m_mixer_buffer_right = std::make_unique<s16[]>(m_sample_rate);;
}
@ -176,181 +222,100 @@ void c140_device::rom_bank_updated()
void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
int i,j;
s32 dt;
int32_t rvol,lvol;
int32_t dt;
int32_t sdt;
int32_t st,ed,sz;
float pbase = (float)m_baserate * 2.0f / (float)m_sample_rate;
long sampleData;
int32_t frequency,delta,offset,pos;
int32_t cnt, voicecnt;
int32_t lastdt,prevdt,dltdt;
float pbase=(float)m_baserate*2.0f / (float)m_sample_rate;
s16 *lmix, *rmix;
int16_t *lmix, *rmix;
if(samples>m_sample_rate) samples=m_sample_rate;
if (samples > m_sample_rate) samples = m_sample_rate;
/* zap the contents of the mixer buffer */
memset(m_mixer_buffer_left.get(), 0, samples * sizeof(int16_t));
memset(m_mixer_buffer_right.get(), 0, samples * sizeof(int16_t));
/* get the number of voices to update */
voicecnt = (m_banking_type == C140_TYPE::ASIC219) ? 16 : 24;
std::fill_n(&m_mixer_buffer_left[0], samples, 0);
std::fill_n(&m_mixer_buffer_right[0], samples, 0);
//--- audio update
for( i=0;i<voicecnt;i++ )
for (int i = 0; i < 24; i++)
{
C140_VOICE *v = &m_voi[i];
const struct voice_registers *vreg = (struct voice_registers *)&m_REG[i*16];
const struct voice_registers *vreg = (struct voice_registers *)&m_REG[i * 16];
if( v->key )
if (v->key)
{
frequency= vreg->frequency_msb*256 + vreg->frequency_lsb;
const u16 frequency = (vreg->frequency_msb << 8) | vreg->frequency_lsb;
/* Abort voice if no frequency value set */
if(frequency==0) continue;
if (frequency == 0) continue;
/* Delta = frequency * ((8MHz/374)*2 / sample rate) */
delta=(long)((float)frequency * pbase);
const int delta = (int)((float)frequency * pbase);
/* Calculate left/right channel volumes */
lvol=(vreg->volume_left*32)/MAX_VOICE; //32ch -> 24ch
rvol=(vreg->volume_right*32)/MAX_VOICE;
const int lvol = (vreg->volume_left * 32) / MAX_VOICE; //32ch -> 24ch
const int rvol = (vreg->volume_right * 32) / MAX_VOICE;
/* Set mixer outputs base pointers */
lmix = m_mixer_buffer_left.get();
rmix = m_mixer_buffer_right.get();
/* Retrieve sample start/end and calculate size */
st=v->sample_start;
ed=v->sample_end;
sz=ed-st;
const int st = v->sample_start;
const int ed = v->sample_end;
const int sz = ed - st;
/* Retrieve base pointer to the sample data */
sampleData = find_sample(st, v->bank, i);
const int sampleData = find_sample(st, v->bank, i);
/* Fetch back previous data pointers */
offset=v->ptoffset;
pos=v->pos;
lastdt=v->lastdt;
prevdt=v->prevdt;
dltdt=v->dltdt;
int offset = v->ptoffset;
int pos = v->pos;
s32 lastdt = v->lastdt;
s32 prevdt = v->prevdt;
s32 dltdt = v->dltdt;
/* Switch on data type - compressed PCM is only for C140 */
if ((v->mode&8) && (m_banking_type != C140_TYPE::ASIC219))
/* linear or compressed 12bit signed PCM */
for (int j = 0; j < samples; j++)
{
//compressed PCM (maybe correct...)
/* Loop for enough to fill sample buffer as requested */
for(j=0;j<samples;j++)
offset += delta;
const int cnt = (offset >> 16) & 0x7fff;
offset &= 0xffff;
pos += cnt;
/* Check for the end of the sample */
if (pos >= sz)
{
offset += delta;
cnt = (offset>>16)&0x7fff;
offset &= 0xffff;
pos+=cnt;
//for(;cnt>0;cnt--)
/* Check if its a looping sample, either stop or loop */
if (ch_looped(v))
{
/* Check for the end of the sample */
if(pos >= sz)
{
/* Check if its a looping sample, either stop or loop */
if(v->mode&0x10)
{
pos = (v->sample_loop - st);
}
else
{
v->key=0;
break;
}
}
/* Read the chosen sample byte */
dt = (int8_t) read_byte(sampleData + pos);
/* decompress to 13bit range */ //2000.06.26 CAB
sdt=dt>>3; //signed
if(sdt<0) sdt = (sdt<<(dt&7)) - m_pcmtbl[dt&7];
else sdt = (sdt<<(dt&7)) + m_pcmtbl[dt&7];
prevdt=lastdt;
lastdt=sdt;
dltdt=(lastdt - prevdt);
pos = (v->sample_loop - st);
}
else
{
v->key = 0;
break;
}
/* Caclulate the sample value */
dt=((dltdt*offset)>>16)+prevdt;
/* Write the data to the sample buffers */
*lmix++ +=(dt*lvol)>>(5+5);
*rmix++ +=(dt*rvol)>>(5+5);
}
}
else
{
/* linear 8bit signed PCM */
for(j=0;j<samples;j++)
if (cnt)
{
offset += delta;
cnt = (offset>>16)&0x7fff;
offset &= 0xffff;
pos += cnt;
/* Check for the end of the sample */
if(pos >= sz)
{
/* Check if its a looping sample, either stop or loop */
if( v->mode&0x10 )
{
pos = (v->sample_loop - st);
}
else
{
v->key=0;
break;
}
}
if( cnt )
{
prevdt=lastdt;
if (m_banking_type == C140_TYPE::ASIC219)
{
lastdt = (int8_t) read_byte(sampleData + BYTE_XOR_BE(pos));
// Sign + magnitude format
if ((v->mode & 0x01) && (lastdt & 0x80))
lastdt = -(lastdt & 0x7f);
// Sign flip
if (v->mode & 0x40)
lastdt = -lastdt;
}
else
{
lastdt = (int8_t) read_byte(sampleData + pos);
}
dltdt = (lastdt - prevdt);
}
/* Caclulate the sample value */
dt=((dltdt*offset)>>16)+prevdt;
/* Write the data to the sample buffers */
*lmix++ +=(dt*lvol)>>5;
*rmix++ +=(dt*rvol)>>5;
prevdt = lastdt;
lastdt = ((ch_mulaw(v)) ? m_pcmtbl[read_byte((sampleData + pos) << 1)] : s16(read_word((sampleData + pos) << 1) & 0xfff0)) >> 4; // 12bit
dltdt = (lastdt - prevdt);
}
/* Caclulate the sample value */
dt = ((dltdt * offset) >> 16) + prevdt;
/* Write the data to the sample buffers */
*lmix++ += (dt * lvol) >> (5 + 4);
*rmix++ += (dt * rvol) >> (5 + 4);
}
/* Save positional data for next callback */
v->ptoffset=offset;
v->pos=pos;
v->lastdt=lastdt;
v->prevdt=prevdt;
v->dltdt=dltdt;
v->ptoffset = offset;
v->pos = pos;
v->lastdt = lastdt;
v->prevdt = prevdt;
v->dltdt = dltdt;
}
}
@ -360,9 +325,146 @@ void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
{
stream_sample_t *dest1 = outputs[0];
stream_sample_t *dest2 = outputs[1];
for (i = 0; i < samples; i++)
for (int i = 0; i < samples; i++)
{
int32_t val;
s32 val;
val = 8 * (*lmix++);
*dest1++ = limit(val);
val = 8 * (*rmix++);
*dest2++ = limit(val);
}
}
}
void c219_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
s32 dt;
float pbase = (float)m_baserate * 2.0f / (float)m_sample_rate;
s16 *lmix, *rmix;
if (samples > m_sample_rate) samples = m_sample_rate;
/* zap the contents of the mixer buffer */
std::fill_n(&m_mixer_buffer_left[0], samples, 0);
std::fill_n(&m_mixer_buffer_right[0], samples, 0);
//--- audio update
for (int i = 0; i < 16; i++)
{
C140_VOICE *v = &m_voi[i];
const struct voice_registers *vreg = (struct voice_registers *)&m_REG[i * 16];
if (v->key)
{
const u16 frequency = (vreg->frequency_msb << 8) | vreg->frequency_lsb;
/* Abort voice if no frequency value set */
if (frequency == 0) continue;
/* Delta = frequency * ((8MHz/374)*2 / sample rate) */
const int delta = (int)((float)frequency * pbase);
/* Calculate left/right channel volumes */
const int lvol = (vreg->volume_left * 32) / MAX_VOICE; //32ch -> 24ch
const int rvol = (vreg->volume_right * 32) / MAX_VOICE;
/* Set mixer outputs base pointers */
lmix = m_mixer_buffer_left.get();
rmix = m_mixer_buffer_right.get();
/* Retrieve sample start/end and calculate size */
const int st = v->sample_start;
const int ed = v->sample_end;
const int sz = ed - st;
/* Retrieve base pointer to the sample data */
const int sampleData = find_sample(st, v->bank, i);
/* Fetch back previous data pointers */
int offset = v->ptoffset;
int pos = v->pos;
s32 lastdt = v->lastdt;
s32 prevdt = v->prevdt;
s32 dltdt = v->dltdt;
/* linear or compressed 8bit signed PCM */
for (int j = 0; j < samples; j++)
{
offset += delta;
const int cnt = (offset >> 16) & 0x7fff;
offset &= 0xffff;
pos += cnt;
/* Check for the end of the sample */
if (pos >= sz)
{
/* Check if its a looping sample, either stop or loop */
if (ch_looped(v) || ch_noise(v))
{
pos = (v->sample_loop - st);
}
else
{
v->key = 0;
break;
}
}
const int shift = ch_noise(v) ? 8 : 3;
if (cnt)
{
prevdt = lastdt;
if (ch_noise(v)) // noise
{
m_lfsr = (m_lfsr >> 1) ^ ((-(m_lfsr & 1)) & 0xfff6);
lastdt = s16(m_lfsr);
}
else
{
lastdt = s8(read_byte(sampleData + pos));
// 11 bit mulaw
if (ch_mulaw(v))
lastdt = m_pcmtbl[lastdt & 0xff] >> 5;
else
lastdt <<= 3; // scale as 11bit
}
// Sign flip
if (ch_inv_sign(v))
lastdt = -lastdt;
dltdt = (lastdt - prevdt);
}
/* Caclulate the sample value */
dt = ((dltdt * offset) >> 16) + prevdt;
/* Write the data to the sample buffers */
*lmix++ += ((ch_inv_lout(v)) ? -(dt * lvol) : (dt * lvol)) >> (5 + shift);
*rmix++ += (dt * rvol) >> (5 + shift);
}
/* Save positional data for next callback */
v->ptoffset = offset;
v->pos = pos;
v->lastdt = lastdt;
v->prevdt = prevdt;
v->dltdt = dltdt;
}
}
/* render to MAME's stream buffer */
lmix = m_mixer_buffer_left.get();
rmix = m_mixer_buffer_right.get();
{
stream_sample_t *dest1 = outputs[0];
stream_sample_t *dest2 = outputs[1];
for (int i = 0; i < samples; i++)
{
s32 val;
val = 8 * (*lmix++);
*dest1++ = limit(val);
@ -375,7 +477,7 @@ void c140_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
u8 c140_device::c140_r(offs_t offset)
{
offset&=0x1ff;
offset &= 0x1ff;
return m_REG[offset];
}
@ -384,58 +486,38 @@ void c140_device::c140_w(offs_t offset, u8 data)
{
m_stream->update();
offset&=0x1ff;
offset &= 0x1ff;
// mirror the bank registers on the 219, fixes bkrtmaq (and probably xday2 based on notes in the HLE)
if ((offset >= 0x1f8) && BIT(offset, 0) && (m_banking_type == C140_TYPE::ASIC219))
m_REG[offset] = data;
if (offset < 0x180)
{
offset -= 8;
}
const u8 ch = offset >> 4;
C140_VOICE *v = &m_voi[ch];
m_REG[offset]=data;
if( offset<0x180 )
{
C140_VOICE *v = &m_voi[offset>>4];
if( (offset&0xf)==0x5 )
if ((offset & 0xf) == 0x5)
{
if( data&0x80 )
if (data & 0x80)
{
const struct voice_registers *vreg = (struct voice_registers *) &m_REG[offset&0x1f0];
v->key=1;
v->ptoffset=0;
v->pos=0;
v->lastdt=0;
v->prevdt=0;
v->dltdt=0;
const struct voice_registers *vreg = (struct voice_registers *) &m_REG[offset & 0x1f0];
v->key = 1;
v->ptoffset = 0;
v->pos = 0;
v->lastdt = 0;
v->prevdt = 0;
v->dltdt = 0;
v->bank = vreg->bank;
v->mode = data;
// on the 219 asic, addresses are in words
if (m_banking_type == C140_TYPE::ASIC219)
{
v->sample_loop = (vreg->loop_msb*256 + vreg->loop_lsb)*2;
v->sample_start = (vreg->start_msb*256 + vreg->start_lsb)*2;
v->sample_end = (vreg->end_msb*256 + vreg->end_lsb)*2;
#if 0
logerror("219: play v %d mode %02x start %x loop %x end %x\n",
offset>>4, v->mode,
find_sample(v->sample_start, v->bank, offset>>4),
find_sample(v->sample_loop, v->bank, offset>>4),
find_sample(v->sample_end, v->bank, offset>>4));
#endif
}
else
{
v->sample_loop = vreg->loop_msb*256 + vreg->loop_lsb;
v->sample_start = vreg->start_msb*256 + vreg->start_lsb;
v->sample_end = vreg->end_msb*256 + vreg->end_lsb;
}
const u32 loop = (vreg->loop_msb << 8) + vreg->loop_lsb;
const u32 start = (vreg->start_msb << 8) + vreg->start_lsb;
const u32 end = (vreg->end_msb << 8) + vreg->end_lsb;
v->sample_loop = loop;
v->sample_start = start;
v->sample_end = end;
}
else
{
v->key=0;
v->key = 0;
}
}
}
@ -466,61 +548,108 @@ void c140_device::c140_w(offs_t offset, u8 data)
}
u8 c219_device::c219_r(offs_t offset)
{
offset &= 0x1ff;
return m_REG[offset];
}
void c219_device::c219_w(offs_t offset, u8 data)
{
m_stream->update();
offset &= 0x1ff;
// mirror the bank registers on the 219, fixes bkrtmaq (and probably xday2 based on notes in the HLE)
if ((offset >= 0x1f8) && BIT(offset, 0))
{
offset -= 8;
}
m_REG[offset] = data;
if (offset < 0x100) // only 16 voices
{
const u8 ch = offset >> 4;
C140_VOICE *v = &m_voi[ch];
if ((offset & 0xf) == 0x5)
{
if (data & 0x80)
{
const struct voice_registers *vreg = (struct voice_registers *) &m_REG[offset & 0x1f0];
v->key = 1;
v->ptoffset = 0;
v->pos = 0;
v->lastdt = 0;
v->prevdt = 0;
v->dltdt = 0;
v->bank = vreg->bank;
v->mode = data;
const u32 loop = (vreg->loop_msb << 8) + vreg->loop_lsb;
const u32 start = (vreg->start_msb << 8) + vreg->start_lsb;
const u32 end = (vreg->end_msb << 8) + vreg->end_lsb;
// on the 219 asic, addresses are in words
v->sample_loop = loop << 1;
v->sample_start = start << 1;
v->sample_end = end << 1;
#if 0
logerror("219: play v %d mode %02x start %x loop %x end %x\n",
ch, v->mode,
find_sample(v->sample_start, v->bank, ch),
find_sample(v->sample_loop, v->bank, ch),
find_sample(v->sample_end, v->bank, ch));
#endif
}
else
{
v->key = 0;
}
}
}
// TODO: No interrupt/timers?
}
TIMER_CALLBACK_MEMBER(c140_device::int1_on)
{
m_int1_callback(ASSERT_LINE);
}
void c140_device::init_voice( C140_VOICE *v )
void c140_device::init_voice(C140_VOICE *v)
{
v->key=0;
v->ptoffset=0;
v->rvol=0;
v->lvol=0;
v->frequency=0;
v->bank=0;
v->mode=0;
v->sample_start=0;
v->sample_end=0;
v->sample_loop=0;
v->key = 0;
v->ptoffset = 0;
v->rvol = 0;
v->lvol = 0;
v->frequency = 0;
v->bank = 0;
v->mode = 0;
v->sample_start = 0;
v->sample_end = 0;
v->sample_loop = 0;
}
/*
find_sample: compute the actual address of a sample given it's
address and banking registers, as well as the board type.
I suspect in "real life" this works like the Sega MultiPCM where the banking
is done by a small PAL or GAL external to the sound chip, which can be switched
per-game or at least per-PCB revision as addressing range needs grow.
address and banking registers, as well as the chip type.
*/
long c140_device::find_sample(long adrs, long bank, int voice)
int c140_device::find_sample(int adrs, int bank, int voice)
{
long newadr = 0;
adrs = (bank << 16) + adrs;
static const int16_t asic219banks[4] = { 0x1f7, 0x1f1, 0x1f3, 0x1f5 };
adrs=(bank<<16)+adrs;
switch (m_banking_type)
{
case C140_TYPE::SYSTEM2:
// System 2 banking
newadr = ((adrs&0x200000)>>2)|(adrs&0x7ffff);
break;
case C140_TYPE::SYSTEM21:
// System 21 banking.
// similar to System 2's.
newadr = ((adrs&0x300000)>>1)+(adrs&0x7ffff);
break;
case C140_TYPE::ASIC219:
// ASIC219's banking is fairly simple
newadr = ((m_REG[asic219banks[voice/4]]&0x3) * 0x20000) + adrs;
break;
}
return (newadr);
return adrs;
}
int c219_device::find_sample(int adrs, int bank, int voice)
{
static const s16 asic219banks[4] = { 0x1f7, 0x1f1, 0x1f3, 0x1f5 };
adrs = (bank << 16) + adrs;
// ASIC219's banking is fairly simple
return ((m_REG[asic219banks[voice / 4]] & 0x3) * 0x20000) + adrs;
}

View File

@ -1,6 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/* C140.h */
/* c140.h */
#ifndef MAME_SOUND_C140_H
#define MAME_SOUND_C140_H
@ -20,23 +20,21 @@ class c140_device : public device_t,
public device_rom_interface
{
public:
enum class C140_TYPE
{
SYSTEM2,
SYSTEM21,
ASIC219
};
c140_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration
void set_bank_type(C140_TYPE bank) { m_banking_type = bank; }
auto int1_callback() { return m_int1_callback.bind(); }
u8 c140_r(offs_t offset);
void c140_w(offs_t offset, u8 data);
// little endian: Swap even and odd word
u8 c140_le_r(offs_t offset) { return c140_r(offset ^ 1); }
void c140_le_w(offs_t offset, u8 data) { c140_w(offset ^ 1, data);}
protected:
c140_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_clock_changed() override;
@ -46,34 +44,38 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
private:
virtual int find_sample(int adrs, int bank, int voice);
static constexpr unsigned MAX_VOICE = 24;
struct C140_VOICE
{
C140_VOICE() { }
int32_t ptoffset = 0;
int32_t pos = 0;
int32_t key = 0;
s32 ptoffset = 0;
s32 pos = 0;
s32 key = 0;
//--work
int32_t lastdt = 0;
int32_t prevdt = 0;
int32_t dltdt = 0;
s32 lastdt = 0;
s32 prevdt = 0;
s32 dltdt = 0;
//--reg
int32_t rvol = 0;
int32_t lvol = 0;
int32_t frequency = 0;
int32_t bank = 0;
int32_t mode = 0;
s32 rvol = 0;
s32 lvol = 0;
s32 frequency = 0;
s32 bank = 0;
s32 mode = 0;
int32_t sample_start = 0;
int32_t sample_end = 0;
int32_t sample_loop = 0;
s32 sample_start = 0;
s32 sample_end = 0;
s32 sample_loop = 0;
};
void init_voice( C140_VOICE *v );
long find_sample(long adrs, long bank, int voice);
void init_voice(C140_VOICE *v);
const inline bool ch_looped(C140_VOICE *v) { return BIT(v->mode, 4); } // shared as c140 and c219
virtual const inline bool ch_mulaw(C140_VOICE *v) { return BIT(v->mode, 3); }
// bit 6 used, unknown
TIMER_CALLBACK_MEMBER(int1_on);
@ -81,21 +83,51 @@ private:
int m_sample_rate;
sound_stream *m_stream;
C140_TYPE m_banking_type;
/* internal buffers */
std::unique_ptr<int16_t[]> m_mixer_buffer_left;
std::unique_ptr<int16_t[]> m_mixer_buffer_right;
std::unique_ptr<s16[]> m_mixer_buffer_left;
std::unique_ptr<s16[]> m_mixer_buffer_right;
int m_baserate;
uint8_t m_REG[0x200];
u8 m_REG[0x200];
int16_t m_pcmtbl[8]; //2000.06.26 CAB
s16 m_pcmtbl[256]; //2000.06.26 CAB
C140_VOICE m_voi[MAX_VOICE];
emu_timer *m_int1_timer;
};
class c219_device : public c140_device
{
public:
c219_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
u8 c219_r(offs_t offset);
void c219_w(offs_t offset, u8 data);
// little endian: Swap even and odd word
u8 c219_le_r(offs_t offset) { return c219_r(offset ^ 1); }
void c219_le_w(offs_t offset, u8 data) { c219_w(offset ^ 1, data);}
protected:
// device-level overrides
virtual void device_start() override;
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
virtual int find_sample(int adrs, int bank, int voice) override;
virtual const inline bool ch_mulaw(C140_VOICE *v) override { return BIT(v->mode, 0); }
private:
// bit 1 used, unknown
const inline bool ch_noise(C140_VOICE *v) { return BIT(v->mode, 2); }
const inline bool ch_inv_lout(C140_VOICE *v) { return BIT(v->mode, 3); }
const inline bool ch_inv_sign(C140_VOICE *v) { return BIT(v->mode, 6); }
u16 m_lfsr;
};
DECLARE_DEVICE_TYPE(C140, c140_device)
DECLARE_DEVICE_TYPE(C219, c219_device)
#endif // MAME_SOUND_C140_H

View File

@ -27,7 +27,7 @@
#if C352_LOG_PCM
#include <map>
static std::map<uint32_t, bool> s_found_pcm;
static std::map<u32, bool> s_found_pcm;
#endif
// device type definition
@ -41,7 +41,7 @@ DEFINE_DEVICE_TYPE(C352, c352_device, "c352", "Namco C352")
// c352_device - constructor
//-------------------------------------------------
c352_device::c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
c352_device::c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, C352, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, device_rom_interface(mconfig, *this, 24)
@ -69,14 +69,14 @@ void c352_device::fetch_sample(c352_voice_t& v)
}
else
{
int8_t s = (int8_t)read_byte(v.pos);
s8 s = (s8)read_byte(v.pos);
if (v.flags & C352_FLG_MULAW)
v.sample = m_mulawtab[s & 0xff];
else
v.sample = s << 8;
uint16_t pos = v.pos & 0xffff;
u16 pos = v.pos & 0xffff;
if ((v.flags & C352_FLG_LOOP) && v.flags & C352_FLG_REVERSE)
{
@ -115,9 +115,9 @@ void c352_device::fetch_sample(c352_voice_t& v)
}
}
void c352_device::ramp_volume(c352_voice_t &v, int ch, uint8_t val)
void c352_device::ramp_volume(c352_voice_t &v, int ch, u8 val)
{
int16_t vol_delta = v.curr_vol[ch] - val;
s16 vol_delta = v.curr_vol[ch] - val;
if (vol_delta != 0)
v.curr_vol[ch] += (vol_delta > 0) ? -1 : 1;
}
@ -131,16 +131,16 @@ void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
for (int i = 0; i < samples; i++)
{
long out[4] = { 0, 0, 0, 0 };
int out[4] = { 0, 0, 0, 0 };
for (int j = 0; j < 32; j++)
{
c352_voice_t &v = m_c352_v[j];
int16_t s = 0;
s16 s = 0;
if (v.flags & C352_FLG_BUSY)
{
int32_t next_counter = v.counter + v.freq;
s32 next_counter = v.counter + v.freq;
if (next_counter & 0x10000)
{
@ -173,32 +173,32 @@ void c352_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
out[3] += (((v.flags & C352_FLG_PHASEFR) ? -s : s) * v.curr_vol[3]) >> 8;
}
*buffer_fl++ = (int16_t)(out[0] >> 3);
*buffer_fr++ = (int16_t)(out[1] >> 3);
*buffer_rl++ = (int16_t)(out[2] >> 3);
*buffer_rr++ = (int16_t)(out[3] >> 3);
*buffer_fl++ = (s16)(out[0] >> 3);
*buffer_fr++ = (s16)(out[1] >> 3);
*buffer_rl++ = (s16)(out[2] >> 3);
*buffer_rr++ = (s16)(out[3] >> 3);
}
}
uint16_t c352_device::read_reg16(unsigned long address)
u16 c352_device::read_reg16(offs_t offset)
{
m_stream->update();
const int reg_map[8] =
{
offsetof(c352_voice_t, vol_f) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_r) / sizeof(uint16_t),
offsetof(c352_voice_t, freq) / sizeof(uint16_t),
offsetof(c352_voice_t, flags) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_bank) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_start) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_end) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_loop) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_f) / sizeof(u16),
offsetof(c352_voice_t, vol_r) / sizeof(u16),
offsetof(c352_voice_t, freq) / sizeof(u16),
offsetof(c352_voice_t, flags) / sizeof(u16),
offsetof(c352_voice_t, wave_bank) / sizeof(u16),
offsetof(c352_voice_t, wave_start) / sizeof(u16),
offsetof(c352_voice_t, wave_end) / sizeof(u16),
offsetof(c352_voice_t, wave_loop) / sizeof(u16),
};
if (address < 0x100)
return *((uint16_t*)&m_c352_v[address / 8] + reg_map[address % 8]);
else if (address == 0x200)
if (offset < 0x100)
return *((u16*)&m_c352_v[offset / 8] + reg_map[offset % 8]);
else if (offset == 0x200)
return m_control;
else
return 0;
@ -206,33 +206,38 @@ uint16_t c352_device::read_reg16(unsigned long address)
return 0;
}
void c352_device::write_reg16(unsigned long address, unsigned short val)
void c352_device::write_reg16(offs_t offset, u16 data, u16 mem_mask)
{
m_stream->update();
const int reg_map[8] =
{
offsetof(c352_voice_t, vol_f) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_r) / sizeof(uint16_t),
offsetof(c352_voice_t, freq) / sizeof(uint16_t),
offsetof(c352_voice_t, flags) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_bank) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_start) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_end) / sizeof(uint16_t),
offsetof(c352_voice_t, wave_loop) / sizeof(uint16_t),
offsetof(c352_voice_t, vol_f) / sizeof(u16),
offsetof(c352_voice_t, vol_r) / sizeof(u16),
offsetof(c352_voice_t, freq) / sizeof(u16),
offsetof(c352_voice_t, flags) / sizeof(u16),
offsetof(c352_voice_t, wave_bank) / sizeof(u16),
offsetof(c352_voice_t, wave_start) / sizeof(u16),
offsetof(c352_voice_t, wave_end) / sizeof(u16),
offsetof(c352_voice_t, wave_loop) / sizeof(u16),
};
if (address < 0x100)
if (offset < 0x100)
{
*((uint16_t*)&m_c352_v[address / 8] + reg_map[address % 8]) = val;
u16 newval = read_reg16(offset);
COMBINE_DATA(&newval);
*((u16*)&m_c352_v[offset / 8] + reg_map[offset % 8]) = newval;
}
else if (address == 0x200)
else if (offset == 0x200)
{
m_control = val;
logerror("C352 control register write: %04x\n",val);
COMBINE_DATA(&m_control);
logerror("C352 control register write: %04x & %04x\n", data, mem_mask);
}
else if (address == 0x202) // execute keyons/keyoffs
else if (offset == 0x202) // execute keyons/keyoffs
{
if (mem_mask != 0xffff) // 16 bit only?
return;
for (int i = 0; i < 32; i++)
{
if (m_c352_v[i].flags & C352_FLG_KEYON)
@ -252,7 +257,7 @@ void c352_device::write_reg16(unsigned long address, unsigned short val)
#if C352_LOG_PCM
if (!(m_c352_v[i].flags & C352_FLG_NOISE))
{
std::map<uint32_t, bool>::iterator iter = s_found_pcm.find(m_c352_v[i].pos);
std::map<u32, bool>::iterator iter = s_found_pcm.find(m_c352_v[i].pos);
if (iter != s_found_pcm.end())
{
return;
@ -266,27 +271,27 @@ void c352_device::write_reg16(unsigned long address, unsigned short val)
if (file != nullptr)
{
c352_voice_t &v = m_c352_v[i];
uint32_t pos = v.pos;
uint32_t flags = v.flags;
uint32_t counter = v.counter;
int16_t sample = 0;
u32 pos = v.pos;
u32 flags = v.flags;
u32 counter = v.counter;
s16 sample = 0;
while (pos != v.wave_end && !(flags & C352_FLG_KEYOFF))
{
int32_t next_counter = counter + v.freq;
s32 next_counter = counter + v.freq;
if (next_counter & 0x10000)
{
counter = next_counter & 0xffff;
int8_t s = (int8_t)read_byte(pos);
s8 s = (s8)read_byte(pos);
if (v.flags & C352_FLG_MULAW)
sample = m_mulawtab[s & 0xff];
else
sample = s << 8;
uint16_t subpos = pos & 0xffff;
u16 subpos = pos & 0xffff;
if ((flags & C352_FLG_LOOP) && flags & C352_FLG_REVERSE)
{
@ -382,22 +387,20 @@ void c352_device::device_start()
m_mulawtab[i + 128] = (~m_mulawtab[i]) & 0xffe0;
// register save state info
for (int i = 0; i < 32; i++)
{
save_item(NAME(m_c352_v[i].pos), i);
save_item(NAME(m_c352_v[i].counter), i);
save_item(NAME(m_c352_v[i].sample), i);
save_item(NAME(m_c352_v[i].last_sample), i);
save_item(NAME(m_c352_v[i].vol_f), i);
save_item(NAME(m_c352_v[i].vol_r), i);
save_item(NAME(m_c352_v[i].curr_vol), i);
save_item(NAME(m_c352_v[i].freq), i);
save_item(NAME(m_c352_v[i].flags), i);
save_item(NAME(m_c352_v[i].wave_bank), i);
save_item(NAME(m_c352_v[i].wave_start), i);
save_item(NAME(m_c352_v[i].wave_end), i);
save_item(NAME(m_c352_v[i].wave_loop), i);
}
save_item(STRUCT_MEMBER(m_c352_v, pos));
save_item(STRUCT_MEMBER(m_c352_v, counter));
save_item(STRUCT_MEMBER(m_c352_v, sample));
save_item(STRUCT_MEMBER(m_c352_v, last_sample));
save_item(STRUCT_MEMBER(m_c352_v, vol_f));
save_item(STRUCT_MEMBER(m_c352_v, vol_r));
save_item(STRUCT_MEMBER(m_c352_v, curr_vol));
save_item(STRUCT_MEMBER(m_c352_v, freq));
save_item(STRUCT_MEMBER(m_c352_v, flags));
save_item(STRUCT_MEMBER(m_c352_v, wave_bank));
save_item(STRUCT_MEMBER(m_c352_v, wave_start));
save_item(STRUCT_MEMBER(m_c352_v, wave_end));
save_item(STRUCT_MEMBER(m_c352_v, wave_loop));
save_item(NAME(m_random));
save_item(NAME(m_control));
}
@ -419,12 +422,5 @@ READ16_MEMBER( c352_device::read )
WRITE16_MEMBER( c352_device::write )
{
if (mem_mask == 0xffff)
{
write_reg16(offset, data);
}
else
{
logerror("C352: byte-wide write unsupported at this time!\n");
}
write_reg16(offset, data, mem_mask);
}

View File

@ -18,13 +18,13 @@ class c352_device : public device_t,
{
public:
// construction/destruction
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, int divider)
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, int divider)
: c352_device(mconfig, tag, owner, clock)
{
set_divider(divider);
}
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void set_divider(int divider) { m_divider = divider; }
@ -67,31 +67,31 @@ private:
struct c352_voice_t
{
uint32_t pos;
uint32_t counter;
u32 pos;
u32 counter;
int16_t sample;
int16_t last_sample;
s16 sample;
s16 last_sample;
uint16_t vol_f;
uint16_t vol_r;
uint8_t curr_vol[4];
u16 vol_f;
u16 vol_r;
u8 curr_vol[4];
uint16_t freq;
uint16_t flags;
u16 freq;
u16 flags;
uint16_t wave_bank;
uint16_t wave_start;
uint16_t wave_end;
uint16_t wave_loop;
u16 wave_bank;
u16 wave_start;
u16 wave_end;
u16 wave_loop;
};
void fetch_sample(c352_voice_t &v);
void ramp_volume(c352_voice_t &v, int ch, uint8_t val);
void ramp_volume(c352_voice_t &v, int ch, u8 val);
unsigned short read_reg16(unsigned long address);
void write_reg16(unsigned long address, unsigned short val);
u16 read_reg16(offs_t offset);
void write_reg16(offs_t offset, u16 data, u16 mem_mask = 0);
sound_stream *m_stream;
@ -100,10 +100,10 @@ private:
c352_voice_t m_c352_v[32];
int16_t m_mulawtab[256];
s16 m_mulawtab[256];
uint16_t m_random;
uint16_t m_control; // control flags, purpose unknown.
u16 m_random;
u16 m_control; // control flags, purpose unknown.
};

View File

@ -16,8 +16,6 @@
#pragma once
#include "machine/rescap.h"
/*
* ATARI Pokey (CO12294) pin-out
*

View File

@ -661,17 +661,17 @@ void scn2674_device::write_delayed_command(uint8_t data)
{
case 0xa4:
// read at pointer address
m_char_buffer = m_char_space->read_byte(m_screen2_address);
m_char_buffer = m_char_space->read_byte(m_display_pointer_address);
if (m_attr_space != nullptr)
m_attr_buffer = m_attr_space->read_byte(m_screen2_address);
m_attr_buffer = m_attr_space->read_byte(m_display_pointer_address);
LOGMASKED(LOG_COMMAND, "%s: DELAYED read at pointer address %02x\n", machine().describe_context(), data);
break;
case 0xa2:
// write at pointer address
m_char_space->write_byte(m_screen2_address, m_char_buffer);
m_char_space->write_byte(m_display_pointer_address, m_char_buffer);
if (m_attr_space != nullptr)
m_attr_space->write_byte(m_screen2_address, m_attr_buffer);
m_attr_space->write_byte(m_display_pointer_address, m_attr_buffer);
LOGMASKED(LOG_COMMAND, "%s: DELAYED write at pointer address %02x\n", machine().describe_context(), data);
break;
@ -730,7 +730,7 @@ void scn2674_device::write_delayed_command(uint8_t data)
m_display_enabled = false;
m_display_enabled_field = true;
m_display_enabled_scanline = false;
for (i = m_cursor_address; i != m_screen2_address; i = ((i + 1) & 0xffff))
for (i = m_cursor_address; i != m_display_pointer_address; i = ((i + 1) & 0xffff))
{
m_char_space->write_byte(i, m_char_buffer);
if (m_attr_space != nullptr)
@ -739,7 +739,7 @@ void scn2674_device::write_delayed_command(uint8_t data)
m_char_space->write_byte(i, m_char_buffer); // get the last
if (m_attr_space != nullptr)
m_attr_space->write_byte(i, m_attr_buffer);
m_cursor_address = m_screen2_address;
m_cursor_address = m_display_pointer_address;
LOGMASKED(LOG_COMMAND, "%s: DELAYED write from cursor address to pointer address %02x\n", machine().describe_context(), data);
break;
@ -963,15 +963,30 @@ void scn2674_device::write(offs_t offset, uint8_t data)
break;
case 6:
m_screen2_address = (m_screen2_address & 0x3f00) | data;
break;
case 7:
write_screen2_address(BIT(offset, 0), data);
break;
}
}
void scn2674_device::write_screen2_address(bool msb, uint8_t data)
{
if (msb)
{
m_screen2_address = (m_screen2_address & 0x00ff) | (data & 0x3f) << 8;
m_spl[0] = BIT(data, 6);
m_spl[1] = BIT(data, 7);
break;
}
else
m_screen2_address = (m_screen2_address & 0x3f00) | data;
}
void scn2672_device::write_screen2_address(bool msb, uint8_t data)
{
if (msb)
m_display_pointer_address = (m_display_pointer_address & 0x00ff) | (data & 0x3f) << 8;
else
m_display_pointer_address = (m_display_pointer_address & 0x3f00) | data;
}
void scn2674_device::recompute_parameters()

View File

@ -119,6 +119,7 @@ protected:
void write_interrupt_mask(bool enabled, uint8_t bits);
void write_delayed_command(uint8_t data);
void write_command(uint8_t data);
virtual void write_screen2_address(bool msb, uint8_t data);
void recompute_parameters();
@ -141,6 +142,7 @@ public:
protected:
virtual void write_init_regs(uint8_t data) override;
virtual void write_screen2_address(bool msb, uint8_t data) override;
};

View File

@ -0,0 +1,116 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Epson SED1500 series LCD Driver
128 bytes internal RAM.
SED1500: 8 commons, 42 segments
SED1501: 10 commons, 40 segments
SED1502: 16 commons, 34 segments
SED1503: 8 commons, 42 segments, needs multiple of 2 chips to function
The default input OSC frequency is 32768Hz, the frame output frequency is
divided by 64 and by number of commons, eg. 64Hz on a SED1500.
TODO:
- bus mode (only mode 3 now)
- EI pin (master/slave mode)
- SYNC pin, used for frame synchronizing if multiple chips are used
- SED1503 only has 8 COM pins, the extra 8 outputs are from the slave chip
*/
#include "emu.h"
#include "video/sed1500.h"
DEFINE_DEVICE_TYPE(SED1500, sed1500_device, "sed1500", "Epson SED1500 LCD Driver")
DEFINE_DEVICE_TYPE(SED1501, sed1501_device, "sed1501", "Epson SED1501 LCD Driver")
DEFINE_DEVICE_TYPE(SED1502, sed1502_device, "sed1502", "Epson SED1502 LCD Driver")
DEFINE_DEVICE_TYPE(SED1503, sed1503_device, "sed1503", "Epson SED1503 LCD Driver")
//-------------------------------------------------
// constructor
//-------------------------------------------------
sed1500_device::sed1500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cmax, u8 smax) :
device_t(mconfig, type, tag, owner, clock),
m_cmax(cmax), m_smax(smax),
m_write_segs(*this)
{ }
sed1500_device::sed1500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1500, tag, owner, clock, 8, 42)
{ }
sed1501_device::sed1501_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1501, tag, owner, clock, 10, 40)
{ }
sed1502_device::sed1502_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1502, tag, owner, clock, 16, 34)
{ }
sed1503_device::sed1503_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
sed1500_device(mconfig, SED1503, tag, owner, clock, 8+8, 42)
{ }
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sed1500_device::device_start()
{
memset(m_ram, 0, sizeof(m_ram));
// resolve callbacks
m_write_segs.resolve_safe();
// timer
m_lcd_timer = timer_alloc();
attotime period = attotime::from_hz(clock() / 64);
m_lcd_timer->adjust(period, 0, period);
// register for savestates
save_item(NAME(m_mode));
save_item(NAME(m_cout));
save_item(NAME(m_ram));
}
//-------------------------------------------------
// handlers
//-------------------------------------------------
void sed1500_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
u64 data = 0;
for (int i = m_smax-1; i >= 0; i--)
data = data << 1 | BIT(m_ram[i | 0x40] << 8 | m_ram[i], m_cout);
// transfer segments to output
m_write_segs(m_cout, data);
m_cout = (m_cout + 1) % m_cmax;
}
void sed1500_device::write(offs_t offset, u8 data)
{
offset &= 0x7f;
m_ram[offset] = data;
// bus mode command:
// 0 = 4-bit addr, 4-bit data, combined
// 1 = 7-bit addr, 4-bit data, separate
// 2 = 7-bit addr, 8-bit data, combined
// 3 = 7-bit addr, 8-bit data, separate
if ((offset & 0x3f) == 0x3f && ~data & 1)
m_mode = data >> 1 & 3;
}
u8 sed1500_device::read(offs_t offset)
{
return m_ram[offset & 0x7f];
}

View File

@ -0,0 +1,85 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Epson SED1500 series LCD Driver
*/
#ifndef MAME_VIDEO_SED1500_H
#define MAME_VIDEO_SED1500_H
#pragma once
/*
pinout reference (brief)
OSC: oscillator (resistors or XTAL)
A0-A6: address
D0-D7: data (I/O)
WR/RD: write/read signal
CS: chip select
SYNC: frame synchronize (I/O)
CL: OSC output
COM: LCD commons
SEG: LCD segments
*/
class sed1500_device : public device_t
{
public:
sed1500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
auto write_segs() { return m_write_segs.bind(); } // common number in offset, segment data in data
void write(offs_t offset, u8 data);
u8 read(offs_t offset);
protected:
sed1500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cmax, u8 smax);
// device-level overrides
virtual void device_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
emu_timer *m_lcd_timer;
const u8 m_cmax; // number of COL pins
const u8 m_smax; // number of SEG pins
u8 m_mode = 0;
u8 m_cout = 0;
u8 m_ram[0x80];
// callbacks
devcb_write64 m_write_segs;
};
class sed1501_device : public sed1500_device
{
public:
sed1501_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class sed1502_device : public sed1500_device
{
public:
sed1502_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class sed1503_device : public sed1500_device
{
public:
sed1503_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
DECLARE_DEVICE_TYPE(SED1500, sed1500_device)
DECLARE_DEVICE_TYPE(SED1501, sed1501_device)
DECLARE_DEVICE_TYPE(SED1502, sed1502_device)
DECLARE_DEVICE_TYPE(SED1503, sed1503_device)
#endif // MAME_VIDEO_SED1500_H

View File

@ -153,3 +153,20 @@ const char *attotime::as_string(int precision) const
}
return buffer;
}
//-------------------------------------------------
// to_string - return a human-readable string
// describing an attotime for use in logs
//-------------------------------------------------
std::string attotime::to_string() const
{
attotime t = *this;
const char *sign = "";
if(t.seconds() < 0) {
t = attotime::zero-t;
sign = "-";
}
int nsec = t.attoseconds() / ATTOSECONDS_PER_NANOSECOND;
return util::string_format("%s%04d.%03d,%03d,%03d", sign, int(t.seconds()), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
}

View File

@ -122,6 +122,9 @@ public:
/** Convert to string using at @p precision */
const char *as_string(int precision = 9) const;
/** Convert to string for human readability in logs */
std::string to_string() const;
/** @return the attoseconds portion. */
constexpr attoseconds_t attoseconds() const noexcept { return m_attoseconds; }
/** @return the seconds portion. */

View File

@ -157,8 +157,8 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("gv", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1, _2));
m_console.register_command("gint", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1, _2));
m_console.register_command("gi", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1, _2));
m_console.register_command("gex", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_exception, this, _1, _2));
m_console.register_command("ge", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_exception, this, _1, _2));
m_console.register_command("gex", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1, _2));
m_console.register_command("ge", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1, _2));
m_console.register_command("gtime", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1, _2));
m_console.register_command("gt", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1, _2));
m_console.register_command("gp", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1, _2));
@ -899,7 +899,11 @@ void debugger_commands::execute_go_exception(int ref, const std::vector<std::str
if (params.size() > 0 && !validate_number_parameter(params[0], exception))
return;
m_cpu.get_visible_cpu()->debug()->go_exception(exception);
parsed_expression condition(m_cpu.get_visible_cpu()->debug()->symtable());
if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition))
return;
m_cpu.get_visible_cpu()->debug()->go_exception(exception, (condition.is_empty()) ? "1" : condition.original_string());
}

View File

@ -1146,8 +1146,15 @@ void debugger_cpu::start_hook(device_t *device, bool stop_on_vblank)
assert(m_livecpu == nullptr);
m_livecpu = device;
// can't stop on a device without a state interface
if (m_execution_state == exec_state::STOPPED && dynamic_cast<device_state_interface *>(device) == nullptr)
{
if (m_stop_when_not_device == nullptr)
m_stop_when_not_device = device;
m_execution_state = exec_state::RUNNING;
}
// if we're a new device, stop now
if (m_stop_when_not_device != nullptr && m_stop_when_not_device != device)
else if (m_stop_when_not_device != nullptr && m_stop_when_not_device != device && device->debug()->observing())
{
m_stop_when_not_device = nullptr;
m_execution_state = exec_state::STOPPED;
@ -1163,7 +1170,7 @@ void debugger_cpu::start_hook(device_t *device, bool stop_on_vblank)
m_machine.debug_view().flush_osd_updates();
m_last_periodic_update_time = osd_ticks();
}
else if (device == m_breakcpu)
if (device == m_breakcpu)
{ // check for pending breaks
m_execution_state = exec_state::STOPPED;
m_breakcpu = nullptr;
@ -1183,7 +1190,10 @@ void debugger_cpu::start_hook(device_t *device, bool stop_on_vblank)
}
// check for debug keypresses
if (m_machine.ui_input().pressed(IPT_UI_DEBUG_BREAK))
{
m_visiblecpu->debug()->ignore(false);
m_visiblecpu->debug()->halt_on_next_instruction("User-initiated break\n");
}
}
}
@ -1191,6 +1201,13 @@ void debugger_cpu::stop_hook(device_t *device)
{
assert(m_livecpu == device);
// if we are supposed to be stopped at this point (most likely because of a watchpoint), keep going until this CPU is live again
if (m_execution_state == exec_state::STOPPED)
{
m_breakcpu = device;
m_execution_state = exec_state::RUNNING;
}
// clear the live CPU
m_livecpu = nullptr;
}
@ -1492,9 +1509,25 @@ void device_debug::exception_hook(int exception)
// see if this matches an exception breakpoint
if ((m_flags & DEBUG_FLAG_STOP_EXCEPTION) != 0 && (m_stopexception == -1 || m_stopexception == exception))
{
m_device.machine().debugger().cpu().set_execution_stopped();
m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %d)\n", m_device.tag(), exception);
compute_debug_flags();
bool matched = true;
if (m_exception_condition && !m_exception_condition->is_empty())
{
try
{
matched = m_exception_condition->execute();
}
catch (expression_error &)
{
return;
}
}
if (matched)
{
m_device.machine().debugger().cpu().set_execution_stopped();
m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %d, PC=%X)\n", m_device.tag(), exception, m_state->pcbase());
compute_debug_flags();
}
}
}
@ -1506,18 +1539,18 @@ void device_debug::exception_hook(int exception)
void device_debug::privilege_hook()
{
bool matched = 1;
if ((m_flags & DEBUG_FLAG_STOP_PRIVILEGE) != 0)
{
bool matched = true;
if (m_privilege_condition && !m_privilege_condition->is_empty())
{
try
{
matched = m_privilege_condition->execute();
}
catch (...)
catch (expression_error &)
{
return;
}
}
@ -1840,12 +1873,13 @@ void device_debug::go_next_device()
// exception fires on the visible CPU
//-------------------------------------------------
void device_debug::go_exception(int exception)
void device_debug::go_exception(int exception, const char *condition)
{
assert(m_exec != nullptr);
m_device.machine().rewind_invalidate();
m_stopexception = exception;
m_exception_condition = std::make_unique<parsed_expression>(m_symtable, condition);
m_flags |= DEBUG_FLAG_STOP_EXCEPTION;
m_device.machine().debugger().cpu().set_execution_running();
}
@ -2956,6 +2990,7 @@ void device_debug::watchpoint::triggered(read_or_write type, offs_t address, u64
}
// halt in the debugger by default
bool was_stopped = debug.cpu().is_stopped();
debug.cpu().set_execution_stopped();
// evaluate the action
@ -2965,19 +3000,28 @@ void device_debug::watchpoint::triggered(read_or_write type, offs_t address, u64
// print a notification, unless the action made us go again
if (debug.cpu().is_stopped())
{
offs_t pc = m_space.device().state().pcbase();
std::string buffer;
buffer = string_format(type == read_or_write::READ ?
"Stopped at watchpoint %X reading %0*X from %08X (PC=%X)" :
"Stopped at watchpoint %X writing %0*X to %08X (PC=%X)",
"Stopped at watchpoint %X reading %0*X from %08X" :
"Stopped at watchpoint %X writing %0*X to %08X",
m_index,
size * unit_size / 4,
data,
address,
pc);
debug.console().printf("%s\n", buffer);
m_debugInterface->compute_debug_flags();
address);
if (debug.cpu().live_cpu() == &m_space.device())
{
offs_t pc = m_space.device().state().pcbase();
debug.console().printf("%s (PC=%X)\n", buffer, pc);
m_debugInterface->compute_debug_flags();
}
else if (!was_stopped)
{
debug.console().printf("%s\n", buffer);
debug.cpu().set_execution_running();
debug.cpu().set_break_cpu(&m_space.device());
}
m_debugInterface->set_triggered_watchpoint(this);
}

View File

@ -201,7 +201,7 @@ public:
void go(offs_t targetpc = ~0);
void go_vblank();
void go_interrupt(int irqline = -1);
void go_exception(int exception);
void go_exception(int exception, const char *condition);
void go_milliseconds(u64 milliseconds);
void go_privilege(const char *condition);
void go_next_device();
@ -320,6 +320,7 @@ private:
int m_stopirq; // stop IRQ number for DEBUG_FLAG_STOP_INTERRUPT
int m_stopexception; // stop exception number for DEBUG_FLAG_STOP_EXCEPTION
std::unique_ptr<parsed_expression> m_privilege_condition; // expression to evaluate on privilege change
std::unique_ptr<parsed_expression> m_exception_condition; // expression to evaluate on exception hit
attotime m_endexectime; // ending time of the current execution
u64 m_total_cycles; // current total cycles
u64 m_last_total_cycles; // last total cycles

View File

@ -137,7 +137,7 @@ static const help_item static_help_list[] =
" o[ver] [<count>=1] -- single steps over <count> instructions (F10)\n"
" out -- single steps until the current subroutine/exception handler is exited (Shift-F11)\n"
" g[o] [<address>] -- resumes execution, sets temp breakpoint at <address> (F5)\n"
" ge[x] [<exception>] -- resumes execution, setting temp breakpoint if <exception> is raised\n"
" ge[x] [<exception>[,<condition>]] -- resumes execution, setting temp breakpoint if <exception> is raised\n"
" gi[nt] [<irqline>] -- resumes execution, setting temp breakpoint if <irqline> is taken (F7)\n"
" gt[ime] <milliseconds> -- resumes execution until the given delay has elapsed\n"
" gv[blank] -- resumes execution, setting temp breakpoint on the next VBLANK (F8)\n"

View File

@ -195,7 +195,7 @@ void device_image_interface::set_image_filename(const std::string &filename)
auto iter = std::find_if(
m_image_name.rbegin(),
m_image_name.rend(),
[](char c) { return (c == '\\') || (c == '/') || (c == ':'); });
[](char c) { return (c == '\\') || (c == '/'); });
if (iter != m_image_name.rend())
m_basename.assign(iter.base(), m_image_name.end());

View File

@ -644,32 +644,33 @@ void natural_keyboard::build_codes(ioport_manager &manager)
{
if (((code < UCHAR_SHIFT_BEGIN) || (code > UCHAR_SHIFT_END)) && (code != 0))
{
// prefer lowest shift state
keycode_map::iterator const found(m_keycode_map.find(code));
if ((m_keycode_map.end() == found) || (found->second.shift > curshift))
keycode_map_entry newcode;
std::fill(std::begin(newcode.field), std::end(newcode.field), nullptr);
newcode.shift = curshift;
newcode.condition = field.condition();
unsigned fieldnum = 0;
for (unsigned i = 0, bits = curshift; (i < SHIFT_COUNT) && bits; ++i, bits >>= 1)
{
keycode_map_entry newcode;
std::fill(std::begin(newcode.field), std::end(newcode.field), nullptr);
newcode.shift = curshift;
if (BIT(bits, 0))
newcode.field[fieldnum++] = shift[i];
}
unsigned fieldnum = 0;
for (unsigned i = 0, bits = curshift; (i < SHIFT_COUNT) && bits; ++i, bits >>= 1)
{
if (BIT(bits, 0))
newcode.field[fieldnum++] = shift[i];
}
newcode.field[fieldnum] = &field;
if (m_keycode_map.end() == found)
{
keycode_map_list map_list;
map_list.emplace_back(newcode);
m_keycode_map.emplace(code, map_list);
}
else
found->second.emplace_back(newcode);
newcode.field[fieldnum] = &field;
if (m_keycode_map.end() == found)
m_keycode_map.emplace(code, newcode);
else
found->second = newcode;
if (LOG_NATURAL_KEYBOARD)
{
machine().logerror("natural_keyboard: code=%u (%s) port=%p field.name='%s'\n",
code, unicode_to_string(code), (void *)&port, field.name());
}
if (LOG_NATURAL_KEYBOARD)
{
machine().logerror("natural_keyboard: code=%u (%s) port=%p field.name='%s'\n",
code, unicode_to_string(code), (void *)&port, field.name());
}
}
}
@ -879,7 +880,13 @@ std::string natural_keyboard::unicode_to_string(char32_t ch) const
const natural_keyboard::keycode_map_entry *natural_keyboard::find_code(char32_t ch) const
{
keycode_map::const_iterator const found(m_keycode_map.find(ch));
return (m_keycode_map.end() != found) ? &found->second : nullptr;
if (m_keycode_map.end() == found) return nullptr;
for(const keycode_map_entry &entry : found->second)
{
if (entry.condition.eval())
return &entry;
}
return nullptr;
}
@ -901,13 +908,16 @@ void natural_keyboard::dump(std::ostream &str) const
// pad with spaces
util::stream_format(str, "%-*s", left_column_width, description);
// identify the keys used
for (std::size_t field = 0; (code.second.field.size() > field) && code.second.field[field]; ++field)
util::stream_format(str, "%s'%s'", first ? "" : ", ", code.second.field[field]->name());
for (auto &entry : code.second)
{
// identify the keys used
for (std::size_t field = 0; (entry.field.size() > field) && entry.field[field]; ++field)
util::stream_format(str, "%s'%s'", first ? "" : ", ", entry.field[field]->name());
// carriage return
str << '\n';
first = false;
// carriage return
str << '\n';
first = false;
}
}
}

View File

@ -74,8 +74,10 @@ private:
{
std::array<ioport_field *, SHIFT_COUNT + 1> field;
unsigned shift;
ioport_condition condition;
};
typedef std::unordered_map<char32_t, keycode_map_entry> keycode_map;
typedef std::list<keycode_map_entry> keycode_map_list;
typedef std::unordered_map<char32_t, keycode_map_list> keycode_map;
// internal helpers
void build_codes(ioport_manager &manager);

View File

@ -24,17 +24,6 @@
#define TIMER_CALLBACK_MEMBER(name) void name(void *ptr, s32 param)
// macro for the RC time constant on a 74LS123 with C > 1000pF
// R is in ohms, C is in farads
#define TIME_OF_74LS123(r,c) (0.45 * (double)(r) * (double)(c))
// macros for the RC time constant on a 555 timer IC
// R is in ohms, C is in farads
#define PERIOD_OF_555_MONOSTABLE_NSEC(r,c) ((attoseconds_t)(1100000000 * (double)(r) * (double)(c)))
#define PERIOD_OF_555_ASTABLE_NSEC(r1,r2,c) ((attoseconds_t)( 693000000 * ((double)(r1) + 2.0 * (double)(r2)) * (double)(c)))
#define PERIOD_OF_555_MONOSTABLE(r,c) attotime::from_nsec(PERIOD_OF_555_MONOSTABLE_NSEC(r,c))
#define PERIOD_OF_555_ASTABLE(r1,r2,c) attotime::from_nsec(PERIOD_OF_555_ASTABLE_NSEC(r1,r2,c))
//**************************************************************************
// TYPE DEFINITIONS

View File

@ -243,6 +243,7 @@ const double XTAL::known_xtals[] = {
16'128'000, /* 16.128_MHz_XTAL Fujitsu FM-7 */
16'200'000, /* 16.2_MHz_XTAL Debut */
16'257'000, /* 16.257_MHz_XTAL IBM PC MDA & EGA */
16'313'000, /* 16.313_MHz_XTAL Micro-Term ERGO 201 */
16'364'000, /* 16.364_MHz_XTAL Corvus Concept */
16'384'000, /* 16.384_MHz_XTAL - */
16'400'000, /* 16.4_MHz_XTAL MS 6102 */

View File

@ -615,7 +615,6 @@ void hfe_format::generate_hfe_bitstream_from_track(int cyl, int head, int& sampl
// Start of track? Use next entry.
if (edge==0)
{
cur_pos = 0;
edge = tbuf[++cur_entry] & floppy_image::TIME_MASK;
}
@ -671,10 +670,6 @@ void hfe_format::generate_hfe_bitstream_from_track(int cyl, int head, int& sampl
}
cur_pos = next;
if(cur_pos >= 200000000) {
cur_pos -= 200000000;
cur_entry = 0;
}
bit = (bit << 1) & 0xff;
if (bit == 0)

View File

@ -5,8 +5,18 @@ buildVS/x64/*
buildVS/.vs/*
nltool
nlwav
nltool.exe
nlwav.exe
# Windows executables
*.exe
# Local doxygen binaries
doxygen
doxyindexer
doxysearch.cgi
# nltool/nlwav output files
*.log
*.wav
# VS 2019
*.user

View File

@ -97,27 +97,26 @@ namespace analog
/// | | FC | coefficient for forward-bias depletion capacitance formula | - | 0.5 | | |
/// | | TNOM | Parameter measurement temperature | C | 27 | 50 | |
///
class bjt_model_t : public param_model_t
class bjt_model_t
{
public:
bjt_model_t(device_t &device, const pstring &name, const pstring &val)
: param_model_t(device, name, val)
, m_IS (*this, "IS")
, m_BF (*this, "BF")
, m_NF (*this, "NF")
, m_BR (*this, "BR")
, m_NR (*this, "NR")
, m_CJE(*this, "CJE")
, m_CJC(*this, "CJC")
bjt_model_t(param_model_t &model)
: m_IS (model, "IS")
, m_BF (model, "BF")
, m_NF (model, "NF")
, m_BR (model, "BR")
, m_NR (model, "NR")
, m_CJE(model, "CJE")
, m_CJC(model, "CJC")
{}
value_t m_IS; //!< transport saturation current
value_t m_BF; //!< ideal maximum forward beta
value_t m_NF; //!< forward current emission coefficient
value_t m_BR; //!< ideal maximum reverse beta
value_t m_NR; //!< reverse current emission coefficient
value_t m_CJE; //!< B-E zero-bias depletion capacitance
value_t m_CJC; //!< B-C zero-bias depletion capacitance
param_model_t::value_t m_IS; //!< transport saturation current
param_model_t::value_t m_BF; //!< ideal maximum forward beta
param_model_t::value_t m_NF; //!< forward current emission coefficient
param_model_t::value_t m_BR; //!< ideal maximum reverse beta
param_model_t::value_t m_NR; //!< reverse current emission coefficient
param_model_t::value_t m_CJE; //!< B-E zero-bias depletion capacitance
param_model_t::value_t m_CJC; //!< B-C zero-bias depletion capacitance
};
@ -147,7 +146,7 @@ namespace analog
void set_qtype(q_type atype) noexcept { m_qtype = atype; }
protected:
bjt_model_t m_model;
param_model_t m_model;
private:
q_type m_qtype;
};
@ -179,7 +178,7 @@ namespace analog
, m_gB(nlconst::cgmin())
, m_gC(nlconst::cgmin())
, m_V(nlconst::zero())
, m_state_on(*this, "m_state_on", 0)
, m_state_on(*this, "m_state_on", 0u)
{
register_subalias("B", m_RB.P());
register_subalias("E", m_RB.N());
@ -216,6 +215,7 @@ namespace analog
{
public:
NETLIB_CONSTRUCTOR_DERIVED(QBJT_EB, QBJT)
, m_modacc(m_model)
, m_gD_BC(*this, "m_D_BC")
, m_gD_BE(*this, "m_D_BE")
, m_D_CB(*this, "m_D_CB", true)
@ -233,13 +233,13 @@ namespace analog
connect(m_D_EB.N(), m_D_CB.N());
connect(m_D_CB.P(), m_D_EC.N());
if (m_model.m_CJE > nlconst::zero())
if (m_modacc.m_CJE > nlconst::zero())
{
create_and_register_subdevice("m_CJE", m_CJE);
connect("B", "m_CJE.1");
connect("E", "m_CJE.2");
}
if (m_model.m_CJC > nlconst::zero())
if (m_modacc.m_CJC > nlconst::zero())
{
create_and_register_subdevice("m_CJC", m_CJC);
connect("B", "m_CJC.1");
@ -256,6 +256,7 @@ namespace analog
NETLIB_UPDATE_TERMINALSI();
private:
bjt_model_t m_modacc;
generic_diode<diode_e::BIPOLAR> m_gD_BC;
generic_diode<diode_e::BIPOLAR> m_gD_BE;
@ -313,11 +314,14 @@ namespace analog
NETLIB_UPDATE_PARAM(QBJT_switch)
{
nl_fptype IS = m_model.m_IS;
nl_fptype BF = m_model.m_BF;
nl_fptype NF = m_model.m_NF;
//nl_fptype VJE = m_model.dValue("VJE", 0.75);
bjt_model_t model(m_model);
nl_fptype IS = model.m_IS;
nl_fptype BF = model.m_BF;
nl_fptype NF = model.m_NF;
//nl_fptype VJE = model.dValue("VJE", 0.75);
// FIXME: check for PNP as well and bail out
set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP);
nl_fptype alpha = BF / (nlconst::one() + BF);
@ -382,12 +386,12 @@ namespace analog
if (m_CJE)
{
m_CJE->reset();
m_CJE->set_cap_embedded(m_model.m_CJE);
m_CJE->set_cap_embedded(m_modacc.m_CJE);
}
if (m_CJC)
{
m_CJC->reset();
m_CJC->set_cap_embedded(m_model.m_CJC);
m_CJC->set_cap_embedded(m_modacc.m_CJC);
}
}
@ -421,13 +425,14 @@ namespace analog
NETLIB_UPDATE_PARAM(QBJT_EB)
{
nl_fptype IS = m_model.m_IS;
nl_fptype BF = m_model.m_BF;
nl_fptype NF = m_model.m_NF;
nl_fptype BR = m_model.m_BR;
nl_fptype NR = m_model.m_NR;
nl_fptype IS = m_modacc.m_IS;
nl_fptype BF = m_modacc.m_BF;
nl_fptype NF = m_modacc.m_NF;
nl_fptype BR = m_modacc.m_BR;
nl_fptype NR = m_modacc.m_NR;
//nl_fptype VJE = m_model.dValue("VJE", 0.75);
// FIXME: check for PNP as well and bail out
set_qtype((m_model.type() == "NPN") ? BJT_NPN : BJT_PNP);
m_alpha_f = BF / (nlconst::one() + BF);

View File

@ -15,7 +15,7 @@
// ----------------------------------------------------------------------------------------
#define VCCS(name, G) \
NET_REGISTER_DEVEXT(VCCS, G)
NET_REGISTER_DEVEXT(VCCS, name, G)
#define CCCS(name, G) \
NET_REGISTER_DEVEXT(CCCS, name, G)

View File

@ -95,53 +95,52 @@ namespace analog
/// | Y |W | Width scaling |-|100e-6||
///
class fet_model_t : public param_model_t
class fet_model_t
{
public:
fet_model_t(device_t &device, const pstring &name, const pstring &val)
: param_model_t(device, name, val)
, m_VTO(*this, "VTO")
, m_N(*this, "N")
, m_ISS(*this, "IS") // Haven't seen a model using ISS / ISD
, m_ISD(*this, "IS")
, m_LD(*this, "LD")
, m_L(*this, "L")
, m_W(*this, "W")
, m_TOX(*this, "TOX")
, m_KP(*this, "KP")
, m_UO(*this, "UO")
, m_PHI(*this, "PHI")
, m_NSUB(*this, "NSUB")
, m_GAMMA(*this, "GAMMA")
, m_LAMBDA(*this, "LAMBDA")
, m_RD(*this, "RD")
, m_RS(*this, "RS")
, m_CGSO(*this, "CGSO")
, m_CGDO(*this, "CGDO")
, m_CGBO(*this, "CGBO")
, m_CAPMOD(*this, "CAPMOD")
fet_model_t(param_model_t &model)
: m_VTO(model, "VTO")
, m_N(model, "N")
, m_ISS(model, "IS") // Haven't seen a model using ISS / ISD
, m_ISD(model, "IS")
, m_LD(model, "LD")
, m_L(model, "L")
, m_W(model, "W")
, m_TOX(model, "TOX")
, m_KP(model, "KP")
, m_UO(model, "UO")
, m_PHI(model, "PHI")
, m_NSUB(model, "NSUB")
, m_GAMMA(model, "GAMMA")
, m_LAMBDA(model, "LAMBDA")
, m_RD(model, "RD")
, m_RS(model, "RS")
, m_CGSO(model, "CGSO")
, m_CGDO(model, "CGDO")
, m_CGBO(model, "CGBO")
, m_CAPMOD(model, "CAPMOD")
{}
value_t m_VTO; //!< Threshold voltage [V]
value_t m_N; //!< Bulk diode emission coefficient
value_t m_ISS; //!< Body diode saturation current
value_t m_ISD; //!< Body diode saturation current
value_t m_LD; //!< Lateral diffusion [m]
value_t m_L; //!< Length scaling
value_t m_W; //!< Width scaling
value_t m_TOX; //!< Oxide thickness
value_t m_KP; //!< Transconductance parameter [A/V²]
value_t m_UO; //!< Surface mobility [cm²/V/s]
value_t m_PHI; //!< Surface inversion potential [V]
value_t m_NSUB; //!< Substrate doping [1/cm³]
value_t m_GAMMA; //!< Bulk threshold parameter [V^½]
value_t m_LAMBDA; //!< Channel-length modulation [1/V]
value_t m_RD; //!< Drain ohmic resistance
value_t m_RS; //!< Source ohmic resistance
value_t m_CGSO; //!< Gate-source overlap capacitance per meter channel width
value_t m_CGDO; //!< Gate-drain overlap capacitance per meter channel width
value_t m_CGBO; //!< Gate-bulk overlap capacitance per meter channel width
value_base_t<int> m_CAPMOD; //!< Capacitance model (0=no model 2=Meyer)
param_model_t::value_t m_VTO; //!< Threshold voltage [V]
param_model_t::value_t m_N; //!< Bulk diode emission coefficient
param_model_t::value_t m_ISS; //!< Body diode saturation current
param_model_t::value_t m_ISD; //!< Body diode saturation current
param_model_t::value_t m_LD; //!< Lateral diffusion [m]
param_model_t::value_t m_L; //!< Length scaling
param_model_t::value_t m_W; //!< Width scaling
param_model_t::value_t m_TOX; //!< Oxide thickness
param_model_t::value_t m_KP; //!< Transconductance parameter [A/V²]
param_model_t::value_t m_UO; //!< Surface mobility [cm²/V/s]
param_model_t::value_t m_PHI; //!< Surface inversion potential [V]
param_model_t::value_t m_NSUB; //!< Substrate doping [1/cm³]
param_model_t::value_t m_GAMMA; //!< Bulk threshold parameter [V^½]
param_model_t::value_t m_LAMBDA; //!< Channel-length modulation [1/V]
param_model_t::value_t m_RD; //!< Drain ohmic resistance
param_model_t::value_t m_RS; //!< Source ohmic resistance
param_model_t::value_t m_CGSO; //!< Gate-source overlap capacitance per meter channel width
param_model_t::value_t m_CGDO; //!< Gate-drain overlap capacitance per meter channel width
param_model_t::value_t m_CGBO; //!< Gate-bulk overlap capacitance per meter channel width
param_model_t::value_base_t<int> m_CAPMOD; //!< Capacitance model (0=no model 2=Meyer)
};
// Have a common start for mosfets
@ -170,7 +169,7 @@ namespace analog
void set_qtype(q_type atype) noexcept { m_qtype = atype; }
protected:
fet_model_t m_model;
param_model_t m_model;
private:
q_type m_qtype;
};
@ -207,6 +206,7 @@ namespace analog
, m_capmod(2)
, m_Vgs(*this, "m_Vgs", nlconst::zero())
, m_Vgd(*this, "m_Vgd", nlconst::zero())
, m_modacc(m_model)
{
register_subalias("S", m_SG.P()); // Source
register_subalias("G", m_SG.N()); // Gate
@ -220,8 +220,8 @@ namespace analog
set_qtype((m_model.type() == "NMOS_DEFAULT") ? FET_NMOS : FET_PMOS);
m_polarity = (qtype() == FET_NMOS ? nlconst::one() : -nlconst::one());
m_capmod = m_model.m_CAPMOD;
// printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_model.m_VTO, m_polarity);
m_capmod = m_modacc.m_CAPMOD;
// printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_modacc.m_VTO, m_polarity);
nl_assert_always(m_capmod == 0 || m_capmod == 2, "Error: CAPMODEL invalid value");
//
@ -234,51 +234,51 @@ namespace analog
// But couldn't find a formula for lambda anywhere
//
m_lambda = m_model.m_LAMBDA; // FIXME: m_lambda only set once
m_lambda = m_modacc.m_LAMBDA; // FIXME: m_lambda only set once
// calculate effective channel length
m_Leff = m_model.m_L - 2 * m_model.m_LD;
m_Leff = m_modacc.m_L - 2 * m_modacc.m_LD;
nl_assert_always(m_Leff > nlconst::zero(), "Effective Lateral diffusion would be negative for model");
nl_fptype Cox = (m_model.m_TOX > nlconst::zero()) ? (constants::eps_SiO2() * constants::eps_0() / m_model.m_TOX) : nlconst::zero();
nl_fptype Cox = (m_modacc.m_TOX > nlconst::zero()) ? (constants::eps_SiO2() * constants::eps_0() / m_modacc.m_TOX) : nlconst::zero();
// calculate DC transconductance coefficient
if (m_model.m_KP > nlconst::zero())
m_beta = m_model.m_KP * m_model.m_W / m_Leff;
else if (Cox > nlconst::zero() && m_model.m_UO > nlconst::zero())
m_beta = m_model.m_UO * nlconst::magic(1e-4) * Cox * m_model.m_W / m_Leff;
if (m_modacc.m_KP > nlconst::zero())
m_beta = m_modacc.m_KP * m_modacc.m_W / m_Leff;
else if (Cox > nlconst::zero() && m_modacc.m_UO > nlconst::zero())
m_beta = m_modacc.m_UO * nlconst::magic(1e-4) * Cox * m_modacc.m_W / m_Leff;
else
m_beta = nlconst::magic(2e-5) * m_model.m_W / m_Leff;
m_beta = nlconst::magic(2e-5) * m_modacc.m_W / m_Leff;
//FIXME::UT can disappear
const nl_fptype Vt = constants::T0() * constants::k_b() / constants::Q_e();
// calculate surface potential if not given
if (m_model.m_PHI > nlconst::zero())
m_phi = m_model.m_PHI;
else if (m_model.m_NSUB > nlconst::zero())
if (m_modacc.m_PHI > nlconst::zero())
m_phi = m_modacc.m_PHI;
else if (m_modacc.m_NSUB > nlconst::zero())
{
nl_assert_always(m_model.m_NSUB * nlconst::magic(1e6) >= constants::NiSi(), "Error calculating phi for model");
m_phi = nlconst::two() * Vt * plib::log (m_model.m_NSUB * nlconst::magic(1e6) / constants::NiSi());
nl_assert_always(m_modacc.m_NSUB * nlconst::magic(1e6) >= constants::NiSi(), "Error calculating phi for model");
m_phi = nlconst::two() * Vt * plib::log (m_modacc.m_NSUB * nlconst::magic(1e6) / constants::NiSi());
}
else
m_phi = nlconst::magic(0.6);
// calculate bulk threshold if not given
if (m_model.m_GAMMA > nlconst::zero())
m_gamma = m_model.m_GAMMA;
if (m_modacc.m_GAMMA > nlconst::zero())
m_gamma = m_modacc.m_GAMMA;
else
{
if (Cox > nlconst::zero() && m_model.m_NSUB > nlconst::zero())
if (Cox > nlconst::zero() && m_modacc.m_NSUB > nlconst::zero())
m_gamma = plib::sqrt (nlconst::two()
* constants::Q_e() * constants::eps_Si() * constants::eps_0()
* m_model.m_NSUB * nlconst::magic(1e6)) / Cox;
* m_modacc.m_NSUB * nlconst::magic(1e6)) / Cox;
else
m_gamma = nlconst::zero();
}
m_vto = m_model.m_VTO;
m_vto = m_modacc.m_VTO;
// FIXME zero conversion
if(m_vto != nlconst::zero())
log().warning(MW_MOSFET_THRESHOLD_VOLTAGE(m_model.name()));
@ -286,7 +286,7 @@ namespace analog
// FIXME: VTO if missing may be calculated from TPG, NSS and temperature. Usually models
// specify VTO so skip this here.
m_CoxWL = Cox * m_model.m_W * m_Leff;
m_CoxWL = Cox * m_modacc.m_W * m_Leff;
//printf("Cox: %g\n", m_Cox);
}
@ -317,9 +317,9 @@ namespace analog
NETLIB_NAME(FET)::reset();
// Bulk diodes
m_D_BD.set_param(m_model.m_ISD, m_model.m_N, exec().gmin(), constants::T0());
m_D_BD.set_param(m_modacc.m_ISD, m_modacc.m_N, exec().gmin(), constants::T0());
#if (!BODY_CONNECTED_TO_SOURCE)
m_D_BS.set_param(m_model.m_ISS, m_model.m_N, exec().gmin(), constants::T0());
m_D_BS.set_param(m_modacc.m_ISS, m_modacc.m_N, exec().gmin(), constants::T0());
#endif
}
@ -362,6 +362,7 @@ namespace analog
int m_capmod;
state_var<nl_fptype> m_Vgs;
state_var<nl_fptype> m_Vgd;
fet_model_t m_modacc;
void set_cap(generic_capacitor<capacitor_e::VARIABLE_CAPACITY> cap,
nl_fptype capval, nl_fptype V,
@ -573,9 +574,9 @@ namespace analog
else
calculate_caps(Vgd, Vgs, Vth, m_Cgd, m_Cgs, m_Cgb);
set_cap(m_cap_gb, m_Cgb + m_model.m_CGBO * m_Leff, Vgb, gGG, gGB, gBG, gBB, IG, IB);
set_cap(m_cap_gs, m_Cgs + m_model.m_CGSO * m_model.m_W, Vgs, gGG, gGS, gSG, gSS, IG, IS);
set_cap(m_cap_gd, m_Cgd + m_model.m_CGDO * m_model.m_W, Vgd, gGG, gGD, gDG, gDD, IG, ID);
set_cap(m_cap_gb, m_Cgb + m_modacc.m_CGBO * m_Leff, Vgb, gGG, gGB, gBG, gBB, IG, IB);
set_cap(m_cap_gs, m_Cgs + m_modacc.m_CGSO * m_modacc.m_W, Vgs, gGG, gGS, gSG, gSS, IG, IS);
set_cap(m_cap_gd, m_Cgd + m_modacc.m_CGDO * m_modacc.m_W, Vgd, gGG, gGD, gDG, gDD, IG, ID);
}
// Source connected to body, Diode S-B shorted!

View File

@ -75,31 +75,30 @@ namespace netlist
/// http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
///
///
class opamp_model_t : public param_model_t
class opamp_model_t
{
public:
opamp_model_t(device_t &device, const pstring &name, const pstring &val)
: param_model_t(device, name, val)
, m_TYPE(*this, "TYPE")
, m_FPF(*this, "FPF")
, m_SLEW(*this, "SLEW")
, m_RI(*this, "RI")
, m_RO(*this, "RO")
, m_UGF(*this, "UGF")
, m_VLL(*this, "VLL")
, m_VLH(*this, "VLH")
, m_DAB(*this, "DAB")
opamp_model_t(param_model_t &model)
: m_TYPE(model, "TYPE")
, m_FPF(model, "FPF")
, m_SLEW(model, "SLEW")
, m_RI(model, "RI")
, m_RO(model, "RO")
, m_UGF(model, "UGF")
, m_VLL(model, "VLL")
, m_VLH(model, "VLH")
, m_DAB(model, "DAB")
{}
value_t m_TYPE; //!< Model Type, 1 and 3 are supported
value_t m_FPF; //!< frequency of first pole
value_t m_SLEW; //!< unity gain slew rate
value_t m_RI; //!< input resistance
value_t m_RO; //!< output resistance
value_t m_UGF; //!< unity gain frequency (transition frequency)
value_t m_VLL; //!< low output swing minus low supply rail
value_t m_VLH; //!< high supply rail minus high output swing
value_t m_DAB; //!< Differential Amp Bias - total quiescent current
param_model_t::value_t m_TYPE; //!< Model Type, 1 and 3 are supported
param_model_t::value_t m_FPF; //!< frequency of first pole
param_model_t::value_t m_SLEW; //!< unity gain slew rate
param_model_t::value_t m_RI; //!< input resistance
param_model_t::value_t m_RO; //!< output resistance
param_model_t::value_t m_UGF; //!< unity gain frequency (transition frequency)
param_model_t::value_t m_VLL; //!< low output swing minus low supply rail
param_model_t::value_t m_VLH; //!< high supply rail minus high output swing
param_model_t::value_t m_DAB; //!< Differential Amp Bias - total quiescent current
};
@ -111,11 +110,12 @@ namespace netlist
, m_VCC(*this, "VCC")
, m_GND(*this, "GND")
, m_model(*this, "MODEL", "LM324")
, m_modacc(m_model)
, m_VH(*this, "VH")
, m_VL(*this, "VL")
, m_VREF(*this, "VREF")
{
m_type = static_cast<int>(m_model.m_TYPE);
m_type = static_cast<int>(m_modacc.m_TYPE);
if (m_type < 1 || m_type > 3)
{
log().fatal(MF_OPAMP_UNKNOWN_TYPE(m_type));
@ -204,7 +204,8 @@ namespace netlist
analog_input_t m_VCC;
analog_input_t m_GND;
opamp_model_t m_model;
param_model_t m_model;
opamp_model_t m_modacc;
analog_output_t m_VH;
analog_output_t m_VL;
analog_output_t m_VREF;
@ -216,33 +217,33 @@ namespace netlist
NETLIB_UPDATE(opamp)
{
const nl_fptype cVt = nlconst::np_VT(nlconst::one()); // * m_n;
const nl_fptype cId = m_model.m_DAB; // 3 mA
const nl_fptype cId = m_modacc.m_DAB; // 3 mA
const nl_fptype cVd = cVt * plib::log(cId / nlconst::np_Is() + nlconst::one());
m_VH.push(m_VCC() - m_model.m_VLH - cVd);
m_VL.push(m_GND() + m_model.m_VLL + cVd);
m_VH.push(m_VCC() - m_modacc.m_VLH - cVd);
m_VL.push(m_GND() + m_modacc.m_VLL + cVd);
m_VREF.push((m_VCC() + m_GND()) / nlconst::two());
}
NETLIB_UPDATE_PARAM(opamp)
{
m_G1.m_RI.set(m_model.m_RI);
m_G1.m_RI.set(m_modacc.m_RI);
if (m_type == 1)
{
nl_fptype RO = m_model.m_RO;
nl_fptype G = m_model.m_UGF / m_model.m_FPF / RO;
nl_fptype RO = m_modacc.m_RO;
nl_fptype G = m_modacc.m_UGF / m_modacc.m_FPF / RO;
m_RP.set_R(RO);
m_G1.m_G.set(G);
}
if (m_type == 3 || m_type == 2)
{
nl_fptype CP = m_model.m_DAB / m_model.m_SLEW;
nl_fptype RP = nlconst::half() / nlconst::pi() / CP / m_model.m_FPF;
nl_fptype G = m_model.m_UGF / m_model.m_FPF / RP;
nl_fptype CP = m_modacc.m_DAB / m_modacc.m_SLEW;
nl_fptype RP = nlconst::half() / nlconst::pi() / CP / m_modacc.m_FPF;
nl_fptype G = m_modacc.m_UGF / m_modacc.m_FPF / RP;
//printf("OPAMP %s: %g %g %g\n", name().c_str(), CP, RP, G);
if (m_model.m_SLEW / (nlconst::four() * nlconst::pi() * nlconst::np_VT()) < m_model.m_UGF)
if (m_modacc.m_SLEW / (nlconst::four() * nlconst::pi() * nlconst::np_VT()) < m_modacc.m_UGF)
log().warning(MW_OPAMP_FAIL_CONVERGENCE(this->name()));
m_CP->set_cap_embedded(CP);
@ -255,9 +256,9 @@ namespace netlist
m_EBUF->m_G.set(nlconst::one());
#if TEST_ALT_OUTPUT
m_EBUF->m_RO.set(0.001);
m_RO->set_R(m_model.m_RO);
m_RO->set_R(m_modacc.m_RO);
#else
m_EBUF->m_RO.set(m_model.m_RO);
m_EBUF->m_RO.set(m_modacc.m_RO);
#endif
}
if (m_type == 3)
@ -265,9 +266,9 @@ namespace netlist
m_EBUF->m_G.set(nlconst::one());
#if TEST_ALT_OUTPUT
m_EBUF->m_RO.set(0.001);
m_RO->set_R(m_model.m_RO);
m_RO->set_R(m_modacc.m_RO);
#else
m_EBUF->m_RO.set(m_model.m_RO);
m_EBUF->m_RO.set(m_modacc.m_RO);
#endif
}
}

View File

@ -145,8 +145,9 @@ namespace analog
NETLIB_RESET(D)
{
nl_fptype Is = m_model.m_IS;
nl_fptype n = m_model.m_N;
diode_model_t modacc(m_model);
nl_fptype Is = modacc.m_IS;
nl_fptype n = modacc.m_N;
m_D.set_param(Is, n, exec().gmin(), nlconst::T0());
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
@ -154,8 +155,9 @@ namespace analog
NETLIB_UPDATE_PARAM(D)
{
nl_fptype Is = m_model.m_IS;
nl_fptype n = m_model.m_N;
diode_model_t modacc(m_model);
nl_fptype Is = modacc.m_IS;
nl_fptype n = modacc.m_N;
m_D.set_param(Is, n, exec().gmin(), nlconst::T0());
}
@ -176,19 +178,21 @@ namespace analog
NETLIB_RESET(Z)
{
nl_fptype IsBV = m_model.m_IBV / (plib::exp(m_model.m_BV / nlconst::np_VT(m_model.m_NBV)) - nlconst::one());
zdiode_model_t modacc(m_model);
nl_fptype IsBV = modacc.m_IBV / (plib::exp(modacc.m_BV / nlconst::np_VT(modacc.m_NBV)) - nlconst::one());
m_D.set_param(m_model.m_IS, m_model.m_N, exec().gmin(), nlconst::T0());
m_R.set_param(IsBV, m_model.m_NBV, exec().gmin(), nlconst::T0());
m_D.set_param(modacc.m_IS, modacc.m_N, exec().gmin(), nlconst::T0());
m_R.set_param(IsBV, modacc.m_NBV, exec().gmin(), nlconst::T0());
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
}
NETLIB_UPDATE_PARAM(Z)
{
nl_fptype IsBV = m_model.m_IBV / (plib::exp(m_model.m_BV / nlconst::np_VT(m_model.m_NBV)) - nlconst::one());
zdiode_model_t modacc(m_model);
nl_fptype IsBV = modacc.m_IBV / (plib::exp(modacc.m_BV / nlconst::np_VT(modacc.m_NBV)) - nlconst::one());
m_D.set_param(m_model.m_IS, m_model.m_N, exec().gmin(), nlconst::T0());
m_R.set_param(IsBV, m_model.m_NBV, exec().gmin(), nlconst::T0());
m_D.set_param(modacc.m_IS, modacc.m_N, exec().gmin(), nlconst::T0());
m_R.set_param(IsBV, modacc.m_NBV, exec().gmin(), nlconst::T0());
set_G_V_I(m_D.G(), nlconst::zero(), m_D.Ieq());
}

View File

@ -452,32 +452,31 @@ namespace analog
/// | Y |IBV |current at breakdown voltage |A | 0.001| | |
/// | |TNOM |parameter measurement temperature|deg C| 27| 50| |
///
class diode_model_t : public param_model_t
class diode_model_t
{
public:
diode_model_t(device_t &device, const pstring &name, const pstring &val)
: param_model_t(device, name, val)
, m_IS(*this, "IS")
, m_N(*this, "N")
diode_model_t(param_model_t &model)
: m_IS(model, "IS")
, m_N(model, "N")
{}
value_t m_IS; //!< saturation current.
value_t m_N; //!< emission coefficient.
param_model_t::value_t m_IS; //!< saturation current.
param_model_t::value_t m_N; //!< emission coefficient.
};
class zdiode_model_t : public diode_model_t
{
public:
zdiode_model_t(device_t &device, const pstring &name, const pstring &val)
: diode_model_t(device, name, val)
, m_NBV(*this, "NBV")
, m_BV(*this, "BV")
, m_IBV(*this, "IBV")
zdiode_model_t(param_model_t &model)
: diode_model_t(model)
, m_NBV(model, "NBV")
, m_BV(model, "BV")
, m_IBV(model, "IBV")
{}
value_t m_NBV; //!< reverse emission coefficient.
value_t m_BV; //!< reverse breakdown voltage.
value_t m_IBV; //!< current at breakdown voltage.
param_model_t::value_t m_NBV; //!< reverse emission coefficient.
param_model_t::value_t m_BV; //!< reverse breakdown voltage.
param_model_t::value_t m_IBV; //!< current at breakdown voltage.
};
// -----------------------------------------------------------------------------
@ -504,7 +503,7 @@ namespace analog
NETLIB_UPDATE_PARAMI();
private:
diode_model_t m_model;
param_model_t m_model;
generic_diode<diode_e::BIPOLAR> m_D;
};
@ -533,7 +532,7 @@ namespace analog
NETLIB_UPDATE_PARAMI();
private:
zdiode_model_t m_model;
param_model_t m_model;
generic_diode<diode_e::BIPOLAR> m_D;
// REVERSE diode
generic_diode<diode_e::BIPOLAR> m_R;
@ -553,14 +552,13 @@ namespace analog
, m_R(*this, "RI", nlconst::magic(0.1))
, m_V(*this, "V", nlconst::zero())
, m_func(*this,"FUNC", "")
, m_compiled()
, m_compiled(*this, "m_compiled")
, m_funcparam({nlconst::zero()})
{
m_compiled.save_state(*this, "m_compiled");
register_subalias("P", P());
register_subalias("N", N());
if (m_func() != "")
m_compiled.compile(m_func(), std::vector<pstring>({{pstring("T")}}));
m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
}
NETLIB_IS_TIMESTEP(m_func() != "")
@ -570,7 +568,7 @@ namespace analog
m_t += step;
m_funcparam[0] = m_t;
this->set_G_V_I(plib::reciprocal(m_R()),
m_compiled.evaluate(m_funcparam),
m_compiled->evaluate(m_funcparam),
nlconst::zero());
}
@ -587,7 +585,7 @@ namespace analog
param_fp_t m_R;
param_fp_t m_V;
param_str_t m_func;
plib::pfunction<nl_fptype> m_compiled;
state_var<plib::pfunction<nl_fptype>> m_compiled;
std::vector<nl_fptype> m_funcparam;
};
@ -602,14 +600,13 @@ namespace analog
, m_t(*this, "m_t", nlconst::zero())
, m_I(*this, "I", nlconst::one())
, m_func(*this,"FUNC", "")
, m_compiled()
, m_compiled(*this, "m_compiled")
, m_funcparam({nlconst::zero()})
{
m_compiled.save_state(*this, "m_compiled");
register_subalias("P", P());
register_subalias("N", N());
if (m_func() != "")
m_compiled.compile(m_func(), std::vector<pstring>({{pstring("T")}}));
m_compiled->compile(m_func(), std::vector<pstring>({{pstring("T")}}));
}
NETLIB_IS_TIMESTEP(m_func() != "")
@ -617,7 +614,7 @@ namespace analog
{
m_t += step;
m_funcparam[0] = m_t;
const nl_fptype I = m_compiled.evaluate(m_funcparam);
const nl_fptype I = m_compiled->evaluate(m_funcparam);
const auto zero(nlconst::zero());
set_mat(zero, zero, -I,
zero, zero, I);
@ -649,7 +646,7 @@ namespace analog
state_var<nl_fptype> m_t;
param_fp_t m_I;
param_str_t m_func;
plib::pfunction<nl_fptype> m_compiled;
state_var<plib::pfunction<nl_fptype>> m_compiled;
std::vector<nl_fptype> m_funcparam;
};

View File

@ -73,7 +73,10 @@ TIDY_DB = $(OBJ)/compile_commands.json
# LTO = -flto=4 -fuse-linker-plugin -flto-partition=balanced -Wodr
CFLAGS = $(LTO) -g -O3 -std=c++14 -I$(CURDIR)/.. -I$(CURDIR)/../.. $(CEXTRAFLAGS)
CCOREFLAGS = -g -O3 -std=c++14 -I$(CURDIR)/.. -I$(CURDIR)/../..
CFLAGS = $(LTO) $(CCOREFLAGS) $(CEXTRAFLAGS)
LDFLAGS = $(LTO) -g -O3 -std=c++14 $(LDEXTRAFLAGS)
LIBS = -lpthread -ldl $(EXTRALIBS)
@ -82,6 +85,8 @@ LD = @g++
MD = @mkdir
RM = @rm
CLANG_TIDY = clang-tidy-11
DEPENDCC=$(CC)
ifndef FAST
FAST=1
@ -278,17 +283,20 @@ native:
$(MAKE) CEXTRAFLAGS="-march=native -msse4.2 -Wall -Wpedantic -Wsign-compare -Wextra "
gcc9:
$(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -fext-numeric-literals -msse4.2 -Wall -pedantic -Wpedantic -Wsign-compare -Wextra" EXTRALIBS="-lquadmath"
$(MAKE) CC=g++-9 LD=g++-9 CEXTRAFLAGS="-march=native -fext-numeric-literals -msse4.2 -Wall -pedantic -Wpedantic -Wsign-compare -Wextra " EXTRALIBS="-lquadmath"
clang:
$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Werror -Wno-padded -Wno-weak-vtables -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
#$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Wno-padded -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
$(MAKE) CC=clang++-11 LD=clang++-11 OBJ=obj/clang CEXTRAFLAGS="-march=native -msse4.2 -Weverything -Wall -pedantic -Wpedantic -Wunused-private-field -Werror -Wno-padded -Wno-weak-vtables -Wno-unused-template -Wno-missing-variable-declarations -Wno-float-equal -Wconversion -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-exit-time-destructors"
clang-5:
$(MAKE) CC=clang++-5.0 LD=clang++-5.0 CEXTRAFLAGS="-march=native -Weverything -Werror -Wno-inconsistent-missing-destructor-override -Wno-unreachable-code -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-format-nonliteral -Wno-weak-template-vtables -Wno-exit-time-destructors"
nvcc:
$(MAKE) CC=/usr/local/cuda-9.0/bin/nvcc LD=/usr/local/cuda-9.2/bin/nvcc OBJ=obj/nvcc \
CEXTRAFLAGS="-x cu -DNVCCBUILD=1 --expt-extended-lambda --expt-relaxed-constexpr --default-stream per-thread --restrict"
$(MAKE) CC=/usr/local/cuda-9.0/bin/nvcc LD=/usr/local/cuda-9.2/bin/nvcc \
OBJ=obj/nvcc CEXTRAFLAGS="-x cu -DNVCCBUILD=1 --expt-extended-lambda \
--expt-relaxed-constexpr --default-stream per-thread --restrict" \
DEPENDCC=g++
tidy_db: compile_commands_prefix $(ALL_TIDY_FILES) compile_commands_postfix
@ -327,7 +335,7 @@ $(DEPEND): maketree $(SOURCES)
@echo creating $(DEPEND)
@rm -f $(DEPEND)
@for i in $(SOURCES); do \
$(CC) $(CFLAGS) -MM $$i -MT `echo $$i | sed -e 's+$(SRC)+$(OBJ)+' -e 's+.cpp+.o+' ` >> $(DEPEND); \
$(DEPENDCC) $(CCOREFLAGS) -MM $$i -MT `echo $$i | sed -e 's+$(SRC)+$(OBJ)+' -e 's+.cpp+.o+' ` >> $(DEPEND); \
done
depend: $(DEPEND)

View File

@ -1,12 +1,14 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "netlistlib", "netlistlib.vcxproj", "{A374399B-B87F-4E0F-9525-6C099600705F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nltool", "nltool.vcxproj", "{9204EC28-A29B-4A36-9E47-2C46041D67D3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nlwav", "nlwav.vcxproj", "{48D0ADAF-62EC-472E-A51B-8D837280649D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -31,8 +33,19 @@ Global
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Release|x64.Build.0 = Release|x64
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Release|x86.ActiveCfg = Release|Win32
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Release|x86.Build.0 = Release|Win32
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x64.ActiveCfg = Debug|x64
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x64.Build.0 = Debug|x64
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x86.ActiveCfg = Debug|Win32
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x86.Build.0 = Debug|Win32
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Release|x64.ActiveCfg = Release|x64
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Release|x64.Build.0 = Release|x64
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Release|x86.ActiveCfg = Release|Win32
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {992701A0-B9F5-4F7D-BF3F-5B0EBEA51F04}
EndGlobalSection
EndGlobal

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\prg\nlwav.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="netlistlib.vcxproj">
<Project>{a374399b-b87f-4e0f-9525-6c099600705f}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{48D0ADAF-62EC-472E-A51B-8D837280649D}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>nlwav</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\prg\nlwav.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -7,7 +7,6 @@
#include "nld_2102A.h"
#include "netlist/nl_base.h"
#include "nlid_system.h"
#define ADDR2BYTE(a) ((a) >> 3)
#define ADDR2BIT(a) ((a) & 0x7)
@ -33,7 +32,8 @@ namespace netlist
NETLIB_RESETI();
NETLIB_UPDATEI();
protected:
friend class NETLIB_NAME(2102A_dip);
private:
object_array_t<logic_input_t, 10> m_A;
logic_input_t m_CEQ;
logic_input_t m_RWQ;
@ -46,31 +46,36 @@ namespace netlist
nld_power_pins m_power_pins;
};
NETLIB_OBJECT_DERIVED(2102A_dip, 2102A)
NETLIB_OBJECT(2102A_dip)
{
NETLIB_CONSTRUCTOR_DERIVED(2102A_dip, 2102A)
NETLIB_CONSTRUCTOR(2102A_dip)
, A(*this, "A")
{
register_subalias("8", m_A[0]);
register_subalias("4", m_A[1]);
register_subalias("5", m_A[2]);
register_subalias("6", m_A[3]);
register_subalias("7", m_A[4]);
register_subalias("2", m_A[5]);
register_subalias("1", m_A[6]);
register_subalias("16", m_A[7]);
register_subalias("15", m_A[8]);
register_subalias("14", m_A[9]);
register_subalias("8", A.m_A[0]);
register_subalias("4", A.m_A[1]);
register_subalias("5", A.m_A[2]);
register_subalias("6", A.m_A[3]);
register_subalias("7", A.m_A[4]);
register_subalias("2", A.m_A[5]);
register_subalias("1", A.m_A[6]);
register_subalias("16", A.m_A[7]);
register_subalias("15", A.m_A[8]);
register_subalias("14", A.m_A[9]);
register_subalias("13", m_CEQ);
register_subalias("3", m_RWQ);
register_subalias("13", A.m_CEQ);
register_subalias("3", A.m_RWQ);
register_subalias("11", m_DI);
register_subalias("12", m_DO);
register_subalias("11", A.m_DI);
register_subalias("12", A.m_DO);
register_subalias("10", "VCC");
register_subalias("9", "GND");
register_subalias("10", "A.VCC");
register_subalias("9", "A.GND");
}
NETLIB_RESETI() {}
NETLIB_UPDATEI() {}
private:
NETLIB_SUB(2102A) A;
};
NETLIB_UPDATE(2102A)

View File

@ -7,7 +7,6 @@
#include "nld_2716.h"
#include "netlist/nl_base.h"
#include "nlid_system.h"
namespace netlist
{
@ -28,7 +27,8 @@ namespace netlist
NETLIB_UPDATEI();
protected:
friend class NETLIB_NAME(2716_dip);
private:
object_array_t<logic_input_t, 11> m_A;
logic_input_t m_GQ;
logic_input_t m_EPQ;
@ -40,37 +40,42 @@ namespace netlist
nld_power_pins m_power_pins;
};
NETLIB_OBJECT_DERIVED(2716_dip, 2716)
NETLIB_OBJECT(2716_dip)
{
NETLIB_CONSTRUCTOR_DERIVED(2716_dip, 2716)
NETLIB_CONSTRUCTOR(2716_dip)
, A(*this, "A")
{
register_subalias("8", m_A[0]);
register_subalias("7", m_A[1]);
register_subalias("6", m_A[2]);
register_subalias("5", m_A[3]);
register_subalias("4", m_A[4]);
register_subalias("3", m_A[5]);
register_subalias("2", m_A[6]);
register_subalias("1", m_A[7]);
register_subalias("23", m_A[8]);
register_subalias("22", m_A[9]);
register_subalias("19", m_A[10]);
register_subalias("8", A.m_A[0]);
register_subalias("7", A.m_A[1]);
register_subalias("6", A.m_A[2]);
register_subalias("5", A.m_A[3]);
register_subalias("4", A.m_A[4]);
register_subalias("3", A.m_A[5]);
register_subalias("2", A.m_A[6]);
register_subalias("1", A.m_A[7]);
register_subalias("23", A.m_A[8]);
register_subalias("22", A.m_A[9]);
register_subalias("19", A.m_A[10]);
register_subalias("20", m_GQ);
register_subalias("18", m_EPQ);
register_subalias("20", A.m_GQ);
register_subalias("18", A.m_EPQ);
register_subalias("9", m_D[0]);
register_subalias("10", m_D[1]);
register_subalias("11", m_D[2]);
register_subalias("13", m_D[3]);
register_subalias("14", m_D[4]);
register_subalias("15", m_D[5]);
register_subalias("16", m_D[6]);
register_subalias("17", m_D[7]);
register_subalias("9", A.m_D[0]);
register_subalias("10", A.m_D[1]);
register_subalias("11", A.m_D[2]);
register_subalias("13", A.m_D[3]);
register_subalias("14", A.m_D[4]);
register_subalias("15", A.m_D[5]);
register_subalias("16", A.m_D[6]);
register_subalias("17", A.m_D[7]);
register_subalias("12", "GND");
register_subalias("24", "VCC");
register_subalias("12", "A.GND");
register_subalias("24", "A.VCC");
}
NETLIB_RESETI() {}
NETLIB_UPDATEI() {}
private:
NETLIB_SUB(2716) A;
};
// FIXME: timing!

View File

@ -6,7 +6,7 @@
*/
#include "nld_4006.h"
#include "nlid_system.h"
#include "nl_base.h"
namespace netlist
{
@ -61,7 +61,8 @@ namespace netlist
}
}
protected:
friend class NETLIB_NAME(CD4006_dip);
private:
logic_input_t m_CLOCK;
object_array_t<logic_input_t, 4> m_I;
object_array_t<logic_output_t, 7> m_Q;
@ -70,27 +71,32 @@ namespace netlist
nld_power_pins m_supply;
};
NETLIB_OBJECT_DERIVED(CD4006_dip, CD4006)
NETLIB_OBJECT(CD4006_dip)
{
NETLIB_CONSTRUCTOR_DERIVED(CD4006_dip, CD4006)
NETLIB_CONSTRUCTOR(CD4006_dip)
, A(*this, "A")
{
register_subalias("1", m_I[0]);
register_subalias("2", m_Q[1]);
register_subalias("3", m_CLOCK);
register_subalias("4", m_I[1]);
register_subalias("5", m_I[2]);
register_subalias("6", m_I[3]);
register_subalias("7", "VSS");
register_subalias("1", A.m_I[0]);
register_subalias("2", A.m_Q[1]);
register_subalias("3", A.m_CLOCK);
register_subalias("4", A.m_I[1]);
register_subalias("5", A.m_I[2]);
register_subalias("6", A.m_I[3]);
register_subalias("7", "A.VSS");
register_subalias("8", m_Q[5]);
register_subalias("9", m_Q[6]);
register_subalias("10", m_Q[4]);
register_subalias("11", m_Q[2]);
register_subalias("12", m_Q[3]);
register_subalias("13", m_Q[0]);
register_subalias("14", "VDD");
register_subalias("8", A.m_Q[5]);
register_subalias("9", A.m_Q[6]);
register_subalias("10", A.m_Q[4]);
register_subalias("11", A.m_Q[2]);
register_subalias("12", A.m_Q[3]);
register_subalias("13", A.m_Q[0]);
register_subalias("14", "A.VDD");
}
NETLIB_RESETI() {}
NETLIB_UPDATEI() {}
private:
NETLIB_SUB(CD4006) A;
};
NETLIB_DEVICE_IMPL(CD4006, "CD4006", "+CLOCK,+D1,+D2,+D3,+D4,+D1P4,+D1P4S,+D2P4,+D2P5,+D3P4,+D4P4,+D3P5,@VCC,@GND")

View File

@ -6,7 +6,8 @@
*/
#include "nld_4020.h"
#include "nlid_system.h"
#include "nl_base.h"
#include "nl_factory.h"
namespace netlist
{

View File

@ -9,7 +9,6 @@
#include "netlist/analog/nlid_twoterm.h"
#include "netlist/solver/nld_solver.h"
#include "nlid_system.h"
// This is an experimental approach to implement the analog switch.
// This will make the switch a 3 terminal element which is completely

View File

@ -8,7 +8,6 @@
#include "nld_4316.h"
#include "netlist/analog/nlid_twoterm.h"
#include "netlist/solver/nld_solver.h"
#include "nlid_system.h"
namespace netlist { namespace devices {

Some files were not shown because too many files have changed in this diff Show More