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:
stephena 2014-12-13 19:45:18 +00:00
parent c7fc207b13
commit 31ca88d283
6 changed files with 368 additions and 87 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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 \

View File

@ -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
};

View File

@ -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;