mirror of https://github.com/stella-emu/stella.git
Merge branch 'feature-moviecart' of git://github.com/lodefmode/stella into feature/lodefmode-moviecart
This commit is contained in:
commit
8873ffd0b7
|
@ -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 },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in New Issue