Added new bankswitch code from 3.9.3 (RevEng and CPUWIZ) to trunk.

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2837 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2014-01-17 15:39:11 +00:00
parent aa5691af8a
commit 7c4a0a331d
27 changed files with 2881 additions and 5 deletions

View File

@ -0,0 +1,41 @@
//============================================================================
//
// 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-2013 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 "Cart4KSC.hxx"
#include "Cart4KSCWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4KSCWidget::Cartridge4KSCWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, Cartridge4KSC& cart)
: CartDebugWidget(boss, lfont, nfont, x, y, w, h)
{
// Eventually, we should query this from the debugger/disassembler
uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC];
start -= start % 0x1000;
ostringstream info;
info << "4KSC cartridge, non-bankswitched\n"
<< "128 bytes RAM @ $F000 - $F0FF\n"
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
<< "Accessible @ $" << Common::Base::HEX4 << start << " - "
<< "$" << (start + 0xFFF);
addBaseInformation(4096, "homebrew intermediate format", info.str());
}

View File

@ -0,0 +1,40 @@
//============================================================================
//
// 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-2013 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 CARTRIDGE4KSC_WIDGET_HXX
#define CARTRIDGE4KSC_WIDGET_HXX
class Cartridge4KSC;
#include "CartDebugWidget.hxx"
class Cartridge4KSCWidget : public CartDebugWidget
{
public:
Cartridge4KSCWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont,
int x, int y, int w, int h,
Cartridge4KSC& cart);
virtual ~Cartridge4KSCWidget() { }
// No implementation for non-bankswitched ROMs
void loadConfig() { }
void handleCommand(CommandSender* sender, int cmd, int data, int id) { }
};
#endif

View File

@ -0,0 +1,165 @@
//============================================================================
//
// 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-2013 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 "CartBFSC.hxx"
#include "PopUpWidget.hxx"
#include "CartBFSCWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeBFSCWidget::CartridgeBFSCWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, CartridgeBFSC& cart)
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
myCart(cart)
{
uInt32 size = 64 * 4096;
ostringstream info;
info << "256K BFSC + RAM, 64 4K banks\n"
<< "128 bytes RAM @ $F000 - $F0FF\n"
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
<< "Startup bank = " << cart.myStartBank << "\n";
// Eventually, we should query this from the debugger/disassembler
for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++i, offset += 0x1000)
{
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
start -= start % 0x1000;
info << "Bank " << dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100)
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
}
int xpos = 10,
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
VariantList items;
items.push_back(" 0 ($F80)");
items.push_back(" 1 ($F81)");
items.push_back(" 2 ($F82)");
items.push_back(" 3 ($F83)");
items.push_back(" 4 ($F84)");
items.push_back(" 5 ($F85)");
items.push_back(" 6 ($F86)");
items.push_back(" 7 ($F87)");
items.push_back(" 8 ($F88)");
items.push_back(" 9 ($F89)");
items.push_back("10 ($F8A)");
items.push_back("11 ($F8B)");
items.push_back("12 ($F8C)");
items.push_back("13 ($F8D)");
items.push_back("14 ($F8E)");
items.push_back("15 ($F8F)");
items.push_back("16 ($F90)");
items.push_back("17 ($F91)");
items.push_back("18 ($F92)");
items.push_back("19 ($F93)");
items.push_back("20 ($F94)");
items.push_back("21 ($F95)");
items.push_back("22 ($F96)");
items.push_back("23 ($F97)");
items.push_back("24 ($F98)");
items.push_back("25 ($F99)");
items.push_back("26 ($F9A)");
items.push_back("27 ($F9B)");
items.push_back("28 ($F9C)");
items.push_back("29 ($F9D)");
items.push_back("30 ($F9E)");
items.push_back("31 ($F9F)");
items.push_back("32 ($FA0)");
items.push_back("33 ($FA1)");
items.push_back("34 ($FA2)");
items.push_back("35 ($FA3)");
items.push_back("36 ($FA4)");
items.push_back("37 ($FA5)");
items.push_back("38 ($FA6)");
items.push_back("39 ($FA7)");
items.push_back("40 ($FA8)");
items.push_back("41 ($FA9)");
items.push_back("42 ($FAA)");
items.push_back("43 ($FAB)");
items.push_back("44 ($FAC)");
items.push_back("45 ($FAD)");
items.push_back("46 ($FAE)");
items.push_back("47 ($FAF)");
items.push_back("48 ($FB0)");
items.push_back("49 ($FB1)");
items.push_back("50 ($FB2)");
items.push_back("51 ($FB3)");
items.push_back("52 ($FB4)");
items.push_back("53 ($FB5)");
items.push_back("54 ($FB6)");
items.push_back("55 ($FB7)");
items.push_back("56 ($FB8)");
items.push_back("57 ($FB9)");
items.push_back("58 ($FBA)");
items.push_back("59 ($FBB)");
items.push_back("60 ($FBC)");
items.push_back("61 ($FBD)");
items.push_back("62 ($FBE)");
items.push_back("63 ($FBF)");
myBank =
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("63 ($FBF) "),
myLineHeight, items, "Set bank: ",
_font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this);
addFocusWidget(myBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBFSCWidget::loadConfig()
{
myBank->setSelectedIndex(myCart.myCurrentBank);
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBFSCWidget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
if(cmd == kBankChanged)
{
myCart.unlockBank();
myCart.bank(myBank->getSelected());
myCart.lockBank();
invalidate();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartridgeBFSCWidget::bankState()
{
ostringstream& buf = buffer();
static const char* spot[] = {
"$F80", "$F81", "$F82", "$F83", "$F84", "$F85", "$F86", "$F87",
"$F88", "$F89", "$F8A", "$F8B", "$F8C", "$F8D", "$F8E", "$F8F",
"$F90", "$F91", "$F92", "$F93", "$F94", "$F95", "$F96", "$F97",
"$F98", "$F99", "$F9A", "$F9B", "$F9C", "$F9D", "$F9E", "$F9F",
"$FA0", "$FA1", "$FA2", "$FA3", "$FA4", "$FA5", "$FA6", "$FA7",
"$FA8", "$FA9", "$FAA", "$FAB", "$FAC", "$FAD", "$FAE", "$FAF",
"$FB0", "$FB1", "$FB2", "$FB3", "$FB4", "$FB5", "$FB6", "$FB7",
"$FB8", "$FB9", "$FBA", "$FBB", "$FBC", "$FBD", "$FBE", "$FBF"
};
buf << "Bank = " << dec << myCart.myCurrentBank
<< ", hotspot = " << spot[myCart.myCurrentBank];
return buf.str();
}

View File

@ -0,0 +1,49 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEBFSC_WIDGET_HXX
#define CARTRIDGEBFSC_WIDGET_HXX
class CartridgeBFSC;
class PopUpWidget;
#include "CartDebugWidget.hxx"
class CartridgeBFSCWidget : public CartDebugWidget
{
public:
CartridgeBFSCWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont,
int x, int y, int w, int h,
CartridgeBFSC& cart);
virtual ~CartridgeBFSCWidget() { }
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
string bankState();
private:
CartridgeBFSC& myCart;
PopUpWidget* myBank;
enum { kBankChanged = 'bkCH' };
};
#endif

View File

@ -0,0 +1,163 @@
//============================================================================
//
// 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-2013 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 "CartBF.hxx"
#include "PopUpWidget.hxx"
#include "CartBFWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeBFWidget::CartridgeBFWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, CartridgeBF& cart)
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
myCart(cart)
{
uInt32 size = 64 * 4096;
ostringstream info;
info << "BF cartridge, 64 4K banks\n"
<< "Startup bank = " << cart.myStartBank << "\n";
// Eventually, we should query this from the debugger/disassembler
for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++i, offset += 0x1000)
{
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
start -= start % 0x1000;
info << "Bank " << dec << i << " @ $" << Common::Base::HEX4 << start << " - "
<< "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
}
int xpos = 10,
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
VariantList items;
items.push_back(" 0 ($F80)");
items.push_back(" 1 ($F81)");
items.push_back(" 2 ($F82)");
items.push_back(" 3 ($F83)");
items.push_back(" 4 ($F84)");
items.push_back(" 5 ($F85)");
items.push_back(" 6 ($F86)");
items.push_back(" 7 ($F87)");
items.push_back(" 8 ($F88)");
items.push_back(" 9 ($F89)");
items.push_back("10 ($F8A)");
items.push_back("11 ($F8B)");
items.push_back("12 ($F8C)");
items.push_back("13 ($F8D)");
items.push_back("14 ($F8E)");
items.push_back("15 ($F8F)");
items.push_back("16 ($F90)");
items.push_back("17 ($F91)");
items.push_back("18 ($F92)");
items.push_back("19 ($F93)");
items.push_back("20 ($F94)");
items.push_back("21 ($F95)");
items.push_back("22 ($F96)");
items.push_back("23 ($F97)");
items.push_back("24 ($F98)");
items.push_back("25 ($F99)");
items.push_back("26 ($F9A)");
items.push_back("27 ($F9B)");
items.push_back("28 ($F9C)");
items.push_back("29 ($F9D)");
items.push_back("30 ($F9E)");
items.push_back("31 ($F9F)");
items.push_back("32 ($FA0)");
items.push_back("33 ($FA1)");
items.push_back("34 ($FA2)");
items.push_back("35 ($FA3)");
items.push_back("36 ($FA4)");
items.push_back("37 ($FA5)");
items.push_back("38 ($FA6)");
items.push_back("39 ($FA7)");
items.push_back("40 ($FA8)");
items.push_back("41 ($FA9)");
items.push_back("42 ($FAA)");
items.push_back("43 ($FAB)");
items.push_back("44 ($FAC)");
items.push_back("45 ($FAD)");
items.push_back("46 ($FAE)");
items.push_back("47 ($FAF)");
items.push_back("48 ($FB0)");
items.push_back("49 ($FB1)");
items.push_back("50 ($FB2)");
items.push_back("51 ($FB3)");
items.push_back("52 ($FB4)");
items.push_back("53 ($FB5)");
items.push_back("54 ($FB6)");
items.push_back("55 ($FB7)");
items.push_back("56 ($FB8)");
items.push_back("57 ($FB9)");
items.push_back("58 ($FBA)");
items.push_back("59 ($FBB)");
items.push_back("60 ($FBC)");
items.push_back("61 ($FBD)");
items.push_back("62 ($FBE)");
items.push_back("63 ($FBF)");
myBank =
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("64 ($FBF) "),
myLineHeight, items, "Set bank: ",
_font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this);
addFocusWidget(myBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBFWidget::loadConfig()
{
myBank->setSelectedIndex(myCart.myCurrentBank);
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBFWidget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
if(cmd == kBankChanged)
{
myCart.unlockBank();
myCart.bank(myBank->getSelected());
myCart.lockBank();
invalidate();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartridgeBFWidget::bankState()
{
ostringstream& buf = buffer();
static const char* spot[] = {
"$F80", "$F81", "$F82", "$F83", "$F84", "$F85", "$F86", "$F87",
"$F88", "$F89", "$F8A", "$F8B", "$F8C", "$F8D", "$F8E", "$F8F",
"$F90", "$F91", "$F92", "$F93", "$F94", "$F95", "$F96", "$F97",
"$F98", "$F99", "$F9A", "$F9B", "$F9C", "$F9D", "$F9E", "$F9F",
"$FA0", "$FA1", "$FA2", "$FA3", "$FA4", "$FA5", "$FA6", "$FA7",
"$FA8", "$FA9", "$FAA", "$FAB", "$FAC", "$FAD", "$FAE", "$FAF",
"$FB0", "$FB1", "$FB2", "$FB3", "$FB4", "$FB5", "$FB6", "$FB7",
"$FB8", "$FB9", "$FBA", "$FBB", "$FBC", "$FBD", "$FBE", "$FBF"
};
buf << "Bank = " << dec << myCart.myCurrentBank
<< ", hotspot = " << spot[myCart.myCurrentBank];
return buf.str();
}

View File

@ -0,0 +1,49 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEBF_WIDGET_HXX
#define CARTRIDGEBF_WIDGET_HXX
class CartridgeBF;
class PopUpWidget;
#include "CartDebugWidget.hxx"
class CartridgeBFWidget : public CartDebugWidget
{
public:
CartridgeBFWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont,
int x, int y, int w, int h,
CartridgeBF& cart);
virtual ~CartridgeBFWidget() { }
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
string bankState();
private:
CartridgeBF& myCart;
PopUpWidget* myBank;
enum { kBankChanged = 'bkCH' };
};
#endif

View File

@ -0,0 +1,129 @@
//============================================================================
//
// 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-2013 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 "CartDFSC.hxx"
#include "PopUpWidget.hxx"
#include "CartDFSCWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDFSCWidget::CartridgeDFSCWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, CartridgeDFSC& cart)
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
myCart(cart)
{
uInt32 size = 32 * 4096;
ostringstream info;
info << "128K DFSC + RAM, 32 4K banks\n"
<< "128 bytes RAM @ $F000 - $F0FF\n"
<< " $F080 - $F0FF (R), $F000 - $F07F (W)\n"
<< "Startup bank = " << cart.myStartBank << "\n";
// Eventually, we should query this from the debugger/disassembler
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFC0; i < 32; ++i, offset += 0x1000)
{
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
start -= start % 0x1000;
info << "Bank " << dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100)
<< " - " << "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
}
int xpos = 10,
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
VariantList items;
items.push_back(" 0 ($FC0)");
items.push_back(" 1 ($FC1)");
items.push_back(" 2 ($FC2)");
items.push_back(" 3 ($FC3)");
items.push_back(" 4 ($FC4)");
items.push_back(" 5 ($FC5)");
items.push_back(" 6 ($FC6)");
items.push_back(" 7 ($FC7)");
items.push_back(" 8 ($FC8)");
items.push_back(" 9 ($FC9)");
items.push_back("10 ($FCA)");
items.push_back("11 ($FCB)");
items.push_back("12 ($FCC)");
items.push_back("13 ($FCD)");
items.push_back("14 ($FCE)");
items.push_back("15 ($FCF)");
items.push_back("16 ($FD0)");
items.push_back("17 ($FD1)");
items.push_back("18 ($FD2)");
items.push_back("19 ($FD3)");
items.push_back("20 ($FD4)");
items.push_back("21 ($FD5)");
items.push_back("22 ($FD6)");
items.push_back("23 ($FD7)");
items.push_back("24 ($FD8)");
items.push_back("25 ($FD9)");
items.push_back("26 ($FDA)");
items.push_back("27 ($FDB)");
items.push_back("28 ($FDC)");
items.push_back("29 ($FDD)");
items.push_back("30 ($FDE)");
items.push_back("31 ($FDF)");
myBank =
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("31 ($FE0) "),
myLineHeight, items, "Set bank: ",
_font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this);
addFocusWidget(myBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFSCWidget::loadConfig()
{
myBank->setSelectedIndex(myCart.myCurrentBank);
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFSCWidget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
if(cmd == kBankChanged)
{
myCart.unlockBank();
myCart.bank(myBank->getSelected());
myCart.lockBank();
invalidate();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartridgeDFSCWidget::bankState()
{
ostringstream& buf = buffer();
static const char* spot[] = {
"$FC0", "$FC1", "$FC2", "$FC3", "$FC4", "$FC5", "$FC6", "$FC7",
"$FC8", "$FC9", "$FCA", "$FCB", "$FCC", "$FCD", "$FCE", "$FCF",
"$FD0", "$FD1", "$FD2", "$FD3", "$FD4", "$FD5", "$FD6", "$FE7",
"$FD8", "$FD9", "$FDA", "$FDB", "$FDC", "$FDD", "$FDE", "$FDF"
};
buf << "Bank = " << dec << myCart.myCurrentBank
<< ", hotspot = " << spot[myCart.myCurrentBank];
return buf.str();
}

View File

@ -0,0 +1,49 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEDFSC_WIDGET_HXX
#define CARTRIDGEDFSC_WIDGET_HXX
class CartridgeDFSC;
class PopUpWidget;
#include "CartDebugWidget.hxx"
class CartridgeDFSCWidget : public CartDebugWidget
{
public:
CartridgeDFSCWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont,
int x, int y, int w, int h,
CartridgeDFSC& cart);
virtual ~CartridgeDFSCWidget() { }
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
string bankState();
private:
CartridgeDFSC& myCart;
PopUpWidget* myBank;
enum { kBankChanged = 'bkCH' };
};
#endif

View File

@ -0,0 +1,127 @@
//============================================================================
//
// 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-2013 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 "CartDF.hxx"
#include "PopUpWidget.hxx"
#include "CartDFWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDFWidget::CartridgeDFWidget(
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
int x, int y, int w, int h, CartridgeDF& cart)
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
myCart(cart)
{
uInt32 size = 32 * 4096;
ostringstream info;
info << "EF 2 cartridge, 32 4K banks\n"
<< "Startup bank = " << cart.myStartBank << "\n";
// Eventually, we should query this from the debugger/disassembler
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFD0; i < 32; ++i, offset += 0x1000)
{
uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset];
start -= start % 0x1000;
info << "Bank " << dec << i << " @ $" << Common::Base::HEX4 << start << " - "
<< "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
}
int xpos = 10,
ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight;
VariantList items;
items.push_back(" 0 ($FC0)");
items.push_back(" 1 ($FC1)");
items.push_back(" 2 ($FC2)");
items.push_back(" 3 ($FC3)");
items.push_back(" 4 ($FC4)");
items.push_back(" 5 ($FC5)");
items.push_back(" 6 ($FC6)");
items.push_back(" 7 ($FC7)");
items.push_back(" 8 ($FC8)");
items.push_back(" 9 ($FC9)");
items.push_back("10 ($FCA)");
items.push_back("11 ($FCB)");
items.push_back("12 ($FCC)");
items.push_back("13 ($FCD)");
items.push_back("14 ($FCE)");
items.push_back("15 ($FCF)");
items.push_back("16 ($FD0)");
items.push_back("17 ($FD1)");
items.push_back("18 ($FD2)");
items.push_back("19 ($FD3)");
items.push_back("20 ($FD4)");
items.push_back("21 ($FD5)");
items.push_back("22 ($FD6)");
items.push_back("23 ($FD7)");
items.push_back("24 ($FD8)");
items.push_back("25 ($FD9)");
items.push_back("26 ($FDA)");
items.push_back("27 ($FDB)");
items.push_back("28 ($FDC)");
items.push_back("29 ($FDD)");
items.push_back("30 ($FDE)");
items.push_back("31 ($FDF)");
myBank =
new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("31 ($FDF) "),
myLineHeight, items, "Set bank: ",
_font.getStringWidth("Set bank: "), kBankChanged);
myBank->setTarget(this);
addFocusWidget(myBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFWidget::loadConfig()
{
myBank->setSelectedIndex(myCart.myCurrentBank);
CartDebugWidget::loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFWidget::handleCommand(CommandSender* sender,
int cmd, int data, int id)
{
if(cmd == kBankChanged)
{
myCart.unlockBank();
myCart.bank(myBank->getSelected());
myCart.lockBank();
invalidate();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartridgeDFWidget::bankState()
{
ostringstream& buf = buffer();
static const char* spot[] = {
"$FC0", "$FC1", "$FC2", "$FC3", "$FC4", "$FC5", "$FC6", "$FC7",
"$FC8", "$FC9", "$FCA", "$FCB", "$FCC", "$FCD", "$FCE", "$FCF",
"$FD0", "$FD1", "$FD2", "$FD3", "$FD4", "$FD5", "$FD6", "$FD7",
"$FD8", "$FD9", "$FDA", "$FDB", "$FDC", "$FDD", "$FDE", "$FDF"
};
buf << "Bank = " << dec << myCart.myCurrentBank
<< ", hotspot = " << spot[myCart.myCurrentBank];
return buf.str();
}

View File

@ -0,0 +1,49 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEDF_WIDGET_HXX
#define CARTRIDGEDF_WIDGET_HXX
class CartridgeDF;
class PopUpWidget;
#include "CartDebugWidget.hxx"
class CartridgeDFWidget : public CartDebugWidget
{
public:
CartridgeDFWidget(GuiObject* boss, const GUI::Font& lfont,
const GUI::Font& nfont,
int x, int y, int w, int h,
CartridgeDF& cart);
virtual ~CartridgeDFWidget() { }
void loadConfig();
void handleCommand(CommandSender* sender, int cmd, int data, int id);
string bankState();
private:
CartridgeDF& myCart;
PopUpWidget* myBank;
enum { kBankChanged = 'bkCH' };
};
#endif

View File

@ -26,6 +26,7 @@ MODULE_OBJS := \
src/debugger/gui/Cart3FWidget.o \
src/debugger/gui/Cart4A50Widget.o \
src/debugger/gui/Cart4KWidget.o \
src/debugger/gui/Cart4KSCWidget.o \
src/debugger/gui/CartARWidget.o \
src/debugger/gui/CartCMWidget.o \
src/debugger/gui/CartCTYWidget.o \
@ -36,6 +37,10 @@ MODULE_OBJS := \
src/debugger/gui/CartE7Widget.o \
src/debugger/gui/CartEFWidget.o \
src/debugger/gui/CartEFSCWidget.o \
src/debugger/gui/CartBFWidget.o \
src/debugger/gui/CartBFSCWidget.o \
src/debugger/gui/CartDFWidget.o \
src/debugger/gui/CartDFSCWidget.o \
src/debugger/gui/CartF0Widget.o \
src/debugger/gui/CartF4Widget.o \
src/debugger/gui/CartF6Widget.o \

View File

@ -29,6 +29,7 @@
#include "Cart3F.hxx"
#include "Cart4A50.hxx"
#include "Cart4K.hxx"
#include "Cart4KSC.hxx"
#include "CartAR.hxx"
#include "CartCM.hxx"
#include "CartCTY.hxx"
@ -39,6 +40,10 @@
#include "CartE7.hxx"
#include "CartEF.hxx"
#include "CartEFSC.hxx"
#include "CartBF.hxx"
#include "CartBFSC.hxx"
#include "CartDF.hxx"
#include "CartDFSC.hxx"
#include "CartF0.hxx"
#include "CartF4.hxx"
#include "CartF4SC.hxx"
@ -184,6 +189,8 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size, string& md5,
cartridge = new Cartridge4A50(image, size, settings);
else if(type == "4K")
cartridge = new Cartridge4K(image, size, settings);
else if(type == "4KSC")
cartridge = new Cartridge4KSC(image, size, settings);
else if(type == "AR")
cartridge = new CartridgeAR(image, size, settings);
else if(type == "CM")
@ -204,6 +211,14 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size, string& md5,
cartridge = new CartridgeEF(image, size, settings);
else if(type == "EFSC")
cartridge = new CartridgeEFSC(image, size, settings);
else if(type == "BF")
cartridge = new CartridgeBF(image, size, settings);
else if(type == "BFSC")
cartridge = new CartridgeBFSC(image, size, settings);
else if(type == "DF")
cartridge = new CartridgeDF(image, size, settings);
else if(type == "DFSC")
cartridge = new CartridgeDFSC(image, size, settings);
else if(type == "F0" || type == "MB")
cartridge = new CartridgeF0(image, size, settings);
else if(type == "F4")
@ -374,7 +389,12 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
}
else if(size == 4096)
{
type = isProbablyCV(image, size) ? "CV" : "4K";
if(isProbablyCV(image,size))
type = "CV";
else if(isProbably4KSC(image,size))
type = "4KSC";
else
type = "4K";
}
else if(size == 8*1024) // 8K
{
@ -471,6 +491,8 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
{
if(isProbably3E(image, size))
type = "3E";
else if(isProbablyDF(image, size, type))
; // type has been set directly in the function
else if(isProbably3F(image, size))
type = "3F";
else if(isProbably4A50(image, size))
@ -484,6 +506,8 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
{
if(isProbably3E(image, size))
type = "3E";
else if(isProbablyBF(image, size, type))
; // type has been set directly in the function
else if(isProbably3F(image, size))
type = "3F";
else /*if(isProbablySB(image, size))*/
@ -549,6 +573,23 @@ bool Cartridge::isProbablySC(const uInt8* image, uInt32 size)
return true;
}
bool Cartridge::isProbably4KSC(const uInt8* image, uInt32 size)
{
// We check if the first 256 bytes are identical *and* if there's
// an "SC" signature for one of our larger SC types at 1FFA.
uInt8 first = image[0];
for(uInt32 i = 1; i < 256; ++i)
if(image[i] != first)
return false;
if((image[size-6]=='S') && (image[size-5]=='C'))
return true;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::isProbablyARM(const uInt8* image, uInt32 size)
{
@ -756,6 +797,50 @@ bool Cartridge::isProbablyEF(const uInt8* image, uInt32 size, const char*& type)
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::isProbablyBF(const uInt8* image, uInt32 size, const char*& type)
{
// BF carts store strings 'BFBF' and 'BFSC' starting at address $FFF8
// This signature is attributed to "RevEng" of AtariAge
uInt8 bf[] = { 'B', 'F', 'B', 'F' };
uInt8 bfsc[] = { 'B', 'F', 'S', 'C' };
if(searchForBytes(image+size-8, 8, bf, 4, 1))
{
type = "BF";
return true;
}
else if(searchForBytes(image+size-8, 8, bfsc, 4, 1))
{
type = "BFSC";
return true;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::isProbablyDF(const uInt8* image, uInt32 size, const char*& type)
{
// BF carts store strings 'DFDF' and 'DFSC' starting at address $FFF8
// This signature is attributed to "RevEng" of AtariAge
uInt8 df[] = { 'D', 'F', 'D', 'F' };
uInt8 dfsc[] = { 'D', 'F', 'S', 'C' };
if(searchForBytes(image+size-8, 8, df, 4, 1))
{
type = "DF";
return true;
}
else if(searchForBytes(image+size-8, 8, dfsc, 4, 1))
{
type = "DFSC";
return true;
}
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge::isProbablyFA2(const uInt8* image, uInt32 size)
{

View File

@ -283,6 +283,11 @@ class Cartridge : public Device
*/
static bool isProbablySC(const uInt8* image, uInt32 size);
/**
Returns true if the image is probably a 4K SuperChip (256 bytes RAM)
*/
static bool isProbably4KSC(const uInt8* image, uInt32 size);
/**
Returns true if the image probably contains ARM code in the first 1K
*/
@ -338,6 +343,15 @@ class Cartridge : public Device
*/
static bool isProbablyEF(const uInt8* image, uInt32 size, const char*& type);
/**
Returns true if the image is probably a BF/BFSC bankswitching cartridge
*/
static bool isProbablyBF(const uInt8* image, uInt32 size, const char*& type);
/**
Returns true if the image is probably a DF/DFSC bankswitching cartridge
*/
static bool isProbablyDF(const uInt8* image, uInt32 size, const char*& type);
/**
Returns true if the image is probably an F6 bankswitching cartridge
*/

210
src/emucore/Cart4KSC.cxx Normal file
View File

@ -0,0 +1,210 @@
//============================================================================
//
// 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-2013 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 <cassert>
#include <cstring>
#include "System.hxx"
#include "Cart4KSC.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4KSC::Cartridge4KSC(const uInt8* image, uInt32 size, const Settings& settings)
: Cartridge(settings)
{
// Copy the ROM image into my buffer
memcpy(myImage, image, BSPF_min(4096u, size));
createCodeAccessBase(4096);
// This cart contains 128 bytes extended RAM @ 0x1000
registerRamArea(0x1000, 128, 0x80, 0x00);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge4KSC::~Cartridge4KSC()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4KSC::reset()
{
// Initialize RAM
if(mySettings.getBool("ramrandom"))
for(uInt32 i = 0; i < 128; ++i)
myRAM[i] = mySystem->randGenerator().next();
else
memset(myRAM, 0, 128);
myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4KSC::install(System& system)
{
mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
// Set the page accessing method for the RAM reading pages
access.directPokeBase = 0;
access.type = System::PA_READ;
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
{
access.directPeekBase = &myRAM[k & 0x007F];
access.codeAccessBase = &myCodeAccessBase[0x80 + (k & 0x007F)];
mySystem->setPageAccess(k >> shift, access);
}
// Map ROM image into the system
for(uInt32 address = 0x1100; address < 0x2000; address += (1 << shift))
{
access.directPeekBase = &myImage[address & 0x0FFF];
access.codeAccessBase = &myCodeAccessBase[address & 0x0FFF];
mySystem->setPageAccess(address >> mySystem->pageShift(), access);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Cartridge4KSC::peek(uInt16 address)
{
uInt16 peekAddress = address;
address &= 0x0FFF;
if(address < 0x0080) // Write port is at 0xF000 - 0xF080 (128 bytes)
{
// Reading from the write port triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF);
if(bankLocked())
return value;
else
{
triggerReadFromWritePort(peekAddress);
return myRAM[address] = value;
}
}
else
return myImage[address & 0x0FFF];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge4KSC::poke(uInt16 address, uInt8)
{
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge4KSC::bank(uInt16 bank)
{
// Doesn't support bankswitching
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 Cartridge4KSC::bank() const
{
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 Cartridge4KSC::bankCount() const
{
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge4KSC::patch(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
if(address < 0x0100)
{
// Normally, a write to the read port won't do anything
// However, the patch command is special in that ignores such
// cart restrictions
myRAM[address & 0x007F] = value;
}
else
myImage[address & 0xFFF] = value;
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* Cartridge4KSC::getImage(int& size) const
{
size = 4096;
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge4KSC::save(Serializer& out) const
{
try
{
out.putString(name());
out.putShort(myCurrentBank);
out.putByteArray(myRAM, 128);
}
catch(...)
{
cerr << "ERROR: Cartridge4KSC::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Cartridge4KSC::load(Serializer& in)
{
try
{
if(in.getString() != name())
return false;
myCurrentBank = in.getShort();
in.getByteArray(myRAM, 128);
}
catch(...)
{
cerr << "ERROR: Cartridge4KSC::load" << endl;
return false;
}
// Remember what bank we were in
bank(myCurrentBank);
return true;
}

166
src/emucore/Cart4KSC.hxx Normal file
View File

@ -0,0 +1,166 @@
//============================================================================
//
// 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-2013 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 CARTRIDGE4KSC_HXX
#define CARTRIDGE4KSC_HXX
class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "Cart4KSCWidget.hxx"
#endif
/**
Cartridge class used for 4KSC games with
128 bytes of RAM. There are two 4K banks.
*/
class Cartridge4KSC : public Cartridge
{
friend class Cartridge4KSCWidget;
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 settings A reference to the various settings (read-only)
*/
Cartridge4KSC(const uInt8* image, uInt32 size, const Settings& settings);
/**
Destructor
*/
virtual ~Cartridge4KSC();
public:
/**
Reset device to its power-on state
*/
void reset();
/**
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);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
bool bank(uInt16 bank);
/**
Get the current bank.
*/
uInt16 bank() const;
/**
Query the number of banks supported by the cartridge.
*/
uInt16 bankCount() const;
/**
Patch the cartridge ROM.
@param address The ROM address to patch
@param value The value to place into the address
@return Success or failure of the patch operation
*/
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
const uInt8* getImage(int& size) const;
/**
Save the current state of this cart to the given Serializer.
@param out The Serializer object to use
@return False on any errors, else true
*/
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@param in The Serializer object to use
@return False on any errors, else true
*/
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const { return "Cartridge4KSC"; }
#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)
{
return new Cartridge4KSCWidget(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);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;
// The 8K ROM image of the cartridge
uInt8 myImage[4096];
// The 128 bytes of RAM
uInt8 myRAM[128];
};
#endif

180
src/emucore/CartBF.cxx Normal file
View File

@ -0,0 +1,180 @@
//============================================================================
//
// 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-2013 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 <cassert>
#include <cstring>
#include "System.hxx"
#include "CartBF.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeBF::CartridgeBF(const uInt8* image, uInt32 size, const Settings& settings)
: Cartridge(settings)
{
// Copy the ROM image into my buffer
memcpy(myImage, image, BSPF_min(262144u, size));
createCodeAccessBase(262144);
// Remember startup bank
myStartBank = 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeBF::~CartridgeBF()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBF::reset()
{
// Upon reset we switch to the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBF::install(System& system)
{
mySystem = &system;
// Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mySystem->pageMask()) == 0);
// Install pages for the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeBF::peek(uInt16 address)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0F80) && (address <= 0x0FBF))
bank(address - 0x0F80);
return myImage[(myCurrentBank << 12) + address];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBF::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0F80) && (address <= 0x0FBF))
bank(address - 0x0F80);
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBF::bank(uInt16 bank)
{
if(bankLocked()) return false;
// Remember what bank we're in
myCurrentBank = bank;
uInt32 offset = myCurrentBank << 12;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1F80 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1F80U & ~mask);
address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeBF::bank() const
{
return myCurrentBank;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeBF::bankCount() const
{
return 64;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBF::patch(uInt16 address, uInt8 value)
{
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* CartridgeBF::getImage(int& size) const
{
size = 262144;
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBF::save(Serializer& out) const
{
try
{
out.putString(name());
out.putShort(myCurrentBank);
}
catch(...)
{
cerr << "ERROR: CartridgeBF::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBF::load(Serializer& in)
{
try
{
if(in.getString() != name())
return false;
myCurrentBank = in.getShort();
}
catch(...)
{
cerr << "ERROR: CartridgeBF::load" << endl;
return false;
}
// Remember what bank we were in
bank(myCurrentBank);
return true;
}

166
src/emucore/CartBF.hxx Normal file
View File

@ -0,0 +1,166 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEBF_HXX
#define CARTRIDGEBF_HXX
class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "CartBFWidget.hxx"
#endif
/**
Update of EF cartridge class used for Homestar Runner by Paul Slocum.
There are 32 4K banks (total of 128K ROM).
Accessing $1FC0 - $1FDF switches to each bank.
@author Mike Saarna
@version $Id$
*/
class CartridgeBF : public Cartridge
{
friend class CartridgeBFWidget;
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 settings A reference to the various settings (read-only)
*/
CartridgeBF(const uInt8* image, uInt32 size, const Settings& settings);
/**
Destructor
*/
virtual ~CartridgeBF();
public:
/**
Reset device to its power-on state
*/
void reset();
/**
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);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
bool bank(uInt16 bank);
/**
Get the current bank.
*/
uInt16 bank() const;
/**
Query the number of banks supported by the cartridge.
*/
uInt16 bankCount() const;
/**
Patch the cartridge ROM.
@param address The ROM address to patch
@param value The value to place into the address
@return Success or failure of the patch operation
*/
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
const uInt8* getImage(int& size) const;
/**
Save the current state of this cart to the given Serializer.
@param out The Serializer object to use
@return False on any errors, else true
*/
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@param in The Serializer object to use
@return False on any errors, else true
*/
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const { return "CartridgeBF"; }
#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)
{
return new CartridgeBFWidget(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);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;
// The 64K ROM image of the cartridge
uInt8 myImage[262144];
};
#endif

244
src/emucore/CartBFSC.cxx Normal file
View File

@ -0,0 +1,244 @@
//============================================================================
//
// 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-2013 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 <cassert>
#include <cstring>
#include "System.hxx"
#include "CartBFSC.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeBFSC::CartridgeBFSC(const uInt8* image, uInt32 size, const Settings& settings)
: Cartridge(settings)
{
// Copy the ROM image into my buffer
memcpy(myImage, image, BSPF_min(262144u, size));
createCodeAccessBase(262144);
// This cart contains 128 bytes extended RAM @ 0x1000
registerRamArea(0x1000, 128, 0x80, 0x00);
// Remember startup bank
myStartBank = 15;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeBFSC::~CartridgeBFSC()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBFSC::reset()
{
// Initialize RAM
if(mySettings.getBool("ramrandom"))
for(uInt32 i = 0; i < 128; ++i)
myRAM[i] = mySystem->randGenerator().next();
else
memset(myRAM, 0, 128);
// Upon reset we switch to the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeBFSC::install(System& system)
{
mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
// Set the page accessing method for the RAM reading pages
access.directPokeBase = 0;
access.type = System::PA_READ;
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
{
access.directPeekBase = &myRAM[k & 0x007F];
access.codeAccessBase = &myCodeAccessBase[0x80 + (k & 0x007F)];
mySystem->setPageAccess(k >> shift, access);
}
// Install pages for the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeBFSC::peek(uInt16 address)
{
uInt16 peekAddress = address;
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0F80) && (address <= 0x0FBF))
bank(address - 0x0F80);
if(address < 0x0080) // Write port is at 0xF000 - 0xF080 (128 bytes)
{
// Reading from the write port triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF);
if(bankLocked())
return value;
else
{
triggerReadFromWritePort(peekAddress);
return myRAM[address] = value;
}
}
else
return myImage[(myCurrentBank << 12) + address];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBFSC::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0F80) && (address <= 0x0FBF))
bank(address - 0x0F80);
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBFSC::bank(uInt16 bank)
{
if(bankLocked()) return false;
// Remember what bank we're in
myCurrentBank = bank;
uInt32 offset = myCurrentBank << 12;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1F80 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1100; address < (0x1F80U & ~mask);
address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeBFSC::bank() const
{
return myCurrentBank;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeBFSC::bankCount() const
{
return 64;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBFSC::patch(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
if(address < 0x0100)
{
// Normally, a write to the read port won't do anything
// However, the patch command is special in that ignores such
// cart restrictions
myRAM[address & 0x007F] = value;
}
else
myImage[(myCurrentBank << 12) + address] = value;
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* CartridgeBFSC::getImage(int& size) const
{
size = 256*1024;
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBFSC::save(Serializer& out) const
{
try
{
out.putString(name());
out.putShort(myCurrentBank);
out.putByteArray(myRAM, 128);
}
catch(...)
{
cerr << "ERROR: CartridgeBFSC::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeBFSC::load(Serializer& in)
{
try
{
if(in.getString() != name())
return false;
myCurrentBank = in.getShort();
in.getByteArray(myRAM, 128);
}
catch(...)
{
cerr << "ERROR: CartridgeBFSC::load" << endl;
return false;
}
// Remember what bank we were in
bank(myCurrentBank);
return true;
}

168
src/emucore/CartBFSC.hxx Normal file
View File

@ -0,0 +1,168 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEBFSC_HXX
#define CARTRIDGEBFSC_HXX
class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "CartBFSCWidget.hxx"
#endif
/**
There are 32 4K banks (total of 128K ROM) with 128 bytes of RAM.
Accessing $1FD0 - $1FEF switches to each bank.
@author Stephen Anthony
@version $Id$
*/
class CartridgeBFSC : public Cartridge
{
friend class CartridgeBFSCWidget;
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 settings A reference to the various settings (read-only)
*/
CartridgeBFSC(const uInt8* image, uInt32 size, const Settings& settings);
/**
Destructor
*/
virtual ~CartridgeBFSC();
public:
/**
Reset device to its power-on state
*/
void reset();
/**
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);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
bool bank(uInt16 bank);
/**
Get the current bank.
*/
uInt16 bank() const;
/**
Query the number of banks supported by the cartridge.
*/
uInt16 bankCount() const;
/**
Patch the cartridge ROM.
@param address The ROM address to patch
@param value The value to place into the address
@return Success or failure of the patch operation
*/
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
const uInt8* getImage(int& size) const;
/**
Save the current state of this cart to the given Serializer.
@param out The Serializer object to use
@return False on any errors, else true
*/
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@param in The Serializer object to use
@return False on any errors, else true
*/
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const { return "CartridgeBFSC"; }
#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)
{
return new CartridgeBFSCWidget(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);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;
// The 64K ROM image of the cartridge
uInt8 myImage[131072*2];
// The 128 bytes of RAM
uInt8 myRAM[128];
};
#endif

180
src/emucore/CartDF.cxx Normal file
View File

@ -0,0 +1,180 @@
//============================================================================
//
// 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-2013 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 <cassert>
#include <cstring>
#include "System.hxx"
#include "CartDF.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDF::CartridgeDF(const uInt8* image, uInt32 size, const Settings& settings)
: Cartridge(settings)
{
// Copy the ROM image into my buffer
memcpy(myImage, image, BSPF_min(131072u, size));
createCodeAccessBase(131072);
// Remember startup bank
myStartBank = 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDF::~CartridgeDF()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDF::reset()
{
// Upon reset we switch to the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDF::install(System& system)
{
mySystem = &system;
// Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mySystem->pageMask()) == 0);
// Install pages for the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeDF::peek(uInt16 address)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0FC0) && (address <= 0x0FDF))
bank(address - 0x0FC0);
return myImage[(myCurrentBank << 12) + address];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDF::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0FC0) && (address <= 0x0FDF))
bank(address - 0x0FC0);
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDF::bank(uInt16 bank)
{
if(bankLocked()) return false;
// Remember what bank we're in
myCurrentBank = bank;
uInt32 offset = myCurrentBank << 12;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FC0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FC0U & ~mask);
address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDF::bank() const
{
return myCurrentBank;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDF::bankCount() const
{
return 32;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDF::patch(uInt16 address, uInt8 value)
{
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value;
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* CartridgeDF::getImage(int& size) const
{
size = 131072;
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDF::save(Serializer& out) const
{
try
{
out.putString(name());
out.putShort(myCurrentBank);
}
catch(...)
{
cerr << "ERROR: CartridgeDF::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDF::load(Serializer& in)
{
try
{
if(in.getString() != name())
return false;
myCurrentBank = in.getShort();
}
catch(...)
{
cerr << "ERROR: CartridgeDF::load" << endl;
return false;
}
// Remember what bank we were in
bank(myCurrentBank);
return true;
}

166
src/emucore/CartDF.hxx Normal file
View File

@ -0,0 +1,166 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEDF_HXX
#define CARTRIDGEDF_HXX
class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "CartDFWidget.hxx"
#endif
/**
Update of EF cartridge class used for Homestar Runner by Paul Slocum.
There are 32 4K banks (total of 128K ROM).
Accessing $1FC0 - $1FDF switches to each bank.
@author Mike Saarna
@version $Id$
*/
class CartridgeDF : public Cartridge
{
friend class CartridgeDFWidget;
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 settings A reference to the various settings (read-only)
*/
CartridgeDF(const uInt8* image, uInt32 size, const Settings& settings);
/**
Destructor
*/
virtual ~CartridgeDF();
public:
/**
Reset device to its power-on state
*/
void reset();
/**
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);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
bool bank(uInt16 bank);
/**
Get the current bank.
*/
uInt16 bank() const;
/**
Query the number of banks supported by the cartridge.
*/
uInt16 bankCount() const;
/**
Patch the cartridge ROM.
@param address The ROM address to patch
@param value The value to place into the address
@return Success or failure of the patch operation
*/
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
const uInt8* getImage(int& size) const;
/**
Save the current state of this cart to the given Serializer.
@param out The Serializer object to use
@return False on any errors, else true
*/
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@param in The Serializer object to use
@return False on any errors, else true
*/
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const { return "CartridgeDF"; }
#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)
{
return new CartridgeDFWidget(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);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;
// The 64K ROM image of the cartridge
uInt8 myImage[131072];
};
#endif

244
src/emucore/CartDFSC.cxx Normal file
View File

@ -0,0 +1,244 @@
//============================================================================
//
// 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-2013 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 <cassert>
#include <cstring>
#include "System.hxx"
#include "CartDFSC.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDFSC::CartridgeDFSC(const uInt8* image, uInt32 size, const Settings& settings)
: Cartridge(settings)
{
// Copy the ROM image into my buffer
memcpy(myImage, image, BSPF_min(131072u, size));
createCodeAccessBase(131072);
// This cart contains 128 bytes extended RAM @ 0x1000
registerRamArea(0x1000, 128, 0x80, 0x00);
// Remember startup bank
myStartBank = 15;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDFSC::~CartridgeDFSC()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFSC::reset()
{
// Initialize RAM
if(mySettings.getBool("ramrandom"))
for(uInt32 i = 0; i < 128; ++i)
myRAM[i] = mySystem->randGenerator().next();
else
memset(myRAM, 0, 128);
// Upon reset we switch to the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFSC::install(System& system)
{
mySystem = &system;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0);
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing method for the RAM writing pages
access.type = System::PA_WRITE;
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPokeBase = &myRAM[j & 0x007F];
access.codeAccessBase = &myCodeAccessBase[j & 0x007F];
mySystem->setPageAccess(j >> shift, access);
}
// Set the page accessing method for the RAM reading pages
access.directPokeBase = 0;
access.type = System::PA_READ;
for(uInt32 k = 0x1080; k < 0x1100; k += (1 << shift))
{
access.directPeekBase = &myRAM[k & 0x007F];
access.codeAccessBase = &myCodeAccessBase[0x80 + (k & 0x007F)];
mySystem->setPageAccess(k >> shift, access);
}
// Install pages for the startup bank
bank(myStartBank);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeDFSC::peek(uInt16 address)
{
uInt16 peekAddress = address;
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0FC0) && (address <= 0x0FDF))
bank(address - 0x0FC0);
if(address < 0x0080) // Write port is at 0xF000 - 0xF080 (128 bytes)
{
// Reading from the write port triggers an unwanted write
uInt8 value = mySystem->getDataBusState(0xFF);
if(bankLocked())
return value;
else
{
triggerReadFromWritePort(peekAddress);
return myRAM[address] = value;
}
}
else
return myImage[(myCurrentBank << 12) + address];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDFSC::poke(uInt16 address, uInt8)
{
address &= 0x0FFF;
// Switch banks if necessary
if((address >= 0x0FC0) && (address <= 0x0FDF))
bank(address - 0x0FC0);
// NOTE: This does not handle accessing RAM, however, this function
// should never be called for RAM because of the way page accessing
// has been setup
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDFSC::bank(uInt16 bank)
{
if(bankLocked()) return false;
// Remember what bank we're in
myCurrentBank = bank;
uInt32 offset = myCurrentBank << 12;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
System::PageAccess access(0, 0, 0, this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FC0 & ~mask); i < 0x2000; i += (1 << shift))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> shift, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1100; address < (0x1FC0U & ~mask);
address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDFSC::bank() const
{
return myCurrentBank;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDFSC::bankCount() const
{
return 32;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDFSC::patch(uInt16 address, uInt8 value)
{
address &= 0x0FFF;
if(address < 0x0100)
{
// Normally, a write to the read port won't do anything
// However, the patch command is special in that ignores such
// cart restrictions
myRAM[address & 0x007F] = value;
}
else
myImage[(myCurrentBank << 12) + address] = value;
return myBankChanged = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* CartridgeDFSC::getImage(int& size) const
{
size = 131072;
return myImage;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDFSC::save(Serializer& out) const
{
try
{
out.putString(name());
out.putShort(myCurrentBank);
out.putByteArray(myRAM, 128);
}
catch(...)
{
cerr << "ERROR: CartridgeDFSC::save" << endl;
return false;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDFSC::load(Serializer& in)
{
try
{
if(in.getString() != name())
return false;
myCurrentBank = in.getShort();
in.getByteArray(myRAM, 128);
}
catch(...)
{
cerr << "ERROR: CartridgeDFSC::load" << endl;
return false;
}
// Remember what bank we were in
bank(myCurrentBank);
return true;
}

168
src/emucore/CartDFSC.hxx Normal file
View File

@ -0,0 +1,168 @@
//============================================================================
//
// 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-2013 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 CARTRIDGEDFSC_HXX
#define CARTRIDGEDFSC_HXX
class System;
#include "bspf.hxx"
#include "Cart.hxx"
#ifdef DEBUGGER_SUPPORT
#include "CartDFSCWidget.hxx"
#endif
/**
There are 32 4K banks (total of 128K ROM) with 128 bytes of RAM.
Accessing $1FD0 - $1FEF switches to each bank.
@author Stephen Anthony
@version $Id$
*/
class CartridgeDFSC : public Cartridge
{
friend class CartridgeDFSCWidget;
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 settings A reference to the various settings (read-only)
*/
CartridgeDFSC(const uInt8* image, uInt32 size, const Settings& settings);
/**
Destructor
*/
virtual ~CartridgeDFSC();
public:
/**
Reset device to its power-on state
*/
void reset();
/**
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);
/**
Install pages for the specified bank in the system.
@param bank The bank that should be installed in the system
*/
bool bank(uInt16 bank);
/**
Get the current bank.
*/
uInt16 bank() const;
/**
Query the number of banks supported by the cartridge.
*/
uInt16 bankCount() const;
/**
Patch the cartridge ROM.
@param address The ROM address to patch
@param value The value to place into the address
@return Success or failure of the patch operation
*/
bool patch(uInt16 address, uInt8 value);
/**
Access the internal ROM image for this cartridge.
@param size Set to the size of the internal ROM image data
@return A pointer to the internal ROM image data
*/
const uInt8* getImage(int& size) const;
/**
Save the current state of this cart to the given Serializer.
@param out The Serializer object to use
@return False on any errors, else true
*/
bool save(Serializer& out) const;
/**
Load the current state of this cart from the given Serializer.
@param in The Serializer object to use
@return False on any errors, else true
*/
bool load(Serializer& in);
/**
Get a descriptor for the device name (used in error checking).
@return The name of the object
*/
string name() const { return "CartridgeDFSC"; }
#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)
{
return new CartridgeDFSCWidget(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);
/**
Change the byte at the specified address to the given value
@param address The address where the value should be stored
@param value The value to be stored at the address
@return True if the poke changed the device address space, else false
*/
bool poke(uInt16 address, uInt8 value);
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;
// The 64K ROM image of the cartridge
uInt8 myImage[131072];
// The 128 bytes of RAM
uInt8 myRAM[128];
};
#endif

View File

@ -10,6 +10,7 @@ MODULE_OBJS := \
src/emucore/Cart3F.o \
src/emucore/Cart4A50.o \
src/emucore/Cart4K.o \
src/emucore/Cart4KSC.o \
src/emucore/CartAR.o \
src/emucore/CartCM.o \
src/emucore/CartCTY.o \
@ -20,6 +21,10 @@ MODULE_OBJS := \
src/emucore/CartE7.o \
src/emucore/CartEF.o \
src/emucore/CartEFSC.o \
src/emucore/CartBF.o \
src/emucore/CartBFSC.o \
src/emucore/CartDF.o \
src/emucore/CartDFSC.o \
src/emucore/CartF0.o \
src/emucore/CartF4.o \
src/emucore/CartF4SC.o \

View File

@ -146,9 +146,14 @@ GameInfoDialog::GameInfoDialog(
items.push_back("3F (512K Tigervision)", "3F" );
items.push_back("4A50 (64K 4A50 + ram)", "4A50" );
items.push_back("4K (4K Atari)", "4K" );
items.push_back("4KSC (CPUWIZ 4K + ram)", "4KSC" );
items.push_back("AR (Supercharger)", "AR" );
items.push_back("BF (CPUWIZ 256K)", "BF" );
items.push_back("BFSC (CPUWIZ 256K + ram)", "BFSC" );
items.push_back("CV (Commavid extra ram)", "CV" );
items.push_back("CM (SpectraVideo CompuMate)", "CM" );
items.push_back("DF (CPUWIZ 128K)", "DF" );
items.push_back("DFSC (CPUWIZ 128K + ram)", "DFSC" );
items.push_back("DPC (Pitfall II)", "DPC" );
items.push_back("DPC+ (Enhanced DPC)", "DPC+" );
items.push_back("E0 (8K Parker Bros)", "E0" );

View File

@ -77,9 +77,14 @@ GlobalPropsDialog::GlobalPropsDialog(GuiObject* boss, const GUI::Font& font)
items.push_back("3F (512K Tigervision)", "3F" );
items.push_back("4A50 (64K 4A50 + ram)", "4A50" );
items.push_back("4K (4K Atari)", "4K" );
items.push_back("4KSC (CPUWIZ 4K + ram)", "4KSC" );
items.push_back("AR (Supercharger)", "AR" );
items.push_back("BF (CPUWIZ 256K)", "BF" );
items.push_back("BFSC (CPUWIZ 256K + ram)", "BFSC" );
items.push_back("CV (Commavid extra ram)", "CV" );
items.push_back("CM (SpectraVideo CompuMate)", "CM" );
items.push_back("DF (CPUWIZ 128K)", "DF" );
items.push_back("DFSC (CPUWIZ 128K + ram)", "DFSC" );
items.push_back("DPC (Pitfall II)", "DPC" );
items.push_back("DPC+ (Enhanced DPC)", "DPC+" );
items.push_back("E0 (8K Parker Bros)", "E0" );

View File

@ -40,11 +40,15 @@ int searchForBytes(const uInt8* image, uInt32 imagesize,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int ac, char* av[])
{
if(ac != 3)
int offset = 0;
if(ac < 3)
{
cout << "usage: " << av[0] << " <filename> <hex pattern>\n";
cout << "usage: " << av[0] << " <filename> <hex pattern> [start address]\n";
exit(0);
}
if(ac > 3)
offset = atoi(av[3]);
ifstream in(av[1], ios_base::binary);
in.seekg(0, ios::end);
@ -68,12 +72,12 @@ int main(int ac, char* av[])
// cerr << "sig size = " << hex << s_size << endl;
list<int> locations;
int result = searchForBytes(image, i_size, sig, s_size, locations);
int result = searchForBytes(image+offset, i_size-offset, sig, s_size, locations);
if(result > 0)
{
cout << setw(3) << result << " hits: \'" << av[2] << "\' - \"" << av[1] << "\" @";
for(list<int>::iterator it = locations.begin(); it != locations.end(); ++it)
cout << ' ' << hex << (int)*it;
cout << ' ' << hex << ((int)*it + offset);
cout << endl;
}