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:
parent
5ebd8c61f0
commit
0855900ded
227
hash/a5200.xml
227
hash/a5200.xml
@ -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><homebrew></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><unlicensed></publisher>
|
||||
<publisher><homebrew></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><unlicensed></publisher>
|
||||
<publisher><homebrew></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><unlicensed></publisher>
|
||||
<publisher><homebrew></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>
|
||||
|
1240
hash/a800.xml
1240
hash/a800.xml
File diff suppressed because it is too large
Load Diff
@ -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">
|
||||
|
@ -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><homebrew></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" />
|
||||
|
@ -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
|
||||
|
||||
|
73
src/devices/bus/a800/a5200_supercart.cpp
Normal file
73
src/devices/bus/a800/a5200_supercart.cpp
Normal 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));
|
||||
}
|
32
src/devices/bus/a800/a5200_supercart.h
Normal file
32
src/devices/bus/a800/a5200_supercart.h
Normal 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
|
||||
|
108
src/devices/bus/a800/a800_carts.cpp
Normal file
108
src/devices/bus/a800/a800_carts.cpp
Normal 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);
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
54
src/devices/bus/a800/atrax.cpp
Normal file
54
src/devices/bus/a800/atrax.cpp
Normal 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;
|
||||
}
|
34
src/devices/bus/a800/atrax.h
Normal file
34
src/devices/bus/a800/atrax.h
Normal 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
|
136
src/devices/bus/a800/bbsb.cpp
Normal file
136
src/devices/bus/a800/bbsb.cpp
Normal 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;
|
||||
}
|
52
src/devices/bus/a800/bbsb.h
Normal file
52
src/devices/bus/a800/bbsb.h
Normal 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
|
@ -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)
|
||||
{
|
||||
|
135
src/devices/bus/a800/corina.cpp
Normal file
135
src/devices/bus/a800/corina.cpp
Normal 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;
|
||||
}
|
59
src/devices/bus/a800/corina.h
Normal file
59
src/devices/bus/a800/corina.h
Normal 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
|
123
src/devices/bus/a800/maxflash.cpp
Normal file
123
src/devices/bus/a800/maxflash.cpp
Normal 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));
|
||||
}
|
53
src/devices/bus/a800/maxflash.h
Normal file
53
src/devices/bus/a800/maxflash.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
176
src/devices/bus/a800/phoenix.cpp
Normal file
176
src/devices/bus/a800/phoenix.cpp
Normal 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]; })
|
||||
);
|
||||
}
|
70
src/devices/bus/a800/phoenix.h
Normal file
70
src/devices/bus/a800/phoenix.h
Normal 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
|
@ -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]; })
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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); })
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
|
114
src/devices/bus/a800/sic.cpp
Normal file
114
src/devices/bus/a800/sic.cpp
Normal 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);
|
||||
}
|
64
src/devices/bus/a800/sic.h
Normal file
64
src/devices/bus/a800/sic.h
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
94
src/devices/bus/a800/supercharger.cpp
Normal file
94
src/devices/bus/a800/supercharger.cpp
Normal 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;
|
||||
}
|
||||
}
|
35
src/devices/bus/a800/supercharger.h
Normal file
35
src/devices/bus/a800/supercharger.h
Normal 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
|
64
src/devices/bus/a800/telelink2.cpp
Normal file
64
src/devices/bus/a800/telelink2.cpp
Normal 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
|
||||
}
|
34
src/devices/bus/a800/telelink2.h
Normal file
34
src/devices/bus/a800/telelink2.h
Normal 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
|
130
src/devices/bus/a800/ultracart.cpp
Normal file
130
src/devices/bus/a800/ultracart.cpp
Normal 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;
|
||||
}
|
55
src/devices/bus/a800/ultracart.h
Normal file
55
src/devices/bus/a800/ultracart.h
Normal 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
|
160
src/devices/bus/a800/williams.cpp
Normal file
160
src/devices/bus/a800/williams.cpp
Normal 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));
|
||||
}
|
69
src/devices/bus/a800/williams.h
Normal file
69
src/devices/bus/a800/williams.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Juergen Buchmueller
|
||||
// copyright-holders:Juergen Buchmueller, Angelo Salese
|
||||
/******************************************************************************
|
||||
|
||||
Atari 400/800
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user