mirror of https://github.com/stella-emu/stella.git
Changed CartWD hotspots from $30 - $3F of the cart RAM area to the TIA area (I really need
to learn to read the specs more closely). Changed hotspot change to trigger 3 cycles after initiated instead of 3 address changes. Added CartWDWidget debugger class, to view/change cart-specific functionality from within the debugger. Still TODO is CartWD patching. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@3105 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c7fc207b13
commit
31ca88d283
|
@ -56,7 +56,7 @@ class CartDebugWidget : public Widget, public CommandSender
|
|||
{
|
||||
const int lwidth = _font.getStringWidth("Manufacturer: "),
|
||||
fwidth = _w - lwidth - 20;
|
||||
EditTextWidget* w = 0;
|
||||
EditTextWidget* w = nullptr;
|
||||
ostringstream buf;
|
||||
|
||||
int x = 10, y = 10;
|
||||
|
@ -80,7 +80,7 @@ class CartDebugWidget : public Widget, public CommandSender
|
|||
w->setEditable(false);
|
||||
y += myLineHeight + 4;
|
||||
|
||||
StringParser bs(desc, (fwidth - kScrollBarWidth) / myFontWidth);
|
||||
StringParser bs(desc, (fwidth - kScrollBarWidth) / myFontWidth - 4);
|
||||
const StringList& sl = bs.stringList();
|
||||
uInt32 lines = (uInt32)sl.size();
|
||||
if(lines < 3) lines = 3;
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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-2014 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.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include "CartWD.hxx"
|
||||
#include "PopUpWidget.hxx"
|
||||
#include "CartWDWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeWDWidget::CartridgeWDWidget(
|
||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||
int x, int y, int w, int h, CartridgeWD& cart)
|
||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||
myCart(cart)
|
||||
{
|
||||
string info =
|
||||
"This scheme has eight 1K slices, which can be mapped into four 1K "
|
||||
"segments in various combinations. Each 'bank' selects a predefined "
|
||||
"segment arrangement (indicated in square brackets)\n"
|
||||
"The last four banks swap in an extra 3 bytes from above the 8K "
|
||||
"cart boundary into the third (uppermost) segment at $3FC - $3FE\n\n"
|
||||
"64 bytes RAM @ $F000 - $F080\n"
|
||||
" $F000 - $F03F (R), $F040 - $F07F (W)\n";
|
||||
|
||||
int xpos = 10,
|
||||
ypos = addBaseInformation(myCart.mySize, "Wickstead Design", info) + myLineHeight;
|
||||
|
||||
VariantList items;
|
||||
VarList::push_back(items, "0 ($30) [0,0,1,2]", 0);
|
||||
VarList::push_back(items, "1 ($31) [0,1,3,2]", 1);
|
||||
VarList::push_back(items, "2 ($32) [4,5,6,7]", 2);
|
||||
VarList::push_back(items, "3 ($33) [7,4,3,2]", 3);
|
||||
VarList::push_back(items, "4 ($34) [0,0,6,7]", 4);
|
||||
VarList::push_back(items, "5 ($35) [0,1,7,6]", 5);
|
||||
VarList::push_back(items, "6 ($36) [3,2,4,5]", 6);
|
||||
VarList::push_back(items, "7 ($37) [6,0,5,1]", 7);
|
||||
VarList::push_back(items, "8 ($38) [0,0,1,2]", 8);
|
||||
VarList::push_back(items, "9 ($39) [0,1,3,2]", 9);
|
||||
VarList::push_back(items, "10 ($3A) [4,5,6,7]", 10);
|
||||
VarList::push_back(items, "11 ($3B) [7,4,3,2]", 11);
|
||||
VarList::push_back(items, "12 ($3C) [0,0,6,7*]", 12);
|
||||
VarList::push_back(items, "13 ($3D) [0,1,7,6*]", 13);
|
||||
VarList::push_back(items, "14 ($3E) [3,2,4,5*]", 14);
|
||||
VarList::push_back(items, "15 ($3F) [6,0,5,1*]", 15);
|
||||
myBank = new PopUpWidget(boss, _font, xpos, ypos-2,
|
||||
_font.getStringWidth("15 ($3F) [6,0,5,1*]"),
|
||||
myLineHeight, items, "Set bank: ",
|
||||
_font.getStringWidth("Set bank: "), kBankChanged);
|
||||
myBank->setTarget(this);
|
||||
addFocusWidget(myBank);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWDWidget::saveOldState()
|
||||
{
|
||||
myOldState.internalram.clear();
|
||||
|
||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||
myOldState.internalram.push_back(myCart.myRAM[i]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWDWidget::loadConfig()
|
||||
{
|
||||
myBank->setSelectedIndex(myCart.getBank());
|
||||
|
||||
CartDebugWidget::loadConfig();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWDWidget::handleCommand(CommandSender* sender,
|
||||
int cmd, int data, int id)
|
||||
{
|
||||
if(cmd == kBankChanged)
|
||||
{
|
||||
myCart.unlockBank();
|
||||
myCart.bank(myBank->getSelected());
|
||||
myCart.lockBank();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeWDWidget::bankState()
|
||||
{
|
||||
ostringstream& buf = buffer();
|
||||
|
||||
static const char* segments[] = {
|
||||
"[0,0,1,2]", "[0,1,3,2]", "[4,5,6,7]", "[7,4,3,2]",
|
||||
"[0,0,6,7]", "[0,1,7,6]", "[3,2,4,5]", "[6,0,5,1]",
|
||||
"[0,0,1,2]", "[0,1,3,2]", "[4,5,6,7]", "[7,4,3,2]",
|
||||
"[0,0,6,7*]", "[0,1,7,6*]", "[3,2,4,5*]", "[6,0,5,1*]"
|
||||
};
|
||||
uInt16 bank = myCart.getBank();
|
||||
buf << "Bank = " << dec << bank << ", segments = " << segments[bank];
|
||||
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 CartridgeWDWidget::internalRamSize()
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 CartridgeWDWidget::internalRamRPort(int start)
|
||||
{
|
||||
return 0xF000 + start;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeWDWidget::internalRamDescription()
|
||||
{
|
||||
ostringstream desc;
|
||||
desc << "$F000 - $F03F used for Read Access\n"
|
||||
<< "$F040 - $F07F used for Write Access";
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const ByteArray& CartridgeWDWidget::internalRamOld(int start, int count)
|
||||
{
|
||||
myRamOld.clear();
|
||||
for(int i = 0; i < count; ++i)
|
||||
myRamOld.push_back(myOldState.internalram[start + i]);
|
||||
return myRamOld;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const ByteArray& CartridgeWDWidget::internalRamCurrent(int start, int count)
|
||||
{
|
||||
myRamCurrent.clear();
|
||||
for(int i = 0; i < count; ++i)
|
||||
myRamCurrent.push_back(myCart.myRAM[start + i]);
|
||||
return myRamCurrent;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWDWidget::internalRamSetValue(int addr, uInt8 value)
|
||||
{
|
||||
myCart.myRAM[addr] = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeWDWidget::internalRamGetValue(int addr)
|
||||
{
|
||||
return myCart.myRAM[addr];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string CartridgeWDWidget::internalRamLabel(int addr)
|
||||
{
|
||||
CartDebug& dbg = instance().debugger().cartDebug();
|
||||
return dbg.getLabel(addr + 0xF000, false);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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-2014 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.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef CARTRIDGEWD_WIDGET_HXX
|
||||
#define CARTRIDGEWD_WIDGET_HXX
|
||||
|
||||
class CartridgeWD;
|
||||
class PopUpWidget;
|
||||
|
||||
#include "CartDebugWidget.hxx"
|
||||
|
||||
class CartridgeWDWidget : public CartDebugWidget
|
||||
{
|
||||
public:
|
||||
CartridgeWDWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
const GUI::Font& nfont,
|
||||
int x, int y, int w, int h,
|
||||
CartridgeWD& cart);
|
||||
virtual ~CartridgeWDWidget() { }
|
||||
|
||||
void saveOldState();
|
||||
void loadConfig();
|
||||
void handleCommand(CommandSender* sender, int cmd, int data, int id);
|
||||
|
||||
string bankState();
|
||||
|
||||
// start of functions for Cartridge RAM tab
|
||||
uInt32 internalRamSize();
|
||||
uInt32 internalRamRPort(int start);
|
||||
string internalRamDescription();
|
||||
const ByteArray& internalRamOld(int start, int count);
|
||||
const ByteArray& internalRamCurrent(int start, int count);
|
||||
void internalRamSetValue(int addr, uInt8 value);
|
||||
uInt8 internalRamGetValue(int addr);
|
||||
string internalRamLabel(int addr);
|
||||
// end of functions for Cartridge RAM tab
|
||||
|
||||
private:
|
||||
CartridgeWD& myCart;
|
||||
PopUpWidget* myBank;
|
||||
|
||||
struct CartState {
|
||||
ByteArray internalram;
|
||||
};
|
||||
CartState myOldState;
|
||||
|
||||
enum { kBankChanged = 'bkCH' };
|
||||
};
|
||||
|
||||
#endif
|
|
@ -57,6 +57,7 @@ MODULE_OBJS := \
|
|||
src/debugger/gui/CartMDMWidget.o \
|
||||
src/debugger/gui/CartSBWidget.o \
|
||||
src/debugger/gui/CartUAWidget.o \
|
||||
src/debugger/gui/CartWDWidget.o \
|
||||
src/debugger/gui/CartX07Widget.o \
|
||||
src/debugger/gui/JoystickWidget.o \
|
||||
src/debugger/gui/PaddleWidget.o \
|
||||
|
|
|
@ -19,16 +19,19 @@
|
|||
|
||||
#include <cstring>
|
||||
|
||||
#include "TIA.hxx"
|
||||
#include "M6502.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartWD.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeWD::CartridgeWD(const uInt8* image, uInt32 size,
|
||||
const Settings& settings)
|
||||
: Cartridge(settings)
|
||||
: Cartridge(settings),
|
||||
mySize(BSPF_min(8195u, size))
|
||||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, BSPF_min(8192u, size));
|
||||
memcpy(myImage, image, mySize);
|
||||
createCodeAccessBase(8192);
|
||||
|
||||
// Remember startup bank
|
||||
|
@ -50,6 +53,9 @@ void CartridgeWD::reset()
|
|||
else
|
||||
memset(myRAM, 0, 64);
|
||||
|
||||
myCyclesAtBankswitchInit = 0;
|
||||
myPendingBank = 0xF0; // one more than the allowable bank #
|
||||
|
||||
// Setup segments to some default slices
|
||||
bank(myStartBank);
|
||||
}
|
||||
|
@ -59,34 +65,29 @@ void CartridgeWD::install(System& system)
|
|||
{
|
||||
mySystem = &system;
|
||||
|
||||
System::PageAccess access(this, System::PA_READ);
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
System::PageAccess read(this, System::PA_READ);
|
||||
for(uInt32 k = 0x1000; k < 0x1040; k += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
read.directPeekBase = &myRAM[k & 0x003F];
|
||||
read.codeAccessBase = &myCodeAccessBase[k & 0x003F];
|
||||
mySystem->setPageAccess(k >> System::PAGE_SHIFT, read);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM writing pages
|
||||
access.type = System::PA_WRITE;
|
||||
System::PageAccess write(this, System::PA_WRITE);
|
||||
for(uInt32 j = 0x1040; j < 0x1080; j += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.directPokeBase = &myRAM[j & 0x003F];
|
||||
access.codeAccessBase = &myCodeAccessBase[0x80 + (j & 0x003F)];
|
||||
mySystem->setPageAccess(j >> System::PAGE_SHIFT, access);
|
||||
write.directPokeBase = &myRAM[j & 0x003F];
|
||||
write.codeAccessBase = &myCodeAccessBase[j & 0x003F];
|
||||
mySystem->setPageAccess(j >> System::PAGE_SHIFT, write);
|
||||
}
|
||||
|
||||
// Set the page accessing method for the RAM reading pages
|
||||
// The first 48 bytes map directly to RAM
|
||||
access.directPeekBase = access.directPokeBase = 0;
|
||||
access.type = System::PA_READ;
|
||||
for(uInt32 k = 0x1000; k < 0x1030; k += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.directPeekBase = &myRAM[k & 0x003F];
|
||||
access.codeAccessBase = &myCodeAccessBase[k & 0x003F];
|
||||
mySystem->setPageAccess(k >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
access.directPeekBase = access.directPokeBase = 0;
|
||||
// The last 16 bytes are hotspots, so they're handled separately
|
||||
for(uInt32 k = 0x1030; k < 0x1040; k += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.codeAccessBase = &myCodeAccessBase[k & 0x003F];
|
||||
mySystem->setPageAccess(k >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
// Set the page accessing methods for the hot spots
|
||||
// These mirror the TIA addresses, so accesses must be chained
|
||||
System::PageAccess hotspot(this, System::PA_READWRITE);
|
||||
for(uInt32 i = 0x30; i < 0x40; i += (1 << System::PAGE_SHIFT))
|
||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, hotspot);
|
||||
|
||||
// Setup segments to some default slices
|
||||
bank(myStartBank);
|
||||
|
@ -95,44 +96,71 @@ void CartridgeWD::install(System& system)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeWD::peek(uInt16 address)
|
||||
{
|
||||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF;
|
||||
// Is it time to do an actual bankswitch?
|
||||
if(myPendingBank != 0xF0 && !bankLocked() &&
|
||||
mySystem->cycles() > (myCyclesAtBankswitchInit + 3))
|
||||
{
|
||||
bank(myPendingBank);
|
||||
myPendingBank = 0xF0;
|
||||
}
|
||||
|
||||
if(address < 0x0040) // RAM read port
|
||||
if(!(address & 0x1000)) // Hotspots below 0x1000 are also TIA addresses
|
||||
{
|
||||
// Hotspots at $30 - $3F
|
||||
bank(address & 0x000F);
|
||||
|
||||
// Read from RAM
|
||||
return myRAM[address & 0x003F];
|
||||
}
|
||||
else if(address < 0x0080) // RAM write port
|
||||
{
|
||||
// Reading from the write port @ $1040 - $107F triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
// Note that a hotspot read triggers a bankswitch after at least 3 cycles
|
||||
// have passed, so we only initiate the switch here
|
||||
if(!bankLocked())
|
||||
{
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return myRAM[address & 0x003F] = value;
|
||||
myCyclesAtBankswitchInit = mySystem->cycles();
|
||||
myPendingBank = address & 0x000F;
|
||||
|
||||
if(!mySystem->autodetectMode())
|
||||
cerr << "BS init: " << dec << myPendingBank << " @ " << dec << mySystem->cycles() << endl;
|
||||
|
||||
}
|
||||
return mySystem->tia().peek(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF;
|
||||
|
||||
if(address < 0x0040) // RAM read port
|
||||
return myRAM[address];
|
||||
else if(address < 0x0080) // RAM write port
|
||||
{
|
||||
// Reading from the write port @ $1040 - $107F triggers an unwanted write
|
||||
uInt8 value = mySystem->getDataBusState(0xFF);
|
||||
|
||||
if(bankLocked())
|
||||
return value;
|
||||
else
|
||||
{
|
||||
triggerReadFromWritePort(peekAddress);
|
||||
return myRAM[address & 0x003F] = value;
|
||||
}
|
||||
}
|
||||
else if(address < 0x0400)
|
||||
return myImage[myOffset[0] + (address & 0x03FF)];
|
||||
else if(address < 0x0800)
|
||||
return myImage[myOffset[1] + (address & 0x03FF)];
|
||||
else if(address < 0x0C00)
|
||||
return myImage[myOffset[2] + (address & 0x03FF)];
|
||||
else
|
||||
return mySegment3[address & 0x03FF];
|
||||
}
|
||||
|
||||
// NOTE: This does not handle reading from ROM, however, this
|
||||
// function should never be called for ROM because of the
|
||||
// way page accessing has been setup
|
||||
return 0;
|
||||
return 0; // We'll never reach this
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeWD::poke(uInt16 address, uInt8)
|
||||
bool CartridgeWD::poke(uInt16 address, uInt8 value)
|
||||
{
|
||||
// NOTE: This does not handle writing to RAM, however, this
|
||||
// function should never be called for RAM because of the
|
||||
// way page accessing has been setup
|
||||
return false;
|
||||
// Only TIA writes will reach here
|
||||
if(!(address & 0x1000))
|
||||
return mySystem->tia().poke(address, value);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -147,13 +175,15 @@ bool CartridgeWD::bank(uInt16 bank)
|
|||
segmentTwo(ourBankOrg[bank].two);
|
||||
segmentThree(ourBankOrg[bank].three, ourBankOrg[bank].map3bytes);
|
||||
|
||||
if(!mySystem->autodetectMode())
|
||||
cerr << "BS done: " << dec << myCurrentBank << " @ " << dec << mySystem->cycles() << endl;
|
||||
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWD::segmentZero(uInt8 slice)
|
||||
{
|
||||
cerr << "segmentZero : slice " << (int)slice << endl;
|
||||
uInt16 offset = slice << 10;
|
||||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
|
@ -161,54 +191,51 @@ cerr << "segmentZero : slice " << (int)slice << endl;
|
|||
for(uInt32 address = 0x1080; address < 0x1400;
|
||||
address += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x03FF)];
|
||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
myOffset[0] = offset;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWD::segmentOne(uInt8 slice)
|
||||
{
|
||||
cerr << "segmentOne : slice " << (int)slice << endl;
|
||||
uInt16 offset = slice << 10;
|
||||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
for(uInt32 address = 0x1400; address < 0x1800;
|
||||
address += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x03FF)];
|
||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
myOffset[1] = offset;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWD::segmentTwo(uInt8 slice)
|
||||
{
|
||||
cerr << "segmentTwo : slice " << (int)slice << endl;
|
||||
uInt16 offset = slice << 10;
|
||||
System::PageAccess access(this, System::PA_READ);
|
||||
|
||||
for(uInt32 address = 0x1800; address < 0x1C00;
|
||||
address += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x03FF)];
|
||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
myOffset[2] = offset;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeWD::segmentThree(uInt8 slice, bool map3bytes)
|
||||
{
|
||||
cerr << "segmentThree: slice " << (int)slice << endl;
|
||||
uInt16 offset = slice << 10;
|
||||
|
||||
// Make a copy of the address space pointed to by the slice
|
||||
// Then map in the extra 3 bytes, if required
|
||||
memcpy(mySegment3, myImage+offset, 1024);
|
||||
if(map3bytes)
|
||||
if(mySize == 8195 && map3bytes)
|
||||
{
|
||||
mySegment3[0x3FC] = myImage[0x2000+0];
|
||||
mySegment3[0x3FD] = myImage[0x2000+1];
|
||||
|
@ -220,10 +247,10 @@ cerr << "segmentThree: slice " << (int)slice << endl;
|
|||
for(uInt32 address = 0x1C00; address < 0x2000;
|
||||
address += (1 << System::PAGE_SHIFT))
|
||||
{
|
||||
access.directPeekBase = &mySegment3[address & 0x03FF];
|
||||
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x03FF)];
|
||||
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
|
||||
}
|
||||
myOffset[3] = offset;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -235,7 +262,7 @@ uInt16 CartridgeWD::getBank() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeWD::bankCount() const
|
||||
{
|
||||
return 8;
|
||||
return 16;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -247,7 +274,7 @@ bool CartridgeWD::patch(uInt16 address, uInt8 value)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt8* CartridgeWD::getImage(int& size) const
|
||||
{
|
||||
size = 8195;
|
||||
size = mySize;
|
||||
return myImage;
|
||||
}
|
||||
|
||||
|
@ -259,6 +286,8 @@ bool CartridgeWD::save(Serializer& out) const
|
|||
out.putString(name());
|
||||
out.putShort(myCurrentBank);
|
||||
out.putByteArray(myRAM, 64);
|
||||
out.putInt(myCyclesAtBankswitchInit);
|
||||
out.putShort(myPendingBank);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -279,6 +308,8 @@ bool CartridgeWD::load(Serializer& in)
|
|||
|
||||
myCurrentBank = in.getShort();
|
||||
in.getByteArray(myRAM, 64);
|
||||
myCyclesAtBankswitchInit = in.getInt();
|
||||
myPendingBank = in.getShort();
|
||||
|
||||
bank(myCurrentBank);
|
||||
}
|
||||
|
@ -293,20 +324,20 @@ bool CartridgeWD::load(Serializer& in)
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeWD::BankOrg CartridgeWD::ourBankOrg[16] = {
|
||||
{ 0, 0, 1, 2, false },
|
||||
{ 0, 1, 3, 2, false },
|
||||
{ 4, 5, 6, 7, false },
|
||||
{ 7, 4, 3, 2, false },
|
||||
{ 0, 0, 6, 7, false },
|
||||
{ 0, 1, 7, 6, false },
|
||||
{ 3, 2, 4, 5, false },
|
||||
{ 6, 0, 5, 1, false },
|
||||
{ 0, 0, 1, 2, false },
|
||||
{ 0, 1, 3, 2, false },
|
||||
{ 4, 5, 6, 7, false },
|
||||
{ 7, 4, 3, 2, false },
|
||||
{ 0, 0, 6, 7, true },
|
||||
{ 0, 1, 7, 6, true },
|
||||
{ 3, 2, 4, 5, true },
|
||||
{ 6, 0, 5, 1, true }
|
||||
{ 0, 0, 1, 2, false }, // Bank 0
|
||||
{ 0, 1, 3, 2, false }, // Bank 1
|
||||
{ 4, 5, 6, 7, false }, // Bank 2
|
||||
{ 7, 4, 3, 2, false }, // Bank 3
|
||||
{ 0, 0, 6, 7, false }, // Bank 4
|
||||
{ 0, 1, 7, 6, false }, // Bank 5
|
||||
{ 3, 2, 4, 5, false }, // Bank 6
|
||||
{ 6, 0, 5, 1, false }, // Bank 7
|
||||
{ 0, 0, 1, 2, false }, // Bank 8
|
||||
{ 0, 1, 3, 2, false }, // Bank 9
|
||||
{ 4, 5, 6, 7, false }, // Bank 10
|
||||
{ 7, 4, 3, 2, false }, // Bank 11
|
||||
{ 0, 0, 6, 7, true }, // Bank 12
|
||||
{ 0, 1, 7, 6, true }, // Bank 13
|
||||
{ 3, 2, 4, 5, true }, // Bank 14
|
||||
{ 6, 0, 5, 1, true } // Bank 15
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ class System;
|
|||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
// #include "CartWDWidget.hxx"
|
||||
#include "CartWDWidget.hxx"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -34,7 +34,7 @@ class System;
|
|||
to be mapped as described below. There is also 64 bytes of RAM.
|
||||
In this bankswitching scheme the 2600's 4K cartridge address space
|
||||
is broken into four 1K segments. The desired arrangement of 1K slices
|
||||
is selected by accessing $30 - $FF of the first segment. The slices
|
||||
is selected by accessing $30 - $3F of TIA address space. The slices
|
||||
are mapped into all 4 segments at once as follows:
|
||||
|
||||
$0030: 0,0,1,2
|
||||
|
@ -47,7 +47,7 @@ class System;
|
|||
$0037: 6,0,5,1
|
||||
$0038: 0,0,1,2
|
||||
$0039: 0,1,3,2
|
||||
$003A: 4,5,6,8
|
||||
$003A: 4,5,6,7
|
||||
$003B: 7,4,3,2
|
||||
$003C: 0,0,6,7*
|
||||
$003D: 0,1,7,6*
|
||||
|
@ -58,9 +58,8 @@ class System;
|
|||
mapped into $3FC - $3FE of the uppermost (third) segment.
|
||||
|
||||
The 64 bytes of RAM are accessible at $1000 - $103F (read port) and
|
||||
$1040 - $107F (write port). Note that all the hotspots are in the
|
||||
read port of RAM. Because the RAM takes 128 bytes of address space,
|
||||
the range $1000 - $107F of segment 0 ROM will never be available.
|
||||
$1040 - $107F (write port). Because the RAM takes 128 bytes of address
|
||||
space, the range $1000 - $107F of segment 0 ROM will never be available.
|
||||
|
||||
@author Stephen Anthony
|
||||
*/
|
||||
|
@ -162,7 +161,7 @@ class CartridgeWD : public Cartridge
|
|||
CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||
const GUI::Font& nfont, int x, int y, int w, int h)
|
||||
{
|
||||
return nullptr;//new CartridgeWDWidget(boss, lfont, nfont, x, y, w, h, *this);
|
||||
return new CartridgeWDWidget(boss, lfont, nfont, x, y, w, h, *this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -218,6 +217,9 @@ class CartridgeWD : public Cartridge
|
|||
// Indicates which bank is currently active
|
||||
uInt16 myCurrentBank;
|
||||
|
||||
// Indicates the actual size of the ROM image (either 8K or 8K + 3)
|
||||
uInt32 mySize;
|
||||
|
||||
// The 8K ROM image of the cartridge
|
||||
uInt8 myImage[8195];
|
||||
|
||||
|
@ -227,6 +229,15 @@ class CartridgeWD : public Cartridge
|
|||
// The 1K ROM mirror of segment 3 (sometimes contains extra 3 bytes)
|
||||
uInt8 mySegment3[1024];
|
||||
|
||||
// Indicates the offset for each of the four segments
|
||||
uInt16 myOffset[4];
|
||||
|
||||
// Indicates the cycle at which a bankswitch was initiated
|
||||
uInt32 myCyclesAtBankswitchInit;
|
||||
|
||||
// Indicates the bank we wish to switch to in the future
|
||||
uInt16 myPendingBank;
|
||||
|
||||
// The arrangement of banks to use on each hotspot read
|
||||
struct BankOrg {
|
||||
uInt8 zero, one, two, three;
|
||||
|
|
Loading…
Reference in New Issue