bus/a800: modernize cart slot interface (#10528)

- use address_maps instead of catch-all handlers;
- implement rd4 and rd5 line views;
- converted a800_rom_williams_device to the new system, make almost every entry in mega* and prisma* SW to actually boot;
- bus/a800: implement maxflash_1mb / maxflash_8mb devices. 
* This allows loading arbitrary collection of .xex files built thru Maxflash Cartridge Studio program as flash ROM binaries;
- bus/a800: implement sic_128kb / sic_256kb / sic_512kb flash ROM devices;
- bus/a800: implement  ast2k, atrax, Blizzard 32kb, Adawliah, SpartaDOS 128KB, A5200 Super Cart variants;
- bus/a800: implement Super Charger math unit device;
- a800_slot.cpp: fix xegs cart default slot for loose cart loading;
- a800_carts.h: merge a800_turbo64 and a800_turbo128 into single a800_turbo slot option;
- bus/a800/a800_slot: split a5200 to own interface

New working software list additions
-----------------------------------
a800.xml: Maxflash Cartridge Studio - Demonstration Workbook [Atarimax Team], SIC! 31-in-1 Demonstration [SIC! Team]
a800.xml: Atrax 01, Atrax 02, Atrax 03, Atrax 04, Atrax 05, Atrax 06, Atrax 08, Atrax 09, Atrax 10, Atrax 11, Atrax 12, Atrax 13, Atrax 15 [Atarimania]
a800.xml: Prince of Persia (AtariMAX i/f), Prince of Persia (SIC! i/f) [AtariAge]

New software list items marked not working
------------------------------------------
a800.xml: Atrax 14, Atrax 16 [Atarimania], Turbo Hit (Blizzard 32kb) [atari.area]
a5200.xml: Bosconian 5200 - Star Destroyer (Ultimate Version) [AtariAge]
This commit is contained in:
Angelo Salese 2023-06-12 01:51:23 +02:00 committed by GitHub
parent 5ebd8c61f0
commit 0855900ded
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 4454 additions and 1940 deletions

View File

@ -102,7 +102,7 @@ Possible Undumped protos: -
<year>1983</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="5200menu.bin" size="8192" crc="0de2db48" sha1="e64fb1a353c72b87c5483bb88cb3523ea5d37b59"/>
</dataarea>
@ -114,7 +114,7 @@ Possible Undumped protos: -
<year>1982</year>
<publisher>Brøderbund Software Inc</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="aep.bin" size="16384" crc="35484751" sha1="e18a603b18b85e24f9c938b33b6077a767c1fa9c"/>
</dataarea>
@ -127,7 +127,7 @@ Possible Undumped protos: -
<publisher>Activision</publisher>
<info name="serial" value="FC-008" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="decathln.bin" size="16384" crc="f43e7cd0" sha1="db203973df13b071da46d52fdb078a76f4db428d"/>
</dataarea>
@ -140,7 +140,7 @@ Possible Undumped protos: -
<publisher>Atari</publisher>
<info name="serial" value="CX5201" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="asteroid.bin" size="8192" crc="38480891" sha1="18697dd8e640fa1578b3b4ae09af484c14fb8410"/>
</dataarea>
@ -167,7 +167,7 @@ Possible Undumped protos: -
<info name="release" value="19830803" />
<info name="serial" value="CX5233" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="0x8000">
<rom name="astrogrover.bin" size="0x8000" crc="18417ada" sha1="f3bad1c66743c8051d7c9c36eb367bdf908bc6fb"/>
</dataarea>
@ -180,7 +180,7 @@ Possible Undumped protos: -
<publisher>Atari / Lucasfilm</publisher>
<info name="serial" value="CX5255" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="ballblze.bin" size="32768" crc="94d97d14" sha1="ed92ffd21abd50339f5be0cbff9bdcc8fafbc67f"/>
</dataarea>
@ -188,7 +188,7 @@ Possible Undumped protos: -
</software>
<!-- Barroom Baseball. This prototype is for an standup arcade environment involving coins/timer and is based on Real Sports
Baseball. While this functions in an Atari 5200 as a cartridge image, it is not a home cartridge. Therefore, it is commented. -->
Baseball. While this functions in an Atari 5200 as a cartridge image, it is not a home cartridge. Handled in atari/bartop52.cpp -->
<!--
<software name="barbball">
@ -196,7 +196,7 @@ Possible Undumped protos: -
<year>1983</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="barbball.bin" size="32768" crc="21d19c8f" sha1="510ccb20df2ecdbe7f8373de6a9fc11493e8c3f2"/>
</dataarea>
@ -223,7 +223,7 @@ Possible Undumped protos: -
<publisher>Atari</publisher>
<info name="serial" value="CX5239" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="0x8000"> <!-- same data as the other set but repeated -->
<rom name="battle zone lo.a" size="0x2000" crc="45247338" sha1="1b27681fb53ab80bd39e4e7ad0a35625c79e7677" offset="0x0000"/>
<rom name="battle zone mlo.b" size="0x2000" crc="45247338" sha1="1b27681fb53ab80bd39e4e7ad0a35625c79e7677" offset="0x2000"/>
@ -239,7 +239,7 @@ Possible Undumped protos: -
<publisher>Activision</publisher>
<info name="serial" value="FZ-009" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="beamrid.bin" size="16384" crc="9bae58dc" sha1="b75d555d059ad61992f9f5a234129ecbf9504c35"/>
</dataarea>
@ -251,7 +251,7 @@ Possible Undumped protos: -
<year>1984</year>
<publisher>Atari / Lucasfilm</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="0x8000">
<rom name="behind jaggi lo 1-18-84 101a.a" size="0x2000" crc="c244bde8" sha1="a08b1764ab3b8f3c30fd90faa3ac62fcf447dbb0" offset="0x0000"/>
<rom name="behind jaggi mlo 1-18-84 c3c1.b" size="0x2000" crc="5ea68db3" sha1="499ec2f48314943f1f3d4cb39f484a21f4d0009a" offset="0x2000"/>
@ -267,7 +267,7 @@ Possible Undumped protos: -
<publisher>Atari</publisher>
<info name="serial" value="CX5221" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="berzerk.bin" size="16384" crc="be3cd348" sha1="e56ccc6bf427a832ce00540b02d065a2688260dc"/>
</dataarea>
@ -278,9 +278,13 @@ Possible Undumped protos: -
<description>Black Belt (prototype)</description>
<year>1983</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Sluggish in gameplay (btanb)
]]></notes>
<info name="usage" value="Select difficulty with 1-8 keys, press start then press 0 key" />
<info name="serial" value="CX5231" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="blckbelt.bin" size="32768" crc="ed47b0d8" sha1="9b7ecd444b6239442ef1f54cd8e14c294c064da2"/>
</dataarea>
@ -292,7 +296,7 @@ Possible Undumped protos: -
<year>1984</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="blaster.bin" size="16384" crc="c8f9c094" sha1="ab3130256d16af09cac8b11749dfaff6aaaa3ea3"/>
</dataarea>
@ -305,13 +309,32 @@ Possible Undumped protos: -
<publisher>CBS Electronics / Bally Midway MFG. Co.</publisher>
<info name="serial" value="80033" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="blueprnt.bin" size="16384" crc="0624e6e7" sha1="1e1a20c104bf4d55eca0ca1e72dc5dc64fa6b1b5"/>
</dataarea>
</part>
</software>
<software name="bosco" supported="no">
<!-- Versioning on title screen, earlier 128KB Super Cart known to exist -->
<description>Bosconian 5200 - Star Destroyer (Ultimate Version)</description>
<year>2019</year>
<publisher>&lt;homebrew&gt;</publisher>
<notes><![CDATA[
Player dot is invisible on radar
Status bar cuts off words (i.e. ROUN instead of ROUND)
Text colors are off on title and score table screens
Title grey animation doesn't mask [ANTIC] playfield properly
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200_supercart" />
<dataarea name="rom" size="0x80000">
<rom name="bosconian.bin" size="0x80000" crc="cedcd5d9" sha1="8a92963b3b0b45393bdc31d86120044282534c4b"/>
</dataarea>
</part>
</software>
<software name="bbsb" supported="partial">
<description>Bounty Bob Strikes Back!</description>
<year>1984</year>
@ -360,7 +383,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5253" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="choplift.bin" size="16384" crc="9ad53bbc" sha1="9f1ee191319ef0261cc7074a81c0e6d6b7464cd2"/>
</dataarea>
@ -400,7 +423,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-011" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="pitfall2.bin" size="16384" crc="4b910461" sha1="b051f0fb2e816787ab6eed0cb008b9f8cc9963dc"/>
</dataarea>
@ -439,7 +462,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-005" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="dredfctr.bin" size="8192" crc="460def2d" sha1="ea7b40ce1106378e1d409cab6634fb2e483ff238"/>
</dataarea>
@ -452,7 +475,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5256" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="finalleg.bin" size="16384" crc="d3bd3221" sha1="48625af4f3e9fe538dab2a0b463887fc8c6b138d"/>
</dataarea>
@ -477,7 +500,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Parker Brothers</publisher>
<info name="serial" value="9530" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="frogger.bin" size="8192" crc="ae7e3444" sha1="d9a695757f0494aee92a50ab8a49558745e0cedf"/>
</dataarea>
@ -497,13 +520,17 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
</part>
</software>
<software name="galaxian">
<software name="galaxian" supported="no">
<description>Galaxian</description>
<year>1982</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Player missile is vertically offset when idle
Some enemies never collides with player bullets
]]></notes>
<info name="serial" value="CX5206" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="8192">
<rom name="galaxian.bin" size="8192" crc="3ef4a23f" sha1="0df0d7f11d89e2c5b59cc9f98d67d98e203831aa"/>
@ -517,7 +544,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>CBS Electronics / Bally Midway MFG. Co.</publisher>
<info name="serial" value="80013" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="gorf.bin" size="8192" crc="e955db74" sha1="80926bb270ea66cb5cacc379de1fc16d8a3d814b"/>
</dataarea>
@ -530,7 +557,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5257" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="gremlins.bin" size="32768" crc="063ec2c4" sha1="f3c32b39580d589799dcead98bb206fbf3df0504"/>
</dataarea>
@ -556,7 +583,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-007" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="hero.bin" size="16384" crc="18a73af3" sha1="d286ecb6793a0dda9c9c68f6355dbe3ade6922f9"/>
</dataarea>
@ -621,7 +648,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>CBS Electronics / Kay Enterprizes Co.</publisher>
<info name="serial" value="80503" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="krazysht.bin" size="8192" crc="ee702214" sha1="c7eb2b4a46a197adfedf33c2ccc17d8424d681c4"/>
</dataarea>
@ -634,7 +661,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-001" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="4096">
<rom name="kaboom.bin" size="4096" crc="420f5d0b" sha1="a80f876a89a8ceacc71da5d9c02b546970b17730"/>
@ -661,7 +688,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-006" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="keystone.bin" size="8192" crc="8fe3bb2c" sha1="9f31c85a13e919135438590601e33bef11a8df8a"/>
</dataarea>
@ -674,7 +701,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5260" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="laststar.bin" size="16384" crc="83517703" sha1="4046f60602254a7d86d2a6efd1a330455eaec119"/>
</dataarea>
@ -699,19 +726,24 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5247" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="mario.bin" size="32768" crc="873742f1" sha1="a293b6b06050e11029d97137f2b1b36059567273"/>
</dataarea>
</part>
</software>
<software name="meebzork">
<software name="meebzork" supported="partial">
<description>Meebzork (prototype)</description>
<year>1983</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Unresponsive menuing (btanb)
Doesn't seem to provide a way to restart a game without system reset (btanb)
Doesn't mask sprites on title and "the end" screens [GTIA] GRACTL
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="meebzork.bin" size="32768" crc="9fb13411" sha1="ff0f1d9ed0ae45e3c81b252f3d0a335e03b0aa4b"/>
</dataarea>
@ -724,7 +756,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-003" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="megamnia.bin" size="8192" crc="240a1e1a" sha1="f5512460c6b6d3a1baa0b23adf6a3a37fe308eb3"/>
</dataarea>
@ -736,7 +768,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1983</year>
<publisher>Electra Concepts</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="meteorit.bin" size="16384" crc="ab8e035b" sha1="32d86a381feff43149b66336dcc4ba2523273228"/>
</dataarea>
@ -761,7 +793,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5248" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="16384">
<rom name="milliped.bin" size="16384" crc="969cfe1a" sha1="1243a8ecfc02a74ae4e1f4fcda38502776f45cb0"/>
@ -769,13 +801,16 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
</part>
</software>
<software name="mine2049">
<software name="mine2049" supported="partial">
<description>Miner 2049er</description>
<year>1983</year>
<publisher>Big Five Software</publisher>
<notes><![CDATA[
Hi-score screen has wrong colored rotating digits and direction desyncs at bottom
]]></notes>
<info name="serial" value="BF1912" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="mine2049.bin" size="16384" crc="7df1adfb" sha1="0564b1867a0b570d66dfcbc11adc3e51a2c6f28c"/>
</dataarea>
@ -801,7 +836,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5202" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="8192">
<rom name="missile.bin" size="8192" crc="44d3ff6f" sha1="5c8ec22e131810ccac08066ca96e9944ccfa4ecb"/>
@ -828,7 +863,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5241" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="mpatrol.bin" size="16384" crc="d0b2f285" sha1="02dd5b9278c06ae8cbb6dacc094e238fbacf08d2"/>
</dataarea>
@ -841,7 +876,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>CBS Electronics</publisher>
<info name="serial" value="80083" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="mntnking.bin" size="8192" crc="0f24243c" sha1="2e7ae57260624d1f5710d445a0936f0c280a6655"/>
</dataarea>
@ -854,7 +889,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Parker Brothers</publisher>
<info name="serial" value="9420" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="docastle.bin" size="8192" crc="aa55f9be" sha1="002e6f8c7533b03f8041e7f1896589c0ab0e17a6"/>
</dataarea>
@ -893,7 +928,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5236" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="pengo.bin" size="32768" crc="e4f8ba8c" sha1="19ff7622dbbc2915e3e98d8d966340e7e893ff34"/>
</dataarea>
@ -906,7 +941,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-004" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="pitfall.bin" size="8192" crc="b2887833" sha1="d1c7dc3de097a4bfab82235acec69a97e6e05f18"/>
</dataarea>
@ -932,7 +967,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1983</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="0x8000">
<rom name="poleposition_133-05.bin" size="0x8000" crc="15b7b5ef" sha1="c22e5ea7cc892f515e4967f6ff0844b5a8d34b62"/>
@ -959,7 +994,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Parker Brothers</publisher>
<info name="serial" value="9500" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="qbert.bin" size="8192" crc="3fe4a401" sha1="e6966bde5cd4167020c9d21bab613af1648b4d75"/>
</dataarea>
@ -979,13 +1014,16 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
</part>
</software>
<software name="quintana">
<software name="quintana" supported="no">
<description>Quest for Quintana Roo</description>
<year>1984</year>
<publisher>Sunrise</publisher>
<notes><![CDATA[
Doesn't recognize start button
]]></notes>
<info name="serial" value="1603" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="questroo.bin" size="16384" crc="b5f3402b" sha1="17a41c5f9a32f8a71939cfaa0e96807b951aedad"/>
</dataarea>
@ -998,7 +1036,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5209" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="32768">
<rom name="rsbsebll.bin" size="32768" crc="44166592" sha1="a94d06739fa19453fa586a836eaacae11fe93989"/>
@ -1012,7 +1050,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5219" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="rsbktbll.bin" size="32768" crc="dd217276" sha1="9b21ac7fec8d556585c6970231318ef1f501b2b5"/>
</dataarea>
@ -1025,7 +1063,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5219" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="rsbktbll1.bin" size="32768" crc="c90196fa" sha1="9edb066a37ca7657979952c946ab89be7926f4f8"/>
</dataarea>
@ -1060,11 +1098,14 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
</part>
</software>
<software name="rssoccer">
<software name="rssoccer" supported="no">
<description>RealSports Soccer</description>
<!-- Originally released as "Soccer" -->
<year>1982</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Analog input ranges don't allow going down and right on full presses (i.e. on digital input tapping goes right, holding goes left)
]]></notes>
<info name="serial" value="CX5213" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200_2chips" />
@ -1095,7 +1136,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari / Lucasfilm</publisher>
<info name="serial" value="CX5254" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="fractal.bin" size="32768" crc="762c591b" sha1="9253d7286cf87999474b37df242ba23b4358ef4a"/>
</dataarea>
@ -1108,7 +1149,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-002" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="riveraid.bin" size="8192" crc="09fc7648" sha1="ce9bd3b0847c5e187c3e8f667c8f5ea771c49965"/>
</dataarea>
@ -1134,7 +1175,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5225" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="robotron.bin" size="16384" crc="4252abd9" sha1="9175e6daca58102ac8b9729d7b0336cf09977d12"/>
</dataarea>
@ -1160,7 +1201,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5204" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="8192">
<rom name="spaceinv.bin" size="8192" crc="de5c354a" sha1="cf411db770217b5af5fcfa32725cc587a8b9e710"/>
@ -1174,7 +1215,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-012" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="spceshut.bin" size="16384" crc="387365dc" sha1="5ae20e767d9819fe601f3b1ea6d4506ae2f2ceef"/>
</dataarea>
@ -1186,7 +1227,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1983</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="spitfire.bin" size="32768" crc="3c311303" sha1="688133761c462d6865bf673ed298b4d828120940"/>
</dataarea>
@ -1238,7 +1279,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Parker Brothers</publisher>
<info name="serial" value="9060" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="starwars.bin" size="8192" crc="0675f0a5" sha1="bf77048abc36ba2cba5eeeac812802d6a0eba891"/>
</dataarea>
@ -1277,7 +1318,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5203" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<feature name="peripheral" value="trackball" /> <!-- Works with Trackball controller -->
<dataarea name="rom" size="4096">
<rom name="sprbreak.bin" size="4096" crc="a0642110" sha1="f5f9c7f97bf09e5647e808d892b656f3ee1e19e0"/>
@ -1291,7 +1332,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Parker Brothers</publisher>
<info name="serial" value="9550" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="scobra.bin" size="8192" crc="97debcd2" sha1="8205093f5fb1fdf0ccb71d667ea0a3849fb0a0f2"/>
</dataarea>
@ -1303,7 +1344,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1984</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="spacman.bin" size="16384" crc="0a4ddb1e" sha1="238cb448555d8bb5c96aa0354718411e8777c613"/>
</dataarea>
@ -1317,7 +1358,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<info name="developer" value="Keithen Hayenga" />
<info name="serial" value="CX5220" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="tempest.bin" size="16384" crc="1187342f" sha1="85fcea0a4d4d1f22437801c96229ba96e0f6b711"/>
</dataarea>
@ -1330,7 +1371,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5258" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="trackfld.bin" size="16384" crc="0ba22ece" sha1="9dfbb5d8b77504c66ce3ac4382daf79820393dd8"/>
</dataarea>
@ -1343,7 +1384,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5216" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="vanguard.bin" size="32768" crc="caaea0a4" sha1="6c633de50e6cc0c0c40061cd24e6f78f552a438f"/>
</dataarea>
@ -1356,17 +1397,20 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>CBS Electronics</publisher>
<info name="serial" value="80003" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="wow.bin" size="16384" crc="d6f7ddfd" sha1="49debdf3c133fde9905d6d9137da5d8dff8d6283"/>
</dataarea>
</part>
</software>
<software name="xari">
<software name="xari" supported="no">
<description>Xari Arena (prototype)</description>
<year>1983</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Flickering player sprite, unplayable
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200_2chips" />
<dataarea name="rom" size="16384">
@ -1381,7 +1425,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Atari</publisher>
<info name="serial" value="CX5246" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="xevious.bin" size="32768" crc="382634dc" sha1="c3cf33216dfa484309b923f21829d040486bc481"/>
</dataarea>
@ -1393,7 +1437,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1983</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="4096">
<rom name="yllowsub.bin" size="4096" crc="f47bc091" sha1="e58e1f257923694dbeb586c860f385e74e460f90"/>
</dataarea>
@ -1406,7 +1450,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Sega</publisher>
<info name="serial" value="008-02" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="zaxxon.bin" size="32768" crc="741746d1" sha1="4a4c4a25c8ed1b0ae79ca22684d7d311a564a7b5"/>
</dataarea>
@ -1419,7 +1463,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-010" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="zenji.bin" size="8192" crc="da228530" sha1="55da563b4394508c23d866fb1e543262fb45536d"/>
</dataarea>
@ -1432,7 +1476,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>Activision</publisher>
<info name="serial" value="FZ-101" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="16384">
<rom name="znerangr.bin" size="16384" crc="2959d827" sha1="18315bec1e62102290feeb77fb290e1266cf5bfc"/>
</dataarea>
@ -1444,17 +1488,20 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1982</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="petetest.bin" size="8192" crc="28278cd6" sha1="d3ff99e080985c9c8e25389dfa74835e8c9be508"/>
</dataarea>
</part>
</software>
<software name="pamdiag2">
<software name="pamdiag2" supported="no">
<description>PAM Diag 2.0</description>
<year>1982</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Crashes on Atari copyright screen
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200_2chips" />
<dataarea name="rom" size="16384">
@ -1463,10 +1510,14 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
</part>
</software>
<software name="pamdg23">
<software name="pamdg23" supported="partial">
<description>Atari PAM Diagnostics (rev 2.3)</description>
<year>1983</year>
<publisher>Atari</publisher>
<notes><![CDATA[
[ANTIC] test returns "soft error 34 01"
[POKEY] test requires an unemulated loopback serial board
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200_2chips" />
<dataarea name="rom" size="16384">
@ -1480,7 +1531,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1982</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="8192">
<rom name="finaltst.bin" size="8192" crc="7ea86e87" sha1="af81c400f1af0ee13a24da5e8b642442a0fc9479"/>
</dataarea>
@ -1492,33 +1543,39 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<year>1982</year>
<publisher>Atari</publisher>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="4096">
<rom name="boogie.bin" size="4096" crc="3bd5fdd6" sha1="5236bc13e4b06d2e16d70b0a0c98588e1726da0c"/>
</dataarea>
</part>
</software>
<software name="cblast">
<software name="cblast" supported="no">
<description>Castle Blast</description>
<year>2002</year>
<publisher>&lt;unlicensed&gt;</publisher>
<publisher>&lt;homebrew&gt;</publisher>
<notes><![CDATA[
Playfield is gray filled, unplayable
]]></notes>
<info name="developer" value="Ronen Habot" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="cblast.bin" size="32768" crc="7c988054" sha1="c1a56a1fc51e09b1d8e93af40ddd7596847e6164"/>
</dataarea>
</part>
</software>
<software name="ccrisis">
<software name="ccrisis" supported="no">
<description>Castle Crisis</description>
<year>2004</year>
<publisher>&lt;unlicensed&gt;</publisher>
<publisher>&lt;homebrew&gt;</publisher>
<notes><![CDATA[
[ANTIC] playfield height doesn't cover full screen
]]></notes>
<info name="developer" value="Bryan Edewaard" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="ccrisis.bin" size="32768" crc="d50e4061" sha1="4e022e101d7346a0a8618018372740e7333b4a36"/>
</dataarea>
@ -1528,10 +1585,10 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<software name="koffiyk">
<description>Koffi: Yellow Kopter</description>
<year>2002</year>
<publisher>&lt;unlicensed&gt;</publisher>
<publisher>&lt;homebrew&gt;</publisher>
<info name="developer" value="Ron Lloyd" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="koffiyk.bin" size="32768" crc="917be656" sha1="9547c56e2951e1b3a713b0b99d3edb43c9d3cdd8"/>
</dataarea>
@ -1544,7 +1601,7 @@ Sometimes it throws [GTIA] glitchy frames (noticeable on player deaths)
<publisher>AtariAge</publisher> <!-- unlicensed? -->
<info name="developer" value="Keithen Hayenga" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="a5200" />
<feature name="slot" value="a5200_rom" />
<dataarea name="rom" size="32768">
<rom name="tempest (atariage).bin" size="32768" crc="a6400e17" sha1="0cb2bd6ed89ce6710ac092533a24f1248688c88c"/>
</dataarea>

File diff suppressed because it is too large Load Diff

View File

@ -887,7 +887,7 @@ Tested with marsmis2, fails
</part>
</software>
<!-- v.1.0 also known to exist (in .xex format -->
<!-- v.1.0 also known to exist (in .xex format) -->
<software name="yoomp" supported="partial">
<description>Yoomp! (v.1.1)</description>
<year>2007</year>
@ -948,28 +948,15 @@ Garbage row strip at bottom of screen
</part>
</software>
<software name="writer">
<description>The Writer's Tool</description>
<year>1985</year>
<publisher>OSS</publisher>
<sharedfeat name="requirement" value="a800:writerd"/>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="92176">
<rom name="writer's tool.atr" size="92176" crc="5a6e2133" sha1="c6d4c49fb53a41b28634b209176c74ed86fbfc64"/>
</dataarea>
</part>
<part name="flop2" interface="floppy_5_25">
<dataarea name="flop" size="92176">
<rom name="writer's tool dictionary.atr" size="92176" crc="18c875b0" sha1="7c727bcc488892dfd83cfbc09b3e1e642d1beff9"/>
</dataarea>
</part>
</software>
<software name="specdemo" supported="no">
<description>Spectraview II Demo Disk</description>
<!-- Disk contains Sparta DOS and won't boot in MAME, works on other emulators -->
<year>198?</year>
<publisher>Display Systems International</publisher>
<notes><![CDATA[
"Error: No DOS"
Trying to DIR in SDX returns error 144 bad sector, trying to CAR will black screen as per a800:spectra2
]]></notes>
<sharedfeat name="requirement" value="a800:spectra2"/>
<part name="flop1" interface="floppy_5_25">
<dataarea name="flop" size="183952">

View File

@ -76,10 +76,13 @@ Compiled by K1W1
</part>
</software>
<software name="barnblst">
<software name="barnblst" supported="no">
<description>Barnyard Blaster</description>
<year>1987</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Requires unsupported [Atari XG-1 light gun]
]]></notes>
<info name="serial" value="RX8086" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -92,9 +95,13 @@ Compiled by K1W1
<software name="beefdrop" supported="partial">
<description>Beef Drop</description>
<!-- This is the last WIP version by Ken Siders, dated 2005-02-16. It is here as a placeholder until the dump of the final release version by Atari Age becomes avaialable. -->
<!-- This is the last WIP version by Ken Siders, dated 2005-02-16. It is here as a placeholder until the dump of the final release version by AtariAge becomes avaialable. -->
<year>2005</year>
<publisher>&lt;homebrew&gt;</publisher>
<notes><![CDATA[
Hangs during gameplay and attract demo, PC=0x7af4 routine loops forever (X gets corrupt somehow from irq routines, regression)
Title screen doesn't draw player sprite properly the first time around [GTIA]
]]></notes>
<info name="developer" value="Ken Siders" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -142,10 +149,13 @@ Compiled by K1W1
</part>
</software>
<software name="bughunt">
<software name="bughunt" supported="no">
<description>Bug Hunt</description>
<year>1987</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Requires unsupported [Atari XG-1 light gun]
]]></notes>
<info name="serial" value="RX8087" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -156,10 +166,13 @@ Compiled by K1W1
</part>
</software>
<software name="ccrisis">
<software name="ccrisis" supported="no">
<description>Castle Crisis</description>
<year>2003</year>
<publisher>Atari Age</publisher>
<publisher>AtariAge</publisher>
<notes><![CDATA[
[ANTIC] playfield height doesn't cover full screen
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
<dataarea name="rom" size="32768">
@ -193,10 +206,13 @@ Compiled by K1W1
</part>
</software>
<software name="crimbstr">
<software name="crimbstr" supported="no">
<description>Crime Buster</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Requires unsupported [Atari XG-1 light gun]
]]></notes>
<info name="serial" value="RX8104" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -207,10 +223,13 @@ Compiled by K1W1
</part>
</software>
<software name="crossbow" supported="partial">
<software name="crossbow" supported="no">
<description>Crossbow</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Requires unsupported [Atari XG-1 light gun]
]]></notes>
<info name="serial" value="RX8088" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -234,10 +253,13 @@ Compiled by K1W1
</part>
</software>
<software name="darkcham">
<software name="darkcham" supported="partial">
<description>Dark Chambers</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
[ANTIC] playfield doesn't mask properly on the right (should match left border), left border display scrolling artifacts
]]></notes>
<info name="serial" value="RX8101" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -272,10 +294,13 @@ Compiled by K1W1
</part>
</software>
<software name="dsrtflcn">
<software name="dsrtflcn" supported="no">
<description>Desert Falcon</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Hangs on gameplay
]]></notes>
<info name="serial" value="RX8089" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -285,10 +310,13 @@ Compiled by K1W1
</part>
</software>
<software name="fightn">
<software name="fightn" supported="partial">
<description>Fight Night</description>
<year>1987</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Unsupported character save to [disk]
]]></notes>
<info name="serial" value="RX8085" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -298,10 +326,13 @@ Compiled by K1W1
</part>
</software>
<software name="fsim2" supported="partial">
<software name="fsim2" supported="no">
<description>Flight Simulator 2</description>
<year>1987</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Doesn't accept any [keyboard] input when prompted to select monitor type
]]></notes>
<info name="serial" value="RX8091" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -363,10 +394,13 @@ Compiled by K1W1
</part>
</software>
<software name="eaglnest">
<software name="eaglnest" supported="partial">
<description>Into the Eagle's Nest</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Doesn't mask sprites on title screen when exiting attract mode [GTIA] GRACTL
]]></notes>
<info name="serial" value="RX8114" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -376,10 +410,13 @@ Compiled by K1W1
</part>
</software>
<software name="karateka">
<software name="karateka" supported="no">
<description>Karateka</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Crashes during attract
]]></notes>
<info name="serial" value="RX8095" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
@ -427,10 +464,15 @@ Compiled by K1W1
</part>
</software>
<software name="midimaze">
<description>MIDI Maze (Reproduction)</description>
<software name="midimaze" supported="partial">
<!-- "Multi-Machine Maze Mayhem" -->
<!-- Alt spelling: MIDImaze/XE -->
<description>MIDI Maze (v1.00, reproduction)</description>
<year>199?</year>
<publisher>Video 61 / Atari</publisher>
<notes><![CDATA[
Multiplayer game requiring [XM301], [SX212], [850] or direct connection with another Atari computer. Only solo mode works
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
<dataarea name="rom" size="131072">
@ -443,6 +485,9 @@ Compiled by K1W1
<description>MIDI Maze (Prototype)</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Multiplayer game requiring [XM301], [SX212], [850] or direct connection with another Atari computer. Only solo mode works
]]></notes>
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />
<dataarea name="rom" size="131072">
@ -540,10 +585,13 @@ Compiled by K1W1
</part>
</software>
<software name="thundfox">
<software name="thundfox" supported="partial">
<description>Thunderfox</description>
<year>1988</year>
<publisher>Atari</publisher>
<notes><![CDATA[
Status bar flickers during gameplay
]]></notes>
<info name="serial" value="RX8113" />
<part name="cart" interface="a8bit_cart">
<feature name="slot" value="xegs" />

View File

@ -48,15 +48,38 @@ if (BUSES["A800"]~=null) then
MAME_DIR .. "src/devices/bus/a800/cassette.h",
MAME_DIR .. "src/devices/bus/a800/a800_slot.cpp",
MAME_DIR .. "src/devices/bus/a800/a800_slot.h",
MAME_DIR .. "src/devices/bus/a800/a800_carts.cpp",
MAME_DIR .. "src/devices/bus/a800/a800_carts.h",
MAME_DIR .. "src/devices/bus/a800/rom.cpp",
MAME_DIR .. "src/devices/bus/a800/rom.h",
MAME_DIR .. "src/devices/bus/a800/a5200_supercart.cpp",
MAME_DIR .. "src/devices/bus/a800/a5200_supercart.h",
MAME_DIR .. "src/devices/bus/a800/atrax.cpp",
MAME_DIR .. "src/devices/bus/a800/atrax.h",
MAME_DIR .. "src/devices/bus/a800/bbsb.cpp",
MAME_DIR .. "src/devices/bus/a800/bbsb.h",
MAME_DIR .. "src/devices/bus/a800/corina.cpp",
MAME_DIR .. "src/devices/bus/a800/corina.h",
MAME_DIR .. "src/devices/bus/a800/maxflash.cpp",
MAME_DIR .. "src/devices/bus/a800/maxflash.h",
MAME_DIR .. "src/devices/bus/a800/oss.cpp",
MAME_DIR .. "src/devices/bus/a800/oss.h",
MAME_DIR .. "src/devices/bus/a800/phoenix.cpp",
MAME_DIR .. "src/devices/bus/a800/phoenix.h",
MAME_DIR .. "src/devices/bus/a800/rtime8.cpp",
MAME_DIR .. "src/devices/bus/a800/rtime8.h",
MAME_DIR .. "src/devices/bus/a800/sic.cpp",
MAME_DIR .. "src/devices/bus/a800/sic.h",
MAME_DIR .. "src/devices/bus/a800/sparta.cpp",
MAME_DIR .. "src/devices/bus/a800/sparta.h",
MAME_DIR .. "src/devices/bus/a800/supercharger.cpp",
MAME_DIR .. "src/devices/bus/a800/supercharger.h",
MAME_DIR .. "src/devices/bus/a800/telelink2.cpp",
MAME_DIR .. "src/devices/bus/a800/telelink2.h",
MAME_DIR .. "src/devices/bus/a800/ultracart.cpp",
MAME_DIR .. "src/devices/bus/a800/ultracart.h",
MAME_DIR .. "src/devices/bus/a800/williams.cpp",
MAME_DIR .. "src/devices/bus/a800/williams.h",
}
end

View File

@ -0,0 +1,73 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
A5200 Bryan Edewaard's Super Cart
Maps on the full A5200 cart space, uses $bfc0-$bfff reading for banking.
A5200 BIOS will read to $bfe0-$bfff range, this will automatically fallback to the last
available bank for convenience.
TODO:
- Checkout if support for non-512K carts works right, supposedly M.U.L.E. conversion
runs on a 64K ROM version, should be right in theory.
**************************************************************************************************/
#include "a5200_supercart.h"
DEFINE_DEVICE_TYPE(A5200_ROM_SUPERCART, a5200_rom_supercart_device, "a5200_supercart", "Atari 5200 Super Cart")
a5200_rom_supercart_device::a5200_rom_supercart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a5200_rom_device(mconfig, A5200_ROM_SUPERCART, tag, owner, clock)
, m_bank(0)
{
}
void a5200_rom_supercart_device::device_start()
{
save_item(NAME(m_bank));
}
void a5200_rom_supercart_device::device_reset()
{
m_bank_mask = (m_rom_size / 0x8000) - 1;
m_bank = m_bank_mask;
}
/*
* --1- ---- fallback to last available bank
* ---1 xx-- selects lower banks
* ---0 xx-- selects upper banks
*
* On non-512K carts upper lines will just be ignored
* i.e. a 64K will only respond to bits 5 or 4 high, with bit 2 as bank selector for latter.
*/
u8 a5200_rom_supercart_device::bank_r(offs_t offset)
{
if (!machine().side_effects_disabled())
{
if (BIT(offset, 5))
m_bank = m_bank_mask;
else
{
if (BIT(offset, 4))
m_bank = (m_bank & 0xc) | ((offset & 0xc) >> 2);
else
m_bank = (m_bank & 3) | (offset & 0xc);
}
m_bank &= m_bank_mask;
}
return m_rom[(offset & 0x3f) + (m_bank * 0x8000) + 0x7fc0];
}
void a5200_rom_supercart_device::cart_map(address_map &map)
{
map(0x0000, 0x7fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x7fff) + (m_bank * 0x8000)]; })
);
map(0x7fc0, 0x7fff).r(FUNC(a5200_rom_supercart_device::bank_r));
}

View File

@ -0,0 +1,32 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A5200_SUPERCART_H
#define MAME_BUS_A5200_SUPERCART_H
#pragma once
#include "rom.h"
class a5200_rom_supercart_device : public a5200_rom_device
{
public:
a5200_rom_supercart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
protected:
virtual void device_start() override;
virtual void device_reset() override;
u8 m_bank;
u8 m_bank_mask;
u8 bank_r(offs_t offset);
};
DECLARE_DEVICE_TYPE(A5200_ROM_SUPERCART, a5200_rom_supercart_device)
#endif // MAME_BUS_A5200_SUPERCART_H

View File

@ -0,0 +1,108 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli, Angelo Salese
#include "a800_carts.h"
// (#num) denotes the canonical number from .car specs for unemulated/undumped variants
void a800_left(device_slot_interface &device)
{
device.option_add_internal("a800_8k", A800_ROM);
device.option_add_internal("a800_8k_right", A800_ROM_RIGHT);
device.option_add_internal("a800_16k", A800_ROM_16KB);
device.option_add_internal("a800_phoenix", A800_ROM_PHOENIX);
device.option_add_internal("a800_blizzard", A800_ROM_BLIZZARD_16KB);
device.option_add_internal("a800_phoenix_ast2k", A800_ROM_PHOENIX_AST2K);
device.option_add_internal("a800_bbsb", A800_ROM_BBSB);
device.option_add_internal("a800_oss8k", A800_ROM_OSS8K);
device.option_add_internal("a800_oss034m", A800_ROM_OSS34);
device.option_add_internal("a800_oss043m", A800_ROM_OSS43);
device.option_add_internal("a800_ossm091", A800_ROM_OSS91);
// OSS cart with subslot
// device.option_add_internal("a800_mddos", A800_ROM_MDDOS);
device.option_add_internal("a800_williams", A800_ROM_WILLIAMS);
device.option_add_internal("a800_diamond", A800_ROM_DIAMOND);
device.option_add_internal("a800_express", A800_ROM_EXPRESS);
device.option_add_internal("a800_turbo", A800_ROM_TURBO);
device.option_add_internal("a800_tlink2", A800_ROM_TELELINK2);
device.option_add_internal("a800_ultracart", A800_ROM_ULTRACART);
device.option_add_internal("a800_blizzard_32kb", A800_ROM_BLIZZARD_32KB);
device.option_add_internal("a800_adawliah", A800_ROM_ADAWLIAH);
device.option_add_internal("a800_atrax", A800_ROM_ATRAX);
device.option_add_internal("a800_sparta", A800_ROM_SPARTADOS);
device.option_add_internal("a800_sparta_128kb", A800_ROM_SPARTADOS_128KB);
// (#48-#49 / #68) SDX 64KB/128KB variants
// device.option_add_internal("a800_sdx_atrax_64kb", A800_ROM_SDX_ATRAX_64KB);
// device.option_add_internal("a800_sdx_atrax_128kb", A800_ROM_SDX_ATRAX_128KB);
// (#5) DB "Dave Bennett" homebrew cartridge, vaporware? cfr. https://forums.atariage.com/topic/307663-32k-db-cart/
// device.option_add_internal("a800_db", A800_ROM_DB);
// (#47) "Atari Super Turbo" 32 KB Polish cart with exotic banking scheme (256 bytes at a time) that maps to CCTL
// device.option_add_internal("a800_ast", A800_ROM_AST);
// TOOLBOX III / RAMBOX 2 Polish carts with additional 256KB RAM
// device.option_add_internal("a800_jrc", A800_ROM_JRC);
// Czech cart, some kind of toolkit with bankswitch that rolls back after set time
// device.option_add_internal("a800_cos32", A800_ROM_COS32);
// XEGS carts
device.option_add_internal("xegs", XEGS_ROM);
// "XEGS demo cartridge", 4 games in 1 with binary counter applied at reset for each reboot
// device.option_add_internal("xegs_demo", XEGS_ROM_DEMO);
// (#33-#38) Carts sold by Nir Dary in the '90s, has fixed last bank to RD5 and selectable RD4 bank. 32KB to 1MB ROM size options
// device.option_add_internal("xegs_switch", XEGS_ROM_SWITCHABLE);
// flash carts
device.option_add_internal("a800_corina", A800_ROM_CORINA);
device.option_add_internal("a800_corina_sram", A800_ROM_CORINA_SRAM);
device.option_add( "maxflash_128kb", A800_MAXFLASH_128KB);
device.option_add( "maxflash_1mb", A800_MAXFLASH_1MB);
// (#61) MegaMax, has switch that toggles between Atarimax 1MB mode and 2MB
// device.option_add( "megamax", A800_MEGAMAX);
device.option_add( "sic_128kb", A800_SIC_128KB);
device.option_add( "sic_256kb", A800_SIC_256KB);
device.option_add( "sic_512kb", A800_SIC_512KB);
// (#26-#32 / #63-#64) MegaCart 16KB up to 4MB variant too
// device.option_add( "megacart", A800_MEGACART);
// Atarimax MyIDE-II, 512 KB flash ROM + 512 KB RAM + CompactFlash i/f, requires DIY MyBIOS ROM installation into main system
// device.option_add( "myideii", A800_MYIDE_II);
// 512KB flash + CompactFlash, emulates a Sparta DOS X, has DS1305 RTC hooked up thru SPI bus, SIDE 2 is an upgraded variant with slightly different CCTL mapping
// device.option_add( "side1", A800_SIDE1);
// device.option_add( "side2", A800_SIDE2);
// Upgrades SIDE 2 with SD card instead of CF, MX29LV640ET NOR flash chip, 2MB RAM, DMA with various OPs, ROM bank emulation modes with relocatable CCTL ...
// device.option_add( "side3", A800_SIDE3);
// STM32 coprocessor with SD card, cfr. https://github.com/robinhedwards/UnoCart
// device.option_add( "unocart", A800_UNOCART);
// earlier variant of above running on FPGA, cfr. https://github.com/robinhedwards/UltimateCart
// device.option_add( "ultimatecart", A800_ULTIMATECART);
// (#62 / #65) The!Cart, 32/64/128MB + 512KB RAM, emulation modes
// device.option_add( "thecart", A800_THECART);
// non-ROM types
device.option_add( "rtime8", A800_RTIME8);
// adds extra 65C816 coprocessor. No firmware, runs on code uploaded by main CPU, also two rev variants (V1 and V2)
// NB: SDX documentation calls this Weronika, which just seems a Polish alias
// device.option_add( "veronica", A800_VERONICA);
// 128 or 256 KB additional RAM, schematics available at atarimax
// device.option_add( "ramcart", A800_RAM_CART);
// converts analog mono sound to digital by reading $d500 low 4 bitset
// device.option_add( "ad_converter", A800_AD_CONVERTER);
device.option_add( "supercharger", A800_SUPER_CHARGER);
// The PILL! / Super PILL! / Super Cart with RD4/RD5 held high and that's about it (lolwut)
// device.option_add( "pill", A800_PILL);
// Thompson Proburner, EPROM burner
// device.option_add( "proburner", A800_PROBURNER);
// The Multiplexer! (MUX!), PBI bus between 1 master and 8 slaves
// cfr. https://sdx.atari8.info/sdx_files/muxsdx.txt & http://realdos.net/mux.html
// device.option_add( "mux", A800_MUX);
}
void a800_right(device_slot_interface &device)
{
device.option_add_internal("a800_8k_right", A800_ROM_RIGHT);
}
void a5200_carts(device_slot_interface &device)
{
device.option_add_internal("a5200_rom", A5200_ROM);
device.option_add_internal("a5200_2chips", A5200_ROM_2CHIPS);
device.option_add_internal("a5200_bbsb", A5200_ROM_BBSB);
device.option_add_internal("a5200_supercart", A5200_ROM_SUPERCART);
}

View File

@ -1,57 +1,28 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
// copyright-holders:Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_A800_CARTS_H
#define MAME_BUS_A800_A800_CARTS_H
#pragma once
#include "rom.h"
#include "rtime8.h"
#include "a5200_supercart.h"
#include "atrax.h"
#include "bbsb.h"
#include "corina.h"
#include "maxflash.h"
#include "oss.h"
#include "phoenix.h"
#include "rtime8.h"
#include "sic.h"
#include "sparta.h"
#include "supercharger.h"
#include "telelink2.h"
#include "ultracart.h"
#include "williams.h"
static void a800_left(device_slot_interface &device)
{
device.option_add_internal("a800_8k", A800_ROM);
device.option_add_internal("a800_8k_right", A800_ROM);
device.option_add_internal("a800_16k", A800_ROM);
device.option_add_internal("a800_phoenix", A800_ROM); // not really emulated at this stage
device.option_add_internal("a800_bbsb", A800_ROM_BBSB);
device.option_add_internal("a800_oss8k", A800_ROM_OSS8K);
device.option_add_internal("a800_oss034m", A800_ROM_OSS34);
device.option_add_internal("a800_oss043m", A800_ROM_OSS43);
device.option_add_internal("a800_ossm091", A800_ROM_OSS91);
device.option_add_internal("a800_williams", A800_ROM_WILLIAMS);
device.option_add_internal("a800_diamond", A800_ROM_EXPRESS);
device.option_add_internal("a800_express", A800_ROM_EXPRESS);
device.option_add_internal("a800_sparta", A800_ROM_SPARTADOS); // this is a passthru cart with unemulated (atm) subslot
device.option_add_internal("a800_blizzard", A800_ROM);
device.option_add_internal("a800_turbo64", A800_ROM_TURBO);
device.option_add_internal("a800_turbo128", A800_ROM_TURBO);
device.option_add_internal("a800_tlink2", A800_ROM_TELELINK2);
device.option_add_internal("a800_sitsa", A800_ROM_MICROCALC);
device.option_add_internal("a800_corina", A800_ROM_CORINA);
device.option_add_internal("a800_corina_sram", A800_ROM_CORINA_SRAM);
device.option_add( "rtime8", A800_RTIME8); // not a ROM cartridge
device.option_add_internal("xegs", XEGS_ROM);
}
static void a800_right(device_slot_interface &device)
{
device.option_add_internal("a800_8k_right", A800_ROM);
}
static void xegs_carts(device_slot_interface &device)
{
device.option_add_internal("xegs", XEGS_ROM);
}
static void a5200_carts(device_slot_interface &device)
{
device.option_add_internal("a5200", A800_ROM);
device.option_add_internal("a5200_2chips", A5200_ROM_2CHIPS);
device.option_add_internal("a5200_bbsb", A5200_ROM_BBSB);
}
void a800_left(device_slot_interface &device);
void a800_right(device_slot_interface &device);
void a5200_carts(device_slot_interface &device);
#endif // MAME_BUS_A800_A800_CARTS_H

View File

@ -1,24 +1,17 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
// copyright-holders:Fabio Priuli, Angelo Salese
/**************************************************************************************************
Atari A800/A5200/XEGS cart slot emulation
Atari 8 bit cart emulation
(through slot devices)
<fill me>
Emulation of the cartslot(s) for Atari 8bit series of home computers
References:
- Altirra HW reference manual 2022-07-07 edition, chapter 8;
- https://github.com/atari800/atari800/blob/master/DOC/cart.txt
- https://www.atarimax.com/jindroush.atari.org/acarts.html
Accessors to ROM are typically given in the area 0xa000-0xbfff, but some
carts (and the right slot in A800) maps ROM to 0x8000-0x9fff too
Bankswitch typically happens by accessing addresses in 0xd500-0xd5ff
Accordingly, this device offers the following handlers
- read_80xx/write_80xx
- read_d5xx/write_d5xx
Notice that these are installed in different ranges at machine start by
the drivers, so that it might well be that offs=0 for read_80xx is 0xa000!
***********************************************************************************************************/
**************************************************************************************************/
#include "emu.h"
#include "a800_slot.h"
@ -30,21 +23,30 @@
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE(A800_CART_SLOT, a800_cart_slot_device, "a800_cart_slot", "Atari 8bit Cartridge Slot")
DEFINE_DEVICE_TYPE(A800_CART_SLOT, a800_cart_slot_device, "a800_cart_slot", "Atari 8-bit Cartridge Slot")
DEFINE_DEVICE_TYPE(A5200_CART_SLOT, a5200_cart_slot_device, "a5200_cart_slot", "Atari 5200 Cartridge Slot")
DEFINE_DEVICE_TYPE(XEGS_CART_SLOT, xegs_cart_slot_device, "xegs_cart_slot", "Atari XEGS Cartridge Slot")
//-------------------------------------------------
// device_vcs_cart_interface - constructor
// device_a800_cart_interface - constructor
//-------------------------------------------------
device_a800_cart_interface::device_a800_cart_interface (const machine_config &mconfig, device_t &device) :
device_interface(device, "a800cart"),
m_rom(nullptr),
m_rom_size(0),
m_bank_mask(0)
device_a800_cart_interface::device_a800_cart_interface (const machine_config &mconfig, device_t &device)
: device_interface(device, "a800cart")
, m_rom(nullptr)
, m_rom_size(0)
, m_bank_mask(0)
{
m_slot = dynamic_cast<a800_cart_slot_device *>(device.owner());
}
device_a5200_cart_interface::device_a5200_cart_interface (const machine_config &mconfig, device_t &device)
: device_interface(device, "a5200cart")
, m_rom(nullptr)
, m_rom_size(0)
, m_bank_mask(0)
{
m_slot = dynamic_cast<a5200_cart_slot_device *>(device.owner());
}
@ -56,6 +58,10 @@ device_a800_cart_interface::~device_a800_cart_interface ()
{
}
device_a5200_cart_interface::~device_a5200_cart_interface ()
{
}
//-------------------------------------------------
// rom_alloc - alloc the space for the cart
//-------------------------------------------------
@ -64,36 +70,77 @@ void device_a800_cart_interface::rom_alloc(uint32_t size)
{
if (m_rom == nullptr)
{
// TODO: shouldn't really load from fixed tag
// (particularly inconvenient for stuff like flash ROM hookups)
m_rom = device().machine().memory().region_alloc(device().subtag("^cart:rom"), size, 1, ENDIANNESS_LITTLE)->base();
m_rom_size = size;
// setup other helpers
// TODO: unusable for SIC! and any other mapping that maps over 0x4000 rather than 0x2000
m_bank_mask = (size / 0x2000) - 1; // code for XEGS carts makes use of this to simplify banking
}
}
//-------------------------------------------------
// ram_alloc - alloc the space for the on-cart RAM
//-------------------------------------------------
void device_a800_cart_interface::ram_alloc(uint32_t size)
void device_a800_cart_interface::interface_pre_start()
{
m_ram.resize(size);
device().save_item(NAME(m_ram));
if (!m_slot->started())
throw device_missing_dependencies();
}
//-------------------------------------------------
// ram_alloc - alloc the space for the on-cart RAM
//-------------------------------------------------
void device_a800_cart_interface::nvram_alloc(uint32_t size)
void device_a800_cart_interface::interface_post_start()
{
m_nvram.resize(size);
device().save_item(NAME(m_nvram));
m_slot->m_space_mem->install_device(0x0000, 0x3fff, *this, &device_a800_cart_interface::cart_map);
m_slot->m_space_io->install_device(0x0000, 0x00ff, *this, &device_a800_cart_interface::cctl_map);
}
void device_a800_cart_interface::cart_map(address_map &map)
{
map(0x0000, 0x3fff).unmaprw();
}
void device_a800_cart_interface::cctl_map(address_map &map)
{
map(0x0000, 0x00ff).unmaprw();
}
void device_a800_cart_interface::rd4_w(int state) { m_slot->m_rd4_cb(state); }
void device_a800_cart_interface::rd5_w(int state) { m_slot->m_rd5_cb(state); }
// helper to call both lines at same time, for anything banking on the full range.
void device_a800_cart_interface::rd_both_w(int state) { rd4_w(state); rd5_w(state); }
// a5200
void device_a5200_cart_interface::rom_alloc(uint32_t size)
{
if (m_rom == nullptr)
{
// TODO: shouldn't really load from fixed tag
// (particularly inconvenient for stuff like flash ROM hookups)
m_rom = device().machine().memory().region_alloc(device().subtag("^cart:rom"), size, 1, ENDIANNESS_LITTLE)->base();
m_rom_size = size;
// setup other helpers
// TODO: unusable for SIC! and any other mapping that maps over 0x4000 rather than 0x2000
m_bank_mask = (size / 0x2000) - 1; // code for XEGS carts makes use of this to simplify banking
}
}
void device_a5200_cart_interface::cart_map(address_map &map)
{
map(0x0000, 0x7fff).unmaprw();
}
void device_a5200_cart_interface::interface_pre_start()
{
if (!m_slot->started())
throw device_missing_dependencies();
}
void device_a5200_cart_interface::interface_post_start()
{
m_slot->m_space_mem->install_device(0x0000, 0x7fff, *this, &device_a5200_cart_interface::cart_map);
}
//**************************************************************************
// LIVE DEVICE
@ -102,29 +149,28 @@ void device_a800_cart_interface::nvram_alloc(uint32_t size)
//-------------------------------------------------
// ****_cart_slot_device - constructor
//-------------------------------------------------
a800_cart_slot_device::a800_cart_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
a800_cart_slot_device::a800_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, A800_CART_SLOT, tag, owner, clock)
, device_memory_interface(mconfig, *this)
, device_cartrom_image_interface(mconfig, *this)
, device_single_card_slot_interface<device_a800_cart_interface>(mconfig, *this)
, m_cart(nullptr)
, m_type(0)
, m_rd4_cb(*this)
, m_rd5_cb(*this)
, m_space_mem_config("cart_mem", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor())
, m_space_io_config("cart_io", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor())
, m_is_xegs(false)
{
}
a800_cart_slot_device::a800_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
a800_cart_slot_device(mconfig, A800_CART_SLOT, tag, owner, clock)
{
}
a5200_cart_slot_device::a5200_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
a800_cart_slot_device(mconfig, A5200_CART_SLOT, tag, owner, clock)
{
}
xegs_cart_slot_device::xegs_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
a800_cart_slot_device(mconfig, XEGS_CART_SLOT, tag, owner, clock)
a5200_cart_slot_device::a5200_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, A5200_CART_SLOT, tag, owner, clock)
, device_memory_interface(mconfig, *this)
, device_cartrom_image_interface(mconfig, *this)
, device_single_card_slot_interface<device_a5200_cart_interface>(mconfig, *this)
, m_cart(nullptr)
, m_space_mem_config("cart_mem", ENDIANNESS_LITTLE, 8, 15, 0, address_map_constructor())
{
}
@ -141,10 +187,6 @@ a5200_cart_slot_device::~a5200_cart_slot_device()
{
}
xegs_cart_slot_device::~xegs_cart_slot_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
@ -152,6 +194,20 @@ xegs_cart_slot_device::~xegs_cart_slot_device()
void a800_cart_slot_device::device_start()
{
m_cart = get_card_device();
m_space_io = &space(AS_IO);
m_space_mem = &space(AS_PROGRAM);
}
void a800_cart_slot_device::device_resolve_objects()
{
m_rd4_cb.resolve_safe();
m_rd5_cb.resolve_safe();
}
void a5200_cart_slot_device::device_start()
{
m_cart = get_card_device();
m_space_mem = &space(AS_PROGRAM);
}
/*-------------------------------------------------
@ -178,26 +234,33 @@ static const a800_slot slot_list[] =
{ A800_OSSM091, "a800_ossm091" },
{ A800_OSS8K, "a800_oss8k" },
{ A800_PHOENIX, "a800_phoenix" },
{ A800_BLIZZARD, "a800_blizzard" },
{ A800_XEGS, "xegs" },
{ A800_BBSB, "a800_bbsb" },
{ A800_DIAMOND, "a800_diamond" },
{ A800_WILLIAMS, "a800_williams" },
{ A800_EXPRESS, "a800_express" },
{ A800_SPARTADOS, "a800_sparta" },
{ A800_TURBO64, "a800_turbo64" },
{ A800_TURBO128, "a800_turbo128" },
{ A800_SPARTADOS_128KB, "a800_sparta_128kb" },
{ A800_TURBO, "a800_turbo" },
{ A800_BLIZZARD, "a800_blizzard" },
{ A800_TELELINK2, "a800_tlink2" },
{ A800_MICROCALC, "a800_sitsa" },
{ A800_ULTRACART, "a800_ultracart" },
{ A800_ATRAX, "a800_atrax" },
{ A800_CORINA, "a800_corina" },
{ A800_CORINA_SRAM, "a800_corina_sram" },
{ SIC_128KB, "sic_128kb" },
{ SIC_256KB, "sic_256kb" },
{ SIC_512KB, "sic_512kb" },
{ ATARIMAX_MAXFLASH_128KB, "maxflash_128kb" },
{ ATARIMAX_MAXFLASH_1MB, "maxflash_1mb" },
{ A800_ADAWLIAH, "a800_adawliah" },
{ A800_8K_RIGHT, "a800_8k_right" },
{ A5200_4K, "a5200" },
{ A5200_8K, "a5200" },
{ A5200_16K, "a5200" },
{ A5200_32K, "a5200" },
{ A5200_4K, "a5200_rom" },
{ A5200_8K, "a5200_rom" },
{ A5200_16K, "a5200_rom" },
{ A5200_32K, "a5200_rom" },
{ A5200_16K_2CHIPS, "a5200_2chips" },
{ A5200_32K, "a5200" },
{ A5200_BBSB, "a5200_bbsb" }
};
@ -274,29 +337,77 @@ std::pair<std::error_condition, std::string> a800_cart_slot_device::call_load()
m_cart->rom_alloc(len);
fread(m_cart->get_rom_base(), len);
}
if (m_type == A800_TELELINK2)
m_cart->nvram_alloc(0x100);
if (m_type == A800_CORINA || m_type == A800_CORINA_SRAM)
m_cart->nvram_alloc(0x2000);
if (m_type == A800_CORINA)
m_cart->ram_alloc(0x4000);
if (m_type == A800_CORINA_SRAM)
m_cart->ram_alloc(0x80000);
logerror("%s loaded cartridge '%s' size %dK\n", machine().system().name, filename(), len/1024);
}
return std::make_pair(std::error_condition(), std::string());
}
std::pair<std::error_condition, std::string> a5200_cart_slot_device::call_load()
{
if (m_cart)
{
uint32_t len;
/*-------------------------------------------------
call_unload
-------------------------------------------------*/
if (loaded_through_softlist())
{
const char *pcb_name;
len = get_software_region_length("rom");
m_cart->rom_alloc(len);
memcpy(m_cart->get_rom_base(), get_software_region("rom"), len);
if ((pcb_name = get_feature("slot")) != nullptr)
m_type = a800_get_pcb_id(pcb_name);
else
m_type = A800_8K;
}
else
{
len = length();
// check whether there is an header, to identify the cart type
if ((len % 0x1000) == 0x10)
{
uint8_t header[16];
fread(header, 0x10);
m_type = identify_cart_type(header);
len -= 0x10; // in identify_cart_type the first 0x10 bytes are read, so we need to adjust here
}
else // otherwise try to guess based on size
{
if (len == 0x8000)
m_type = A5200_32K;
if (len == 0x4000)
m_type = A800_16K;
if (len == 0x2000)
m_type = A800_8K;
if (len == 0x1000)
m_type = A5200_4K;
// also make a try with .hsi file (for .a52 files)
std::string info;
if (hashfile_extrainfo(*this, info) && info.compare("A13MIRRORING")==0)
m_type = A5200_16K_2CHIPS;
}
m_cart->rom_alloc(len);
fread(m_cart->get_rom_base(), len);
}
logerror("%s loaded cartridge '%s' size %dK\n", machine().system().name, filename(), len/1024);
}
return std::make_pair(std::error_condition(), std::string());
}
void a800_cart_slot_device::call_unload()
{
}
void a5200_cart_slot_device::call_unload()
{
}
/*-------------------------------------------------
identify_cart_type - code to detect cart type from
fullpath
@ -306,6 +417,8 @@ int a800_cart_slot_device::identify_cart_type(const uint8_t *header) const
{
int type = A800_8K;
// TODO: canonically applies to .car extension only, have 10 bytes extra header on top
// check CART format
if (strncmp((const char *)header, "CART", 4))
fatalerror("Invalid header detected!\n");
@ -339,6 +452,9 @@ int a800_cart_slot_device::identify_cart_type(const uint8_t *header) const
case 15:
type = A800_OSSM091;
break;
case 17:
type = A800_ATRAX;
break;
case 18:
type = A800_BBSB;
break;
@ -351,19 +467,154 @@ int a800_cart_slot_device::identify_cart_type(const uint8_t *header) const
case 40:
type = A800_BLIZZARD;
break;
case 41:
type = ATARIMAX_MAXFLASH_128KB;
break;
case 42:
type = ATARIMAX_MAXFLASH_1MB;
break;
case 43:
type = A800_SPARTADOS_128KB;
break;
case 44:
type = A800_OSS8K;
break;
case 50:
type = A800_TURBO64;
type = A800_TURBO;
break;
case 51:
type = A800_TURBO128;
type = A800_TURBO;
break;
case 52:
type = A800_MICROCALC;
type = A800_ULTRACART;
break;
// Atari 5200 CART files
case 54:
type = SIC_128KB;
break;
case 55:
type = SIC_256KB;
break;
case 56:
type = SIC_512KB;
break;
case 69:
type = A800_ADAWLIAH;
break;
// Atari 5200 CART files
case 4:
type = A5200_32K;
break;
case 16:
type = A5200_16K;
break;
case 19:
type = A5200_8K;
break;
case 20:
type = A5200_4K;
break;
case 6:
type = A5200_16K_2CHIPS;
break;
case 7:
type = A5200_BBSB;
break;
default:
osd_printf_info("Cart type \"%d\" is currently unsupported.\n", (header[4] << 24) + (header[5] << 16) + (header[6] << 8) + (header[7] << 0));
break;
}
return type;
}
int a5200_cart_slot_device::identify_cart_type(const uint8_t *header) const
{
int type = A800_8K;
// TODO: canonically applies to .car extension only, have 10 bytes extra header on top
// check CART format
if (strncmp((const char *)header, "CART", 4))
fatalerror("Invalid header detected!\n");
switch ((header[4] << 24) + (header[5] << 16) + (header[6] << 8) + (header[7] << 0))
{
case 1:
type = A800_8K;
break;
case 2:
type = A800_16K;
break;
case 3:
type = A800_OSS034M;
break;
case 8:
type = A800_WILLIAMS;
break;
case 9:
type = A800_DIAMOND;
break;
case 10:
type = A800_EXPRESS;
break;
case 11:
type = A800_SPARTADOS;
break;
case 12:
type = A800_XEGS;
break;
case 15:
type = A800_OSSM091;
break;
case 17:
type = A800_ATRAX;
break;
case 18:
type = A800_BBSB;
break;
case 21:
type = A800_8K_RIGHT;
break;
case 39:
type = A800_PHOENIX;
break;
case 40:
type = A800_BLIZZARD;
break;
case 41:
type = ATARIMAX_MAXFLASH_128KB;
break;
case 42:
type = ATARIMAX_MAXFLASH_1MB;
break;
case 43:
type = A800_SPARTADOS_128KB;
break;
case 44:
type = A800_OSS8K;
break;
case 50:
type = A800_TURBO;
break;
case 51:
type = A800_TURBO;
break;
case 52:
type = A800_ULTRACART;
break;
case 54:
type = SIC_128KB;
break;
case 55:
type = SIC_256KB;
break;
case 56:
type = SIC_512KB;
break;
case 69:
type = A800_ADAWLIAH;
break;
// Atari 5200 CART files
case 4:
type = A5200_32K;
break;
@ -396,13 +647,17 @@ int a800_cart_slot_device::identify_cart_type(const uint8_t *header) const
std::string a800_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
// Nope, will crash when mounting the SDX subslot
// std::string slot_default_option = default_option();
const bool is_xegs = m_is_xegs;
if (hook.image_file())
{
uint64_t len;
hook.image_file()->length(len); // FIXME: check error return
int type = is_xegs ? A800_XEGS : A800_8K;
// check whether there is an header, to identify the cart type
int type = A800_8K;
if ((len % 0x1000) == 0x10)
{
size_t actual;
@ -412,13 +667,23 @@ std::string a800_cart_slot_device::get_default_card_software(get_default_card_so
}
else // otherwise try to guess based on size
{
if (is_xegs)
return std::string("xegs");
// TODO: very incomplete, is it also worth it?
// Altirra sports a very complex scoring analysis (including code binary patterns),
// and it still grants to the user multiple options
if (len == 0x4000)
type = A800_16K;
if (len == 0x2000)
type = A800_8K;
}
if (type >= A5200_4K)
if (is_xegs && type != A800_XEGS)
{
osd_printf_info("This game is not designed for XEGS.\n");
osd_printf_info("You might want to run it in %s.\n", type >= A5200_4K ? "A5200" : "A800");
}
else if (type >= A5200_4K)
osd_printf_info("This game is not designed for A800. You might want to run it in A5200.\n");
char const *const slot_string = a800_get_slot(type);
@ -426,7 +691,7 @@ std::string a800_cart_slot_device::get_default_card_software(get_default_card_so
return std::string(slot_string);
}
return software_get_default_slot("a800_8k");
return software_get_default_slot(is_xegs ? "xegs" : "a800_8k");
}
@ -460,41 +725,7 @@ std::string a5200_cart_slot_device::get_default_card_software(get_default_card_s
return std::string(slot_string);
}
return software_get_default_slot("a5200");
}
std::string xegs_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
if (hook.image_file())
{
uint64_t len;
hook.image_file()->length(len); // FIXME: check error return
// check whether there is an header, to identify the cart type
int type = A800_8K;
if ((len % 0x1000) == 0x10)
{
size_t actual;
uint8_t head[0x10];
hook.image_file()->read(&head[0], 0x10, actual); // FIXME: check error return or read returning short
type = identify_cart_type(&head[0]);
}
if (type != A800_XEGS)
{
osd_printf_info("This game is not designed for XEGS. ");
if (type >= A5200_4K)
osd_printf_info("You might want to run it in A5200.\n");
else
osd_printf_info("You might want to run it in A800 or A800XL.\n");
}
char const *const slot_string = a800_get_slot(type);
return std::string(slot_string);
}
return software_get_default_slot("xegs");
return software_get_default_slot("a5200_rom");
}
@ -502,35 +733,53 @@ std::string xegs_cart_slot_device::get_default_card_software(get_default_card_so
read
-------------------------------------------------*/
uint8_t a800_cart_slot_device::read_80xx(offs_t offset)
device_memory_interface::space_config_vector a800_cart_slot_device::memory_space_config() const
{
if (m_cart)
return m_cart->read_80xx(offset);
else
return 0xff;
return space_config_vector{
std::make_pair(AS_PROGRAM, &m_space_mem_config),
std::make_pair(AS_IO, &m_space_io_config)
};
}
uint8_t a800_cart_slot_device::read_d5xx(offs_t offset)
template <unsigned Bank> uint8_t a800_cart_slot_device::read_cart(offs_t offset)
{
if (m_cart)
return m_cart->read_d5xx(offset);
else
return 0xff;
return m_space_mem->read_byte(offset | Bank << 13);
}
/*-------------------------------------------------
write
-------------------------------------------------*/
void a800_cart_slot_device::write_80xx(offs_t offset, uint8_t data)
template <unsigned Bank> void a800_cart_slot_device::write_cart(offs_t offset, uint8_t data)
{
if (m_cart)
m_cart->write_80xx(offset, data);
return m_space_mem->write_byte(offset | Bank << 13, data);
}
void a800_cart_slot_device::write_d5xx(offs_t offset, uint8_t data)
// Instantiate maps
template uint8_t a800_cart_slot_device::read_cart<0>(offs_t offset);
template uint8_t a800_cart_slot_device::read_cart<1>(offs_t offset);
template void a800_cart_slot_device::write_cart<0>(offs_t offset, uint8_t data);
template void a800_cart_slot_device::write_cart<1>(offs_t offset, uint8_t data);
uint8_t a800_cart_slot_device::read_cctl(offs_t offset)
{
if (m_cart)
m_cart->write_d5xx(offset, data);
return m_space_io->read_byte(offset);
}
void a800_cart_slot_device::write_cctl(offs_t offset, uint8_t data)
{
m_space_io->write_byte(offset, data);
}
device_memory_interface::space_config_vector a5200_cart_slot_device::memory_space_config() const
{
return space_config_vector{
std::make_pair(AS_PROGRAM, &m_space_mem_config)
};
}
uint8_t a5200_cart_slot_device::read_cart(offs_t offset)
{
return m_space_mem->read_byte(offset);
}
void a5200_cart_slot_device::write_cart(offs_t offset, uint8_t data)
{
return m_space_mem->write_byte(offset, data);
}

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
// copyright-holders:Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_A800_SLOT_H
#define MAME_BUS_A800_A800_SLOT_H
@ -13,6 +13,7 @@
***************************************************************************/
/* PCB */
// TODO: make this enum to actually follow up the .car specs, not the other way around
enum
{
A800_8K = 0,
@ -23,19 +24,26 @@ enum
A800_OSSM091,
A800_OSS8K,
A800_PHOENIX,
A800_BLIZZARD,
A800_XEGS,
A800_BBSB,
A800_DIAMOND,
A800_WILLIAMS,
A800_EXPRESS,
A800_SPARTADOS,
A800_BLIZZARD,
A800_TURBO64,
A800_TURBO128,
A800_SPARTADOS_128KB,
A800_TURBO,
A800_TELELINK2,
A800_MICROCALC,
A800_ULTRACART,
A800_ADAWLIAH,
A800_ATRAX,
A800_CORINA,
A800_CORINA_SRAM,
ATARIMAX_MAXFLASH_128KB,
ATARIMAX_MAXFLASH_1MB,
SIC_128KB,
SIC_256KB,
SIC_512KB,
A5200_4K,
A5200_8K,
A5200_16K,
@ -44,8 +52,7 @@ enum
A5200_BBSB
};
// ======================> device_a800_cart_interface
class a800_cart_slot_device;
class device_a800_cart_interface : public device_interface
{
@ -53,41 +60,49 @@ public:
// construction/destruction
virtual ~device_a800_cart_interface();
// memory accessor
virtual uint8_t read_80xx(offs_t offset) { return 0xff; }
virtual uint8_t read_d5xx(offs_t offset) { return 0xff; }
virtual void write_80xx(offs_t offset, uint8_t data) {}
virtual void write_d5xx(offs_t offset, uint8_t data) {}
virtual void cart_map(address_map &map);
virtual void cctl_map(address_map &map);
// TODO: remove all of this
void rom_alloc(uint32_t size);
void ram_alloc(uint32_t size);
void nvram_alloc(uint32_t size);
uint8_t* get_rom_base() { return m_rom; }
uint8_t* get_ram_base() { return &m_ram[0]; }
uint8_t* get_nvram_base() { return &m_nvram[0]; }
uint32_t get_rom_size() { return m_rom_size; }
uint32_t get_ram_size() { return m_ram.size(); }
uint32_t get_nvram_size() { return m_nvram.size(); }
///
/// Carts can either init RD4/RD5 at startup or not, depending on if they have
/// reset circuitry or not. Future expansion of this getter will return a third value,
/// giving back the timing value where the initialization should happen.
///
/// \return RD4, RD5 initial state
virtual std::tuple<int, int> get_initial_rd_state() { return std::make_tuple(0, 0); }
protected:
device_a800_cart_interface(const machine_config &mconfig, device_t &device);
virtual void interface_pre_start() override;
virtual void interface_post_start() override;
a800_cart_slot_device *m_slot;
// internal state
uint8_t *m_rom;
uint32_t m_rom_size;
std::vector<uint8_t> m_ram;
std::vector<uint8_t> m_nvram; // HiScore cart can save scores!
// helpers
int m_bank_mask;
void rd4_w( int state );
void rd5_w( int state );
void rd_both_w ( int state );
};
// ======================> a800_cart_slot_device
class a800_cart_slot_device : public device_t,
public device_memory_interface,
public device_cartrom_image_interface,
public device_single_card_slot_interface<device_a800_cart_interface>
{
friend class device_a800_cart_interface;
public:
// construction/destruction
template <typename T>
@ -102,46 +117,87 @@ public:
a800_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
virtual ~a800_cart_slot_device();
// device_image_interface implementation
virtual std::pair<std::error_condition, std::string> call_load() override;
virtual void call_unload() override;
virtual bool is_reset_on_load() const noexcept override { return true; }
virtual const char *image_interface() const noexcept override { return "a8bit_cart"; }
virtual const char *file_extensions() const noexcept override { return "bin,rom,car"; }
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
int get_cart_type() { return m_type; }
int identify_cart_type(const uint8_t *header) const;
bool has_cart() { return m_cart != nullptr; }
virtual std::pair<std::error_condition, std::string> call_load() override;
virtual void call_unload() override;
// reading and writing
uint8_t read_80xx(offs_t offset);
uint8_t read_d5xx(offs_t offset);
void write_80xx(offs_t offset, uint8_t data);
void write_d5xx(offs_t offset, uint8_t data);
bool has_cart() { return m_cart != nullptr; }
auto rd4_callback() { return m_rd4_cb.bind(); }
auto rd5_callback() { return m_rd5_cb.bind(); }
void set_is_xegs(bool is_xegs) { m_is_xegs = is_xegs; }
template <unsigned Bank> uint8_t read_cart(offs_t offset);
template <unsigned Bank> void write_cart(offs_t offset, uint8_t data);
uint8_t read_cctl(offs_t offset);
void write_cctl(offs_t offset, uint8_t data);
auto get_initial_rd_state() { return m_cart->get_initial_rd_state(); }
protected:
a800_cart_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
//a800_cart_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device_t implementation
virtual void device_start() override;
virtual void device_resolve_objects() override;
virtual space_config_vector memory_space_config() const override;
private:
device_a800_cart_interface *m_cart;
int m_type;
device_a800_cart_interface* m_cart;
devcb_write_line m_rd4_cb;
devcb_write_line m_rd5_cb;
address_space_config m_space_mem_config;
address_space_config m_space_io_config;
address_space *m_space_mem;
address_space *m_space_io;
int m_type = 0;
bool m_is_xegs = false;
};
class a5200_cart_slot_device;
class device_a5200_cart_interface : public device_interface
{
public:
// construction/destruction
virtual ~device_a5200_cart_interface();
virtual void cart_map(address_map &map);
// TODO: remove all of this
void rom_alloc(uint32_t size);
uint8_t* get_rom_base() { return m_rom; }
uint32_t get_rom_size() { return m_rom_size; }
protected:
device_a5200_cart_interface(const machine_config &mconfig, device_t &device);
virtual void interface_pre_start() override;
virtual void interface_post_start() override;
a5200_cart_slot_device *m_slot;
// internal state
uint8_t *m_rom;
uint32_t m_rom_size;
// helpers
int m_bank_mask;
};
// The variants below are added to handle the additional formats for a5200, and to give more
// clear error messages if you try to load an A5200 game into an A800 or a XEGS, etc.
// ======================> a5200_cart_slot_device
class a5200_cart_slot_device : public a800_cart_slot_device
class a5200_cart_slot_device : public device_t,
public device_memory_interface,
public device_cartrom_image_interface,
public device_single_card_slot_interface<device_a5200_cart_interface>
{
friend class device_a5200_cart_interface;
public:
// construction/destruction
template <typename T>
@ -156,39 +212,33 @@ public:
a5200_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~a5200_cart_slot_device();
virtual bool is_reset_on_load() const noexcept override { return true; }
virtual const char *image_interface() const noexcept override { return "a8bit_cart"; }
virtual const char *file_extensions() const noexcept override { return "bin,rom,car,a52"; }
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
};
int identify_cart_type(const uint8_t *header) const;
virtual std::pair<std::error_condition, std::string> call_load() override;
virtual void call_unload() override;
// ======================> xegs_cart_slot_device
u8 read_cart(offs_t offset);
void write_cart(offs_t offset, u8 data);
class xegs_cart_slot_device : public a800_cart_slot_device
{
public:
// construction/destruction
template <typename T>
xegs_cart_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt)
: xegs_cart_slot_device(mconfig, tag, owner, (uint32_t)0)
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
}
xegs_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~xegs_cart_slot_device();
protected:
virtual void device_start() override;
virtual space_config_vector memory_space_config() const override;
virtual const char *file_extensions() const noexcept override { return "bin,rom,car"; }
private:
device_a5200_cart_interface* m_cart;
address_space_config m_space_mem_config;
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
address_space *m_space_mem;
int m_type;
};
// device type definition
DECLARE_DEVICE_TYPE(A800_CART_SLOT, a800_cart_slot_device)
DECLARE_DEVICE_TYPE(A5200_CART_SLOT, a5200_cart_slot_device)
DECLARE_DEVICE_TYPE(XEGS_CART_SLOT, xegs_cart_slot_device)
#endif // MAME_BUS_A800_A800_SLOT_H

View File

@ -41,7 +41,7 @@
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE(A8SIO, a8sio_device, "a8sio", "Atari 8 bit SIO Slot")
DEFINE_DEVICE_TYPE(A8SIO, a8sio_device, "a8sio", "Atari 8-bit SIO Slot")
//**************************************************************************
// LIVE DEVICE

View File

@ -42,7 +42,6 @@ private:
required_device<wd2793_device> m_fdc;
};
// device type declaration
DECLARE_DEVICE_TYPE(ATARI1050, atari1050_device)
#endif // MAME_BUS_A800_ATARI1050

View File

@ -42,7 +42,6 @@ private:
required_device<fd1771_device> m_fdc;
};
// device type declaration
DECLARE_DEVICE_TYPE(ATARI810, atari810_device)
#endif // MAME_BUS_A800_ATARI810

View File

@ -0,0 +1,54 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
Atrax 128KB cart ROM
Not to be confused with the Sparta DOS X variants, this one is just a standalone cart with
single CCTL register that covers RD5 and bank.
**************************************************************************************************/
#include "emu.h"
#include "atrax.h"
DEFINE_DEVICE_TYPE(A800_ROM_ATRAX, a800_rom_atrax_device, "a800_atrax", "Atari 8-bit Atrax 128KB cart")
a800_rom_atrax_device::a800_rom_atrax_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_ATRAX, tag, owner, clock)
, m_bank(0)
{
}
void a800_rom_atrax_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_atrax_device::device_reset()
{
m_bank = 0;
}
void a800_rom_atrax_device::cart_map(address_map &map)
{
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; })
);
}
void a800_rom_atrax_device::cctl_map(address_map &map)
{
map(0x00, 0xff).w(FUNC(a800_rom_atrax_device::config_bank_w));
}
/*
* x--- ---- RD5 disabled (1) enabled (0)
* ---- xxxx bank number
*/
void a800_rom_atrax_device::config_bank_w(offs_t offset, u8 data)
{
rd5_w(!BIT(data, 7));
m_bank = data & 0xf;
}

View File

@ -0,0 +1,34 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A800_ATRAX_H
#define MAME_BUS_A800_ATRAX_H
#pragma once
#include "rom.h"
class a800_rom_atrax_device : public a800_rom_device
{
public:
a800_rom_atrax_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
void config_bank_w(offs_t offset, u8 data);
private:
int m_bank;
};
DECLARE_DEVICE_TYPE(A800_ROM_ATRAX, a800_rom_atrax_device)
#endif // MAME_BUS_A800_ATRAX_H

View File

@ -0,0 +1,136 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
/**************************************************************************************************
A800/A5200 Bounty Bob Strikes Back ROM schemes
Dual banking overlay access mapped in cart_map rd4 space at $xff6-$xff9,
A12 select bank window, bank bases are different.
rd5 just points to the last bank.
A5200 BBSB is mostly similar to the A800 version but with shuffled around data banks
i.e. fixed bank is actually the first one, and the overlay banks comes afterwards in the ROM space.
TODO:
- It's unknown if rd4 and rd5 can even be disabled from software (probably not);
**************************************************************************************************/
#include "emu.h"
#include "bbsb.h"
DEFINE_DEVICE_TYPE(A800_ROM_BBSB, a800_rom_bbsb_device, "a800_bbsb", "Atari 8-bit Bounty Bob Strikes Back cart")
DEFINE_DEVICE_TYPE(A5200_ROM_BBSB, a5200_rom_bbsb_device, "a5200_bbsb", "Atari 5200 ROM Bounty Bob Strikes Back cart")
a800_rom_bbsb_device::a800_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_BBSB, tag, owner, clock)
{
}
void a800_rom_bbsb_device::device_start()
{
// TODO: m_banks should be an extra interface for a5200
save_item(NAME(m_banks));
}
void a800_rom_bbsb_device::device_reset()
{
m_banks[0] = 0;
m_banks[1] = 0;
}
template <unsigned BankNum> u8 a800_rom_bbsb_device::read_bank(offs_t offset)
{
return m_rom[(offset & 0xfff) + (m_banks[BankNum] * 0x1000) + (BankNum * 0x4000)];
}
void a800_rom_bbsb_device::cart_map(address_map &map)
{
map(0x0000, 0x0fff).r(FUNC(a800_rom_bbsb_device::read_bank<0>));
map(0x1000, 0x1fff).r(FUNC(a800_rom_bbsb_device::read_bank<1>));
map(0x0ff6, 0x0ff9).select(0x1000).rw(FUNC(a800_rom_bbsb_device::bank_r), FUNC(a800_rom_bbsb_device::bank_w));
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + 0x8000]; } )
);
}
uint8_t a800_rom_bbsb_device::bank_r(offs_t offset)
{
const u8 bank_window = (offset & ~3) != 0;
const u8 bank_num = offset & 3;
if (!machine().side_effects_disabled())
m_banks[bank_window] = bank_num;
// TODO: unconfirmed, all $xff6-$xff9 just points to 0xff values
// Real cart overlay may return floating bus or the contents of the previous bank instead,
// needs to be tested by trying to execute code from there.
return 0xff;
}
void a800_rom_bbsb_device::bank_w(offs_t offset, uint8_t data)
{
const u8 bank_window = (offset & ~3) != 0;
const u8 bank_num = offset & 3;
m_banks[bank_window] = bank_num;
}
/*-------------------------------------------------
A5200 Bounty Bob Strikes Back! cart
-------------------------------------------------*/
a5200_rom_bbsb_device::a5200_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a5200_rom_device(mconfig, A5200_ROM_BBSB, tag, owner, clock)
{
}
void a5200_rom_bbsb_device::device_start()
{
save_item(NAME(m_banks));
}
void a5200_rom_bbsb_device::device_reset()
{
m_banks[0] = 0;
m_banks[1] = 0;
}
template <unsigned BankNum> u8 a5200_rom_bbsb_device::read_bank(offs_t offset)
{
return m_rom[(offset & 0xfff) + (m_banks[BankNum] * 0x1000) + (BankNum ? 0x6000 : 0x2000)];
}
void a5200_rom_bbsb_device::cart_map(address_map &map)
{
map(0x0000, 0x0fff).r(FUNC(a5200_rom_bbsb_device::read_bank<0>));
map(0x1000, 0x1fff).r(FUNC(a5200_rom_bbsb_device::read_bank<1>));
map(0x0ff6, 0x0ff9).select(0x1000).rw(FUNC(a5200_rom_bbsb_device::bank_r), FUNC(a5200_rom_bbsb_device::bank_w));
map(0x4000, 0x7fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & 0x1fff]; } )
);
}
uint8_t a5200_rom_bbsb_device::bank_r(offs_t offset)
{
const u8 bank_window = (offset & ~3) != 0;
const u8 bank_num = offset & 3;
if (!machine().side_effects_disabled())
m_banks[bank_window] = bank_num;
// TODO: unconfirmed, all $xff6-$xff9 just points to 0xff values
// Real cart overlay may return floating bus or the contents of the previous bank instead,
// needs to be tested by trying to execute code from there.
return 0xff;
}
void a5200_rom_bbsb_device::bank_w(offs_t offset, uint8_t data)
{
const u8 bank_window = (offset & ~3) != 0;
const u8 bank_num = offset & 3;
m_banks[bank_window] = bank_num;
}

View File

@ -0,0 +1,52 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_BBSB_H
#define MAME_BUS_A800_BBSB_H
#pragma once
#include "rom.h"
class a800_rom_bbsb_device : public a800_rom_device
{
public:
a800_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 1); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
int m_banks[2];
template <unsigned BankNum> u8 read_bank(offs_t offset);
u8 bank_r(offs_t offset);
void bank_w(offs_t offset, u8 data);
};
class a5200_rom_bbsb_device : public a5200_rom_device
{
public:
a5200_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
protected:
virtual void device_start() override;
virtual void device_reset() override;
int m_banks[2];
template <unsigned BankNum> u8 read_bank(offs_t offset);
u8 bank_r(offs_t offset);
void bank_w(offs_t offset, u8 data);
};
DECLARE_DEVICE_TYPE(A800_ROM_BBSB, a800_rom_bbsb_device)
DECLARE_DEVICE_TYPE(A5200_ROM_BBSB, a5200_rom_bbsb_device)
#endif // MAME_BUS_A800_BBSB_H

View File

@ -25,7 +25,7 @@ TODO:
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE(A8SIO_CASSETTE, a8sio_cassette_device, "a8sio_cass", "Atari 8 bit cassette")
DEFINE_DEVICE_TYPE(A8SIO_CASSETTE, a8sio_cassette_device, "a8sio_cass", "Atari 8-bit cassette")
void a8sio_cassette_device::device_add_mconfig(machine_config &config)
{

View File

@ -0,0 +1,135 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
Corina
Known configs:
- 1MB Flash ROM (yakungfu)
- 512KB Flash ROM + 512KB SRAM (bombjake)
Both contains 8KB NVRAM
TODO:
- Pinpoint and convert to flash interface;
- Unknown behaviour when accessing the "reserved" view;
**************************************************************************************************/
#include "emu.h"
#include "corina.h"
DEFINE_DEVICE_TYPE(A800_ROM_CORINA, a800_rom_corina_device, "a800_corina", "Atari 8-bit Corina 1MB flash ROM cart")
DEFINE_DEVICE_TYPE(A800_ROM_CORINA_SRAM, a800_rom_corina_sram_device, "a800_corina_sram", "Atari 8-bit Corina 512KB flash ROM + 512KB RAM cart")
a800_rom_corina_device::a800_rom_corina_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_nvram(*this, "nvram")
, m_view(*this, "corina_view")
, m_rom_bank(0)
{
}
a800_rom_corina_device::a800_rom_corina_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_corina_device(mconfig, A800_ROM_CORINA, tag, owner, clock)
{
}
void a800_rom_corina_device::device_add_mconfig(machine_config &config)
{
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
}
void a800_rom_corina_device::device_start()
{
const u32 nvram_size = 0x2000;
m_nvram_ptr = std::make_unique<uint8_t[]>(nvram_size);
m_nvram->set_base(m_nvram_ptr.get(), nvram_size);
save_pointer(NAME(m_nvram_ptr), nvram_size);
save_item(NAME(m_rom_bank));
}
void a800_rom_corina_device::device_reset()
{
m_rom_bank = 0;
m_view.select(0);
}
void a800_rom_corina_device::cart_map(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x3fff).view(m_view);
// TODO: spam writes during loading, flash commands?
m_view[0](0x0000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x3fff) + (m_rom_bank * 0x4000)]; })
);
m_view[1](0x0000, 0x3fff).rw(FUNC(a800_rom_corina_device::read_view_1), FUNC(a800_rom_corina_device::write_view_1));
m_view[2](0x0000, 0x3fff).lrw8(
NAME([this](offs_t offset) { return m_nvram_ptr[offset & 0x1fff]; }),
NAME([this](offs_t offset, uint8_t data) { m_nvram_ptr[offset & 0x1fff] = data; })
);
m_view[3](0x0000, 0x3fff).unmaprw();
}
void a800_rom_corina_device::cctl_map(address_map &map)
{
map(0x00, 0x00).w(FUNC(a800_rom_corina_device::ctrl_w));
}
uint8_t a800_rom_corina_device::read_view_1(offs_t offset)
{
return m_rom[(offset & 0x3fff) + (m_rom_bank * 0x4000) + 0x80000];
}
void a800_rom_corina_device::write_view_1(offs_t offset, u8 data)
{
}
/*
* 0--- ---- enable Corina window
* 1--- ---- disable Corina and select main unit 8000-bfff window instead
* -xx- ---- view select
* -00- ---- first half of ROM
* -01- ---- second half of ROM or RAM (^ depending on PCB config)
* -10- ---- NVRAM
* -11- ---- <reserved>
* ---x xxxx ROM/RAM lower bank value,
* ignored if view select is not in ROM/RAM mode
* or Corina window is disabled
*/
void a800_rom_corina_device::ctrl_w(offs_t offset, uint8_t data)
{
m_rom_bank = data & 0x1f;
m_view.select((data & 0x60) >> 5);
rd_both_w(!BIT(data, 7));
}
/*-------------------------------------------------
SRAM variant overrides
-------------------------------------------------*/
a800_rom_corina_sram_device::a800_rom_corina_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_corina_device(mconfig, A800_ROM_CORINA_SRAM, tag, owner, clock)
{
}
void a800_rom_corina_sram_device::device_start()
{
a800_rom_corina_device::device_start();
m_ram.resize(0x80000);
save_item(NAME(m_ram));
}
uint8_t a800_rom_corina_sram_device::read_view_1(offs_t offset)
{
return m_ram[(offset & 0x3fff) + (m_rom_bank * 0x4000)];
}
void a800_rom_corina_sram_device::write_view_1(offs_t offset, u8 data)
{
m_ram[(offset & 0x3fff) + (m_rom_bank * 0x4000)] = data;
}

View File

@ -0,0 +1,59 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A800_CORINA_H
#define MAME_BUS_A800_CORINA_H
#pragma once
#include "rom.h"
//#include "machine/intelfsh.h"
class a800_rom_corina_device : public a800_rom_device
{
public:
a800_rom_corina_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_corina_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 1); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
std::unique_ptr<uint8_t[]> m_nvram_ptr;
virtual uint8_t read_view_1(offs_t offset);
virtual void write_view_1(offs_t offset, u8 data);
void ctrl_w(offs_t offset, u8 data);
required_device<nvram_device> m_nvram;
memory_view m_view;
u8 m_rom_bank;
};
class a800_rom_corina_sram_device : public a800_rom_corina_device
{
public:
// construction/destruction
a800_rom_corina_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_start() override;
virtual uint8_t read_view_1(offs_t offset) override;
virtual void write_view_1(offs_t offset, u8 data) override;
private:
std::vector<uint8_t> m_ram;
};
DECLARE_DEVICE_TYPE(A800_ROM_CORINA, a800_rom_corina_device)
DECLARE_DEVICE_TYPE(A800_ROM_CORINA_SRAM, a800_rom_corina_sram_device)
#endif // MAME_BUS_A800_CORINA_H

View File

@ -0,0 +1,123 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
Maxflash
TODO:
- alt flash configs;
- alt buggy revision of 1MB version, with m_bank starting at 0x7f;
**************************************************************************************************/
#include "emu.h"
#include "maxflash.h"
// device type definition
DEFINE_DEVICE_TYPE(A800_MAXFLASH_128KB, a800_maxflash_128kb_device, "maxflash_128kb", "Atari 8-bit Atarimax Maxflash 128K flash ROM cart")
DEFINE_DEVICE_TYPE(A800_MAXFLASH_1MB, a800_maxflash_1mb_device, "maxflash_1mb", "Atari 8-bit Atarimax Maxflash 1MB flash ROM cart")
a800_maxflash_128kb_device::a800_maxflash_128kb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_flash(*this, "flash")
, m_bank(0)
{
}
a800_maxflash_128kb_device::a800_maxflash_128kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: a800_maxflash_128kb_device(mconfig, A800_MAXFLASH_128KB, tag, owner, clock)
{
}
void a800_maxflash_128kb_device::device_add_mconfig(machine_config &config)
{
AMD_29F010(config, m_flash);
// TODO: alt config with Micron M29F010B ($20/$20)
}
void a800_maxflash_128kb_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_maxflash_128kb_device::device_reset()
{
// TODO: ugly assignment, and shouldn't happen in device_reset
// TODO: assert against intended size for slot
memcpy(m_flash->base(), m_rom, get_rom_size());
// NB: this starts with 0x7f in the older Atarimax 1MB version
m_bank = 0;
}
void a800_maxflash_128kb_device::cart_map(address_map &map)
{
map(0x2000, 0x3fff).lrw8(
NAME([this](offs_t offset) {
return m_flash->read((offset & 0x1fff) + (m_bank * 0x2000));
}),
NAME([this](offs_t offset, u8 data) {
m_flash->write((offset & 0x1fff) + (m_bank * 0x2000), data);
})
);
}
void a800_maxflash_128kb_device::cctl_map(address_map &map)
{
map(0x00, 0x0f).rw(FUNC(a800_maxflash_128kb_device::rom_bank_r), FUNC(a800_maxflash_128kb_device::rom_bank_w));
map(0x10, 0x1f).rw(FUNC(a800_maxflash_128kb_device::disable_rom_r), FUNC(a800_maxflash_128kb_device::disable_rom_w));
}
uint8_t a800_maxflash_128kb_device::disable_rom_r(offs_t offset)
{
if(!machine().side_effects_disabled())
rd5_w(0);
return 0xff;
}
void a800_maxflash_128kb_device::disable_rom_w(offs_t offset, uint8_t data)
{
rd5_w(0);
}
uint8_t a800_maxflash_128kb_device::rom_bank_r(offs_t offset)
{
if(!machine().side_effects_disabled())
{
rd5_w(1);
m_bank = (offset & m_bank_mask);
}
return 0xff;
}
void a800_maxflash_128kb_device::rom_bank_w(offs_t offset, uint8_t data)
{
rd5_w(1);
m_bank = (offset & m_bank_mask);
}
// 8MB overrides
a800_maxflash_1mb_device::a800_maxflash_1mb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: a800_maxflash_128kb_device(mconfig, A800_MAXFLASH_1MB, tag, owner, clock)
{
}
void a800_maxflash_1mb_device::device_add_mconfig(machine_config &config)
{
// TODO: AMD_29F040B according to Altirra?
// AMD_29F040 doesn't match 0x100000 size requirement, 'B is still 4 megabits?
// replace it with a suitable flash device for now
INTEL_E28F008SA(config, m_flash);
// TODO: alt config with Bright BM29F040 ($ad/$40)
}
void a800_maxflash_1mb_device::cctl_map(address_map &map)
{
map(0x00, 0x7f).rw(FUNC(a800_maxflash_1mb_device::rom_bank_r), FUNC(a800_maxflash_1mb_device::rom_bank_w));
map(0x80, 0xff).rw(FUNC(a800_maxflash_1mb_device::disable_rom_r), FUNC(a800_maxflash_1mb_device::disable_rom_w));
}

View File

@ -0,0 +1,53 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A800_MAXFLASH_H
#define MAME_BUS_A800_MAXFLASH_H
#pragma once
#include "rom.h"
#include "machine/intelfsh.h"
class a800_maxflash_128kb_device : public a800_rom_device
{
public:
a800_maxflash_128kb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_maxflash_128kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
required_device<intelfsh8_device> m_flash;
uint8_t disable_rom_r(offs_t offset);
void disable_rom_w(offs_t offset, uint8_t data);
uint8_t rom_bank_r(offs_t offset);
void rom_bank_w(offs_t offset, uint8_t data);
private:
int m_bank;
};
class a800_maxflash_1mb_device : public a800_maxflash_128kb_device
{
public:
a800_maxflash_1mb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual void cctl_map(address_map &map) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
DECLARE_DEVICE_TYPE(A800_MAXFLASH_128KB, a800_maxflash_128kb_device)
DECLARE_DEVICE_TYPE(A800_MAXFLASH_1MB, a800_maxflash_1mb_device)
#endif // MAME_BUS_A800_MAXFLASH_H

View File

@ -1,10 +1,17 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
// copyright-holders:Fabio Priuli, Angelo Salese
/**************************************************************************************************
A800 ROM cart emulation
"Optimized System Software" OSS ROM cart emulation
***********************************************************************************************************/
https://en.wikipedia.org/wiki/Optimized_Systems_Software
Running on similar non-linear but incompatible banking schemes.
TODO:
- OSS034M doesn't really exist, it's an OSS043M with wrong ROM contents.
**************************************************************************************************/
#include "emu.h"
@ -15,37 +22,30 @@
// constructor
//-------------------------------------------------
DEFINE_DEVICE_TYPE(A800_ROM_OSS8K, a800_rom_oss8k_device, "a800_oss8k", "Atari 800 ROM Carts OSS 8K")
DEFINE_DEVICE_TYPE(A800_ROM_OSS34, a800_rom_oss34_device, "a800_034m", "Atari 800 ROM Carts OSS-034M")
DEFINE_DEVICE_TYPE(A800_ROM_OSS43, a800_rom_oss43_device, "a800_043m", "Atari 800 ROM Carts OSS-043M")
DEFINE_DEVICE_TYPE(A800_ROM_OSS91, a800_rom_oss91_device, "a800_m091", "Atari 800 ROM Carts OSS-M091")
DEFINE_DEVICE_TYPE(A800_ROM_OSS8K, a800_rom_oss8k_device, "a800_oss8k", "Atari 8-bit OSS 8K cart")
DEFINE_DEVICE_TYPE(A800_ROM_OSS34, a800_rom_oss034m_device, "a800_034m", "Atari 8-bit OSS-034M cart")
DEFINE_DEVICE_TYPE(A800_ROM_OSS43, a800_rom_oss043m_device, "a800_043m", "Atari 8-bit OSS-043M cart")
DEFINE_DEVICE_TYPE(A800_ROM_OSS91, a800_rom_oss091m_device, "a800_m091", "Atari 8-bit OSS-M091 cart")
/*-------------------------------------------------
OSS 8K
This is used by The Writer's Tool only.
-------------------------------------------------*/
a800_rom_oss8k_device::a800_rom_oss8k_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_oss8k_device::a800_rom_oss8k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_OSS8K, tag, owner, clock), m_bank(0)
: a800_rom_oss8k_device(mconfig, A800_ROM_OSS8K, tag, owner, clock)
{
}
a800_rom_oss34_device::a800_rom_oss34_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_OSS34, tag, owner, clock), m_bank(0)
{
}
a800_rom_oss43_device::a800_rom_oss43_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_OSS43, tag, owner, clock), m_bank(0)
{
}
a800_rom_oss91_device::a800_rom_oss91_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_OSS91, tag, owner, clock), m_bank(0)
{
}
void a800_rom_oss8k_device::device_start()
{
save_item(NAME(m_bank));
@ -56,197 +56,200 @@ void a800_rom_oss8k_device::device_reset()
m_bank = 0;
}
void a800_rom_oss34_device::device_start()
void a800_rom_oss8k_device::cart_map(address_map &map)
{
save_item(NAME(m_bank));
map(0x2000, 0x2fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank * 0x1000]; })
);
map(0x3000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & 0x0fff]; })
);
}
void a800_rom_oss34_device::device_reset()
/*
* ---- 0--x selects bank 1
* ---- 1--0 RD5 clear
* ---- 1--1 selects bank 0
*/
inline void a800_rom_oss8k_device::bank_config_access(offs_t offset)
{
m_bank = 1;
}
void a800_rom_oss43_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_oss43_device::device_reset()
{
m_bank = 0;
}
void a800_rom_oss91_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_oss91_device::device_reset()
{
m_bank = 0;
}
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
/*-------------------------------------------------
OSS 8K
This is used by The Writer's Tool only.
-------------------------------------------------*/
uint8_t a800_rom_oss8k_device::read_80xx(offs_t offset)
{
if (offset >= 0x1000)
return m_rom[offset & 0xfff];
else
return m_rom[(offset & 0xfff) + (m_bank * 0x1000)];
}
void a800_rom_oss8k_device::write_d5xx(offs_t offset, uint8_t data)
{
switch (offset & 0x09)
if (!(BIT(offset, 3)))
{
case 0:
case 1:
m_bank = 1;
break;
case 9:
m_bank = 0;
break;
default:
break;
rd5_w(1);
m_bank = 1;
}
else
{
rd5_w(BIT(offset, 0));
m_bank = 0;
}
}
u8 a800_rom_oss8k_device::rom_bank_r(offs_t offset)
{
if (!machine().side_effects_disabled())
bank_config_access(offset);
return 0xff;
}
void a800_rom_oss8k_device::rom_bank_w(offs_t offset, u8 data)
{
bank_config_access(offset);
}
void a800_rom_oss8k_device::cctl_map(address_map &map)
{
map(0x00, 0xff).rw(FUNC(a800_rom_oss8k_device::rom_bank_r), FUNC(a800_rom_oss8k_device::rom_bank_w));
}
/*-------------------------------------------------
OSS 034M
OSS 091M
This apparently comes from a dump with the wrong bank order...
investigate whether we should remove it!
Later variant of OSS 8k
-------------------------------------------------*/
uint8_t a800_rom_oss34_device::read_80xx(offs_t offset)
a800_rom_oss091m_device::a800_rom_oss091m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_oss8k_device(mconfig, A800_ROM_OSS91, tag, owner, clock)
{
if (offset >= 0x1000)
return m_rom[(offset & 0xfff) + 0x3000];
else if (m_bank == 3)
return 0xff;
else
return m_rom[(offset & 0xfff) + (m_bank * 0x1000)];
}
void a800_rom_oss34_device::write_d5xx(offs_t offset, uint8_t data)
/*
* ---- 0--0 bank 1
* ---- 0--1 bank 3
* ---- 1--0 RD5 clear
* ---- 1--1 bank 2
*/
inline void a800_rom_oss091m_device::bank_config_access(offs_t offset)
{
switch (offset & 0x0f)
const u8 a0 = BIT(offset, 0);
if (!(BIT(offset, 3)))
{
case 0:
case 1:
m_bank = 0;
break;
case 2:
case 6:
m_bank = 3; // in this case the ROM gets disabled and 0xff is returned in 0xa000-0xafff
break;
case 3:
case 7:
m_bank = 1;
break;
case 4:
case 5:
m_bank = 2;
break;
default:
break;
rd5_w(1);
m_bank = 1 | (a0 << 1);
}
else
{
rd5_w(a0);
m_bank = 2;
}
}
/*-------------------------------------------------
OSS 043M
Same as above but with correct bank order
-------------------------------------------------*/
uint8_t a800_rom_oss43_device::read_80xx(offs_t offset)
a800_rom_oss043m_device::a800_rom_oss043m_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_bankdev(*this, "bankdev")
, m_bank_base1(0)
, m_bank_base2(0)
{
if (offset >= 0x1000)
return m_rom[(offset & 0xfff) + 0x3000];
else if (m_bank == 3)
return 0xff;
else
return m_rom[(offset & 0xfff) + (m_bank * 0x1000)];
}
void a800_rom_oss43_device::write_d5xx(offs_t offset, uint8_t data)
a800_rom_oss043m_device::a800_rom_oss043m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_oss043m_device(mconfig, A800_ROM_OSS43, tag, owner, clock)
{
switch (offset & 0x0f)
{
case 0:
case 1:
m_bank = 0;
break;
case 2:
case 6:
m_bank = 3; // in this case the ROM gets disabled and 0xff is returned in 0xa000-0xafff
break;
case 3:
case 7:
m_bank = 2;
break;
case 4:
case 5:
m_bank = 1;
break;
default:
break;
}
}
void a800_rom_oss043m_device::device_add_mconfig(machine_config &config)
{
ADDRESS_MAP_BANK(config, m_bankdev).set_map(&a800_rom_oss043m_device::bankdev_map).set_options(ENDIANNESS_LITTLE, 8, 12 + 3, 0x1000);
}
void a800_rom_oss043m_device::device_start()
{
m_bank_base1 = 0x2000;
m_bank_base2 = 0x1000;
}
void a800_rom_oss043m_device::device_reset()
{
m_bankdev->set_bank(0);
rd4_w(0);
rd5_w(1);
}
void a800_rom_oss043m_device::bankdev_map(address_map &map)
{
map(0x0000, 0x0fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & 0x0fff]; })
);
map(0x1000, 0x1fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & 0x0fff] & m_rom[(offset & 0x0fff) | m_bank_base1]; })
);
map(0x2000, 0x2fff).mirror(0x4000).lr8(
NAME([]() { return 0xff; })
);
map(0x3000, 0x3fff).mirror(0x4000).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank_base1]; })
);
map(0x4000, 0x4fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank_base2]; })
);
map(0x5000, 0x5fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank_base1] & m_rom[(offset & 0x0fff) | m_bank_base2]; })
);
}
void a800_rom_oss043m_device::cart_map(address_map &map)
{
map(0x2000, 0x2fff).m(m_bankdev, FUNC(address_map_bank_device::amap8));
map(0x3000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | 0x3000]; })
);
}
void a800_rom_oss043m_device::cctl_map(address_map &map)
{
map(0x00, 0xff).rw(FUNC(a800_rom_oss043m_device::rom_bank_r), FUNC(a800_rom_oss043m_device::rom_bank_w));
}
/*
* 0000 bank 0
* 0001 returns AND-ed contents of banks 0 & 2
* 0x10 returns 0xff to window (i.e. RD5 is still asserted)
* 0x11 bank 2
* 0100 bank 1
* 0101 returns AND-ed contents of banks 1 & 2
* 1000 RD5 clear
*/
inline void a800_rom_oss043m_device::bank_config_access(offs_t offset)
{
rd5_w(!(BIT(offset, 3)));
m_bankdev->set_bank(offset & 7);
}
u8 a800_rom_oss043m_device::rom_bank_r(offs_t offset)
{
if (!machine().side_effects_disabled())
bank_config_access(offset);
return 0xff;
}
void a800_rom_oss043m_device::rom_bank_w(offs_t offset, u8 data)
{
bank_config_access(offset);
}
/*-------------------------------------------------
OSS M091
Simplified banking system which only uses two
address lines (A0 & A3)
OSS 034M (fake)
-------------------------------------------------*/
uint8_t a800_rom_oss91_device::read_80xx(offs_t offset)
a800_rom_oss034m_device::a800_rom_oss034m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_oss043m_device(mconfig, A800_ROM_OSS34, tag, owner, clock)
{
if (offset >= 0x1000)
return m_rom[offset & 0xfff];
else
return m_rom[(offset & 0xfff) + (m_bank * 0x1000)];
}
void a800_rom_oss91_device::write_d5xx(offs_t offset, uint8_t data)
void a800_rom_oss034m_device::device_start()
{
switch (offset & 0x09)
{
case 0:
m_bank = 1;
break;
case 1:
m_bank = 3;
break;
case 9:
m_bank = 2;
break;
default:
break;
}
a800_rom_oss043m_device::device_start();
m_bank_base1 = 0x1000;
m_bank_base2 = 0x2000;
}

View File

@ -1,99 +1,86 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
// copyright-holders:Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_OSS_H
#define MAME_BUS_A800_OSS_H
#pragma once
#include "rom.h"
#include "machine/bankdev.h"
// ======================> a800_rom_oss8k_device
class a800_rom_oss8k_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_oss8k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
a800_rom_oss8k_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
virtual void bank_config_access(offs_t offset);
u8 rom_bank_r(offs_t offset);
void rom_bank_w(offs_t offset, u8 data);
};
// ======================> a800_rom_oss34_device
class a800_rom_oss34_device : public a800_rom_device
class a800_rom_oss043m_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_oss34_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
a800_rom_oss043m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
a800_rom_oss043m_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
int m_bank;
void bankdev_map(address_map &map);
void bank_config_access(offs_t offset);
u8 rom_bank_r(offs_t offset);
void rom_bank_w(offs_t offset, u8 data);
required_device<address_map_bank_device> m_bankdev;
u16 m_bank_base1, m_bank_base2;
};
// ======================> a800_rom_oss43_device
class a800_rom_oss43_device : public a800_rom_device
class a800_rom_oss034m_device : public a800_rom_oss043m_device
{
public:
// construction/destruction
a800_rom_oss43_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
a800_rom_oss034m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
};
// ======================> a800_rom_oss91_device
class a800_rom_oss91_device : public a800_rom_device
class a800_rom_oss091m_device : public a800_rom_oss8k_device
{
public:
// construction/destruction
a800_rom_oss91_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
a800_rom_oss091m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
virtual void bank_config_access(offs_t offset) override;
};
// device type definition
DECLARE_DEVICE_TYPE(A800_ROM_OSS8K, a800_rom_oss8k_device)
DECLARE_DEVICE_TYPE(A800_ROM_OSS34, a800_rom_oss34_device)
DECLARE_DEVICE_TYPE(A800_ROM_OSS43, a800_rom_oss43_device)
DECLARE_DEVICE_TYPE(A800_ROM_OSS91, a800_rom_oss91_device)
DECLARE_DEVICE_TYPE(A800_ROM_OSS34, a800_rom_oss034m_device)
DECLARE_DEVICE_TYPE(A800_ROM_OSS43, a800_rom_oss043m_device)
DECLARE_DEVICE_TYPE(A800_ROM_OSS91, a800_rom_oss091m_device)
#endif // MAME_BUS_A800_OSS_H

View File

@ -0,0 +1,176 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
Phoenix/Blizzard cart schemes
RD5 is special here: once disarmed it cannot be armed again from software.
TODO:
- Reset button optionally located on cart allows RD5 to be rearmed;
Notes:
- "Blizzard 4KB" note from .car specs suggests being a Phoenix in disguise,
they are definitely a better suit to use the a800_phoenix def rather than blizzard_device
given the RD4 access of latter.
- For "Blizzard 32KB" cfr. ultracart.cpp
- "Phoenix AST2K" is an oddity, according to Kr0tki on AtariAge forums:
"AST 2000 was two cartridges in one - it contained an AST Utility cartridge,
and a cartridge for Turbo 2000 (another turbo system popular in Poland).
The "AST 2000" contained a 16KB ROM and a two-position switch, which allowed to choose between
one of two 8KB banks. [...] the second half (Turbo 2000) [...] contained a capacitor that
automatically switched off the cartridge from memory after a certain time [...]"
https://forums.atariage.com/topic/169199-mess-a800-cartridge-software-list/#comment-2136371
**************************************************************************************************/
#include "emu.h"
#include "phoenix.h"
DEFINE_DEVICE_TYPE(A800_ROM_PHOENIX, a800_rom_phoenix_device, "a800_phoenix", "Atari 8-bit Phoenix cart")
DEFINE_DEVICE_TYPE(A800_ROM_BLIZZARD_16KB, a800_rom_blizzard_16kb_device, "a800_blizzard", "Atari 8-bit Blizzard 16KB ROM cart")
DEFINE_DEVICE_TYPE(A800_ROM_PHOENIX_AST2K, a800_rom_phoenix_ast2k_device, "a800_phoenix_ast2k", "Atari 8-bit Phoenix AST2K 2-in-1 cart")
a800_rom_phoenix_device::a800_rom_phoenix_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
{
}
a800_rom_phoenix_device::a800_rom_phoenix_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_phoenix_device(mconfig, A800_ROM_PHOENIX, tag, owner, clock)
{
}
void a800_rom_phoenix_device::device_start()
{
m_rom_mask = get_rom_size() - 1;
}
void a800_rom_phoenix_device::device_reset()
{
}
void a800_rom_phoenix_device::cart_map(address_map &map)
{
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & m_rom_mask)]; })
);
}
u8 a800_rom_phoenix_device::disable_rom_r(offs_t offset)
{
if(!machine().side_effects_disabled())
rd5_w(0);
return 0xff;
}
void a800_rom_phoenix_device::disable_rom_w(offs_t offset, u8 data)
{
rd5_w(0);
}
void a800_rom_phoenix_device::cctl_map(address_map &map)
{
map(0x00, 0xff).rw(FUNC(a800_rom_phoenix_device::disable_rom_r), FUNC(a800_rom_phoenix_device::disable_rom_w));
}
/*-------------------------------------------------
Blizzard 16KB carts
-------------------------------------------------*/
a800_rom_blizzard_16kb_device::a800_rom_blizzard_16kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_phoenix_device(mconfig, A800_ROM_BLIZZARD_16KB, tag, owner, clock)
{
}
void a800_rom_blizzard_16kb_device::device_reset()
{
}
void a800_rom_blizzard_16kb_device::cart_map(address_map &map)
{
map(0x0000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & m_rom_mask)]; })
);
}
u8 a800_rom_blizzard_16kb_device::disable_rom_r(offs_t offset)
{
if(!machine().side_effects_disabled())
rd_both_w(0);
return 0xff;
}
void a800_rom_blizzard_16kb_device::disable_rom_w(offs_t offset, u8 data)
{
rd_both_w(0);
}
/*-------------------------------------------------
Phoenix AST2K variant
-------------------------------------------------*/
a800_rom_phoenix_ast2k_device::a800_rom_phoenix_ast2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_phoenix_device(mconfig, A800_ROM_PHOENIX_AST2K, tag, owner, clock)
, m_dsw(*this, "DSW")
, m_rom_select(0)
{
}
static INPUT_PORTS_START(ast2k)
PORT_START("DSW")
// two position switch located on cart
// we default to Turbo 2000 mode since it's a bit more worth in regtest scenarios
PORT_DIPNAME(0x01, 0x01, "Boot mode" )
PORT_DIPSETTING(0x00, "AST Utility" )
PORT_DIPSETTING(0x01, "Turbo 2000" )
INPUT_PORTS_END
ioport_constructor a800_rom_phoenix_ast2k_device::device_input_ports() const
{
return INPUT_PORTS_NAME(ast2k);
}
void a800_rom_phoenix_ast2k_device::device_start()
{
// a800_rom_phoenix_device::device_start();
// FIXME: not initing this properly, needs memory_region
m_rom_mask = 0x1fff;
m_rd5_disarm_timer = timer_alloc(FUNC(a800_rom_phoenix_ast2k_device::rd5_disarm_cb), this);
save_item(NAME(m_rom_select));
}
void a800_rom_phoenix_ast2k_device::device_reset()
{
a800_rom_phoenix_device::device_reset();
m_rom_select = BIT(m_dsw->read(), 0) << 13;
// TODO: unknown RD5 disarm time details
// - frame 137 is the first attempt of Turbo 2k software that tries to write to RD5 space;
// - is the disarm mechanic really disabled in AST Utility mode?
// - 4 seconds is a very lax time so that it doesn't backfire in case of atari400 driver timing changes;
m_rd5_disarm_timer->adjust((m_rom_select) ? attotime::from_seconds(4) : attotime::never);
}
TIMER_CALLBACK_MEMBER(a800_rom_phoenix_ast2k_device::rd5_disarm_cb)
{
logerror("RD5 disarmed thru timer\n");
rd5_w(0);
}
void a800_rom_phoenix_ast2k_device::cart_map(address_map &map)
{
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & m_rom_mask) | m_rom_select]; })
);
}

View File

@ -0,0 +1,70 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A800_PHOENIX_H
#define MAME_BUS_A800_PHOENIX_H
#pragma once
#include "rom.h"
class a800_rom_phoenix_device : public a800_rom_device
{
public:
a800_rom_phoenix_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_phoenix_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
u32 m_rom_mask;
virtual u8 disable_rom_r(offs_t offset);
virtual void disable_rom_w(offs_t offset, u8 data);
};
class a800_rom_blizzard_16kb_device : public a800_rom_phoenix_device
{
public:
a800_rom_blizzard_16kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 1); }
protected:
virtual void device_reset() override;
virtual u8 disable_rom_r(offs_t offset) override;
virtual void disable_rom_w(offs_t offset, u8 data) override;
};
class a800_rom_phoenix_ast2k_device : public a800_rom_phoenix_device
{
public:
a800_rom_phoenix_ast2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual ioport_constructor device_input_ports() const override;
private:
required_ioport m_dsw;
u32 m_rom_select;
emu_timer *m_rd5_disarm_timer;
TIMER_CALLBACK_MEMBER(rd5_disarm_cb);
};
DECLARE_DEVICE_TYPE(A800_ROM_PHOENIX, a800_rom_phoenix_device)
DECLARE_DEVICE_TYPE(A800_ROM_BLIZZARD_16KB, a800_rom_blizzard_16kb_device)
DECLARE_DEVICE_TYPE(A800_ROM_PHOENIX_AST2K, a800_rom_phoenix_ast2k_device)
#endif // MAME_BUS_A800_PHOENIX_H

View File

@ -1,35 +1,25 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
// copyright-holders:Fabio Priuli, Angelo Salese
/**************************************************************************************************
A800/A5200/XEGS ROM cart emulation
Basic carts work the same (in addition of being mostly compatible) for all these systems
and thus we deal with them in a single file
***********************************************************************************************************/
A800/A5200/XEGS ROM base cart emulation
**************************************************************************************************/
#include "emu.h"
#include "rom.h"
//-------------------------------------------------
// constructor
//-------------------------------------------------
DEFINE_DEVICE_TYPE(A800_ROM, a800_rom_device, "a800_rom", "Atari 800 ROM Carts")
DEFINE_DEVICE_TYPE(A800_ROM_BBSB, a800_rom_bbsb_device, "a800_bbsb", "Atari 800 ROM Carts BBSB")
DEFINE_DEVICE_TYPE(A800_ROM_WILLIAMS, a800_rom_williams_device, "a800_williams", "Atari 800 64K ROM Carts Williams")
DEFINE_DEVICE_TYPE(A800_ROM_EXPRESS, a800_rom_express_device, "a800_express", "Atari 800 64K ROM Carts Express/Diamond")
DEFINE_DEVICE_TYPE(A800_ROM_TURBO, a800_rom_turbo_device, "a800_turbo", "Atari 800 64K ROM Carts Turbosoft")
DEFINE_DEVICE_TYPE(A800_ROM_TELELINK2, a800_rom_telelink2_device, "a800_tlink2", "Atari 800 64K ROM Cart Telelink II")
DEFINE_DEVICE_TYPE(A800_ROM_MICROCALC, a800_rom_microcalc_device, "a800_sitsa", "Atari 800 64K ROM Carts SITSA MicroCalc")
DEFINE_DEVICE_TYPE(A800_ROM_CORINA, a800_rom_corina_device, "a800_corina", "Atari 800 ROM Carts Corina 1MB Flash ROM")
DEFINE_DEVICE_TYPE(A800_ROM_CORINA_SRAM, a800_rom_corina_sram_device, "a800_corina_sram", "Atari 800 ROM Carts Corina 512KB Flash ROM + 512KB RAM")
DEFINE_DEVICE_TYPE(XEGS_ROM, xegs_rom_device, "a800_xegs", "Atari XEGS 64K ROM Carts")
DEFINE_DEVICE_TYPE(A5200_ROM_2CHIPS, a5200_rom_2chips_device, "a5200_16k2c", "Atari 5200 ROM Cart 16K in 2 Chips")
DEFINE_DEVICE_TYPE(A5200_ROM_BBSB, a5200_rom_bbsb_device, "a5200_bbsb", "Atari 5200 ROM Cart BBSB")
DEFINE_DEVICE_TYPE(A800_ROM, a800_rom_device, "a800_rom", "Atari 8-bit ROM cart")
DEFINE_DEVICE_TYPE(A800_ROM_16KB, a800_rom_16kb_device, "a800_rom_16kb", "Atari 8-bit ROM 16kb cart")
DEFINE_DEVICE_TYPE(A800_ROM_RIGHT, a800_rom_right_device, "a800_rom_right","Atari 8-bit ROM Right cart")
DEFINE_DEVICE_TYPE(XEGS_ROM, xegs_rom_device, "a800_xegs", "Atari XEGS 64K cart")
DEFINE_DEVICE_TYPE(A5200_ROM, a5200_rom_device, "a5200_rom", "Atari 5200 ROM cart")
DEFINE_DEVICE_TYPE(A5200_ROM_2CHIPS, a5200_rom_2chips_device, "a5200_16k2c", "Atari 5200 ROM cart 16K in 2 Chips")
a800_rom_device::a800_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
@ -38,90 +28,17 @@ a800_rom_device::a800_rom_device(const machine_config &mconfig, device_type type
{
}
/*-------------------------------------------------
Generic left cart 8kb
-------------------------------------------------*/
a800_rom_device::a800_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM, tag, owner, clock)
{
}
a800_rom_bbsb_device::a800_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_BBSB, tag, owner, clock)
{
}
xegs_rom_device::xegs_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, XEGS_ROM, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_williams_device::a800_rom_williams_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_WILLIAMS, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_express_device::a800_rom_express_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_EXPRESS, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_turbo_device::a800_rom_turbo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_TURBO, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_telelink2_device::a800_rom_telelink2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_TELELINK2, tag, owner, clock)
{
}
a800_rom_microcalc_device::a800_rom_microcalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_MICROCALC, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_corina_device::a800_rom_corina_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_rom_bank(0)
, m_view_select(0)
{
}
a800_rom_corina_device::a800_rom_corina_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_CORINA, tag, owner, clock)
{
}
a800_rom_corina_sram_device::a800_rom_corina_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_corina_device(mconfig, A800_ROM_CORINA_SRAM, tag, owner, clock)
{
}
a5200_rom_2chips_device::a5200_rom_2chips_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A5200_ROM_2CHIPS, tag, owner, clock)
{
}
a5200_rom_bbsb_device::a5200_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A5200_ROM_BBSB, tag, owner, clock)
{
}
void a800_rom_device::device_start()
{
}
@ -130,18 +47,79 @@ void a800_rom_device::device_reset()
{
}
void a800_rom_bbsb_device::device_start()
void a800_rom_device::cart_map(address_map &map)
{
save_item(NAME(m_banks));
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & (m_rom_size - 1)]; })
);
}
void a800_rom_bbsb_device::device_reset()
/*-------------------------------------------------
Generic right cart 8kb
-------------------------------------------------*/
a800_rom_right_device::a800_rom_right_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_RIGHT, tag, owner, clock)
{
m_banks[0] = 0;
m_banks[1] = 0;
}
void a800_rom_right_device::device_start()
{
}
void a800_rom_right_device::device_reset()
{
rd4_w(1);
rd5_w(0);
}
void a800_rom_right_device::cart_map(address_map &map)
{
map(0x0000, 0x1fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & (m_rom_size - 1)]; })
);
}
/*-------------------------------------------------
Generic 16kb RD4 + RD5 cart
-------------------------------------------------*/
a800_rom_16kb_device::a800_rom_16kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_16KB, tag, owner, clock)
{
}
void a800_rom_16kb_device::device_start()
{
}
void a800_rom_16kb_device::device_reset()
{
rd_both_w(1);
}
void a800_rom_16kb_device::cart_map(address_map &map)
{
map(0x0000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & (m_rom_size - 1)]; })
);
}
/*-------------------------------------------------
XEGS carts (32K, 64K or 128K)
-------------------------------------------------*/
xegs_rom_device::xegs_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, XEGS_ROM, tag, owner, clock)
, m_bank(0)
{
}
void xegs_rom_device::device_start()
{
@ -150,362 +128,29 @@ void xegs_rom_device::device_start()
void xegs_rom_device::device_reset()
{
// TODO: random
m_bank = 0;
}
void a800_rom_williams_device::device_start()
// RD5 always maps to the last bank
void xegs_rom_device::cart_map(address_map &map)
{
save_item(NAME(m_bank));
map(0x0000, 0x1fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; })
);
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank_mask * 0x2000)]; })
);
}
void a800_rom_williams_device::device_reset()
void xegs_rom_device::cctl_map(address_map &map)
{
m_bank = 0;
map(0x00, 0xff).lw8(
NAME([this](offs_t offset, u8 data) { m_bank = data & m_bank_mask; })
);
}
void a800_rom_express_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_express_device::device_reset()
{
m_bank = 0;
}
void a800_rom_turbo_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_turbo_device::device_reset()
{
m_bank = 0;
}
void a800_rom_microcalc_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_microcalc_device::device_reset()
{
m_bank = 0;
}
void a800_rom_corina_device::device_start()
{
save_item(NAME(m_rom_bank));
save_item(NAME(m_view_select));
}
void a800_rom_corina_device::device_reset()
{
m_rom_bank = 0;
m_view_select = 0;
}
void a5200_rom_bbsb_device::device_start()
{
save_item(NAME(m_banks));
}
void a5200_rom_bbsb_device::device_reset()
{
m_banks[0] = 0;
m_banks[1] = 0;
}
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
/*-------------------------------------------------
Carts with no bankswitch (8K, 16K)
The cart accessors are mapped in the correct
range at driver start
-------------------------------------------------*/
uint8_t a800_rom_device::read_80xx(offs_t offset)
{
return m_rom[offset & (m_rom_size - 1)];
}
/*-------------------------------------------------
Bounty Bob Strikes Back! cart (40K)
Area 0xa000-0xbfff always point to last 8K bank
Areas 0x8000-0x8fff and 0x9000-0x9fff are
separate banks of 4K mapped either in the first
16K chunk or in the second 16K chunk
Bankswitch is controlled by data written in
0x8000-0x8fff and 0x9000-0x9fff respectively
-------------------------------------------------*/
uint8_t a800_rom_bbsb_device::read_80xx(offs_t offset)
{
if ((offset & 0x2000) == 0 && !machine().side_effects_disabled())
{
uint16_t addr = offset & 0xfff;
if (addr >= 0xff6 && addr <= 0xff9)
m_banks[BIT(offset, 12)] = (addr - 0xff6);
}
if (offset < 0x1000)
return m_rom[(offset & 0xfff) + (m_banks[0] * 0x1000) + 0];
else if (offset < 0x2000)
return m_rom[(offset & 0xfff) + (m_banks[1] * 0x1000) + 0x4000];
else
return m_rom[(offset & 0x1fff) + 0x8000];
}
void a800_rom_bbsb_device::write_80xx(offs_t offset, uint8_t data)
{
uint16_t addr = offset & 0xfff;
if (addr >= 0xff6 && addr <= 0xff9)
m_banks[BIT(offset, 12)] = (addr - 0xff6);
}
/*-------------------------------------------------
XEGS carts (32K, 64K or 128K)
Bankswitch is controlled by data written in
0xd500-0xd5ff
-------------------------------------------------*/
uint8_t xegs_rom_device::read_80xx(offs_t offset)
{
if (offset < 0x2000)
return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)];
else
return m_rom[(offset & 0x1fff) + (m_bank_mask * 0x2000)]; // always last 8K bank
}
void xegs_rom_device::write_d5xx(offs_t offset, uint8_t data)
{
m_bank = data & m_bank_mask;
}
/*-------------------------------------------------
Williams 64K
The rom is accessed in 8K chunks at 0xa000-0xbfff
Bankswitch is controlled by writing to 7 diff
offsets (their location varies with the cart type):
offs 0 points to bank 0, offs 1 points to bank 1,
and so on... the rom can be disabled by writing to
the offsets 0x8-0xf of the same range as the bankswitch
-------------------------------------------------*/
uint8_t a800_rom_williams_device::read_80xx(offs_t offset)
{
return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)];
}
void a800_rom_williams_device::write_d5xx(offs_t offset, uint8_t data)
{
m_bank = (offset & 0x07);
}
/*-------------------------------------------------
Express 64K / Diamond 64K carts
The rom is accessed in 8K chunks at 0xa000-0xbfff
Bankswitch is the same as above, but writes trigger
banks in reverse order: offs 7 points to bank 0, offs 6
points to bank 1, and so on... the rom can be disabled
by writing to the offsets 0x8-0xf of the same range
as the bankswitch
-------------------------------------------------*/
uint8_t a800_rom_express_device::read_80xx(offs_t offset)
{
return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)];
}
void a800_rom_express_device::write_d5xx(offs_t offset, uint8_t data)
{
m_bank = (offset ^ 0x07) & 0x0f;
}
/*-------------------------------------------------
Turbosoft 64K / 128K
-------------------------------------------------*/
uint8_t a800_rom_turbo_device::read_80xx(offs_t offset)
{
return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)];
}
void a800_rom_turbo_device::write_d5xx(offs_t offset, uint8_t data)
{
m_bank = offset & m_bank_mask;
}
/*-------------------------------------------------
Telelink II
-------------------------------------------------*/
uint8_t a800_rom_telelink2_device::read_80xx(offs_t offset)
{
if (offset >= 0x2000)
return m_rom[offset & 0x1fff];
if (offset >= 0x1000 && offset < 0x1100)
return m_nvram[offset & 0xff];
return 0xff;
}
void a800_rom_telelink2_device::write_80xx(offs_t offset, uint8_t data)
{
m_nvram[offset & 0xff] = data | 0xf0; // low 4bits only
}
uint8_t a800_rom_telelink2_device::read_d5xx(offs_t offset)
{
// this should affect NVRAM enable / save
return 0xff;
}
void a800_rom_telelink2_device::write_d5xx(offs_t offset, uint8_t data)
{
// this should affect NVRAM enable / save
}
/*-------------------------------------------------
SITSA Microcalc
-------------------------------------------------*/
uint8_t a800_rom_microcalc_device::read_80xx(offs_t offset)
{
return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)];
}
void a800_rom_microcalc_device::write_d5xx(offs_t offset, uint8_t data)
{
m_bank = data;
}
/*-------------------------------------------------
Corina
Comes in two configs:
- 1MB Flash ROM (yakungfu)
- 512KB Flash ROM + 512KB SRAM (bombjake)
Both contains 8KB NVRAM
-------------------------------------------------*/
uint8_t a800_rom_corina_device::read_view_1(offs_t offset)
{
return m_rom[(offset & 0x3fff) + (m_rom_bank * 0x4000) + 0x80000];
}
void a800_rom_corina_device::write_view_1(offs_t offset, u8 data)
{
}
uint8_t a800_rom_corina_sram_device::read_view_1(offs_t offset)
{
return m_ram[(offset & 0x3fff) + (m_rom_bank * 0x4000)];
}
void a800_rom_corina_sram_device::write_view_1(offs_t offset, u8 data)
{
m_ram[(offset & 0x3fff) + (m_rom_bank * 0x4000)] = data;
}
uint8_t a800_rom_corina_device::read_80xx(offs_t offset)
{
switch( m_view_select )
{
case 0:
return m_rom[(offset & 0x3fff) + (m_rom_bank * 0x4000)];
case 1:
return read_view_1(offset);
case 2:
return m_nvram[offset & 0x1fff];
}
logerror("view select R=3 [%04x]\n", offset);
return 0xff;
}
void a800_rom_corina_device::write_80xx(offs_t offset, uint8_t data)
{
switch( m_view_select )
{
case 1:
write_view_1(offset, data);
return;
case 2:
m_nvram[offset & 0x1fff] = data;
return;
}
// view 0: flash ROM commands?
// TODO: identify
logerror("view select W=%d [%04x, %02x] -> %02x\n", m_view_select, offset, m_rom_bank, data);
}
/*
* 0--- ---- enable Corina window
* 1--- ---- disable Corina and select main unit 8000-bfff window instead
* -xx- ---- view select
* -00- ---- first half of ROM
* -01- ---- second half of ROM or RAM (^ depending on PCB config)
* -10- ---- NVRAM
* -11- ---- <reserved>
* ---x xxxx ROM/RAM lower bank value,
* ignored if view select is not in ROM/RAM mode
* or Corina window is disabled
*/
void a800_rom_corina_device::write_d5xx(offs_t offset, uint8_t data)
{
m_rom_bank = data & 0x1f;
m_view_select = (data & 0x60) >> 5;
// TODO: bit 7, currently handled in a400_state
}
// Atari 5200
@ -517,6 +162,28 @@ void a800_rom_corina_device::write_d5xx(offs_t offset, uint8_t data)
-------------------------------------------------*/
a5200_rom_device::a5200_rom_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_a5200_cart_interface( mconfig, *this )
{
}
a5200_rom_device::a5200_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a5200_rom_device(mconfig, A5200_ROM, tag, owner, clock)
{
}
void a5200_rom_device::cart_map(address_map &map)
{
map(0x0000, 0x7fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & (m_rom_size - 1))]; })
);
}
void a5200_rom_device::device_start()
{
}
/*-------------------------------------------------
Carts with 2x8K (16K) with A13 line not connected
@ -527,52 +194,17 @@ void a800_rom_corina_device::write_d5xx(offs_t offset, uint8_t data)
-------------------------------------------------*/
uint8_t a5200_rom_2chips_device::read_80xx(offs_t offset)
a5200_rom_2chips_device::a5200_rom_2chips_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A5200_ROM_2CHIPS, tag, owner, clock)
{
if (offset < 0x4000)
return m_rom[offset & 0x1fff];
else
return m_rom[(offset & 0x1fff) + 0x2000];
}
/*-------------------------------------------------
Bounty Bob Strikes Back! cart (40K)
Similar to the A800 version, but:
Area 0x8000-0xbfff always point to last 8K bank
(repeated twice)
Areas 0x4000-0x4fff and 0x5000-0x5fff are
separate banks of 4K mapped either in the first
16K chunk or in the second 16K chunk
Bankswitch is controlled by data written in
0x4000-0x4fff and 0x5000-0x5fff respectively
-------------------------------------------------*/
uint8_t a5200_rom_bbsb_device::read_80xx(offs_t offset)
void a5200_rom_2chips_device::cart_map(address_map &map)
{
if ((offset & 0xe000) == 0 && !machine().side_effects_disabled())
{
uint16_t addr = offset & 0xfff;
if (addr >= 0xff6 && addr <= 0xff9)
m_banks[BIT(offset, 12)] = (addr - 0xff6);
}
if (offset < 0x1000)
return m_rom[(offset & 0xfff) + (m_banks[0] * 0x1000) + 0x2000];
else if (offset < 0x2000)
return m_rom[(offset & 0xfff) + (m_banks[1] * 0x1000) + 0x6000];
else if (offset >= 0x4000)
return m_rom[(offset & 0x1fff) + 0x0000];
else
return 0;
}
void a5200_rom_bbsb_device::write_80xx(offs_t offset, uint8_t data)
{
uint16_t addr = offset & 0xfff;
if (addr >= 0xff6 && addr <= 0xff9)
m_banks[BIT(offset, 12)] = (addr - 0xff6);
map(0x0000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & 0x1fff]; })
);
map(0x4000, 0x7fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + 0x2000]; })
);
}

View File

@ -1,268 +1,102 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
// copyright-holders:Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_ROM_H
#define MAME_BUS_A800_ROM_H
#pragma once
#include "a800_slot.h"
#include "machine/nvram.h"
// ======================> a800_rom_device
class a800_rom_device : public device_t,
public device_a800_cart_interface
{
public:
// construction/destruction
a800_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void cart_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
a800_rom_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_reset() override;
};
// ======================> a800_rom_bbsb_device
class a800_rom_bbsb_device : public a800_rom_device
class a800_rom_right_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
a800_rom_right_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_80xx(offs_t offset, uint8_t data) override;
virtual void cart_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 0); }
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_banks[2];
};
// ======================> a800_rom_williams_device
class a800_rom_williams_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_williams_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
};
// ======================> a800_rom_express_device
class a800_rom_express_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_express_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
};
// ======================> a800_rom_blizzard_device
class a800_rom_blizzard_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_blizzard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
};
// ======================> a800_rom_turbo_device
class a800_rom_turbo_device : public a800_rom_device
class a800_rom_16kb_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_turbo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
a800_rom_16kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
virtual void cart_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 1); }
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
};
// ======================> a800_rom_telelink2_device
class a800_rom_telelink2_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_telelink2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_80xx(offs_t offset, uint8_t data) override;
virtual uint8_t read_d5xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
};
// ======================> a800_rom_microcalc_device
class a800_rom_microcalc_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_microcalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
};
// ======================> a800_rom_corina_device
class a800_rom_corina_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_corina_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_corina_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_80xx(offs_t offset, uint8_t data) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual uint8_t read_view_1(offs_t offset);
virtual void write_view_1(offs_t offset, u8 data);
u8 m_rom_bank;
u8 m_view_select;
};
class a800_rom_corina_sram_device : public a800_rom_corina_device
{
public:
// construction/destruction
a800_rom_corina_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual uint8_t read_view_1(offs_t offset) override;
virtual void write_view_1(offs_t offset, u8 data) override;
};
// ======================> xegs_rom_device
class xegs_rom_device : public a800_rom_device
{
public:
// construction/destruction
xegs_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 1); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
protected:
int m_bank;
};
class a5200_rom_device : public device_t,
public device_a5200_cart_interface
{
public:
a5200_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// ======================> a5200_rom_2chips_device
virtual void cart_map(address_map &map) override;
protected:
a5200_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
};
class a5200_rom_2chips_device : public a800_rom_device
{
public:
// construction/destruction
a5200_rom_2chips_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void cart_map(address_map &map) override;
};
// ======================> a5200_rom_bbsb_device
class a5200_rom_bbsb_device : public a800_rom_device
{
public:
// construction/destruction
a5200_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_80xx(offs_t offset, uint8_t data) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_banks[2];
};
// device type definition
DECLARE_DEVICE_TYPE(A800_ROM, a800_rom_device)
DECLARE_DEVICE_TYPE(A800_ROM_BBSB, a800_rom_bbsb_device)
DECLARE_DEVICE_TYPE(A800_ROM_WILLIAMS, a800_rom_williams_device)
DECLARE_DEVICE_TYPE(A800_ROM_EXPRESS, a800_rom_express_device)
DECLARE_DEVICE_TYPE(A800_ROM_TURBO, a800_rom_turbo_device)
DECLARE_DEVICE_TYPE(A800_ROM_TELELINK2, a800_rom_telelink2_device)
DECLARE_DEVICE_TYPE(A800_ROM_MICROCALC, a800_rom_microcalc_device)
DECLARE_DEVICE_TYPE(A800_ROM_CORINA, a800_rom_corina_device)
DECLARE_DEVICE_TYPE(A800_ROM_CORINA_SRAM, a800_rom_corina_sram_device)
DECLARE_DEVICE_TYPE(A800_ROM_RIGHT, a800_rom_right_device)
DECLARE_DEVICE_TYPE(A800_ROM_16KB, a800_rom_16kb_device)
DECLARE_DEVICE_TYPE(XEGS_ROM, xegs_rom_device)
DECLARE_DEVICE_TYPE(A5200_ROM, a5200_rom_device)
DECLARE_DEVICE_TYPE(A5200_ROM_2CHIPS, a5200_rom_2chips_device)
DECLARE_DEVICE_TYPE(A5200_ROM_BBSB, a5200_rom_bbsb_device)
#endif // MAME_BUS_A800_ROM_H

View File

@ -6,8 +6,7 @@
The circuitry in this clock cartridge is very simple, containing the RTC itself, oscillator and
battery, and a 74HCT138 to decode the $D5B8-$D5BF address range from the /CCTL and A7-A3 pins. No ROM
is included; however, the cartridge can be placed in the (currently unemulated) passthrough slot of the
SpartaDOS X cartridge.
is included; the cartridge can be placed in the passthrough slot of the SpartaDOS X cartridge.
***********************************************************************************************************/
@ -51,20 +50,11 @@ void a800_rtime8_device::device_start()
// read_d5xx - handle reads from $D500-$D5FF
//-------------------------------------------------
u8 a800_rtime8_device::read_d5xx(offs_t offset)
// TODO: 4-bit access, D7-D4 returns open bus
void a800_rtime8_device::cctl_map(address_map &map)
{
if ((offset & 0xf8) == 0xb8)
return m_rtc->read(); // TODO: D7-D4 is open bus, in case this matters
else
return 0xff;
}
//-------------------------------------------------
// write_d5xx - handle writes to $D500-$D5FF
//-------------------------------------------------
void a800_rtime8_device::write_d5xx(offs_t offset, u8 data)
{
if ((offset & 0xf8) == 0xb8)
m_rtc->write(data & 0x0f);
map(0xb8, 0xbf).lrw8(
NAME([this](offs_t offset) { return m_rtc->read() | 0xf0; }),
NAME([this](offs_t offset, u8 data) { m_rtc->write(data & 0x0f); })
);
}

View File

@ -15,23 +15,18 @@
class a800_rtime8_device : public device_t, public device_a800_cart_interface
{
public:
// construction/destruction
a800_rtime8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual void cctl_map(address_map &map) override;
protected:
// device-level overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
// device_a800_cart_interface overrides
virtual u8 read_d5xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, u8 data) override;
private:
required_device<m3002_device> m_rtc;
};
// device type declaration
DECLARE_DEVICE_TYPE(A800_RTIME8, a800_rtime8_device)
#endif // MAME_BUS_A800_RTIME8_H

View File

@ -0,0 +1,114 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
SIC! "Super Inexpensive Cartridge!"
TODO:
- Unknown flash types used, Altirra just observed a Winbond 29C020;
- Customizable Jumper/switch handling for pin signals;
**************************************************************************************************/
#include "emu.h"
#include "sic.h"
// device type definition
DEFINE_DEVICE_TYPE(A800_SIC_128KB, a800_sic_128kb_device, "a800_siccart_128kb", "Atari 8-bit SIC! 128KB flash ROM cart")
DEFINE_DEVICE_TYPE(A800_SIC_256KB, a800_sic_256kb_device, "a800_siccart_256kb", "Atari 8-bit SIC! 256KB flash ROM cart")
DEFINE_DEVICE_TYPE(A800_SIC_512KB, a800_sic_512kb_device, "a800_siccart_512kb", "Atari 8-bit SIC! 512KB flash ROM cart")
a800_sic_128kb_device::a800_sic_128kb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_flash(*this, "flash")
, m_bank(0)
, m_write_protect(true)
{
}
a800_sic_128kb_device::a800_sic_128kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: a800_sic_128kb_device(mconfig, A800_SIC_128KB, tag, owner, clock)
{
}
void a800_sic_128kb_device::device_add_mconfig(machine_config &config)
{
AMD_29F010(config, m_flash);
}
void a800_sic_128kb_device::device_start()
{
save_item(NAME(m_bank));
save_item(NAME(m_write_protect));
}
void a800_sic_128kb_device::device_reset()
{
// TODO: ugly assignment, and shouldn't happen in device_reset
// TODO: assert against intended size for slot
memcpy(m_flash->base(), m_rom, get_rom_size());
m_bank_mask = (get_rom_size() / 0x4000) - 1;
// value of 0 for config_bank_w confirmed
m_bank = 0;
m_write_protect = true;
}
// SIC! maps rd4 and rd5 linearly
// so that 0x8000 maps to 0 and 0xa000 to 0x2000
u8 a800_sic_128kb_device::read(offs_t offset)
{
return m_flash->read((offset & 0x3fff) | (m_bank * 0x4000));
}
void a800_sic_128kb_device::write(offs_t offset, u8 data)
{
if (!m_write_protect)
m_flash->write((offset & 0x3fff) | (m_bank * 0x4000), data);
}
void a800_sic_128kb_device::cart_map(address_map &map)
{
map(0x0000, 0x3fff).rw(FUNC(a800_sic_128kb_device::read), FUNC(a800_sic_128kb_device::write));
}
/*
* 1--- ---- enable flash write
* -1-- ---- RD4 enable
* --0- ---- RD5 enable
* ---x xxxx ROM bank, where upper bits are unused for 128KB and 256KB versions
*/
void a800_sic_128kb_device::config_bank_w(offs_t offset, u8 data)
{
m_bank = (data & m_bank_mask);
rd4_w(BIT(data, 5));
rd5_w(!(BIT(data, 6)));
m_write_protect = !(BIT(data, 7));
}
void a800_sic_128kb_device::cctl_map(address_map &map)
{
map(0x00, 0x1f).w(FUNC(a800_sic_128kb_device::config_bank_w));
}
// 256/512KB variants
a800_sic_256kb_device::a800_sic_256kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: a800_sic_128kb_device(mconfig, A800_SIC_256KB, tag, owner, clock)
{
}
void a800_sic_256kb_device::device_add_mconfig(machine_config &config)
{
AMD_29LV200T(config, m_flash);
}
a800_sic_512kb_device::a800_sic_512kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: a800_sic_128kb_device(mconfig, A800_SIC_512KB, tag, owner, clock)
{
}
void a800_sic_512kb_device::device_add_mconfig(machine_config &config)
{
AMD_29F040(config, m_flash);
}

View File

@ -0,0 +1,64 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A800_SIC_H
#define MAME_BUS_A800_SIC_H
#pragma once
#include "rom.h"
#include "machine/intelfsh.h"
class a800_sic_128kb_device : public a800_rom_device
{
public:
a800_sic_128kb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_sic_128kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
required_device<intelfsh8_device> m_flash;
private:
int m_bank;
bool m_write_protect;
int m_bank_mask;
u8 read(offs_t offset);
void write(offs_t offset, u8 data);
u8 config_bank_r(offs_t offset);
void config_bank_w(offs_t offset, u8 data);
};
class a800_sic_256kb_device : public a800_sic_128kb_device
{
public:
a800_sic_256kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
class a800_sic_512kb_device : public a800_sic_128kb_device
{
public:
a800_sic_512kb_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
DECLARE_DEVICE_TYPE(A800_SIC_128KB, a800_sic_128kb_device)
DECLARE_DEVICE_TYPE(A800_SIC_256KB, a800_sic_256kb_device)
DECLARE_DEVICE_TYPE(A800_SIC_512KB, a800_sic_512kb_device)
#endif // MAME_BUS_A800_SIC_H

View File

@ -1,73 +1,189 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
// copyright-holders:Fabio Priuli, Angelo Salese
/**************************************************************************************************
A800 SpartaDOS cart emulation
SpartaDOS X (SDX) cart emulation
***********************************************************************************************************/
https://sdx.atari8.info/index.php?show=en_introduction
SDX 128KB a newer format used by the 200x releases: adds an extra bank access to $d5f0-$d5f7.
Should mirror $e8-$ef to $fx by logic.
**************************************************************************************************/
#include "emu.h"
#include "sparta.h"
#include "a800_carts.h"
//-------------------------------------------------
// constructor
//-------------------------------------------------
DEFINE_DEVICE_TYPE(A800_ROM_SPARTADOS, a800_rom_spartados_device, "a800_sparta", "Atari 800 SpartaDOS ROM Carts")
DEFINE_DEVICE_TYPE(A800_ROM_SPARTADOS, a800_rom_spartados_device, "a800_sparta", "Atari 8-bit SpartaDOS X cart")
DEFINE_DEVICE_TYPE(A800_ROM_SPARTADOS_128KB, a800_rom_spartados_128kb_device, "a800_sparta_128kb", "Atari 8-bit SpartaDOS X 128KB cart")
a800_rom_spartados_device::a800_rom_spartados_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_bank(0)
, m_subcart(*this, "subcart")
, m_cart_view(*this, "cart_view")
{
}
a800_rom_spartados_device::a800_rom_spartados_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_SPARTADOS, tag, owner, clock)
, m_bank(0)
, m_subslot_enabled(0)
: a800_rom_spartados_device(mconfig, A800_ROM_SPARTADOS, tag, owner, clock)
{
}
static void spartados_carts(device_slot_interface &device)
{
// NB: game carts will usually override SDX boot, meaning that they aren't all that useful to hook up here.
// also a SDX attached to another SDX just produces a black screen.
// we just hook them all up for the sake of completeness.
a800_left(device);
}
void a800_rom_spartados_device::subcart_rd4_w(int state)
{
m_subcart_rd4_enabled = state;
if (m_subcart_enabled)
{
rd4_w(m_subcart_rd4_enabled);
rd5_w(m_subcart_rd5_enabled);
}
}
void a800_rom_spartados_device::subcart_rd5_w(int state)
{
m_subcart_rd5_enabled = state;
if (m_subcart_enabled)
{
rd4_w(m_subcart_rd4_enabled);
rd5_w(m_subcart_rd5_enabled);
}
}
void a800_rom_spartados_device::device_add_mconfig(machine_config &config)
{
A800_CART_SLOT(config, m_subcart, spartados_carts, nullptr);
m_subcart->rd4_callback().set(FUNC(a800_rom_spartados_device::subcart_rd4_w));
m_subcart->rd5_callback().set(FUNC(a800_rom_spartados_device::subcart_rd5_w));
}
void a800_rom_spartados_device::device_start()
{
save_item(NAME(m_bank));
save_item(NAME(m_subslot_enabled));
save_item(NAME(m_subcart_enabled));
}
void a800_rom_spartados_device::device_reset()
{
m_bank = 0;
m_subslot_enabled = 0;
m_bank = 7;
m_subcart_enabled = false;
if (!m_subcart->exists())
m_subcart_rd4_enabled = m_subcart_rd5_enabled = 0;
else
std::tie(m_subcart_rd4_enabled, m_subcart_rd5_enabled) = m_subcart->get_initial_rd_state();
m_cart_view.select(0);
}
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
void a800_rom_spartados_device::cart_map(address_map &map)
{
map(0x0000, 0x3fff).view(m_cart_view);
m_cart_view[0](0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; })
);
m_cart_view[1](0x0000, 0x1fff).rw(m_subcart, FUNC(a800_cart_slot_device::read_cart<0>), FUNC(a800_cart_slot_device::write_cart<0>));
m_cart_view[1](0x2000, 0x3fff).rw(m_subcart, FUNC(a800_cart_slot_device::read_cart<1>), FUNC(a800_cart_slot_device::write_cart<1>));
}
void a800_rom_spartados_device::cctl_map(address_map &map)
{
map(0x00, 0xff).rw(m_subcart, FUNC(a800_cart_slot_device::read_cctl), FUNC(a800_cart_slot_device::write_cctl));
map(0xe0, 0xe7).rw(FUNC(a800_rom_spartados_device::rom_bank_r), FUNC(a800_rom_spartados_device::rom_bank_w));
map(0xe8, 0xef).rw(FUNC(a800_rom_spartados_device::subslot_r), FUNC(a800_rom_spartados_device::subslot_w));
}
inline void a800_rom_spartados_device::bank_config_access(offs_t offset)
{
rd4_w(0);
rd5_w(1);
m_cart_view.select(0);
m_bank = ((offset ^ m_bank_mask) & m_bank_mask);
m_subcart_enabled = false;
}
uint8_t a800_rom_spartados_device::rom_bank_r(offs_t offset)
{
if(!machine().side_effects_disabled())
bank_config_access(offset);
return m_subcart->read_cctl(offset | 0xe0);
}
void a800_rom_spartados_device::rom_bank_w(offs_t offset, uint8_t data)
{
bank_config_access(offset);
m_subcart->write_cctl(offset | 0xe0, data);
}
inline void a800_rom_spartados_device::subslot_config_access(offs_t offset)
{
if (!BIT(offset, 2))
{
m_subcart_enabled = true;
rd4_w(m_subcart_rd4_enabled);
rd5_w(m_subcart_rd5_enabled);
m_cart_view.select(1);
}
else
{
m_subcart_enabled = false;
rd4_w(0);
rd5_w(0);
}
}
u8 a800_rom_spartados_device::subslot_r(offs_t offset)
{
if(!machine().side_effects_disabled())
subslot_config_access(offset);
return m_subcart->read_cctl(offset | 0xe8);
}
void a800_rom_spartados_device::subslot_w(offs_t offset, u8 data)
{
subslot_config_access(offset);
return m_subcart->write_cctl(offset | 0xe8, data);
}
/*-------------------------------------------------
SpartaDOS 64K carts
Similar to Express / Diamond carts, because
bankswitch is controlled by writing to 7 diff
offsets in reverse order, but writes to offsets
0x8-0xf also enable/disable subslot
SpartaDOS 128KB variant
-------------------------------------------------*/
uint8_t a800_rom_spartados_device::read_80xx(offs_t offset)
a800_rom_spartados_128kb_device::a800_rom_spartados_128kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_spartados_device(mconfig, A800_ROM_SPARTADOS_128KB, tag, owner, clock)
{
if (!m_subslot_enabled)
return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)];
else
return 0xff; // subslot, currently not implemented
}
void a800_rom_spartados_device::write_d5xx(offs_t offset, uint8_t data)
// NB: .select not .mirror, we need the offset to propagate to sub cart cctl
void a800_rom_spartados_128kb_device::cctl_map(address_map &map)
{
if (offset & 0x08)
m_subslot_enabled = !BIT(offset, 2);
else
m_bank = (offset ^ 0x07) & 0x0f;
a800_rom_spartados_device::cctl_map(map);
map(0xe0, 0xe7).select(0x10).rw(FUNC(a800_rom_spartados_128kb_device::rom_bank_r), FUNC(a800_rom_spartados_128kb_device::rom_bank_w));
map(0xe8, 0xef).select(0x10).rw(FUNC(a800_rom_spartados_128kb_device::subslot_r), FUNC(a800_rom_spartados_128kb_device::subslot_w));
}
inline void a800_rom_spartados_128kb_device::bank_config_access(offs_t offset)
{
a800_rom_spartados_device::bank_config_access(offset);
const u8 upper_bank = !BIT(offset, 4);
m_bank = ((offset ^ 7) & 7) | (upper_bank << 3);
}

View File

@ -1,36 +1,63 @@
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
// copyright-holders:Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_SPARTA_H
#define MAME_BUS_A800_SPARTA_H
#pragma once
#include "rom.h"
// ======================> a800_rom_spartados_device
#include "a800_slot.h"
class a800_rom_spartados_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_spartados_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_spartados_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t read_80xx(offs_t offset) override;
virtual void write_d5xx(offs_t offset, uint8_t data) override;
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
int m_bank, m_subslot_enabled;
virtual void device_add_mconfig(machine_config &config) override;
virtual void bank_config_access(offs_t offset);
int m_bank;
u8 rom_bank_r(offs_t offset);
void rom_bank_w(offs_t offset, u8 data);
u8 subslot_r(offs_t offset);
void subslot_w(offs_t offset, u8 data);
private:
required_device<a800_cart_slot_device> m_subcart;
memory_view m_cart_view;
void subslot_config_access(offs_t offset);
void subcart_rd4_w( int state );
void subcart_rd5_w( int state );
bool m_subcart_enabled;
int m_subcart_rd4_enabled = 0, m_subcart_rd5_enabled = 0;
};
class a800_rom_spartados_128kb_device : public a800_rom_spartados_device
{
public:
a800_rom_spartados_128kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cctl_map(address_map &map) override;
// device type definition
DECLARE_DEVICE_TYPE(A800_ROM_SPARTADOS, a800_rom_spartados_device)
protected:
virtual void bank_config_access(offs_t offset) override;
};
DECLARE_DEVICE_TYPE(A800_ROM_SPARTADOS, a800_rom_spartados_device)
DECLARE_DEVICE_TYPE(A800_ROM_SPARTADOS_128KB, a800_rom_spartados_128kb_device)
#endif // MAME_BUS_A800_SPARTA_H

View File

@ -0,0 +1,94 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
// thanks-to: Jindroush, HiassofT
/**************************************************************************************************
"SuperCharger"
multiply/divide math unit (unknown 18-pins chip type, scratched on PCB)
used by "Assault Force" floppy disk.
Not to be confused with Starpath SuperCharger, which is for Atari VCS.
**************************************************************************************************/
#include "emu.h"
#include "supercharger.h"
// device type definition
DEFINE_DEVICE_TYPE(A800_SUPER_CHARGER, a800_supercharger_device, "a800_supercharger", "Atari 8-bit SuperCharger 3D math unit cart")
a800_supercharger_device::a800_supercharger_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, A800_SUPER_CHARGER, tag, owner, clock)
, device_a800_cart_interface(mconfig, *this)
, m_status(0)
{
}
void a800_supercharger_device::device_start()
{
save_pointer(NAME(m_data), 3);
save_item(NAME(m_status));
}
void a800_supercharger_device::device_reset()
{
std::fill(std::begin(m_data), std::end(m_data), 0);
m_status = 1;
}
void a800_supercharger_device::cctl_map(address_map &map)
{
map(0x00, 0x02).mirror(0xfc).lrw8(
NAME([this](offs_t offset) { return m_data[offset]; }),
NAME([this](offs_t offset, u8 data) { m_data[offset] = data; })
);
map(0x03, 0x03).mirror(0xfc).rw(FUNC(a800_supercharger_device::status_r), FUNC(a800_supercharger_device::command_w));
}
/*
* ---- ---x last command status
* (0) valid
* (1) error (division by zero, result == 0 or unsupported command)
*/
u8 a800_supercharger_device::status_r(offs_t offset)
{
return m_status;
}
// TODO: not instant
// (program sets four NOPs after each call)
void a800_supercharger_device::command_w(offs_t offset, u8 data)
{
switch (data)
{
// division
case 1:
{
const u32 numerator = (m_data[1] << 8) | (m_data[2] & 0xff);
const u32 denominator = m_data[0];
if (m_data[0] < m_data[1] || denominator == 0)
m_status = 1;
else
{
m_data[1] = (u8)(numerator % denominator);
m_data[2] = (u8)(numerator / denominator);
m_status = 0;
}
break;
}
// multiplication
case 2:
{
const u32 result = m_data[0] * m_data[2];
m_data[1] = (u8)(result >> 8);
m_data[2] = (u8)(result & 0xff);
m_status = 0;
break;
}
default:
m_status = 1;
break;
}
}

View File

@ -0,0 +1,35 @@
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
#ifndef MAME_BUS_A800_SUPERCHARGER_H
#define MAME_BUS_A800_SUPERCHARGER_H
#pragma once
#include "a800_slot.h"
// ======================> a800_rtime8_device
class a800_supercharger_device : public device_t,
public device_a800_cart_interface
{
public:
a800_supercharger_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual void cctl_map(address_map &map) override;
protected:
virtual void device_start() override;
virtual void device_reset() override;
u8 m_data[3]{};
u8 m_status;
u8 status_r(offs_t offset);
void command_w(offs_t offset, u8 data);
};
DECLARE_DEVICE_TYPE(A800_SUPER_CHARGER, a800_supercharger_device)
#endif // MAME_BUS_A800_SUPERCHARGER_H

View File

@ -0,0 +1,64 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
/**************************************************************************************************
Telelink II
4-bit X2212 NVRAM and other stuff not known at current stage.
RD4 hardwired to +5V
TODO:
- CCTL mapping details are unknown;
- Requires modem i/f to work;
**************************************************************************************************/
#include "emu.h"
#include "telelink2.h"
DEFINE_DEVICE_TYPE(A800_ROM_TELELINK2, a800_rom_telelink2_device, "a800_tlink2", "Atari 8-bit Telelink II cart")
a800_rom_telelink2_device::a800_rom_telelink2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, A800_ROM_TELELINK2, tag, owner, clock)
, m_nvram(*this, "nvram")
{
}
void a800_rom_telelink2_device::device_add_mconfig(machine_config &config)
{
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
}
void a800_rom_telelink2_device::device_start()
{
const u32 nvram_size = 0x100;
m_nvram_ptr = std::make_unique<uint8_t[]>(nvram_size);
m_nvram->set_base(m_nvram_ptr.get(), nvram_size);
save_pointer(NAME(m_nvram_ptr), nvram_size);
}
void a800_rom_telelink2_device::device_reset()
{
}
void a800_rom_telelink2_device::cart_map(address_map &map)
{
// 4-bit NVRAM
map(0x1000, 0x10ff).lrw8(
NAME([this](offs_t offset) { return m_nvram_ptr[offset & 0xff]; }),
NAME([this](offs_t offset, u8 data) { m_nvram_ptr[offset & 0xff] = data | 0xf0; })
);
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[offset & 0x1fff]; })
);
}
void a800_rom_telelink2_device::cctl_map(address_map &map)
{
// map(0x01, 0x01) read before reading NVRAM, value discarded
// map(0x02, 0x02) written before writing NVRAM when changing stored information
}

View File

@ -0,0 +1,34 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_TELELINK2_H
#define MAME_BUS_A800_TELELINK2_H
#pragma once
#include "rom.h"
class a800_rom_telelink2_device : public a800_rom_device
{
public:
// construction/destruction
a800_rom_telelink2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
// RD4 tied to +5V, assume always enabled
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(1, 1); }
private:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
required_device<nvram_device> m_nvram;
std::unique_ptr<uint8_t[]> m_nvram_ptr;
};
DECLARE_DEVICE_TYPE(A800_ROM_TELELINK2, a800_rom_telelink2_device)
#endif // MAME_BUS_A800_TELELINK2_H

View File

@ -0,0 +1,130 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
/**************************************************************************************************
Ultracart ROM scheme
Observed in SITSA MicroCalc SW (Altirra calls it this way),
PCB label pic has clear "ULTRACART" with an unreadable sub-title from available pic
("PIGNY MEXICO"?)
Sports extra SN74LS169BN (synchronous 4-bit up/down binary counter), any access to CCTL
bankswitch to the next index, disarms RD5 after bank 3, re-enables from bank 0 if accessed again.
"Blizzard 32KB" looks a derived design of Ultracart, it joins a binary counter with RD5 disarm
once it goes past 3rd bank index.
"aDawliah" scheme is again very similar but without any RD5 disarm (just loops back to index 0)
PCB marking "A-NA0002"
TODO:
- exact interface with SN74LS169;
**************************************************************************************************/
#include "emu.h"
#include "ultracart.h"
DEFINE_DEVICE_TYPE(A800_ROM_ULTRACART, a800_rom_ultracart_device, "a800_ultracart", "Atari 8-bit Ultracart \"MicroCalc\" cart")
DEFINE_DEVICE_TYPE(A800_ROM_BLIZZARD_32KB, a800_rom_blizzard_32kb_device, "a800_blizzard_32kb", "Atari 8-bit Blizzard 32KB cart")
DEFINE_DEVICE_TYPE(A800_ROM_ADAWLIAH, a800_rom_adawliah_device, "a800_adawliah", "Atari 8-bit aDawliah 32KB cart")
a800_rom_ultracart_device::a800_rom_ultracart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_ultracart_device::a800_rom_ultracart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_ultracart_device(mconfig, A800_ROM_ULTRACART, tag, owner, clock)
{
}
void a800_rom_ultracart_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_ultracart_device::device_reset()
{
m_bank = 0;
}
void a800_rom_ultracart_device::cart_map(address_map &map)
{
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; })
);
}
void a800_rom_ultracart_device::cctl_map(address_map &map)
{
map(0x00, 0xff).rw(FUNC(a800_rom_ultracart_device::config_bank_r), FUNC(a800_rom_ultracart_device::config_bank_w));
}
inline void a800_rom_ultracart_device::binary_counter_access()
{
// TODO: simplification, the real counter has several config options
m_bank = (m_bank + 1) & 0xf;
if (m_bank & 0xc)
{
rd5_w(0);
m_bank = 0xf;
}
else
rd5_w(1);
}
u8 a800_rom_ultracart_device::config_bank_r(offs_t offset)
{
if (!machine().side_effects_disabled())
binary_counter_access();
return 0xff;
}
void a800_rom_ultracart_device::config_bank_w(offs_t offset, u8 data)
{
binary_counter_access();
}
/*-------------------------------------------------
Blizzard 32KB carts
-------------------------------------------------*/
a800_rom_blizzard_32kb_device::a800_rom_blizzard_32kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_ultracart_device(mconfig, A800_ROM_BLIZZARD_32KB, tag, owner, clock)
{
}
inline void a800_rom_blizzard_32kb_device::binary_counter_access()
{
// TODO: simplification, the real counter has several config options
m_bank = (m_bank + 1) & 0xf;
// as per phoenix carts RD5 can only be re-enabled by restarting the machine
// it's unknown about how the binary counter behaves once this event occurs
if (m_bank & 0xc)
rd5_w(0);
}
/*-------------------------------------------------
aDawliah 32KB carts
-------------------------------------------------*/
a800_rom_adawliah_device::a800_rom_adawliah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_ultracart_device(mconfig, A800_ROM_ADAWLIAH, tag, owner, clock)
{
}
inline void a800_rom_adawliah_device::binary_counter_access()
{
// TODO: simplification, the real counter has several config options
m_bank = (m_bank + 1) & 0x3;
}

View File

@ -0,0 +1,55 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_ULTRACART_H
#define MAME_BUS_A800_ULTRACART_H
#pragma once
#include "rom.h"
class a800_rom_ultracart_device : public a800_rom_device
{
public:
a800_rom_ultracart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_ultracart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); }
protected:
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
virtual void binary_counter_access();
u8 config_bank_r(offs_t offset);
void config_bank_w(offs_t offset, u8 data);
};
class a800_rom_blizzard_32kb_device : public a800_rom_ultracart_device
{
public:
a800_rom_blizzard_32kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void binary_counter_access() override;
};
class a800_rom_adawliah_device : public a800_rom_ultracart_device
{
public:
a800_rom_adawliah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void binary_counter_access() override;
};
DECLARE_DEVICE_TYPE(A800_ROM_ULTRACART, a800_rom_ultracart_device)
DECLARE_DEVICE_TYPE(A800_ROM_BLIZZARD_32KB, a800_rom_blizzard_32kb_device)
DECLARE_DEVICE_TYPE(A800_ROM_ADAWLIAH, a800_rom_adawliah_device)
#endif // MAME_BUS_A800_ULTRACART_H

View File

@ -0,0 +1,160 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
/**************************************************************************************************
Williams cart scheme and variants
- Regular Williams cart maps ROM bankswitch to $x0 - $x7, RD5 disables with A3. x is mirrored.
- Express carts maps x = $7x, bank map is xor-ed
- Diamond carts maps x = $dx, bank map is xor-ed
- Turbosoft carts raises number of banks to 16, moves RD5 disable to A4 instead of A3
- All CCTL accesses works both on reading and writing.
**************************************************************************************************/
#include "emu.h"
#include "williams.h"
DEFINE_DEVICE_TYPE(A800_ROM_WILLIAMS, a800_rom_williams_device, "a800_williams", "Atari 8-bit Williams cart")
DEFINE_DEVICE_TYPE(A800_ROM_EXPRESS, a800_rom_express_device, "a800_express", "Atari 8-bit Express cart")
DEFINE_DEVICE_TYPE(A800_ROM_DIAMOND, a800_rom_diamond_device, "a800_diamond", "Atari 8-bit Diamond cart")
DEFINE_DEVICE_TYPE(A800_ROM_TURBO, a800_rom_turbo_device, "a800_turbo", "Atari 8-bit Turbosoft 64KB/128KB cart")
a800_rom_williams_device::a800_rom_williams_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_device(mconfig, type, tag, owner, clock)
, m_bank(0)
{
}
a800_rom_williams_device::a800_rom_williams_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_williams_device(mconfig, A800_ROM_WILLIAMS, tag, owner, clock)
{
}
void a800_rom_williams_device::device_start()
{
save_item(NAME(m_bank));
}
void a800_rom_williams_device::device_reset()
{
// turboc1 (at least) reads ROM window without setting bank first,
// any non-zero value will make it to punt
m_bank = 0;
}
void a800_rom_williams_device::cart_map(address_map &map)
{
map(0x2000, 0x3fff).lr8(
NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; })
);
}
void a800_rom_williams_device::cctl_map(address_map &map)
{
map(0x00, 0x07).mirror(0xf0).rw(FUNC(a800_rom_williams_device::rom_bank_r), FUNC(a800_rom_williams_device::rom_bank_w));
map(0x08, 0x0f).mirror(0xf0).rw(FUNC(a800_rom_williams_device::disable_rom_r), FUNC(a800_rom_williams_device::disable_rom_w));
}
uint8_t a800_rom_williams_device::disable_rom_r(offs_t offset)
{
if(!machine().side_effects_disabled())
rd5_w(0);
return 0xff;
}
void a800_rom_williams_device::disable_rom_w(offs_t offset, uint8_t data)
{
rd5_w(0);
}
// m_bank_mask necessary for turbo128 carts
uint8_t a800_rom_williams_device::rom_bank_r(offs_t offset)
{
if(!machine().side_effects_disabled())
{
rd5_w(1);
m_bank = (offset & m_bank_mask);
}
return 0xff;
}
void a800_rom_williams_device::rom_bank_w(offs_t offset, uint8_t data)
{
rd5_w(1);
m_bank = (offset & m_bank_mask);
}
/*-------------------------------------------------
Express 64K carts
-------------------------------------------------*/
a800_rom_express_device::a800_rom_express_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_williams_device(mconfig, type, tag, owner, clock)
{
}
a800_rom_express_device::a800_rom_express_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_williams_device(mconfig, A800_ROM_EXPRESS, tag, owner, clock)
{
}
void a800_rom_express_device::cctl_map(address_map &map)
{
map(0x70, 0x77).rw(FUNC(a800_rom_express_device::rom_bank_r), FUNC(a800_rom_express_device::rom_bank_w));
map(0x78, 0x7f).rw(FUNC(a800_rom_express_device::disable_rom_r), FUNC(a800_rom_express_device::disable_rom_w));
}
uint8_t a800_rom_express_device::rom_bank_r(offs_t offset)
{
if(!machine().side_effects_disabled())
{
rd5_w(1);
m_bank = ((offset ^ m_bank_mask) & m_bank_mask);
}
return 0xff;
}
void a800_rom_express_device::rom_bank_w(offs_t offset, uint8_t data)
{
rd5_w(1);
m_bank = ((offset ^ m_bank_mask) & m_bank_mask);
}
/*-------------------------------------------------
Diamond 64K carts
-------------------------------------------------*/
a800_rom_diamond_device::a800_rom_diamond_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_express_device(mconfig, A800_ROM_DIAMOND, tag, owner, clock)
{
}
void a800_rom_diamond_device::cctl_map(address_map &map)
{
map(0xd0, 0xd7).rw(FUNC(a800_rom_diamond_device::rom_bank_r), FUNC(a800_rom_diamond_device::rom_bank_w));
map(0xd8, 0xdf).rw(FUNC(a800_rom_diamond_device::disable_rom_r), FUNC(a800_rom_diamond_device::disable_rom_w));
}
/*-------------------------------------------------
Turbosoft 64K / 128K
-------------------------------------------------*/
a800_rom_turbo_device::a800_rom_turbo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: a800_rom_williams_device(mconfig, A800_ROM_TURBO, tag, owner, clock)
{
}
void a800_rom_turbo_device::cctl_map(address_map &map)
{
map(0x00, 0x0f).mirror(0xe0).rw(FUNC(a800_rom_turbo_device::rom_bank_r), FUNC(a800_rom_turbo_device::rom_bank_w));
map(0x10, 0x1f).mirror(0xe0).rw(FUNC(a800_rom_turbo_device::disable_rom_r), FUNC(a800_rom_turbo_device::disable_rom_w));
}

View File

@ -0,0 +1,69 @@
// license: BSD-3-Clause
// copyright-holders: Fabio Priuli, Angelo Salese
#ifndef MAME_BUS_A800_WILLIAMS_H
#define MAME_BUS_A800_WILLIAMS_H
#pragma once
#include "rom.h"
class a800_rom_williams_device : public a800_rom_device
{
public:
a800_rom_williams_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_williams_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cart_map(address_map &map) override;
virtual void cctl_map(address_map &map) override;
virtual std::tuple<int, int> get_initial_rd_state() override { return std::make_tuple(0, 1); };
protected:
virtual void device_start() override;
virtual void device_reset() override;
int m_bank;
uint8_t disable_rom_r(offs_t offset);
void disable_rom_w(offs_t offset, uint8_t data);
virtual uint8_t rom_bank_r(offs_t offset);
virtual void rom_bank_w(offs_t offset, uint8_t data);
};
class a800_rom_express_device : public a800_rom_williams_device
{
public:
a800_rom_express_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
a800_rom_express_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void cctl_map(address_map &map) override;
virtual uint8_t rom_bank_r(offs_t offset) override;
virtual void rom_bank_w(offs_t offset, uint8_t data) override;
};
class a800_rom_diamond_device : public a800_rom_express_device
{
public:
a800_rom_diamond_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
private:
virtual void cctl_map(address_map &map) override;
};
class a800_rom_turbo_device : public a800_rom_williams_device
{
public:
a800_rom_turbo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void cctl_map(address_map &map) override;
};
DECLARE_DEVICE_TYPE(A800_ROM_WILLIAMS, a800_rom_williams_device)
DECLARE_DEVICE_TYPE(A800_ROM_EXPRESS, a800_rom_express_device)
DECLARE_DEVICE_TYPE(A800_ROM_DIAMOND, a800_rom_diamond_device)
DECLARE_DEVICE_TYPE(A800_ROM_TURBO, a800_rom_turbo_device)
#endif // MAME_BUS_A800_WILLIAMS_H

View File

@ -2242,12 +2242,18 @@ void antic_device::scanline_dma(int param)
/* bits 6+7 of the priority select register determine */
/* if newer GTIA or plain graphics modes are used */
switch (m_gtia->get_w_prior() >> 6)
{
case 0: break;
case 1: m_render2 = 16; break;
case 2: m_render2 = 17; break;
case 3: m_render2 = 18; break;
}
{
case 0: break;
case 1: m_render2 = 16; break;
case 2: m_render2 = 17; break;
case 3: m_render2 = 18; break;
}
// TODO: implement GTIA 9++ Mode
// This is an artifact of abusing VSCROL so that scanlines gets 4x the normal height.
// Abused by 20xx homebrew releases such as:
// - Avery Breakout 2012
// - Final Assault
// - Numen
m_modelines = 1;
break;
}

View File

@ -1,5 +1,5 @@
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller
// copyright-holders:Juergen Buchmueller, Angelo Salese
/******************************************************************************
Atari 400/800
@ -7,8 +7,6 @@
Juergen Buchmueller, June 1998
TODO (generic):
- modernize memory maps;
- modernize cart handling;
- add cassette support;
- add floppy .atx support;
- Investigate supported RAM sizes and OS versions in different models;
@ -16,14 +14,26 @@
- Freddy emulation for 800XLF?
- Add support for proto boards and expansions (a1400xl, C/PM board, etc.)
- a130xe: support extended bank readback for Antic;
- a1200xl: boots to self-test ROM the first time around, fixes on
soft reset;
- a1200xl: requires reading TRIG3 high for detecting a cart inserted,
depends on above;
- a600xl, a800xl, a1200xl: crashes on MMU test in Acid800;
- eventually support unofficial mod for dual Pokey,
either make it a specific franken-machine with a130xe as base or use
slots.
- a600xl, a1200xl: crashes on MMU test in Acid800;
- slot support for PBI/ECI bus;
- slot support for overlay DIY HW mods:
\- PokeyMAX
(with stereo support via second Pokey alias accessed to $d280-$d2ff,
cfr. yoomp);
\- Ultimate1MB;
\- Covox;
\- VBXE "VideoBoard XE";
\- Incognito;
\- Rapidus;
\- AKI PS/2 keyboard inteface;
\- RAMBO XL and COMPY RAM expansion;
\- APE Warp+ OS 32-in-1;
\- MyBIOS for MyIDE-II;
\- Bit-3 Full-View 80
(technically maps in cart CCTL space, but installs in RAM card slot 3
and overrides ANTIC+GTIA layer when enabled);
2009-05 FP changes:
Factored out MESS specific code from MAME
@ -268,6 +278,8 @@ public:
, m_dac(*this, "dac")
, m_region_maincpu(*this, "maincpu")
, m_cartleft(*this, "cartleft")
, m_cart_rd4_view(*this, "cart_rd4_view")
, m_cart_rd5_view(*this, "cart_rd5_view")
, m_ctrl(*this, "ctrl%u", 1U)
{ }
@ -304,6 +316,8 @@ protected:
m_ram->pointer()[memory_offset] = data;
}
virtual uint8_t djoy_b_r();
private:
void a400_palette(palette_device &palette) const;
@ -313,37 +327,24 @@ private:
void djoy_0_1_w(uint8_t data);
uint8_t djoy_2_3_r();
void djoy_2_3_w(uint8_t data);
uint8_t djoy_b_r();
uint8_t read_d5xx(offs_t offset); // at least one cart type can enable/disable roms when reading
void disable_cart(offs_t offset, uint8_t data);
// these are needed to handle carts which can disable ROM without
// installing/disinstalling continuously RAM and ROM (with e.g. big
// performance hit in Williams carts)
uint8_t special_read_8000(offs_t offset);
void special_write_8000(offs_t offset, uint8_t data);
uint8_t special_read_a000(offs_t offset);
void special_write_a000(offs_t offset, uint8_t data);
uint8_t read_corina_overlay(offs_t offset);
void write_corina_overlay(offs_t offset, uint8_t data);
void write_corina_d5xx(offs_t offset, uint8_t data);
protected:
//required_device<cpu_device> m_maincpu; // maincpu is already contained in atari_common_state
optional_device<ram_device> m_ram;
optional_device<pia6821_device> m_pia;
optional_device<dac_bit_interface> m_dac;
required_memory_region m_region_maincpu;
required_device<a800_cart_slot_device> m_cartleft;
optional_device<a800_cart_slot_device> m_cartleft;
memory_view m_cart_rd4_view, m_cart_rd5_view;
optional_device_array<vcs_control_port_device, 4> m_ctrl;
int m_cart_disabled, m_cart_helper;
int m_last_offs;
void setup_cart(a800_cart_slot_device *slot);
void hw_iomap(address_map &map);
int m_cart_rd4_enabled = 0, m_cart_rd5_enabled = 0;
void cart_rd4_w( int state );
void cart_rd5_w( int state );
virtual void area_8000_map(address_map &map);
virtual void area_a000_map(address_map &map);
};
class a800_state : public a400_state
@ -358,7 +359,8 @@ public:
void a800pal(machine_config &config);
protected:
virtual void machine_start() override;
// virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_device<a800_cart_slot_device> m_cartright;
@ -391,6 +393,7 @@ protected:
memory_view m_selftest_view;
virtual void portb_cb(uint8_t data);
virtual uint8_t djoy_b_r() override;
void selftest_map(memory_view::memory_view_entry &block, bool is_rom_mapping);
private:
@ -417,6 +420,8 @@ protected:
void a800xl_mem(address_map &map);
virtual void area_a000_map(address_map &map) override;
memory_view m_basic_view;
};
@ -479,15 +484,19 @@ private:
class a5200_state : public a400_state
{
public:
a5200_state(const machine_config &mconfig, device_type type, const char *tag) :
a400_state(mconfig, type, tag)
a5200_state(const machine_config &mconfig, device_type type, const char *tag)
: a400_state(mconfig, type, tag)
, m_cart(*this, "cart")
{ }
void a5200(machine_config &config);
void a5200a(machine_config &config);
private:
// virtual void machine_start() override;
virtual void machine_start() override;
virtual void machine_reset() override;
required_device<a5200_cart_slot_device> m_cart;
TIMER_DEVICE_CALLBACK_MEMBER(a5200_interrupt);
@ -500,28 +509,41 @@ private:
*
**************************************************************/
// TODO: better memory map inheritance
// TODO: transparent support for cart window & cart rd5 line (active_high) for enable/disable
// (applies to 0xa000-0xbfff only?)
// TODO: transparent support for cart CCTL at 0xd500
// TODO: transparent support for PBI (XL) / ECI (XE series), at 0xd1xx, 0xd6xx, 0xd7xx + ROM at 0xd800-0xdfff
void a400_state::hw_iomap(address_map &map)
{
map(0x0000, 0x00ff).rw(m_gtia, FUNC(gtia_device::read), FUNC(gtia_device::write));
map(0x0100, 0x01ff).noprw();
// map(0x0100, 0x01ff).noprw();
map(0x0200, 0x02ff).rw(m_pokey, FUNC(pokey_device::read), FUNC(pokey_device::write));
map(0x0300, 0x03ff).rw(m_pia, FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0x0400, 0x04ff).rw(m_antic, FUNC(antic_device::read), FUNC(antic_device::write));
map(0x0500, 0x05ff).noprw();
map(0x0600, 0x07ff).noprw();
map(0x0500, 0x05ff).rw(m_cartleft, FUNC(a800_cart_slot_device::read_cctl), FUNC(a800_cart_slot_device::write_cctl));
// map(0x0600, 0x07ff).noprw();
}
void a400_state::area_8000_map(address_map &map)
{
map(0x8000, 0x9fff).view(m_cart_rd4_view);
m_cart_rd4_view[0](0x8000, 0x9fff).rw(FUNC(a400_state::ram_r<0x8000>), FUNC(a400_state::ram_w<0x8000>));
m_cart_rd4_view[1](0x8000, 0x9fff).rw(m_cartleft, FUNC(a800_cart_slot_device::read_cart<0>), FUNC(a800_cart_slot_device::write_cart<0>));
}
void a400_state::area_a000_map(address_map &map)
{
map(0xa000, 0xbfff).view(m_cart_rd5_view);
m_cart_rd5_view[0](0xa000, 0xbfff).rw(FUNC(a400_state::ram_r<0xa000>), FUNC(a400_state::ram_w<0xa000>));
m_cart_rd5_view[1](0xa000, 0xbfff).rw(m_cartleft, FUNC(a800_cart_slot_device::read_cart<1>), FUNC(a800_cart_slot_device::write_cart<1>));
}
// a400/a800 explicitly expects floating bus for unmapped ranges, will punt with value_low()
void a400_state::a400_mem(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0xbfff).rw(FUNC(a400_state::ram_r<0x0000>), FUNC(a400_state::ram_w<0x0000>));
map(0x0000, 0x7fff).rw(FUNC(a400_state::ram_r<0x0000>), FUNC(a400_state::ram_w<0x0000>));
area_8000_map(map);
area_a000_map(map);
map(0xc000, 0xcfff).rom();
map(0xd000, 0xd7ff).m(*this, FUNC(a400_state::hw_iomap));
map(0xd800, 0xffff).rom();
@ -557,21 +579,36 @@ void a1200xl_state::a1200xl_mem(address_map &map)
map(0x4000, 0x7fff).view(m_selftest_view);
selftest_map(m_selftest_view[0], false);
selftest_map(m_selftest_view[1], true);
map(0x8000, 0x9fff).rw(FUNC(a1200xl_state::ram_r<0x8000>), FUNC(a1200xl_state::ram_w<0x8000>));
map(0xa000, 0xbfff).rw(FUNC(a1200xl_state::ram_r<0xa000>), FUNC(a1200xl_state::ram_w<0xa000>));
area_8000_map(map);
area_a000_map(map);
map(0xc000, 0xffff).view(m_kernel_view);
m_kernel_view[0](0xc000, 0xffff).rw(FUNC(a1200xl_state::ram_r<0xc000>), FUNC(a1200xl_state::ram_w<0xc000>));
m_kernel_view[1](0xc000, 0xffff).rom().region("maincpu", 0xc000);
map(0xd000, 0xd7ff).m(*this, FUNC(a1200xl_state::hw_iomap));
}
void a800xl_state::area_a000_map(address_map &map)
{
map(0xa000, 0xbfff).view(m_cart_rd5_view);
m_cart_rd5_view[0](0xa000, 0xbfff).view(m_basic_view);
m_basic_view[0](0xa000, 0xbfff).rw(FUNC(a800xl_state::ram_r<0xa000>), FUNC(a800xl_state::ram_w<0xa000>));
m_basic_view[1](0xa000, 0xbfff).rom().region("maincpu", 0xa000);
m_cart_rd5_view[1](0xa000, 0xbfff).rw(m_cartleft, FUNC(a800_cart_slot_device::read_cart<1>), FUNC(a800_cart_slot_device::write_cart<1>));
}
void a800xl_state::a800xl_mem(address_map &map)
{
map.unmap_value_high();
a1200xl_mem(map);
map(0xa000, 0xbfff).view(m_basic_view);
m_basic_view[0](0xa000, 0xbfff).rw(FUNC(a800xl_state::ram_r<0xa000>), FUNC(a800xl_state::ram_w<0xa000>));
m_basic_view[1](0xa000, 0xbfff).rom().region("maincpu", 0xa000);
map(0x0000, 0x3fff).rw(FUNC(a800xl_state::ram_r<0x0000>), FUNC(a800xl_state::ram_w<0x0000>));
map(0x4000, 0x7fff).view(m_selftest_view);
selftest_map(m_selftest_view[0], false);
selftest_map(m_selftest_view[1], true);
area_8000_map(map);
area_a000_map(map);
map(0xc000, 0xffff).view(m_kernel_view);
m_kernel_view[0](0xc000, 0xffff).rw(FUNC(a800xl_state::ram_r<0xc000>), FUNC(a800xl_state::ram_w<0xc000>));
m_kernel_view[1](0xc000, 0xffff).rom().region("maincpu", 0xc000);
map(0xd000, 0xd7ff).m(*this, FUNC(a800xl_state::hw_iomap));
}
// selftest ROM has still priority over regular a130xe extended RAM
@ -591,10 +628,8 @@ void a130xe_state::a130xe_mem(address_map &map)
selftest_map(m_selftest_view[0], false);
selftest_map(m_selftest_view[1], true);
m_ext_view[1](0x4000, 0x7fff).m(m_ext_bank, FUNC(address_map_bank_device::amap8));
map(0x8000, 0x9fff).rw(FUNC(a130xe_state::ram_r<0x8000>), FUNC(a130xe_state::ram_w<0x8000>));
map(0xa000, 0xbfff).view(m_basic_view);
m_basic_view[0](0xa000, 0xbfff).rw(FUNC(a130xe_state::ram_r<0xa000>), FUNC(a130xe_state::ram_w<0xa000>));
m_basic_view[1](0xa000, 0xbfff).rom().region("maincpu", 0xa000);
area_8000_map(map);
area_a000_map(map);
map(0xc000, 0xffff).view(m_kernel_view);
m_kernel_view[0](0xc000, 0xffff).rw(FUNC(a130xe_state::ram_r<0xc000>), FUNC(a130xe_state::ram_w<0xc000>));
m_kernel_view[1](0xc000, 0xffff).rom().region("maincpu", 0xc000);
@ -610,11 +645,17 @@ void xegs_state::xegs_mem(address_map &map)
m_selftest_view[0](0x5000, 0x57ff).ram();
m_selftest_view[1](0x5000, 0x57ff).rom().region("maincpu", 0xd000);
map(0x5800, 0x7fff).ram();
// TODO: map cart space overlays
map(0x8000, 0x9fff).ram();
map(0xa000, 0xbfff).view(m_basic_view);
map(0x8000, 0x9fff).view(m_cart_rd4_view);
m_cart_rd4_view[0](0x8000, 0x9fff).ram();
m_cart_rd4_view[1](0x8000, 0x9fff).rw(m_cartleft, FUNC(a800_cart_slot_device::read_cart<0>), FUNC(a800_cart_slot_device::write_cart<0>));
map(0xa000, 0xbfff).view(m_cart_rd5_view);
m_cart_rd5_view[0](0xa000, 0xbfff).view(m_basic_view);
m_basic_view[0](0xa000, 0xbfff).ram();
m_basic_view[1](0xa000, 0xbfff).bankr(m_bank);
m_cart_rd5_view[1](0xa000, 0xbfff).rw(m_cartleft, FUNC(a800_cart_slot_device::read_cart<1>), FUNC(a800_cart_slot_device::write_cart<1>));
map(0xc000, 0xffff).view(m_kernel_view);
m_kernel_view[0](0xc000, 0xffff).ram();
m_kernel_view[1](0xc000, 0xffff).rom().region("maincpu", 0xc000);
@ -625,7 +666,7 @@ void xegs_state::xegs_mem(address_map &map)
void a5200_state::a5200_mem(address_map &map)
{
map(0x0000, 0x3fff).ram();
map(0x4000, 0xbfff).noprw(); // ROM installed at machine start
map(0x4000, 0xbfff).rw(m_cart, FUNC(a5200_cart_slot_device::read_cart), FUNC(a5200_cart_slot_device::write_cart));
map(0xc000, 0xcfff).rw(m_gtia, FUNC(gtia_device::read), FUNC(gtia_device::write));
map(0xd400, 0xd4ff).rw(m_antic, FUNC(antic_device::read), FUNC(antic_device::write));
// 0xe000-0xe7ff - Expansion?
@ -1658,282 +1699,18 @@ LIGHT-ORANGE
*
**************************************************************/
// these handle cart enable/disable without calling setup_ram thousands of times
// TODO: this should really live in a800_slot file
uint8_t a400_state::special_read_8000(offs_t offset)
void a400_state::cart_rd4_w(int state)
{
if (!m_cart_disabled)
return m_cartleft->read_80xx(offset);
else
{
offset += 0x8000;
if (m_ram->size() < offset)
return 0;
else
return m_ram->pointer()[offset];
}
m_cart_rd4_enabled = state;
m_cart_rd4_view.select(m_cart_rd4_enabled);
}
void a400_state::special_write_8000(offs_t offset, uint8_t data)
void a400_state::cart_rd5_w(int state)
{
if (m_cart_disabled)
{
offset += 0x8000;
if (m_ram->size() >= offset)
m_ram->pointer()[offset] = data;
}
m_cart_rd5_enabled = state;
m_cart_rd5_view.select(m_cart_rd5_enabled);
}
uint8_t a400_state::special_read_a000(offs_t offset)
{
if (!m_cart_disabled)
return m_cartleft->read_80xx(offset);
else
{
offset += 0xa000;
if (m_ram->size() < offset)
return 0;
else
return m_ram->pointer()[offset];
}
}
void a400_state::special_write_a000(offs_t offset, uint8_t data)
{
if (m_cart_disabled)
{
offset += 0xa000;
if (m_ram->size() >= offset)
m_ram->pointer()[offset] = data;
}
}
uint8_t a400_state::read_d5xx(offs_t offset)
{
if (!machine().side_effects_disabled())
disable_cart(offset, 0);
return 0xff;
}
uint8_t a400_state::read_corina_overlay(offs_t offset)
{
if (!m_cart_disabled)
return m_cartleft->read_80xx(offset);
offset += 0x8000;
if (m_ram->size() < offset)
return 0;
else
return m_ram->pointer()[offset];
}
void a400_state::write_corina_overlay(offs_t offset, uint8_t data)
{
if (!m_cart_disabled)
{
m_cartleft->write_80xx(offset, data);
return;
}
offset += 0x8000;
if (m_ram->size() >= offset)
m_ram->pointer()[offset] = data;
}
void a400_state::write_corina_d5xx(offs_t offset, uint8_t data)
{
m_cart_disabled = BIT(data, 7);
m_cartleft->write_d5xx(offset, data);
}
void a400_state::disable_cart(offs_t offset, uint8_t data)
{
if (m_cartleft->exists())
{
switch (m_cartleft->get_cart_type())
{
case A800_PHOENIX:
case A800_BLIZZARD:
if (!m_cart_disabled)
m_cart_disabled = 1;
break;
case A800_OSS034M:
case A800_OSS043M:
case A800_EXPRESS:
case A800_DIAMOND:
case A800_WILLIAMS:
// use m_cart_disabled & m_last_offs to avoid continuous remapping of
// the memory space in some games (e.g. dropzone)
if (offset & 0x8 && !m_cart_disabled)
m_cart_disabled = 1;
else if (!(offset & 0x8))
{
if (m_cart_disabled)
m_cart_disabled = 0;
if ((offset & 0x7) != m_last_offs)
{
// we enter here only if we are writing to a different offset than last time
m_last_offs = offset & 0x7;
m_cartleft->write_d5xx(offset, data);
}
}
break;
case A800_TURBO64:
case A800_TURBO128:
if (offset & 0x10 && !m_cart_disabled)
m_cart_disabled = 1;
else if (!(offset & 0x10))
{
if (m_cart_disabled)
m_cart_disabled = 0;
if ((offset & 0x0f) != m_last_offs)
{
// we enter here only if we are writing to a different offset than last time
m_last_offs = offset & 0x0f;
m_cartleft->write_d5xx(offset & 0x0f, data);
}
}
break;
case A800_SPARTADOS:
// writes with offset & 8 are also used to enable/disable the subcart, so they go through!
m_cartleft->write_d5xx(offset, data);
break;
case A800_OSSM091:
case A800_OSS8K:
if ((offset & 0x9) == 0x08)
m_cart_disabled = 1;
else
{
m_cart_disabled = 0;
m_cartleft->write_d5xx(offset, data);
}
break;
case A800_MICROCALC:
m_cart_helper = (m_cart_helper + 1) % 5;
if (m_cart_helper == 4)
m_cart_disabled = 1;
else
{
m_cart_disabled = 0;
m_cartleft->write_d5xx(offset, m_cart_helper);
}
break;
default:
break;
}
}
}
void a400_state::setup_cart(a800_cart_slot_device *slot)
{
m_cart_disabled = 0;
m_last_offs = -1;
// FIXME: this driver should not have to differentiate between cartridge types
if (slot->exists())
{
switch (slot->get_cart_type())
{
case A800_8K:
m_maincpu->space(AS_PROGRAM).install_read_handler(0xa000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0xa000, 0xbfff);
break;
case A800_8K_RIGHT:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0x9fff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0x9fff);
break;
case A800_16K:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0xbfff);
break;
case A800_BBSB:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0x9fff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0xa000, 0xbfff);
break;
case A800_OSS034M:
case A800_OSS043M:
case A800_OSSM091:
case A800_OSS8K:
case A800_TURBO64:
case A800_TURBO128:
case A800_PHOENIX:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_a000)), write8sm_delegate(*this, FUNC(a400_state::special_write_a000)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd5ff, write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_EXPRESS:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_a000)), write8sm_delegate(*this, FUNC(a400_state::special_write_a000)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd570, 0xd57f, write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_DIAMOND:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_a000)), write8sm_delegate(*this, FUNC(a400_state::special_write_a000)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd5d0, 0xd5df, write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_WILLIAMS:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_a000)), write8sm_delegate(*this, FUNC(a400_state::special_write_a000)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd50f, write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_SPARTADOS:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_a000)), write8sm_delegate(*this, FUNC(a400_state::special_write_a000)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd5e0, 0xd5ef, write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_BLIZZARD:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x8000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_8000)), write8sm_delegate(*this, FUNC(a400_state::special_write_8000)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd5ff, write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_MICROCALC:
// this can also disable ROM when reading in 0xd500-0xd5ff
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xa000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::special_read_a000)), write8sm_delegate(*this, FUNC(a400_state::special_write_a000)));
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xd500, 0xd5ff, read8sm_delegate(*this, FUNC(a400_state::read_d5xx)), write8sm_delegate(*this, FUNC(a400_state::disable_cart)));
break;
case A800_TELELINK2:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0x9000, 0x90ff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0xa000, 0xbfff);
m_maincpu->space(AS_PROGRAM).install_read_handler(0xd501, 0xd501, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_d5xx)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd502, 0xd502, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_d5xx)));
break;
case A800_XEGS:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0x8000, 0xbfff);
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd5ff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_d5xx)));
break;
case A800_CORINA:
case A800_CORINA_SRAM:
//m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
//m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xbfff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_80xx)));
//m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd500, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_d5xx)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*this, FUNC(a400_state::read_corina_overlay)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xbfff, write8sm_delegate(*this, FUNC(a400_state::write_corina_overlay)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd500, write8sm_delegate(*this, FUNC(a400_state::write_corina_d5xx)));
break;
case A5200_4K:
case A5200_8K:
case A5200_16K:
case A5200_32K:
case A5200_16K_2CHIPS:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x4000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0x4000, 0xbfff);
break;
case A5200_BBSB:
m_maincpu->space(AS_PROGRAM).install_read_handler(0x4000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0x4000, 0x5fff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_80xx)));
m_maincpu->space(AS_PROGRAM).unmap_write(0x6000, 0xbfff);
break;
}
}
else if (slot->get_card_device() != nullptr)
{
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xbfff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_80xx)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0x8000, 0xbfff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_80xx)));
m_maincpu->space(AS_PROGRAM).install_read_handler(0xd500, 0xd5ff, read8sm_delegate(*slot, FUNC(a800_cart_slot_device::read_d5xx)));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xd500, 0xd5ff, write8sm_delegate(*slot, FUNC(a800_cart_slot_device::write_d5xx)));
}
}
TIMER_DEVICE_CALLBACK_MEMBER( a400_state::a400_interrupt )
{
m_antic->generic_interrupt(4);
@ -1951,17 +1728,8 @@ TIMER_DEVICE_CALLBACK_MEMBER( a5200_state::a5200_interrupt )
void a400_state::machine_start()
{
setup_cart(m_cartleft);
save_item(NAME(m_cart_disabled));
save_item(NAME(m_cart_helper));
save_item(NAME(m_last_offs));
}
void a800_state::machine_start()
{
a400_state::machine_start();
setup_cart(m_cartright);
save_item(NAME(m_cart_rd4_enabled));
save_item(NAME(m_cart_rd5_enabled));
}
void a1200xl_state::machine_start()
@ -1979,6 +1747,31 @@ void xegs_state::machine_start()
void a400_state::machine_reset()
{
m_pokey->write(15, 0);
// TODO: stub reset state
if (!m_cartleft->exists())
{
m_cart_rd4_enabled = 0;
m_cart_rd5_enabled = 0;
}
else
std::tie(m_cart_rd4_enabled, m_cart_rd5_enabled) = m_cartleft->get_initial_rd_state();
m_cart_rd4_view.select(m_cart_rd4_enabled);
m_cart_rd5_view.select(m_cart_rd5_enabled);
}
void a800_state::machine_reset()
{
a400_state::machine_reset();
// TODO: stub reset state, verify if any can be run stand-alone
/*
if (!m_cartright->exists())
{
m_cart_rd4_enabled = false;
m_cart_rd4_view.select(0);
}*/
}
void a1200xl_state::machine_reset()
@ -2008,6 +1801,14 @@ void a130xe_state::machine_reset()
m_ext_bank->set_bank(3);
}
void a5200_state::machine_start()
{
}
void a5200_state::machine_reset()
{
m_pokey->write(15, 0);
}
/**************************************************************
*
@ -2057,12 +1858,31 @@ uint8_t a400_state::djoy_b_r()
return b;
}
uint8_t a1200xl_state::djoy_b_r()
{
uint8_t b = 0;
for (int i = 0; i < 2; i++)
if (!m_ctrl[i].found() || BIT(m_ctrl[i]->read_joy(), 5))
b |= 1 << i;
// TODO: TRIG2 (0) for XEGS keyboard disconnected, always 1 otherwise
b |= 1 << 2;
// TODO: TRIG3 should really read from RD5 instead
// - non-64KB SDX boot (will hang in kernel during POST by boot conflict with BASIC if not handled properly)
// - a1200xl cart boot (expects this to be reversed)
// - returning m_cartleft->exists() makes BASIC disable thru OPTION to not work and makes maxflash to fail loading most .xex
// b |= m_cart_rd5_enabled << 3;
b |= !m_cartleft->exists() << 3;
return b;
}
void a1200xl_state::pia_portb_w(uint8_t data)
{
const u8 dir = m_pia->port_b_z_mask();
// On a1200xl BIOS jumps from PC=0xc550, expecting ROM to be still
// enabled at PC=0xe40c, expecting the dir to work properly.
// enabled at PC=0xe40c, needing direction to work properly.
const u8 new_mmu = (data & ~dir) | (m_mmu & dir);
if (m_mmu != new_mmu)
@ -2136,6 +1956,10 @@ void a130xe_state::portb_cb(uint8_t data)
}
else
m_ext_view.select(0);
// TODO: ANTIC extended memory access enable
// Prince of Persia homebrew has it always on.
// May be used for the intro screen (where text don't draw at the time of this writing)
}
// TODO: propagate portb to RAMBO XL and COMPY sub-devices for a800xl and onward
@ -2243,12 +2067,14 @@ void a400_state::atari_common(machine_config &config)
ATARI_FDC(config, "fdc", 0);
A800_CART_SLOT(config, m_cartleft, a800_left, nullptr);
m_cartleft->rd4_callback().set(FUNC(a400_state::cart_rd4_w));
m_cartleft->rd5_callback().set(FUNC(a400_state::cart_rd5_w));
/* software lists */
SOFTWARE_LIST(config, "flop_list").set_original("a800_flop");
SOFTWARE_LIST(config, "cart_list").set_original("a800");
SOFTWARE_LIST(config, "cass_list").set_original("a800_cass");
SOFTWARE_LIST(config, "xegs_list").set_original("xegs");
SOFTWARE_LIST(config, "cart_list").set_original("a800");
SOFTWARE_LIST(config, "xegs_list").set_compatible("xegs");
VCS_CONTROL_PORT(config, m_ctrl[0], a800_control_port_devices, "joy");
VCS_CONTROL_PORT(config, m_ctrl[1], a800_control_port_devices, "joy");
@ -2342,6 +2168,10 @@ void a1200xl_state::a1200xl(machine_config &config)
m_pokey->pot_r<6>().set_ioport("J3");
m_pokey->pot_r<7>().set_ioport("J4");
// TODO: console LEDs for this model only
// retail has 64KB minimum
m_ram->set_default_size("64K");
// m_ram->set_extra_options("16K,32K,48K");
}
// memory map A800XL + NTSC screen + MMU via PIA portB
@ -2395,13 +2225,15 @@ void xegs_state::xegs(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &xegs_state::xegs_mem);
config.device_remove("cartleft");
config.device_remove("cart_list");
// not installable unless with DIY mods
config.device_remove("ram");
XEGS_CART_SLOT(config, m_cartleft, xegs_carts, nullptr);
// m_cartleft->set_default_option("xegs");
m_cartleft->set_is_xegs(true);
// uses exact same slot connector
SOFTWARE_LIST(config.replace(), "cart_list").set_compatible("a800");
SOFTWARE_LIST(config.replace(), "xegs_list").set_original("xegs");
}
// memory map A5200, different ports, less RAM
@ -2434,7 +2266,7 @@ void a5200_state::a5200(machine_config &config)
config_ntsc_screen(config);
A5200_CART_SLOT(config, m_cartleft, a5200_carts, nullptr);
A5200_CART_SLOT(config, m_cart, a5200_carts, nullptr);
/* Software lists */
SOFTWARE_LIST(config, "cart_list").set_original("a5200");

View File

@ -1,5 +1,5 @@
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller
// copyright-holders:Juergen Buchmueller, Angelo Salese
/******************************************************************************
Atari 400/800

View File

@ -317,12 +317,13 @@ void gtia_device::button_interrupt(int button_count)
}
/* button registers for xl/xe */
// these don't really unregister on latch but are instant
if (button_count == 2)
{
// TRIG2: unused on xl/xe (1), xegs keyboard (1) connected (0) disconnected
m_r.but[2] = 1;
m_r.but[2] = BIT(button_port, 2);
// TRIG3: RD5 external cart readback (1) present (0) disabled thru bankswitch or absent
m_r.but[3] = 0;
m_r.but[3] = BIT(button_port, 3);
}
}