mirror of https://github.com/stella-emu/stella.git
added limited GameLine Master Module bankswitching support
This commit is contained in:
parent
67a039b111
commit
21ff152c49
|
@ -34,6 +34,8 @@
|
|||
|
||||
* Acclerated emulation up to ~15% (ARM).
|
||||
|
||||
* Added limited GameLine Master Module bankswitching support.
|
||||
|
||||
* Added BUS bankswitching support for some older demos.
|
||||
|
||||
* Fixed broken 7800 pause key support.
|
||||
|
|
|
@ -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>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>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>MVC </td><td>Movie Cart</td><td>.MVC </td></tr>
|
||||
<tr><td>SB </td><td>128-256K SUPERbanking </td><td>.SB </td></tr>
|
||||
|
|
|
@ -25,16 +25,6 @@ Cartridge4KWidget::Cartridge4KWidget(
|
|||
: CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -181,11 +181,20 @@ void CartridgeEnhancedWidget::bankList(uInt16 bankCount, int seg, VariantList& i
|
|||
{
|
||||
width = 0;
|
||||
|
||||
const bool hasRamBanks = myCart.myRamBankCount > 0;
|
||||
|
||||
for(int bank = 0; bank < bankCount; ++bank)
|
||||
{
|
||||
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)
|
||||
buf << " " << hotspotStr(bank, seg);
|
||||
VarList::push_back(items, buf.str());
|
||||
|
@ -196,7 +205,7 @@ void CartridgeEnhancedWidget::bankList(uInt16 bankCount, int seg, VariantList& i
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEnhancedWidget::bankSelect(int& ypos)
|
||||
{
|
||||
if(myCart.romBankCount() > 1)
|
||||
if(myCart.romBankCount() + myCart.ramBankCount() > 1)
|
||||
{
|
||||
constexpr int xpos = 2;
|
||||
|
||||
|
@ -208,7 +217,7 @@ void CartridgeEnhancedWidget::bankSelect(int& ypos)
|
|||
VariantList items;
|
||||
int pw = 0;
|
||||
|
||||
bankList(myCart.romBankCount(), seg, items, pw);
|
||||
bankList(myCart.romBankCount() + myCart.ramBankCount(), seg, items, pw);
|
||||
|
||||
// create widgets
|
||||
ostringstream buf;
|
||||
|
@ -249,7 +258,6 @@ string CartridgeEnhancedWidget::bankState()
|
|||
const int bank = myCart.getSegmentBank(seg);
|
||||
const bool isRamBank = (bank >= myCart.romBankCount());
|
||||
|
||||
|
||||
if(seg > 0)
|
||||
buf << " / ";
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -46,6 +46,7 @@ MODULE_OBJS := \
|
|||
src/debugger/gui/CartFAWidget.o \
|
||||
src/debugger/gui/CartFCWidget.o \
|
||||
src/debugger/gui/CartFEWidget.o \
|
||||
src/debugger/gui/CartGLWidget.o \
|
||||
src/debugger/gui/CartMDMWidget.o \
|
||||
src/debugger/gui/CartRamWidget.o \
|
||||
src/debugger/gui/CartSBWidget.o \
|
||||
|
|
|
@ -119,6 +119,7 @@ Bankswitch::BSList = {{
|
|||
{ "FA2" , "FA2 (CBS RAM Plus 24-32K)" },
|
||||
{ "FC" , "FC (32K Amiga)" },
|
||||
{ "FE" , "FE (8K Activision)" },
|
||||
{ "GL" , "GL (GameLine Master Module)" },
|
||||
{ "MDM" , "MDM (Menu Driven Megacart)" },
|
||||
{ "MVC" , "MVC (Movie Cart)" },
|
||||
{ "SB" , "SB (128-256K SUPERbank)" },
|
||||
|
@ -129,7 +130,7 @@ Bankswitch::BSList = {{
|
|||
{ "WDSW" , "WDSW (Pink Panther, bad)" },
|
||||
{ "X07" , "X07 (64K AtariAge)" },
|
||||
#if defined(CUSTOM_ARM)
|
||||
{ "CUSTOM" , "CUSTOM (ARM)" }
|
||||
{ "CUSTOM" , "CUSTOM (ARM)" }
|
||||
#endif
|
||||
}};
|
||||
|
||||
|
@ -181,6 +182,7 @@ Bankswitch::Sizes = {{
|
|||
{ 24_KB, 32_KB }, // _FA2
|
||||
{ 32_KB, 32_KB }, // _FC
|
||||
{ 8_KB, 8_KB }, // _FE
|
||||
{ 4_KB, 4_KB }, // _GL
|
||||
{ 8_KB, Bankswitch::any_KB }, // _MDM
|
||||
{ 1024_KB, Bankswitch::any_KB }, // _MVC
|
||||
{ 128_KB, 256_KB }, // _SB
|
||||
|
@ -270,6 +272,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = {
|
|||
{ "FA2" , Bankswitch::Type::_FA2 },
|
||||
{ "FC" , Bankswitch::Type::_FC },
|
||||
{ "FE" , Bankswitch::Type::_FE },
|
||||
{ "GL" , Bankswitch::Type::_GL },
|
||||
{ "MDM" , Bankswitch::Type::_MDM },
|
||||
{ "MVC" , Bankswitch::Type::_MVC },
|
||||
{ "SB" , Bankswitch::Type::_SB },
|
||||
|
@ -329,6 +332,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = {
|
|||
{ "FA2" , Bankswitch::Type::_FA2 },
|
||||
{ "FC" , Bankswitch::Type::_FC },
|
||||
{ "FE" , Bankswitch::Type::_FE },
|
||||
{ "GL" , Bankswitch::Type::_GL },
|
||||
{ "MDM" , Bankswitch::Type::_MDM },
|
||||
{ "MVC" , Bankswitch::Type::_MVC },
|
||||
{ "SB" , Bankswitch::Type::_SB },
|
||||
|
|
|
@ -43,8 +43,8 @@ class Bankswitch
|
|||
_4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF, _CM,
|
||||
_CTY, _CV, _DF, _DFSC, _DPC, _DPCP, _E0, _E7,
|
||||
_EF, _EFSC, _F0, _F4, _F4SC, _F6, _F6SC, _F8,
|
||||
_F8SC, _FA, _FA2, _FC, _FE, _MDM, _MVC, _SB,
|
||||
_TVBOY, _UA, _UASW, _WD, _WDSW, _X07,
|
||||
_F8SC, _FA, _FA2, _FC, _FE, _GL, _MDM, _MVC,
|
||||
_SB, _TVBOY, _UA, _UASW, _WD, _WDSW, _X07,
|
||||
#ifdef CUSTOM_ARM
|
||||
_CUSTOM,
|
||||
#endif
|
||||
|
|
|
@ -434,6 +434,9 @@ class Cartridge : public Device
|
|||
// Callback to output messages
|
||||
messageCallback myMsgCallback{nullptr};
|
||||
|
||||
// Semi-random values to use when a read from write port occurs
|
||||
std::array<uInt8, 256> myRWPRandomValues;
|
||||
|
||||
private:
|
||||
// The startup bank to use (where to look for the reset vector address)
|
||||
uInt16 myStartBank{0};
|
||||
|
@ -442,9 +445,6 @@ class Cartridge : public Device
|
|||
// by the debugger, when disassembling/dumping ROM.
|
||||
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
|
||||
// This needs to be stored separately from child classes, since
|
||||
// sometimes the information in both do not match
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "CartFA2.hxx"
|
||||
#include "CartFC.hxx"
|
||||
#include "CartFE.hxx"
|
||||
#include "CartGL.hxx"
|
||||
#include "CartMDM.hxx"
|
||||
#include "CartMVC.hxx"
|
||||
#include "CartSB.hxx"
|
||||
|
@ -305,6 +306,8 @@ CartCreator::createFromImage(const ByteBuffer& image, size_t size,
|
|||
return make_unique<CartridgeFC>(image, size, md5, settings);
|
||||
case Bankswitch::Type::_FE:
|
||||
return make_unique<CartridgeFE>(image, size, md5, settings);
|
||||
case Bankswitch::Type::_GL:
|
||||
return make_unique<CartridgeGL>(image, size, md5, settings);
|
||||
case Bankswitch::Type::_MDM:
|
||||
return make_unique<CartridgeMDM>(image, size, md5, settings);
|
||||
case Bankswitch::Type::_UA:
|
||||
|
|
|
@ -27,9 +27,12 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si
|
|||
// Guess type based on size
|
||||
Bankswitch::Type type = Bankswitch::Type::_AUTO;
|
||||
|
||||
if((size % 8448) == 0 || size == 6144)
|
||||
if((size % 8448) == 0 || size == 6_KB)
|
||||
{
|
||||
type = Bankswitch::Type::_AR;
|
||||
if(size == 6_KB && isProbablyGL(image, size))
|
||||
type = Bankswitch::Type::_GL;
|
||||
else
|
||||
type = Bankswitch::Type::_AR;
|
||||
}
|
||||
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;
|
||||
else if (isProbablyFC(image, size))
|
||||
type = Bankswitch::Type::_FC;
|
||||
else if (isProbablyGL(image, size))
|
||||
type = Bankswitch::Type::_GL;
|
||||
else
|
||||
type = Bankswitch::Type::_4K;
|
||||
}
|
||||
|
@ -706,6 +711,14 @@ bool CartDetector::isProbablyFE(const ByteBuffer& image, size_t size)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -201,6 +201,11 @@ class CartDetector
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -65,8 +65,11 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEnhanced::install(System& system)
|
||||
{
|
||||
if(!myRamBankShift)
|
||||
myRamBankShift = myBankShift - 1;
|
||||
|
||||
// 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);
|
||||
|
||||
// calculate bank switching and RAM sizes and masks
|
||||
|
@ -200,7 +203,8 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value)
|
|||
|
||||
if(isRamBank(address))
|
||||
{
|
||||
if(static_cast<bool>(address & (myBankSize >> 1)) == myRamWpHigh)
|
||||
if(static_cast<bool>(address & (myBankSize >> 1)) == myRamWpHigh
|
||||
|| myBankShift == myRamBankShift)
|
||||
{
|
||||
address &= myRamMask;
|
||||
// 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;
|
||||
// The RAM banks follow the ROM banks and are half the size of a ROM bank
|
||||
const uInt32 bankOffset = static_cast<uInt32>(mySize) +
|
||||
(ramBank << (myBankShift - 1));
|
||||
(ramBank << myRamBankShift);
|
||||
|
||||
// Remember what bank is in this segment
|
||||
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
|
||||
// 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 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);
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE)
|
||||
|
|
|
@ -214,6 +214,9 @@ class CartridgeEnhanced : public Cartridge
|
|||
// The mask for a bank segment
|
||||
uInt16 myBankMask{ROM_MASK};
|
||||
|
||||
// Usually myBankShift - 1
|
||||
uInt16 myRamBankShift{0};
|
||||
|
||||
protected:
|
||||
// The extra RAM size
|
||||
size_t myRamSize{RAM_SIZE}; // default 0
|
||||
|
@ -318,7 +321,7 @@ class CartridgeEnhanced : public Cartridge
|
|||
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
|
||||
@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
|
||||
@return The calculated offset
|
||||
*/
|
||||
uInt16 ramAddressSegmentOffset(uInt16 address) const {
|
||||
return static_cast<uInt16>((myCurrentSegOffset[
|
||||
((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize) >> 1);
|
||||
return static_cast<uInt16>(
|
||||
(myCurrentSegOffset[((address & ROM_MASK) >> myBankShift) % myBankSegs] - mySize)
|
||||
>> (myBankShift - myRamBankShift));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -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];
|
||||
}
|
|
@ -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
|
|
@ -46,6 +46,7 @@ MODULE_OBJS := \
|
|||
src/emucore/CartFA2.o \
|
||||
src/emucore/CartFC.o \
|
||||
src/emucore/CartFE.o \
|
||||
src/emucore/CartGL.o \
|
||||
src/emucore/CartMDM.o \
|
||||
src/emucore/CartMVC.o \
|
||||
src/emucore/CartSB.o \
|
||||
|
|
|
@ -911,6 +911,7 @@
|
|||
<ClCompile Include="..\..\debugger\gui\CartFEWidget.cxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\debugger\gui\CartGLWidget.cxx" />
|
||||
<ClCompile Include="..\..\debugger\gui\CartMDMWidget.cxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
@ -996,6 +997,7 @@
|
|||
<ClCompile Include="..\..\emucore\CartDFSC.cxx" />
|
||||
<ClCompile Include="..\..\emucore\CartFA2.cxx" />
|
||||
<ClCompile Include="..\..\emucore\CartFC.cxx" />
|
||||
<ClCompile Include="..\..\emucore\CartGL.cxx" />
|
||||
<ClCompile Include="..\..\emucore\CartMDM.cxx" />
|
||||
<ClCompile Include="..\..\emucore\CartMVC.cxx" />
|
||||
<ClCompile Include="..\..\emucore\CartTVBoy.cxx" />
|
||||
|
@ -2223,6 +2225,7 @@
|
|||
<ClInclude Include="..\..\debugger\gui\CartFEWidget.hxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\debugger\gui\CartGLWidget.hxx" />
|
||||
<ClInclude Include="..\..\debugger\gui\CartMDMWidget.hxx">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
|
@ -2319,6 +2322,7 @@
|
|||
<ClInclude Include="..\..\emucore\CartDFSC.hxx" />
|
||||
<ClInclude Include="..\..\emucore\CartFA2.hxx" />
|
||||
<ClInclude Include="..\..\emucore\CartFC.hxx" />
|
||||
<ClInclude Include="..\..\emucore\CartGL.hxx" />
|
||||
<ClInclude Include="..\..\emucore\CartMDM.hxx" />
|
||||
<ClInclude Include="..\..\emucore\CartMVC.hxx" />
|
||||
<ClInclude Include="..\..\emucore\CartTVBoy.hxx" />
|
||||
|
|
|
@ -1197,6 +1197,12 @@
|
|||
<ClCompile Include="..\..\debugger\TimerMap.cxx">
|
||||
<Filter>Source Files\debugger</Filter>
|
||||
</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>
|
||||
<ClInclude Include="..\..\common\bspf.hxx">
|
||||
|
@ -2441,6 +2447,12 @@
|
|||
<ClInclude Include="..\..\debugger\TimerMap.hxx">
|
||||
<Filter>Header Files\debugger</Filter>
|
||||
</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>
|
||||
<None Include="stella.ico">
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue