Merge branch 'feature-moviecart' of git://github.com/lodefmode/stella into feature/lodefmode-moviecart

This commit is contained in:
Stephen Anthony 2021-04-21 19:47:14 -02:30
commit 8873ffd0b7
10 changed files with 1727 additions and 2 deletions

View File

@ -140,6 +140,7 @@ Bankswitch::BSList = {{
{ "FC" , "FC (32K Amiga)" },
{ "FE" , "FE (8K Decathlon)" },
{ "MDM" , "MDM (Menu Driven Megacart)" },
{ "MVC" , "MVC (Movie Cart)" },
{ "SB" , "SB (128-256K SUPERbank)" },
{ "TVBOY" , "TV Boy (512K)" },
{ "UA" , "UA (8K UA Ltd.)" },
@ -226,6 +227,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
{ "FC" , Bankswitch::Type::_FC },
{ "FE" , Bankswitch::Type::_FE },
{ "MDM" , Bankswitch::Type::_MDM },
{ "MVC" , Bankswitch::Type::_MVC },
{ "SB" , Bankswitch::Type::_SB },
{ "TVB" , Bankswitch::Type::_TVBOY },
{ "TVBOY" , Bankswitch::Type::_TVBOY },
@ -284,6 +286,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
{ "FC" , Bankswitch::Type::_FC },
{ "FE" , Bankswitch::Type::_FE },
{ "MDM" , Bankswitch::Type::_MDM },
{ "MVC" , Bankswitch::Type::_MVC },
{ "SB" , Bankswitch::Type::_SB },
{ "TVBOY" , Bankswitch::Type::_TVBOY },
{ "UA" , Bankswitch::Type::_UA },

View File

@ -44,8 +44,8 @@ class Bankswitch
_CDF, _CM, _CTY, _CV, _DF, _DFSC, _DPC,
_DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0,
_F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA,
_FA2, _FC, _FE, _MDM, _SB, _TVBOY, _UA,
_UASW, _WD, _WDSW, _X07,
_FA2, _FC, _FE, _MDM, _MVC, _SB, _TVBOY,
_UA, _UASW, _WD, _WDSW, _X07,
#ifdef CUSTOM_ARM
_CUSTOM,
#endif

View File

@ -55,6 +55,7 @@
#include "CartFC.hxx"
#include "CartFE.hxx"
#include "CartMDM.hxx"
#include "CartMVC.hxx"
#include "CartSB.hxx"
#include "CartTVBoy.hxx"
#include "CartUA.hxx"
@ -197,6 +198,10 @@ unique_ptr<Cartridge> CartCreator::create(const FilesystemNode& file,
Bankswitch::typeToName(type) + "'");
break;
case Bankswitch::Type::_MVC:
cartridge = make_unique<CartridgeMVC>(file.getPath(), size, md5, settings);
break;
default:
cartridge = createFromImage(image, size, detectedType, md5, settings);
break;

View File

@ -19,6 +19,7 @@
#include "Logger.hxx"
#include "CartDetector.hxx"
#include "CartMVC.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t size)
@ -240,6 +241,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
type = Bankswitch::Type::_3EP;
else if(isProbablyMDM(image, size))
type = Bankswitch::Type::_MDM;
else if(isProbablyMVC(image, size))
type = Bankswitch::Type::_MVC;
// If we get here and autodetection failed, then we force '4K'
if(type == Bankswitch::Type::_AUTO)
@ -689,6 +692,38 @@ bool CartDetector::isProbablyMDM(const ByteBuffer& image, size_t size)
return searchForBytes(image, std::min<size_t>(size, 8_KB), mdmc, 4);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyMVC(const ByteBuffer& image, size_t size)
{
// MVC version 0
uInt8 sig[] = { 'M', 'V', 'C', 0 };
int sigSize = sizeof(sig);
return searchForBytes(image, std::min<size_t>(size, sigSize+1), sig, sigSize);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
size_t CartDetector::isProbablyMVC(std::istream &in, size_t maxSize)
{
const size_t frameSize = 2 * MVC_FIELD_PAD_SIZE;
bool found = false;
// Returns size of field if stream is probably an MVC movie cartridge
if (maxSize >= frameSize)
{
auto pos = in.tellg();
ByteBuffer image = make_unique<uInt8[]>(frameSize);
in.read(reinterpret_cast<char*>(image.get()), frameSize);
in.seekg(pos);
found = isProbablyMVC(image, frameSize);
}
return found ? frameSize : 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablySB(const ByteBuffer& image, size_t size)
{

View File

@ -40,6 +40,13 @@ class CartDetector
*/
static Bankswitch::Type autodetectType(const ByteBuffer& image, size_t size);
/**
MVC cartridges are of arbitary large length
Returns size of frame if stream is probably an MVC movie cartridge
*/
static size_t isProbablyMVC(std::istream &in, size_t size);
private:
/**
Search the image for the specified byte signature
@ -189,6 +196,11 @@ class CartDetector
*/
static bool isProbablyMDM(const ByteBuffer& image, size_t size);
/**
Returns true if the image is probably an MVC movie cartridge
*/
static bool isProbablyMVC(const ByteBuffer& image, size_t size);
/**
Returns true if the image is probably a SB bankswitching cartridge
*/

1470
src/emucore/CartMVC.cxx Executable file

File diff suppressed because it is too large Load Diff

185
src/emucore/CartMVC.hxx Executable file
View File

@ -0,0 +1,185 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef CARTRIDGEMVC_HXX
#define CARTRIDGEMVC_HXX
class System;
class MovieCart;
#include "bspf.hxx"
#include "Cart.hxx"
/**
Implementation of MovieCart.
1K of memory is presented on the bus, but is repeated to fill the 4K image space.
Contents are dynamically altered with streaming image and audio content as specific
128-byte regions are entered.
Original implementation: github.com/lodefmode/moviecart
@author Rob Bairos
*/
#define MVC_FIELD_SIZE 2560 // round field to nearest 512 byte boundary
#define MVC_FIELD_PAD_SIZE 4096 // round to nearest 4K
class CartridgeMVC : public Cartridge
{
public:
/**
Create a new cartridge using the specified image
@param image Pointer to the ROM image
@param size The size of the ROM image (<= 2048 bytes)
@param md5 The md5sum of the ROM image
@param settings A reference to the various settings (read-only)
@param bsSize The size specified by the bankswitching scheme
*/
CartridgeMVC(const string& path, size_t size, const string& md5,
const Settings& settings, size_t bsSize = 2_KB);
~CartridgeMVC() override = default;
/**
Reset device to its power-on state
*/
void reset() override;
/**
Install cartridge in the specified system. Invoked by the system
when the cartridge is attached to it.
@param system The system the device should install itself in
*/
void install(System& system) override;
/**
Access the internal ROM image for this cartridge.
@param size Set to the size of the internal ROM image data
@return A reference to the internal ROM image data
*/
virtual const ByteBuffer& getImage(size_t& size) const;
/**
Patch the cartridge ROM.
@param address The ROM address to patch
@param value The value to place into the address
@return Success or failure of the patch operation
*/
virtual bool patch(uInt16 address, uInt8 value);
/**
Get the byte at the specified address.
@return The byte at the specified address
*/
uInt8 peek(uInt16 address) override;
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
bool poke(uInt16 address, uInt8 value) override;
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const override { return "CartridgeMVC"; }
/**
Save the current state of this cart to the given Serializer.
@param out The Serializer object to use
@return False on any errors, else true
*/
bool save(Serializer& out) const override
{
return false;
}
/**
Load the current state of this cart from the given Serializer.
@param in The Serializer object to use
@return False on any errors, else true
*/
bool load(Serializer& in) override
{
return false;
}
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
@param segment The segment the bank should be using
@return true, if bank has changed
*/
bool bank(uInt16 bank, uInt16 segment = 0) override
{
return false;
}
/**
Get the current bank.
@param address The address to use when querying the bank
*/
uInt16 getBank(uInt16 address = 0) const override
{
return 0;
}
/**
Query the number of banks supported by the cartridge.
*/
uInt16 romBankCount() const override
{
return 1;
}
private:
// Currently not used:
// Pointer to a dynamically allocated ROM image of the cartridge
ByteBuffer myImage{nullptr};
size_t mySize{0};
private:
// Following constructors and assignment operators not supported
CartridgeMVC() = delete;
CartridgeMVC(const CartridgeMVC&) = delete;
CartridgeMVC(CartridgeMVC&&) = delete;
CartridgeMVC& operator=(const CartridgeMVC&) = delete;
CartridgeMVC& operator=(CartridgeMVC&&) = delete;
private:
unique_ptr<MovieCart> myMovie;
string myPath;
};
#endif

View File

@ -17,6 +17,7 @@
#include "FSNodeFactory.hxx"
#include "FSNode.hxx"
#include "CartDetector.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNode::FilesystemNode(const AbstractFSNodePtr& realNode)
@ -355,6 +356,12 @@ size_t FilesystemNode::read(ByteBuffer& buffer) const
if (sizeRead == 0)
throw runtime_error("Zero-byte file");
// In the case of MVC (MovieCart) files, contents are streaming data
// of arbitrary length, so just read first frame.
size_t subSize = CartDetector::isProbablyMVC(in, sizeRead);
if (subSize > 0)
sizeRead = subSize;
buffer = make_unique<uInt8[]>(sizeRead);
in.read(reinterpret_cast<char*>(buffer.get()), sizeRead);
}

2
src/windows/Stella.vcxproj Normal file → Executable file
View File

@ -753,6 +753,7 @@
<ClCompile Include="..\emucore\CartMDM.cxx" />
<ClCompile Include="..\emucore\CartMNetwork.cxx" />
<ClCompile Include="..\emucore\CartE78K.cxx" />
<ClCompile Include="..\emucore\CartMVC.cxx" />
<ClCompile Include="..\emucore\CartTVBoy.cxx" />
<ClCompile Include="..\emucore\CartWD.cxx" />
<ClCompile Include="..\emucore\CompuMate.cxx" />
@ -1817,6 +1818,7 @@
<ClInclude Include="..\emucore\CartMDM.hxx" />
<ClInclude Include="..\emucore\CartMNetwork.hxx" />
<ClInclude Include="..\emucore\CartE78K.hxx" />
<ClInclude Include="..\emucore\CartMVC.hxx" />
<ClInclude Include="..\emucore\CartTVBoy.hxx" />
<ClInclude Include="..\emucore\CartWD.hxx" />
<ClInclude Include="..\emucore\CompuMate.hxx" />

View File

@ -1110,6 +1110,9 @@
<ClCompile Include="..\common\repository\CompositeKeyValueRepository.cxx">
<Filter>Source Files\repository</Filter>
</ClCompile>
<ClCompile Include="..\emucore\CartMVC.cxx">
<Filter>Source Files\emucore</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\bspf.hxx">
@ -2282,6 +2285,9 @@
<ClInclude Include="..\emucore\OSystemStandalone.hxx">
<Filter>Header Files\emucore</Filter>
</ClInclude>
<ClInclude Include="..\emucore\CartMVC.hxx">
<Filter>Header Files\emucore</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="stella.ico">