added limited GameLine Master Module bankswitching support

This commit is contained in:
thrust26 2023-06-03 21:03:07 +02:00
parent 67a039b111
commit 21ff152c49
23 changed files with 453 additions and 31 deletions

View File

@ -34,6 +34,8 @@
* Acclerated emulation up to ~15% (ARM). * Acclerated emulation up to ~15% (ARM).
* Added limited GameLine Master Module bankswitching support.
* Added BUS bankswitching support for some older demos. * Added BUS bankswitching support for some older demos.
* Fixed broken 7800 pause key support. * Fixed broken 7800 pause key support.

View File

@ -4947,6 +4947,7 @@ Ms Pac-Man (Stella extended codes):
<tr><td>FA2 </td><td>CBS RAM Plus 24/28K </td><td>.FA2 </td></tr> <tr><td>FA2 </td><td>CBS RAM Plus 24/28K </td><td>.FA2 </td></tr>
<tr><td>FC </td><td>Amiga Power Play Aracde 16/32K </td><td>.FC </td></tr> <tr><td>FC </td><td>Amiga Power Play Aracde 16/32K </td><td>.FC </td></tr>
<tr><td>FE </td><td>8K Activision (aka SCABS)</td><td>.FE </td></tr> <tr><td>FE </td><td>8K Activision (aka SCABS)</td><td>.FE </td></tr>
<tr><td>GL </td><td>GameLine Master Module</td><td>.GL </td></tr>
<tr><td>MDM </td><td>Menu Driven Megacart </td><td>.MDM </td></tr> <tr><td>MDM </td><td>Menu Driven Megacart </td><td>.MDM </td></tr>
<tr><td>MVC </td><td>Movie Cart</td><td>.MVC </td></tr> <tr><td>MVC </td><td>Movie Cart</td><td>.MVC </td></tr>
<tr><td>SB </td><td>128-256K SUPERbanking </td><td>.SB </td></tr> <tr><td>SB </td><td>128-256K SUPERbanking </td><td>.SB </td></tr>

View File

@ -25,16 +25,6 @@ Cartridge4KWidget::Cartridge4KWidget(
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
{ {
initialize(); initialize();
//// Eventually, we should query this from the debugger/disassembler
//uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
//start -= start % 0x1000;
//ostringstream info;
//info << "Standard 4K cartridge, non-bankswitched\n"
// << "Accessible @ $" << Common::Base::HEX4 << start << " - "
// << "$" << (start + 0xFFF);
//addBaseInformation(4096, "Atari", info.str());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -181,11 +181,20 @@ void CartridgeEnhancedWidget::bankList(uInt16 bankCount, int seg, VariantList& i
{ {
width = 0; width = 0;
const bool hasRamBanks = myCart.myRamBankCount > 0;
for(int bank = 0; bank < bankCount; ++bank) for(int bank = 0; bank < bankCount; ++bank)
{ {
ostringstream buf; ostringstream buf;
const bool isRamBank = (bank >= myCart.romBankCount());
const int bankNum = (bank - (isRamBank ? myCart.romBankCount() : 0));
buf << std::setw(bankNum < 10 ? 2 : 1) << "#" << std::dec << bankNum;
if(isRamBank) // was RAM mapped here?
buf << " RAM";
else if (hasRamBanks)
buf << " ROM";
buf << std::setw(bank < 10 ? 2 : 1) << "#" << std::dec << bank;
if(myCart.hotspot() != 0 && myHotspotDelta > 0) if(myCart.hotspot() != 0 && myHotspotDelta > 0)
buf << " " << hotspotStr(bank, seg); buf << " " << hotspotStr(bank, seg);
VarList::push_back(items, buf.str()); VarList::push_back(items, buf.str());
@ -196,7 +205,7 @@ void CartridgeEnhancedWidget::bankList(uInt16 bankCount, int seg, VariantList& i
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeEnhancedWidget::bankSelect(int& ypos) void CartridgeEnhancedWidget::bankSelect(int& ypos)
{ {
if(myCart.romBankCount() > 1) if(myCart.romBankCount() + myCart.ramBankCount() > 1)
{ {
constexpr int xpos = 2; constexpr int xpos = 2;
@ -208,7 +217,7 @@ void CartridgeEnhancedWidget::bankSelect(int& ypos)
VariantList items; VariantList items;
int pw = 0; int pw = 0;
bankList(myCart.romBankCount(), seg, items, pw); bankList(myCart.romBankCount() + myCart.ramBankCount(), seg, items, pw);
// create widgets // create widgets
ostringstream buf; ostringstream buf;
@ -249,7 +258,6 @@ string CartridgeEnhancedWidget::bankState()
const int bank = myCart.getSegmentBank(seg); const int bank = myCart.getSegmentBank(seg);
const bool isRamBank = (bank >= myCart.romBankCount()); const bool isRamBank = (bank >= myCart.romBankCount());
if(seg > 0) if(seg > 0)
buf << " / "; buf << " / ";

View File

@ -0,0 +1,50 @@
//============================================================================
//
// 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-2023 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.
//============================================================================
#include "CartGL.hxx"
#include "CartGLWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeGLWidget::CartridgeGLWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, CartridgeGL& cart)
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
{
initialize();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartridgeGLWidget::description()
{
ostringstream info;
info << "GameLine Master Module cartridge, 4K ROM, 10/12K RAM\n"
<< "mapped into four 1K segments\n"
<< "THIS SCHEME IS NOT FULLY IMPLEMENTED OR TESTED";
return info.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartridgeGLWidget::internalRamDescription()
{
ostringstream desc;
desc << "Accessible 1K" << " at a time";
return desc.str();
}

View File

@ -0,0 +1,50 @@
//============================================================================
//
// 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-2023 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 CARTRIDGEGL_WIDGET_HXX
#define CARTRIDGEGL_WIDGET_HXX
class CartridgeGL;
#include "CartEnhanced.hxx"
class CartridgeGLWidget : public CartridgeEnhancedWidget
{
public:
CartridgeGLWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont,
int x, int y, int w, int h,
CartridgeGL& cart);
~CartridgeGLWidget() override = default;
private:
string manufacturer() override { return "Control Video Corporation (CVC)"; }
string description() override;
string internalRamDescription() override;
private:
// Following constructors and assignment operators not supported
CartridgeGLWidget() = delete;
CartridgeGLWidget(const CartridgeGLWidget&) = delete;
CartridgeGLWidget(CartridgeGLWidget&&) = delete;
CartridgeGLWidget& operator=(const CartridgeGLWidget&) = delete;
CartridgeGLWidget& operator=(CartridgeGLWidget&&) = delete;
};
#endif

View File

@ -46,6 +46,7 @@ MODULE_OBJS := \
src/debugger/gui/CartFAWidget.o \ src/debugger/gui/CartFAWidget.o \
src/debugger/gui/CartFCWidget.o \ src/debugger/gui/CartFCWidget.o \
src/debugger/gui/CartFEWidget.o \ src/debugger/gui/CartFEWidget.o \
src/debugger/gui/CartGLWidget.o \
src/debugger/gui/CartMDMWidget.o \ src/debugger/gui/CartMDMWidget.o \
src/debugger/gui/CartRamWidget.o \ src/debugger/gui/CartRamWidget.o \
src/debugger/gui/CartSBWidget.o \ src/debugger/gui/CartSBWidget.o \

View File

@ -119,6 +119,7 @@ Bankswitch::BSList = {{
{ "FA2" , "FA2 (CBS RAM Plus 24-32K)" }, { "FA2" , "FA2 (CBS RAM Plus 24-32K)" },
{ "FC" , "FC (32K Amiga)" }, { "FC" , "FC (32K Amiga)" },
{ "FE" , "FE (8K Activision)" }, { "FE" , "FE (8K Activision)" },
{ "GL" , "GL (GameLine Master Module)" },
{ "MDM" , "MDM (Menu Driven Megacart)" }, { "MDM" , "MDM (Menu Driven Megacart)" },
{ "MVC" , "MVC (Movie Cart)" }, { "MVC" , "MVC (Movie Cart)" },
{ "SB" , "SB (128-256K SUPERbank)" }, { "SB" , "SB (128-256K SUPERbank)" },
@ -181,6 +182,7 @@ Bankswitch::Sizes = {{
{ 24_KB, 32_KB }, // _FA2 { 24_KB, 32_KB }, // _FA2
{ 32_KB, 32_KB }, // _FC { 32_KB, 32_KB }, // _FC
{ 8_KB, 8_KB }, // _FE { 8_KB, 8_KB }, // _FE
{ 4_KB, 4_KB }, // _GL
{ 8_KB, Bankswitch::any_KB }, // _MDM { 8_KB, Bankswitch::any_KB }, // _MDM
{ 1024_KB, Bankswitch::any_KB }, // _MVC { 1024_KB, Bankswitch::any_KB }, // _MVC
{ 128_KB, 256_KB }, // _SB { 128_KB, 256_KB }, // _SB
@ -270,6 +272,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
{ "FA2" , Bankswitch::Type::_FA2 }, { "FA2" , Bankswitch::Type::_FA2 },
{ "FC" , Bankswitch::Type::_FC }, { "FC" , Bankswitch::Type::_FC },
{ "FE" , Bankswitch::Type::_FE }, { "FE" , Bankswitch::Type::_FE },
{ "GL" , Bankswitch::Type::_GL },
{ "MDM" , Bankswitch::Type::_MDM }, { "MDM" , Bankswitch::Type::_MDM },
{ "MVC" , Bankswitch::Type::_MVC }, { "MVC" , Bankswitch::Type::_MVC },
{ "SB" , Bankswitch::Type::_SB }, { "SB" , Bankswitch::Type::_SB },
@ -329,6 +332,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
{ "FA2" , Bankswitch::Type::_FA2 }, { "FA2" , Bankswitch::Type::_FA2 },
{ "FC" , Bankswitch::Type::_FC }, { "FC" , Bankswitch::Type::_FC },
{ "FE" , Bankswitch::Type::_FE }, { "FE" , Bankswitch::Type::_FE },
{ "GL" , Bankswitch::Type::_GL },
{ "MDM" , Bankswitch::Type::_MDM }, { "MDM" , Bankswitch::Type::_MDM },
{ "MVC" , Bankswitch::Type::_MVC }, { "MVC" , Bankswitch::Type::_MVC },
{ "SB" , Bankswitch::Type::_SB }, { "SB" , Bankswitch::Type::_SB },

View File

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

View File

@ -434,6 +434,9 @@ class Cartridge : public Device
// Callback to output messages // Callback to output messages
messageCallback myMsgCallback{nullptr}; messageCallback myMsgCallback{nullptr};
// Semi-random values to use when a read from write port occurs
std::array<uInt8, 256> myRWPRandomValues;
private: private:
// The startup bank to use (where to look for the reset vector address) // The startup bank to use (where to look for the reset vector address)
uInt16 myStartBank{0}; uInt16 myStartBank{0};
@ -442,9 +445,6 @@ class Cartridge : public Device
// by the debugger, when disassembling/dumping ROM. // by the debugger, when disassembling/dumping ROM.
bool myHotspotsLocked{false}; bool myHotspotsLocked{false};
// Semi-random values to use when a read from write port occurs
std::array<uInt8, 256> myRWPRandomValues;
// Contains various info about this cartridge // Contains various info about this cartridge
// This needs to be stored separately from child classes, since // This needs to be stored separately from child classes, since
// sometimes the information in both do not match // sometimes the information in both do not match

View File

@ -54,6 +54,7 @@
#include "CartFA2.hxx" #include "CartFA2.hxx"
#include "CartFC.hxx" #include "CartFC.hxx"
#include "CartFE.hxx" #include "CartFE.hxx"
#include "CartGL.hxx"
#include "CartMDM.hxx" #include "CartMDM.hxx"
#include "CartMVC.hxx" #include "CartMVC.hxx"
#include "CartSB.hxx" #include "CartSB.hxx"
@ -305,6 +306,8 @@ CartCreator::createFromImage(const ByteBuffer& image, size_t size,
return make_unique<CartridgeFC>(image, size, md5, settings); return make_unique<CartridgeFC>(image, size, md5, settings);
case Bankswitch::Type::_FE: case Bankswitch::Type::_FE:
return make_unique<CartridgeFE>(image, size, md5, settings); return make_unique<CartridgeFE>(image, size, md5, settings);
case Bankswitch::Type::_GL:
return make_unique<CartridgeGL>(image, size, md5, settings);
case Bankswitch::Type::_MDM: case Bankswitch::Type::_MDM:
return make_unique<CartridgeMDM>(image, size, md5, settings); return make_unique<CartridgeMDM>(image, size, md5, settings);
case Bankswitch::Type::_UA: case Bankswitch::Type::_UA:

View File

@ -27,8 +27,11 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
// Guess type based on size // Guess type based on size
Bankswitch::Type type = Bankswitch::Type::_AUTO; Bankswitch::Type type = Bankswitch::Type::_AUTO;
if((size % 8448) == 0 || size == 6144) if((size % 8448) == 0 || size == 6_KB)
{ {
if(size == 6_KB && isProbablyGL(image, size))
type = Bankswitch::Type::_GL;
else
type = Bankswitch::Type::_AR; type = Bankswitch::Type::_AR;
} }
else if(size < 2_KB) // Sub2K images else if(size < 2_KB) // Sub2K images
@ -48,6 +51,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
type = Bankswitch::Type::_4KSC; type = Bankswitch::Type::_4KSC;
else if (isProbablyFC(image, size)) else if (isProbablyFC(image, size))
type = Bankswitch::Type::_FC; type = Bankswitch::Type::_FC;
else if (isProbablyGL(image, size))
type = Bankswitch::Type::_GL;
else else
type = Bankswitch::Type::_4K; type = Bankswitch::Type::_4K;
} }
@ -706,6 +711,14 @@ bool CartDetector::isProbablyFE(const ByteBuffer& image, size_t size)
return false; return false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyGL(const ByteBuffer& image, size_t size)
{
static constexpr uInt8 signature[] = { 0xad, 0xb8, 0x0c }; // LDA $0CB8
return searchForBytes(image, size, signature, 3);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyMDM(const ByteBuffer& image, size_t size) bool CartDetector::isProbablyMDM(const ByteBuffer& image, size_t size)
{ {

View File

@ -201,6 +201,11 @@ class CartDetector
*/ */
static bool isProbablyFE(const ByteBuffer& image, size_t size); static bool isProbablyFE(const ByteBuffer& image, size_t size);
/**
Returns true if the image is probably a GameLine cartridge
*/
static bool isProbablyGL(const ByteBuffer& image, size_t size);
/** /**
Returns true if the image is probably a MDM bankswitching cartridge Returns true if the image is probably a MDM bankswitching cartridge
*/ */

View File

@ -65,8 +65,11 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeEnhanced::install(System& system) void CartridgeEnhanced::install(System& system)
{ {
if(!myRamBankShift)
myRamBankShift = myBankShift - 1;
// limit banked RAM size to the size of one RAM bank // limit banked RAM size to the size of one RAM bank
const uInt16 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : const uInt16 ramSize = myRamBankCount > 0 ? 1 << myRamBankShift :
static_cast<uInt16>(myRamSize); static_cast<uInt16>(myRamSize);
// calculate bank switching and RAM sizes and masks // calculate bank switching and RAM sizes and masks
@ -200,7 +203,8 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value)
if(isRamBank(address)) if(isRamBank(address))
{ {
if(static_cast<bool>(address & (myBankSize >> 1)) == myRamWpHigh) if(static_cast<bool>(address & (myBankSize >> 1)) == myRamWpHigh
|| myBankShift == myRamBankShift)
{ {
address &= myRamMask; address &= myRamMask;
// The RAM banks follow the ROM banks and are half the size of a ROM bank // The RAM banks follow the ROM banks and are half the size of a ROM bank
@ -271,7 +275,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
const uInt16 ramBank = (bank - romBankCount()) % myRamBankCount; const uInt16 ramBank = (bank - romBankCount()) % myRamBankCount;
// The RAM banks follow the ROM banks and are half the size of a ROM bank // The RAM banks follow the ROM banks and are half the size of a ROM bank
const uInt32 bankOffset = static_cast<uInt32>(mySize) + const uInt32 bankOffset = static_cast<uInt32>(mySize) +
(ramBank << (myBankShift - 1)); (ramBank << myRamBankShift);
// Remember what bank is in this segment // Remember what bank is in this segment
myCurrentSegOffset[segment] = static_cast<uInt32>(mySize) + myCurrentSegOffset[segment] = static_cast<uInt32>(mySize) +
@ -280,7 +284,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
// Set the page accessing method for the RAM writing pages // Set the page accessing method for the RAM writing pages
// Note: Writes are mapped to poke() (NOT using directPokeBase) to check for read from write port (RWP) // Note: Writes are mapped to poke() (NOT using directPokeBase) to check for read from write port (RWP)
uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myWriteOffset) & ~System::PAGE_MASK;
uInt16 toAddr = (ROM_OFFSET + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; uInt16 toAddr = (ROM_OFFSET + segmentOffset + myWriteOffset
+ (myBankSize >> (myBankShift - myRamBankShift))) & ~System::PAGE_MASK;
System::PageAccess access(this, System::PageAccessType::WRITE); System::PageAccess access(this, System::PageAccessType::WRITE);
for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE)
@ -295,7 +300,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment)
// Set the page accessing method for the RAM reading pages // Set the page accessing method for the RAM reading pages
fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK; fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK;
toAddr = (ROM_OFFSET + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; toAddr = (ROM_OFFSET + segmentOffset + myReadOffset
+ (myBankSize >> (myBankShift - myRamBankShift))) & ~System::PAGE_MASK;
access.type = System::PageAccessType::READ; access.type = System::PageAccessType::READ;
for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE)

View File

@ -214,6 +214,9 @@ class CartridgeEnhanced : public Cartridge
// The mask for a bank segment // The mask for a bank segment
uInt16 myBankMask{ROM_MASK}; uInt16 myBankMask{ROM_MASK};
// Usually myBankShift - 1
uInt16 myRamBankShift{0};
protected: protected:
// The extra RAM size // The extra RAM size
size_t myRamSize{RAM_SIZE}; // default 0 size_t myRamSize{RAM_SIZE}; // default 0
@ -318,7 +321,7 @@ class CartridgeEnhanced : public Cartridge
virtual uInt16 getStartBank() const { return 0; } virtual uInt16 getStartBank() const { return 0; }
/** /**
Get the ROM offset of the segment of the given address Get the ROM offset of the segment of the given address.
@param address The address to get the offset for @param address The address to get the offset for
@return The calculated offset @return The calculated offset
@ -328,14 +331,16 @@ class CartridgeEnhanced : public Cartridge
} }
/** /**
Get the RAM offset of the segment of the given address Get the RAM offset of the segment of the given address.
The RAM banks are half the size of a ROM bank.
@param address The address to get the offset for @param address The address to get the offset for
@return The calculated offset @return The calculated offset
*/ */
uInt16 ramAddressSegmentOffset(uInt16 address) const { uInt16 ramAddressSegmentOffset(uInt16 address) const {
return static_cast<uInt16>((myCurrentSegOffset[ return static_cast<uInt16>(
((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1); (myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize)
>> (myBankShift - myRamBankShift));
} }
private: private:

133
src/emucore/CartGL.cxx Normal file
View File

@ -0,0 +1,133 @@
//============================================================================
//
// 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-2023 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.
//============================================================================
#include "System.hxx"
#include "CartGL.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeGL::CartridgeGL(const ByteBuffer& image, size_t size,
string_view md5, const Settings& settings,
size_t bsSize)
: CartridgeEnhanced(image, size, md5, settings, bsSize)
{
myBankShift = myRamBankShift = BANK_SHIFT;
myRamSize = RAM_SIZE;
myRamBankCount = RAM_BANKS;
if(size == 4_KB + 2_KB) // ROM containing RAM data?
{
myInitialRAM = make_unique<uInt8[]>(2_KB);
// Copy the RAM image into a buffer for use in reset()
std::copy_n(image.get() + 4_KB, 2_KB, myInitialRAM.get());
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeGL::reset()
{
CartridgeEnhanced::reset();
// Initially bank 0 is mapped into all four segments
bank(0, 0);
bank(0, 1);
bank(0, 2);
bank(0, 3);
myBankChanged = true;
myOrgAccess = mySystem->getPageAccess(0x1fc0);
initializeRAM(myRAM.get(), myRamSize);
if(myInitialRAM != nullptr)
{
// Copy the RAM image into my RAM buffer
std::copy_n(myInitialRAM.get(), 2_KB, myRAM.get());
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeGL::install(System& system)
{
CartridgeEnhanced::install(system);
System::PageAccess access(this, System::PageAccessType::READ);
mySystem->setPageAccess(0x480, access);
mySystem->setPageAccess(0x580, access);
mySystem->setPageAccess(0x680, access);
mySystem->setPageAccess(0x880, access);
mySystem->setPageAccess(0x980, access);
mySystem->setPageAccess(0xc80, access);
mySystem->setPageAccess(0xd80, access);
myReadOffset = myWriteOffset = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeGL::checkSwitchBank(uInt16 address, uInt8)
{
int slice = -1;
bool control = false;
// Switch banks if necessary
switch(address & 0x1f80)
{
case 0x480:
slice = 0;
break;
case 0x580:
slice = 1;
break;
case 0x880:
slice = 2;
break;
case 0x980:
slice = 3;
break;
case 0xc80:
control = true;
break;
}
if(slice >= 0)
{
//const bool isWrite = address & 0x20; // could be checked, but not necessary for known GL ROMs
bank(address & 0xf, slice);
return true;
}
if(control)
{
myEnablePROM = (address & 0x30) == 0x30;
if(myEnablePROM)
mySystem->setPageAccess(0x1fc0, System::PageAccess(this, System::PageAccessType::READ));
else
mySystem->setPageAccess(0x1fc0, myOrgAccess);
return true;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeGL::peek(uInt16 address)
{
if(myEnablePROM && ((address & ADDR_MASK) >= 0x1fc0) && ((address & ADDR_MASK) <= 0x1fdf))
{
return 0; // sufficient for PROM check
}
checkSwitchBank(address, 0);
return myRWPRandomValues[address & 0xFF];
}

134
src/emucore/CartGL.hxx Normal file
View File

@ -0,0 +1,134 @@
//============================================================================
//
// 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-2023 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 CARTRIDGEGL_HXX
#define CARTRIDGEGL_HXX
#include "CartEnhanced.hxx"
#ifdef DEBUGGER_SUPPORT
#include "CartGLWidget.hxx"
#endif
#include "System.hxx"
/**
Cartridge class used for the GameLine Master module. In this bankswitching
scheme the 2600's 4K cartridge address space is broken into four 1K segments.
The desired 1K bank of the ROM or RAM is selected as follows:
- $0480 + x: 1st 1K segment
- $0580 + x: 2nd 1K segment
- $0880 + x: 3rd 1K segment
- $0980 + x: 4th 1K segment
Where x is defined as follows:
- bits 0..3: mapped 1K bank (0..3 = ROM bank, 4..f = RAM bank)
- bit 5: 0 = read, 1 = write (RAM only)
Initially bank 0 is mapped to all four segments.
The scheme supports 4K ROM and 2K RAM.
$0c80.. and $0d80.. control the modem (not implemented, except for PROM access).
@author Thomas Jentzsch
*/
class CartridgeGL : public CartridgeEnhanced
{
friend class CartridgeGLWidget;
public:
/**
Create a new cartridge using the specified image
@param image Pointer to the ROM image
@param size The size of the ROM image
@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
*/
CartridgeGL(const ByteBuffer& image, size_t size, string_view md5,
const Settings& settings, size_t bsSize = 4_KB);
~CartridgeGL() override = default;
public:
/**
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;
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const override { return "CartridgeGL"; }
#ifdef DEBUGGER_SUPPORT
/**
Get debugger widget responsible for accessing the inner workings
of the cart.
*/
CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont, int x, int y, int w, int h) override
{
return new CartridgeGLWidget(boss, lfont, nfont, x, y, w, h, *this);
}
#endif
public:
/**
Get the byte at the specified address.
@return The byte at the specified address
*/
uInt8 peek(uInt16 address) override;
private:
bool checkSwitchBank(uInt16 address, uInt8) override;
protected:
// log(ROM bank segment size) / log(2)
static constexpr uInt16 BANK_SHIFT = 10; // = 1K = 0x0400
// The number of RAM banks
static constexpr uInt16 RAM_BANKS = 12;
// RAM size
static constexpr size_t RAM_SIZE = RAM_BANKS << BANK_SHIFT; // = 12K;
private:
// Initial RAM data from the cart (doesn't always exist)
ByteBuffer myInitialRAM{nullptr};
bool myEnablePROM{false};
System::PageAccess myOrgAccess;
private:
// Following constructors and assignment operators not supported
CartridgeGL() = delete;
CartridgeGL(const CartridgeGL&) = delete;
CartridgeGL(CartridgeGL&&) = delete;
CartridgeGL& operator=(const CartridgeGL&) = delete;
CartridgeGL& operator=(CartridgeGL&&) = delete;
};
#endif

View File

@ -46,6 +46,7 @@ MODULE_OBJS := \
src/emucore/CartFA2.o \ src/emucore/CartFA2.o \
src/emucore/CartFC.o \ src/emucore/CartFC.o \
src/emucore/CartFE.o \ src/emucore/CartFE.o \
src/emucore/CartGL.o \
src/emucore/CartMDM.o \ src/emucore/CartMDM.o \
src/emucore/CartMVC.o \ src/emucore/CartMVC.o \
src/emucore/CartSB.o \ src/emucore/CartSB.o \

View File

@ -911,6 +911,7 @@
<ClCompile Include="..\..\debugger\gui\CartFEWidget.cxx"> <ClCompile Include="..\..\debugger\gui\CartFEWidget.cxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\debugger\gui\CartGLWidget.cxx" />
<ClCompile Include="..\..\debugger\gui\CartMDMWidget.cxx"> <ClCompile Include="..\..\debugger\gui\CartMDMWidget.cxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -996,6 +997,7 @@
<ClCompile Include="..\..\emucore\CartDFSC.cxx" /> <ClCompile Include="..\..\emucore\CartDFSC.cxx" />
<ClCompile Include="..\..\emucore\CartFA2.cxx" /> <ClCompile Include="..\..\emucore\CartFA2.cxx" />
<ClCompile Include="..\..\emucore\CartFC.cxx" /> <ClCompile Include="..\..\emucore\CartFC.cxx" />
<ClCompile Include="..\..\emucore\CartGL.cxx" />
<ClCompile Include="..\..\emucore\CartMDM.cxx" /> <ClCompile Include="..\..\emucore\CartMDM.cxx" />
<ClCompile Include="..\..\emucore\CartMVC.cxx" /> <ClCompile Include="..\..\emucore\CartMVC.cxx" />
<ClCompile Include="..\..\emucore\CartTVBoy.cxx" /> <ClCompile Include="..\..\emucore\CartTVBoy.cxx" />
@ -2223,6 +2225,7 @@
<ClInclude Include="..\..\debugger\gui\CartFEWidget.hxx"> <ClInclude Include="..\..\debugger\gui\CartFEWidget.hxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\debugger\gui\CartGLWidget.hxx" />
<ClInclude Include="..\..\debugger\gui\CartMDMWidget.hxx"> <ClInclude Include="..\..\debugger\gui\CartMDMWidget.hxx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClInclude> </ClInclude>
@ -2319,6 +2322,7 @@
<ClInclude Include="..\..\emucore\CartDFSC.hxx" /> <ClInclude Include="..\..\emucore\CartDFSC.hxx" />
<ClInclude Include="..\..\emucore\CartFA2.hxx" /> <ClInclude Include="..\..\emucore\CartFA2.hxx" />
<ClInclude Include="..\..\emucore\CartFC.hxx" /> <ClInclude Include="..\..\emucore\CartFC.hxx" />
<ClInclude Include="..\..\emucore\CartGL.hxx" />
<ClInclude Include="..\..\emucore\CartMDM.hxx" /> <ClInclude Include="..\..\emucore\CartMDM.hxx" />
<ClInclude Include="..\..\emucore\CartMVC.hxx" /> <ClInclude Include="..\..\emucore\CartMVC.hxx" />
<ClInclude Include="..\..\emucore\CartTVBoy.hxx" /> <ClInclude Include="..\..\emucore\CartTVBoy.hxx" />

View File

@ -1197,6 +1197,12 @@
<ClCompile Include="..\..\debugger\TimerMap.cxx"> <ClCompile Include="..\..\debugger\TimerMap.cxx">
<Filter>Source Files\debugger</Filter> <Filter>Source Files\debugger</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\emucore\CartGL.cxx">
<Filter>Source Files\emucore</Filter>
</ClCompile>
<ClCompile Include="..\..\debugger\gui\CartGLWidget.cxx">
<Filter>Source Files\debugger\gui</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\common\bspf.hxx"> <ClInclude Include="..\..\common\bspf.hxx">
@ -2441,6 +2447,12 @@
<ClInclude Include="..\..\debugger\TimerMap.hxx"> <ClInclude Include="..\..\debugger\TimerMap.hxx">
<Filter>Header Files\debugger</Filter> <Filter>Header Files\debugger</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\emucore\CartGL.hxx">
<Filter>Header Files\emucore</Filter>
</ClInclude>
<ClInclude Include="..\..\debugger\gui\CartGLWidget.hxx">
<Filter>Header Files\debugger\gui</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="stella.ico"> <None Include="stella.ico">

Binary file not shown.

Binary file not shown.