mirror of https://github.com/stella-emu/stella.git
Some updates to the last BUS/CDF commit:
- update some code to the '5.0' way of doing things - allow compilation in Linux - whitespace/tab fixes to match main codebase - add some extra comments - test compile under gcc 6 and clang 5, and fix some warnings
This commit is contained in:
parent
7c6821dfcb
commit
95c7b30a45
|
@ -1,20 +1,18 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// SSSS tt lll lll
|
// SSSS tt lll lll
|
||||||
// SS SS tt ll ll
|
// SS SS tt ll ll
|
||||||
// SS tttttt eeee ll ll aaaa
|
// SS tttttt eeee ll ll aaaa
|
||||||
// SSSS tt ee ee ll ll aa
|
// SSSS tt ee ee ll ll aa
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartBUSWidget.cxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartBUS.hxx"
|
#include "CartBUS.hxx"
|
||||||
|
@ -76,7 +74,7 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Datastream Pointers: ", kTextAlignLeft);
|
myFontHeight, "Datastream Pointers: ", kTextAlignLeft);
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myDatastreamPointers = new DataGridWidget(boss, _nfont, 0, ypos+myLineHeight-2, 4, 4, 6, 32, Common::Base::F_16_3_2);
|
myDatastreamPointers = new DataGridWidget(boss, _nfont, 0, ypos+myLineHeight-2, 4, 4, 6, 32, Common::Base::F_16_3_2);
|
||||||
myDatastreamPointers->setTarget(this);
|
myDatastreamPointers->setTarget(this);
|
||||||
myDatastreamPointers->setEditable(false);
|
myDatastreamPointers->setEditable(false);
|
||||||
|
@ -85,20 +83,20 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
xpos = 0 + myDatastreamPointers->getWidth();
|
xpos = 0 + myDatastreamPointers->getWidth();
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Datastream Increments: ", kTextAlignLeft);
|
myFontHeight, "Datastream Increments: ", kTextAlignLeft);
|
||||||
|
|
||||||
myDatastreamIncrements = new DataGridWidget(boss, _nfont, xpos, ypos+myLineHeight-2, 4, 4, 5, 32, Common::Base::F_16_2_2);
|
myDatastreamIncrements = new DataGridWidget(boss, _nfont, xpos, ypos+myLineHeight-2, 4, 4, 5, 32, Common::Base::F_16_2_2);
|
||||||
myDatastreamIncrements->setTarget(this);
|
myDatastreamIncrements->setTarget(this);
|
||||||
myDatastreamIncrements->setEditable(false);
|
myDatastreamIncrements->setEditable(false);
|
||||||
|
|
||||||
// Datastream Maps
|
// Datastream Maps
|
||||||
xpos = 0; ypos += myLineHeight*5 + 4;
|
xpos = 0; ypos += myLineHeight*5 + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Address Maps: ", kTextAlignLeft);
|
myFontHeight, "Address Maps: ", kTextAlignLeft);
|
||||||
|
|
||||||
myAddressMaps = new DataGridWidget(boss, _nfont, 0, ypos+myLineHeight-2, 8, 5, 8, 32, Common::Base::F_16_8);
|
myAddressMaps = new DataGridWidget(boss, _nfont, 0, ypos+myLineHeight-2, 8, 5, 8, 32, Common::Base::F_16_8);
|
||||||
myAddressMaps->setTarget(this);
|
myAddressMaps->setTarget(this);
|
||||||
myAddressMaps->setEditable(false);
|
myAddressMaps->setEditable(false);
|
||||||
|
|
||||||
// Music counters
|
// Music counters
|
||||||
xpos = 10; ypos += myLineHeight*6 + 4;
|
xpos = 10; ypos += myLineHeight*6 + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
|
@ -138,8 +136,8 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
myMusicWaveformSizes = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 4, 16, Common::Base::F_16_2);
|
myMusicWaveformSizes = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 4, 16, Common::Base::F_16_2);
|
||||||
myMusicWaveformSizes->setTarget(this);
|
myMusicWaveformSizes->setTarget(this);
|
||||||
myMusicWaveformSizes->setEditable(false);
|
myMusicWaveformSizes->setEditable(false);
|
||||||
|
|
||||||
|
|
||||||
// BUS stuff and ZP STY flags
|
// BUS stuff and ZP STY flags
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 10; ypos += myLineHeight + 4;
|
||||||
myBusOverdrive = new CheckboxWidget(boss, _font, xpos, ypos, "BUS Overdrive enabled");
|
myBusOverdrive = new CheckboxWidget(boss, _font, xpos, ypos, "BUS Overdrive enabled");
|
||||||
|
@ -149,7 +147,6 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
myZPSTY = new CheckboxWidget(boss, _font, xpos, ypos, "Zero Page STY");
|
myZPSTY = new CheckboxWidget(boss, _font, xpos, ypos, "Zero Page STY");
|
||||||
myZPSTY->setTarget(this);
|
myZPSTY->setTarget(this);
|
||||||
myZPSTY->setEditable(false);
|
myZPSTY->setEditable(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -177,7 +174,7 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// I = Increment
|
// I = Increment
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
myOldState.datastreampointers.push_back(myCart.getDatastreamPointer(i)>>12);
|
myOldState.datastreampointers.push_back(myCart.getDatastreamPointer(i)>>12);
|
||||||
myOldState.datastreamincrements.push_back(myCart.getDatastreamIncrement(i));
|
myOldState.datastreamincrements.push_back(myCart.getDatastreamIncrement(i));
|
||||||
}
|
}
|
||||||
|
@ -186,7 +183,7 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
{
|
{
|
||||||
myOldState.addressmaps.push_back(myCart.getAddressMap(i));
|
myOldState.addressmaps.push_back(myCart.getAddressMap(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 3; ++i)
|
for(uInt32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
myOldState.mcounters.push_back(myCart.myMusicCounters[i]);
|
myOldState.mcounters.push_back(myCart.myMusicCounters[i]);
|
||||||
|
@ -198,7 +195,7 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
myOldState.mwaves.push_back(myCart.getWaveform(i) >> 5);
|
myOldState.mwaves.push_back(myCart.getWaveform(i) >> 5);
|
||||||
myOldState.mwavesizes.push_back(myCart.getWaveformSize((i)));
|
myOldState.mwavesizes.push_back(myCart.getWaveformSize((i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||||
myOldState.internalram.push_back(myCart.myBUSRAM[i]);
|
myOldState.internalram.push_back(myCart.myBUSRAM[i]);
|
||||||
}
|
}
|
||||||
|
@ -225,8 +222,8 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// I = Increment
|
// I = Increment
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
uInt32 pointervalue = myCart.getDatastreamPointer(i) >> 12;
|
Int32 pointervalue = myCart.getDatastreamPointer(i) >> 12;
|
||||||
alist.push_back(0); vlist.push_back(pointervalue);
|
alist.push_back(0); vlist.push_back(pointervalue);
|
||||||
changed.push_back(pointervalue != myOldState.datastreampointers[i]);
|
changed.push_back(pointervalue != myOldState.datastreampointers[i]);
|
||||||
}
|
}
|
||||||
|
@ -235,21 +232,21 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 16; ++i)
|
for(int i = 0; i < 16; ++i)
|
||||||
{
|
{
|
||||||
uInt32 incrementvalue = myCart.getDatastreamIncrement(i);
|
Int32 incrementvalue = myCart.getDatastreamIncrement(i);
|
||||||
alist.push_back(0); vlist.push_back(incrementvalue);
|
alist.push_back(0); vlist.push_back(incrementvalue);
|
||||||
changed.push_back(incrementvalue != myOldState.datastreamincrements[i]);
|
changed.push_back(incrementvalue != myOldState.datastreamincrements[i]);
|
||||||
}
|
}
|
||||||
myDatastreamIncrements->setList(alist, vlist, changed);
|
myDatastreamIncrements->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 40; ++i)
|
for(int i = 0; i < 40; ++i)
|
||||||
{
|
{
|
||||||
uInt32 mapvalue = myCart.getAddressMap(i);
|
Int32 mapvalue = myCart.getAddressMap(i);
|
||||||
alist.push_back(0); vlist.push_back(mapvalue);
|
alist.push_back(0); vlist.push_back(mapvalue);
|
||||||
changed.push_back(mapvalue != myOldState.addressmaps[i]);
|
changed.push_back(mapvalue != myOldState.addressmaps[i]);
|
||||||
}
|
}
|
||||||
myAddressMaps->setList(alist, vlist, changed);
|
myAddressMaps->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
|
@ -270,7 +267,7 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(0); vlist.push_back(myCart.getWaveform(i) >> 5);
|
alist.push_back(0); vlist.push_back(myCart.getWaveform(i) >> 5);
|
||||||
changed.push_back((myCart.getWaveform(i) >> 5) != myOldState.mwaves[i]);
|
changed.push_back((myCart.getWaveform(i) >> 5) != uInt32(myOldState.mwaves[i]));
|
||||||
}
|
}
|
||||||
myMusicWaveforms->setList(alist, vlist, changed);
|
myMusicWaveforms->setList(alist, vlist, changed);
|
||||||
|
|
||||||
|
@ -278,10 +275,10 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(0); vlist.push_back(myCart.getWaveformSize(i));
|
alist.push_back(0); vlist.push_back(myCart.getWaveformSize(i));
|
||||||
changed.push_back((myCart.getWaveformSize(i)) != myOldState.mwavesizes[i]);
|
changed.push_back((myCart.getWaveformSize(i)) != uInt32(myOldState.mwavesizes[i]));
|
||||||
}
|
}
|
||||||
myMusicWaveformSizes->setList(alist, vlist, changed);
|
myMusicWaveformSizes->setList(alist, vlist, changed);
|
||||||
|
|
||||||
myBusOverdrive->setState(myCart.getBusStuffFlag());
|
myBusOverdrive->setState(myCart.getBusStuffFlag());
|
||||||
myZPSTY->setState(myCart.mySTYZeroPage);
|
myZPSTY->setState(myCart.mySTYZeroPage);
|
||||||
|
|
||||||
|
@ -290,7 +287,7 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUSWidget::handleCommand(CommandSender* sender,
|
void CartridgeBUSWidget::handleCommand(CommandSender* sender,
|
||||||
int cmd, int data, int id)
|
int cmd, int data, int id)
|
||||||
{
|
{
|
||||||
if(cmd == kBankChanged)
|
if(cmd == kBankChanged)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +313,7 @@ string CartridgeBUSWidget::bankState()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeBUSWidget::internalRamSize()
|
uInt32 CartridgeBUSWidget::internalRamSize()
|
||||||
{
|
{
|
||||||
return 8*1024;
|
return 8*1024;
|
||||||
}
|
}
|
||||||
|
@ -328,7 +325,7 @@ uInt32 CartridgeBUSWidget::internalRamRPort(int start)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string CartridgeBUSWidget::internalRamDescription()
|
string CartridgeBUSWidget::internalRamDescription()
|
||||||
{
|
{
|
||||||
ostringstream desc;
|
ostringstream desc;
|
||||||
desc << "$0000 - $07FF - BUS driver\n"
|
desc << "$0000 - $07FF - BUS driver\n"
|
||||||
|
@ -338,7 +335,7 @@ string CartridgeBUSWidget::internalRamDescription()
|
||||||
<< " via BUS's Data Stream registers\n"
|
<< " via BUS's Data Stream registers\n"
|
||||||
<< "$1800 - $1FFF - 2K C variable storage and stack\n"
|
<< "$1800 - $1FFF - 2K C variable storage and stack\n"
|
||||||
<< " not accessible to 6507";
|
<< " not accessible to 6507";
|
||||||
|
|
||||||
return desc.str();
|
return desc.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// SSSS tt lll lll
|
// SSSS tt lll lll
|
||||||
// SS SS tt ll ll
|
// SS SS tt ll ll
|
||||||
// SS tttttt eeee ll ll aaaa
|
// SS tttttt eeee ll ll aaaa
|
||||||
// SSSS tt ee ee ll ll aa
|
// SSSS tt ee ee ll ll aa
|
||||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartBUSWidget.hxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef CARTRIDGEBUS_WIDGET_HXX
|
#ifndef CARTRIDGEBUS_WIDGET_HXX
|
||||||
|
@ -31,10 +29,10 @@ class CartridgeBUSWidget : public CartDebugWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeBUSWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeBUSWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
const GUI::Font& nfont,
|
const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h,
|
int x, int y, int w, int h,
|
||||||
CartridgeBUS& cart);
|
CartridgeBUS& cart);
|
||||||
virtual ~CartridgeBUSWidget() { }
|
virtual ~CartridgeBUSWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CartState {
|
struct CartState {
|
||||||
|
@ -67,14 +65,14 @@ class CartridgeBUSWidget : public CartDebugWidget
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
enum { kBankChanged = 'bkCH' };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
void saveOldState() override;
|
||||||
|
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
string bankState() override;
|
string bankState() override;
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
// start of functions for Cartridge RAM tab
|
||||||
uInt32 internalRamSize() override;
|
uInt32 internalRamSize() override;
|
||||||
uInt32 internalRamRPort(int start) override;
|
uInt32 internalRamRPort(int start) override;
|
||||||
|
@ -84,7 +82,7 @@ private:
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
void internalRamSetValue(int addr, uInt8 value) override;
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
uInt8 internalRamGetValue(int addr) override;
|
||||||
// end of functions for Cartridge RAM tab
|
// end of functions for Cartridge RAM tab
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeBUSWidget() = delete;
|
CartridgeBUSWidget() = delete;
|
||||||
CartridgeBUSWidget(const CartridgeBUSWidget&) = delete;
|
CartridgeBUSWidget(const CartridgeBUSWidget&) = delete;
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartCDFWidget.cxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "CartCDF.hxx"
|
#include "CartCDF.hxx"
|
||||||
|
@ -24,13 +22,13 @@
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeCDFWidget::CartridgeCDFWidget(
|
CartridgeCDFWidget::CartridgeCDFWidget(
|
||||||
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h, CartridgeCDF& cart)
|
int x, int y, int w, int h, CartridgeCDF& cart)
|
||||||
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
: CartDebugWidget(boss, lfont, nfont, x, y, w, h),
|
||||||
myCart(cart)
|
myCart(cart)
|
||||||
{
|
{
|
||||||
uInt16 size = 8 * 4096;
|
uInt16 size = 8 * 4096;
|
||||||
|
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "CDF Stuffing cartridge\n"
|
info << "CDF Stuffing cartridge\n"
|
||||||
<< "32K ROM, seven 4K banks are accessible to 2600\n"
|
<< "32K ROM, seven 4K banks are accessible to 2600\n"
|
||||||
|
@ -38,7 +36,7 @@ myCart(cart)
|
||||||
<< "CDF registers accessible @ $F000 - $F03F\n"
|
<< "CDF registers accessible @ $F000 - $F03F\n"
|
||||||
<< "Banks accessible at hotspots $FF5 to $FFB\n"
|
<< "Banks accessible at hotspots $FF5 to $FFB\n"
|
||||||
<< "Startup bank = " << cart.myStartBank << "\n";
|
<< "Startup bank = " << cart.myStartBank << "\n";
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Eventually, we should query this from the debugger/disassembler
|
// Eventually, we should query this from the debugger/disassembler
|
||||||
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < 7; ++i, offset += 0x1000)
|
for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < 7; ++i, offset += 0x1000)
|
||||||
|
@ -49,11 +47,11 @@ myCart(cart)
|
||||||
<< "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
|
<< "$" << (start + 0xFFF) << " (hotspot = $" << (spot+i) << ")\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int xpos = 10,
|
int xpos = 10,
|
||||||
ypos = addBaseInformation(size, "AtariAge", info.str()) +
|
ypos = addBaseInformation(size, "AtariAge", info.str()) +
|
||||||
myLineHeight;
|
myLineHeight;
|
||||||
|
|
||||||
VariantList items;
|
VariantList items;
|
||||||
VarList::push_back(items, "0 ($FF5)");
|
VarList::push_back(items, "0 ($FF5)");
|
||||||
VarList::push_back(items, "1 ($FF6)");
|
VarList::push_back(items, "1 ($FF6)");
|
||||||
|
@ -68,68 +66,68 @@ myCart(cart)
|
||||||
_font.getStringWidth("Set bank: "), kBankChanged);
|
_font.getStringWidth("Set bank: "), kBankChanged);
|
||||||
myBank->setTarget(this);
|
myBank->setTarget(this);
|
||||||
addFocusWidget(myBank);
|
addFocusWidget(myBank);
|
||||||
|
|
||||||
int lwidth = _font.getStringWidth("Datastream Increments: "); // get width of the widest label
|
int lwidth = _font.getStringWidth("Datastream Increments: "); // get width of the widest label
|
||||||
|
|
||||||
// Datastream Pointers
|
// Datastream Pointers
|
||||||
xpos = 0; ypos += myLineHeight + 4;
|
xpos = 0; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Datastream Pointers: ", kTextAlignLeft);
|
myFontHeight, "Datastream Pointers: ", kTextAlignLeft);
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myDatastreamPointers = new DataGridWidget(boss, _nfont, 0, ypos+myLineHeight-2, 4, 8, 6, 32, Common::Base::F_16_3_2);
|
myDatastreamPointers = new DataGridWidget(boss, _nfont, 0, ypos+myLineHeight-2, 4, 8, 6, 32, Common::Base::F_16_3_2);
|
||||||
myDatastreamPointers->setTarget(this);
|
myDatastreamPointers->setTarget(this);
|
||||||
myDatastreamPointers->setEditable(false);
|
myDatastreamPointers->setEditable(false);
|
||||||
|
|
||||||
// Datastream Increments
|
// Datastream Increments
|
||||||
xpos = 0 + myDatastreamPointers->getWidth();
|
xpos = 0 + myDatastreamPointers->getWidth();
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Datastream Increments: ", kTextAlignLeft);
|
myFontHeight, "Datastream Increments: ", kTextAlignLeft);
|
||||||
|
|
||||||
myDatastreamIncrements = new DataGridWidget(boss, _nfont, xpos, ypos+myLineHeight-2, 4, 8, 5, 32, Common::Base::F_16_2_2);
|
myDatastreamIncrements = new DataGridWidget(boss, _nfont, xpos, ypos+myLineHeight-2, 4, 8, 5, 32, Common::Base::F_16_2_2);
|
||||||
myDatastreamIncrements->setTarget(this);
|
myDatastreamIncrements->setTarget(this);
|
||||||
myDatastreamIncrements->setEditable(false);
|
myDatastreamIncrements->setEditable(false);
|
||||||
|
|
||||||
// Music counters
|
// Music counters
|
||||||
xpos = 10; ypos += myLineHeight*10 + 4;
|
xpos = 10; ypos += myLineHeight*10 + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Music Counters: ", kTextAlignLeft);
|
myFontHeight, "Music Counters: ", kTextAlignLeft);
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myMusicCounters = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 8, 32, Common::Base::F_16_8);
|
myMusicCounters = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 8, 32, Common::Base::F_16_8);
|
||||||
myMusicCounters->setTarget(this);
|
myMusicCounters->setTarget(this);
|
||||||
myMusicCounters->setEditable(false);
|
myMusicCounters->setEditable(false);
|
||||||
|
|
||||||
// Music frequencies
|
// Music frequencies
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 10; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Music Frequencies: ", kTextAlignLeft);
|
myFontHeight, "Music Frequencies: ", kTextAlignLeft);
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myMusicFrequencies = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 8, 32, Common::Base::F_16_8);
|
myMusicFrequencies = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 8, 32, Common::Base::F_16_8);
|
||||||
myMusicFrequencies->setTarget(this);
|
myMusicFrequencies->setTarget(this);
|
||||||
myMusicFrequencies->setEditable(false);
|
myMusicFrequencies->setEditable(false);
|
||||||
|
|
||||||
// Music waveforms
|
// Music waveforms
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 10; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Music Waveforms: ", kTextAlignLeft);
|
myFontHeight, "Music Waveforms: ", kTextAlignLeft);
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myMusicWaveforms = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 4, 16, Common::Base::F_16_2);
|
myMusicWaveforms = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 4, 16, Common::Base::F_16_2);
|
||||||
myMusicWaveforms->setTarget(this);
|
myMusicWaveforms->setTarget(this);
|
||||||
myMusicWaveforms->setEditable(false);
|
myMusicWaveforms->setEditable(false);
|
||||||
|
|
||||||
// Music waveform sizes
|
// Music waveform sizes
|
||||||
xpos = 10; ypos += myLineHeight + 4;
|
xpos = 10; ypos += myLineHeight + 4;
|
||||||
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
new StaticTextWidget(boss, _font, xpos, ypos, lwidth,
|
||||||
myFontHeight, "Music Waveform Sizes: ", kTextAlignLeft);
|
myFontHeight, "Music Waveform Sizes: ", kTextAlignLeft);
|
||||||
xpos += lwidth;
|
xpos += lwidth;
|
||||||
|
|
||||||
myMusicWaveformSizes = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 4, 16, Common::Base::F_16_2);
|
myMusicWaveformSizes = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 4, 16, Common::Base::F_16_2);
|
||||||
myMusicWaveformSizes->setTarget(this);
|
myMusicWaveformSizes->setTarget(this);
|
||||||
myMusicWaveformSizes->setEditable(false);
|
myMusicWaveformSizes->setEditable(false);
|
||||||
|
|
||||||
// done differently than in DPC+, need to rethink debugger support
|
// done differently than in DPC+, need to rethink debugger support
|
||||||
// // Fast fetch and immediate mode LDA flags
|
// // Fast fetch and immediate mode LDA flags
|
||||||
// xpos = 10; ypos += myLineHeight + 4;
|
// xpos = 10; ypos += myLineHeight + 4;
|
||||||
|
@ -155,7 +153,7 @@ void CartridgeCDFWidget::saveOldState()
|
||||||
myOldState.mwaves.clear();
|
myOldState.mwaves.clear();
|
||||||
myOldState.mwavesizes.clear();
|
myOldState.mwavesizes.clear();
|
||||||
myOldState.internalram.clear();
|
myOldState.internalram.clear();
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 32; i++)
|
for(uInt32 i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
// Pointers are stored as:
|
// Pointers are stored as:
|
||||||
|
@ -167,23 +165,23 @@ void CartridgeCDFWidget::saveOldState()
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// I = Increment
|
// I = Increment
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
myOldState.datastreampointers.push_back(myCart.getDatastreamPointer(i)>>12);
|
myOldState.datastreampointers.push_back(myCart.getDatastreamPointer(i)>>12);
|
||||||
myOldState.datastreamincrements.push_back(myCart.getDatastreamIncrement(i));
|
myOldState.datastreamincrements.push_back(myCart.getDatastreamIncrement(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 3; ++i)
|
for(uInt32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
myOldState.mcounters.push_back(myCart.myMusicCounters[i]);
|
myOldState.mcounters.push_back(myCart.myMusicCounters[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 3; ++i)
|
for(uInt32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
myOldState.mfreqs.push_back(myCart.myMusicFrequencies[i]);
|
myOldState.mfreqs.push_back(myCart.myMusicFrequencies[i]);
|
||||||
myOldState.mwaves.push_back(myCart.getWaveform(i) >> 5);
|
myOldState.mwaves.push_back(myCart.getWaveform(i) >> 5);
|
||||||
myOldState.mwavesizes.push_back(myCart.getWaveformSize((i)));
|
myOldState.mwavesizes.push_back(myCart.getWaveformSize((i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
for(uInt32 i = 0; i < internalRamSize(); ++i)
|
||||||
myOldState.internalram.push_back(myCart.myCDFRAM[i]);
|
myOldState.internalram.push_back(myCart.myCDFRAM[i]);
|
||||||
}
|
}
|
||||||
|
@ -192,12 +190,12 @@ void CartridgeCDFWidget::saveOldState()
|
||||||
void CartridgeCDFWidget::loadConfig()
|
void CartridgeCDFWidget::loadConfig()
|
||||||
{
|
{
|
||||||
myBank->setSelectedIndex(myCart.myCurrentBank);
|
myBank->setSelectedIndex(myCart.myCurrentBank);
|
||||||
|
|
||||||
// Get registers, using change tracking
|
// Get registers, using change tracking
|
||||||
IntArray alist;
|
IntArray alist;
|
||||||
IntArray vlist;
|
IntArray vlist;
|
||||||
BoolArray changed;
|
BoolArray changed;
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 32; ++i)
|
for(int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
|
@ -210,58 +208,58 @@ void CartridgeCDFWidget::loadConfig()
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// I = Increment
|
// I = Increment
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
uInt32 pointervalue = myCart.getDatastreamPointer(i) >> 12;
|
Int32 pointervalue = myCart.getDatastreamPointer(i) >> 12;
|
||||||
alist.push_back(0); vlist.push_back(pointervalue);
|
alist.push_back(0); vlist.push_back(pointervalue);
|
||||||
changed.push_back(pointervalue != myOldState.datastreampointers[i]);
|
changed.push_back(pointervalue != myOldState.datastreampointers[i]);
|
||||||
}
|
}
|
||||||
myDatastreamPointers->setList(alist, vlist, changed);
|
myDatastreamPointers->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 32; ++i)
|
for(int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
uInt32 incrementvalue = myCart.getDatastreamIncrement(i);
|
Int32 incrementvalue = myCart.getDatastreamIncrement(i);
|
||||||
alist.push_back(0); vlist.push_back(incrementvalue);
|
alist.push_back(0); vlist.push_back(incrementvalue);
|
||||||
changed.push_back(incrementvalue != myOldState.datastreamincrements[i]);
|
changed.push_back(incrementvalue != myOldState.datastreamincrements[i]);
|
||||||
}
|
}
|
||||||
myDatastreamIncrements->setList(alist, vlist, changed);
|
myDatastreamIncrements->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(0); vlist.push_back(myCart.myMusicCounters[i]);
|
alist.push_back(0); vlist.push_back(myCart.myMusicCounters[i]);
|
||||||
changed.push_back(myCart.myMusicCounters[i] != (uInt32)myOldState.mcounters[i]);
|
changed.push_back(myCart.myMusicCounters[i] != uInt32(myOldState.mcounters[i]));
|
||||||
}
|
}
|
||||||
myMusicCounters->setList(alist, vlist, changed);
|
myMusicCounters->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(0); vlist.push_back(myCart.myMusicFrequencies[i]);
|
alist.push_back(0); vlist.push_back(myCart.myMusicFrequencies[i]);
|
||||||
changed.push_back(myCart.myMusicFrequencies[i] != (uInt32)myOldState.mfreqs[i]);
|
changed.push_back(myCart.myMusicFrequencies[i] != uInt32(myOldState.mfreqs[i]));
|
||||||
}
|
}
|
||||||
myMusicFrequencies->setList(alist, vlist, changed);
|
myMusicFrequencies->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(0); vlist.push_back(myCart.getWaveform(i) >> 5);
|
alist.push_back(0); vlist.push_back(myCart.getWaveform(i) >> 5);
|
||||||
changed.push_back((myCart.getWaveform(i) >> 5) != myOldState.mwaves[i]);
|
changed.push_back((myCart.getWaveform(i) >> 5) != uInt32(myOldState.mwaves[i]));
|
||||||
}
|
}
|
||||||
myMusicWaveforms->setList(alist, vlist, changed);
|
myMusicWaveforms->setList(alist, vlist, changed);
|
||||||
|
|
||||||
alist.clear(); vlist.clear(); changed.clear();
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(0); vlist.push_back(myCart.getWaveformSize(i));
|
alist.push_back(0); vlist.push_back(myCart.getWaveformSize(i));
|
||||||
changed.push_back((myCart.getWaveformSize(i)) != myOldState.mwavesizes[i]);
|
changed.push_back((myCart.getWaveformSize(i)) != uInt32(myOldState.mwavesizes[i]));
|
||||||
}
|
}
|
||||||
myMusicWaveformSizes->setList(alist, vlist, changed);
|
myMusicWaveformSizes->setList(alist, vlist, changed);
|
||||||
|
|
||||||
// done differently than in DPC+, need to rethink debugger support
|
// done differently than in DPC+, need to rethink debugger support
|
||||||
// myFastFetch->setState(myCart.myFastFetch);
|
// myFastFetch->setState(myCart.myFastFetch);
|
||||||
// myIMLDA->setState(myCart.myLDAimmediate);
|
// myIMLDA->setState(myCart.myLDAimmediate);
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,13 +280,13 @@ void CartridgeCDFWidget::handleCommand(CommandSender* sender,
|
||||||
string CartridgeCDFWidget::bankState()
|
string CartridgeCDFWidget::bankState()
|
||||||
{
|
{
|
||||||
ostringstream& buf = buffer();
|
ostringstream& buf = buffer();
|
||||||
|
|
||||||
static const char* spot[] = {
|
static const char* spot[] = {
|
||||||
"$FF5", "$FF6", "$FF7", "$FF8", "$FF9", "$FFA", "$FFB"
|
"$FF5", "$FF6", "$FF7", "$FF8", "$FF9", "$FFA", "$FFB"
|
||||||
};
|
};
|
||||||
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
buf << "Bank = " << std::dec << myCart.myCurrentBank
|
||||||
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
<< ", hotspot = " << spot[myCart.myCurrentBank];
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +313,7 @@ string CartridgeCDFWidget::internalRamDescription()
|
||||||
<< " via CDF's Data Stream registers\n"
|
<< " via CDF's Data Stream registers\n"
|
||||||
<< "$1800 - $1FFF - 2K C variable storage and stack\n"
|
<< "$1800 - $1FFF - 2K C variable storage and stack\n"
|
||||||
<< " not accessible to 6507";
|
<< " not accessible to 6507";
|
||||||
|
|
||||||
return desc.str();
|
return desc.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartCDFWidget.hxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef CARTRIDGECDF_WIDGET_HXX
|
#ifndef CARTRIDGECDF_WIDGET_HXX
|
||||||
|
@ -29,68 +27,68 @@ class DataGridWidget;
|
||||||
|
|
||||||
class CartridgeCDFWidget : public CartDebugWidget
|
class CartridgeCDFWidget : public CartDebugWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CartridgeCDFWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartridgeCDFWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
const GUI::Font& nfont,
|
const GUI::Font& nfont,
|
||||||
int x, int y, int w, int h,
|
int x, int y, int w, int h,
|
||||||
CartridgeCDF& cart);
|
CartridgeCDF& cart);
|
||||||
virtual ~CartridgeCDFWidget() { }
|
virtual ~CartridgeCDFWidget() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CartState {
|
struct CartState {
|
||||||
ByteArray tops;
|
ByteArray tops;
|
||||||
ByteArray bottoms;
|
ByteArray bottoms;
|
||||||
IntArray datastreampointers;
|
IntArray datastreampointers;
|
||||||
IntArray datastreamincrements;
|
IntArray datastreamincrements;
|
||||||
IntArray addressmaps;
|
IntArray addressmaps;
|
||||||
IntArray mcounters;
|
IntArray mcounters;
|
||||||
IntArray mfreqs;
|
IntArray mfreqs;
|
||||||
IntArray mwaves;
|
IntArray mwaves;
|
||||||
IntArray mwavesizes;
|
IntArray mwavesizes;
|
||||||
uInt32 random;
|
uInt32 random;
|
||||||
ByteArray internalram;
|
ByteArray internalram;
|
||||||
};
|
};
|
||||||
|
|
||||||
CartridgeCDF& myCart;
|
CartridgeCDF& myCart;
|
||||||
PopUpWidget* myBank;
|
PopUpWidget* myBank;
|
||||||
|
|
||||||
DataGridWidget* myDatastreamPointers;
|
DataGridWidget* myDatastreamPointers;
|
||||||
DataGridWidget* myDatastreamIncrements;
|
DataGridWidget* myDatastreamIncrements;
|
||||||
DataGridWidget* myMusicCounters;
|
DataGridWidget* myMusicCounters;
|
||||||
DataGridWidget* myMusicFrequencies;
|
DataGridWidget* myMusicFrequencies;
|
||||||
DataGridWidget* myMusicWaveforms;
|
DataGridWidget* myMusicWaveforms;
|
||||||
DataGridWidget* myMusicWaveformSizes;
|
DataGridWidget* myMusicWaveformSizes;
|
||||||
// done differently than in DPC+, need to rethink debugger support
|
// done differently than in DPC+, need to rethink debugger support
|
||||||
// CheckboxWidget* myFastFetch;
|
// CheckboxWidget* myFastFetch;
|
||||||
// CheckboxWidget* myIMLDA;
|
// CheckboxWidget* myIMLDA;
|
||||||
CartState myOldState;
|
CartState myOldState;
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
enum { kBankChanged = 'bkCH' };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveOldState() override;
|
void saveOldState() override;
|
||||||
|
|
||||||
void loadConfig() override;
|
void loadConfig() override;
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
|
||||||
string bankState() override;
|
string bankState() override;
|
||||||
|
|
||||||
// start of functions for Cartridge RAM tab
|
// start of functions for Cartridge RAM tab
|
||||||
uInt32 internalRamSize() override;
|
uInt32 internalRamSize() override;
|
||||||
uInt32 internalRamRPort(int start) override;
|
uInt32 internalRamRPort(int start) override;
|
||||||
string internalRamDescription() override;
|
string internalRamDescription() override;
|
||||||
const ByteArray& internalRamOld(int start, int count) override;
|
const ByteArray& internalRamOld(int start, int count) override;
|
||||||
const ByteArray& internalRamCurrent(int start, int count) override;
|
const ByteArray& internalRamCurrent(int start, int count) override;
|
||||||
void internalRamSetValue(int addr, uInt8 value) override;
|
void internalRamSetValue(int addr, uInt8 value) override;
|
||||||
uInt8 internalRamGetValue(int addr) override;
|
uInt8 internalRamGetValue(int addr) override;
|
||||||
// end of functions for Cartridge RAM tab
|
// end of functions for Cartridge RAM tab
|
||||||
|
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeCDFWidget() = delete;
|
CartridgeCDFWidget() = delete;
|
||||||
CartridgeCDFWidget(const CartridgeCDFWidget&) = delete;
|
CartridgeCDFWidget(const CartridgeCDFWidget&) = delete;
|
||||||
CartridgeCDFWidget(CartridgeCDFWidget&&) = delete;
|
CartridgeCDFWidget(CartridgeCDFWidget&&) = delete;
|
||||||
CartridgeCDFWidget& operator=(const CartridgeCDFWidget&) = delete;
|
CartridgeCDFWidget& operator=(const CartridgeCDFWidget&) = delete;
|
||||||
CartridgeCDFWidget& operator=(CartridgeCDFWidget&&) = delete;
|
CartridgeCDFWidget& operator=(CartridgeCDFWidget&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -690,6 +690,7 @@ void DataGridWidget::endEditMode()
|
||||||
editString().insert(0, 1, '#');
|
editString().insert(0, 1, '#');
|
||||||
break;
|
break;
|
||||||
case Common::Base::F_DEFAULT:
|
case Common::Base::F_DEFAULT:
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
return (c >= '0' && c <= '9') || c == ' ';
|
return (c >= '0' && c <= '9') || c == ' ';
|
||||||
|
|
||||||
case Common::Base::F_DEFAULT:
|
case Common::Base::F_DEFAULT:
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -31,6 +31,8 @@ MODULE_OBJS := \
|
||||||
src/debugger/gui/Cart4KWidget.o \
|
src/debugger/gui/Cart4KWidget.o \
|
||||||
src/debugger/gui/Cart4KSCWidget.o \
|
src/debugger/gui/Cart4KSCWidget.o \
|
||||||
src/debugger/gui/CartARWidget.o \
|
src/debugger/gui/CartARWidget.o \
|
||||||
|
src/debugger/gui/CartBUSWidget.o \
|
||||||
|
src/debugger/gui/CartCDFWidget.o \
|
||||||
src/debugger/gui/CartCMWidget.o \
|
src/debugger/gui/CartCMWidget.o \
|
||||||
src/debugger/gui/CartCTYWidget.o \
|
src/debugger/gui/CartCTYWidget.o \
|
||||||
src/debugger/gui/CartCVWidget.o \
|
src/debugger/gui/CartCVWidget.o \
|
||||||
|
@ -74,5 +76,5 @@ MODULE_OBJS := \
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
src/debugger/gui
|
src/debugger/gui
|
||||||
|
|
||||||
# Include common rules
|
# Include common rules
|
||||||
include $(srcdir)/common.rules
|
include $(srcdir)/common.rules
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ Cartridge::BankswitchType Cartridge::ourBSList[ourNumBSTypes] = {
|
||||||
{ "BF", "BF (CPUWIZ 256K)" },
|
{ "BF", "BF (CPUWIZ 256K)" },
|
||||||
{ "BFSC", "BFSC (CPUWIZ 256K + ram)" },
|
{ "BFSC", "BFSC (CPUWIZ 256K + ram)" },
|
||||||
{ "BUS", "BUS (Bus Stuffing)" },
|
{ "BUS", "BUS (Bus Stuffing)" },
|
||||||
{ "CDF", "CDF (Chris, Darrell, Fred)" },
|
{ "CDF", "CDF (Chris, Darrell, Fred)" },
|
||||||
{ "CM", "CM (SpectraVideo CompuMate)" },
|
{ "CM", "CM (SpectraVideo CompuMate)" },
|
||||||
{ "CTY", "CTY (CDW - Chetiry)" },
|
{ "CTY", "CTY (CDW - Chetiry)" },
|
||||||
{ "CV", "CV (Commavid extra ram)" },
|
{ "CV", "CV (Commavid extra ram)" },
|
||||||
|
|
|
@ -178,7 +178,7 @@ class Cartridge : public Device
|
||||||
to pass values back to the cartridge class to emulate those subroutines.
|
to pass values back to the cartridge class to emulate those subroutines.
|
||||||
*/
|
*/
|
||||||
virtual uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) { return 0; }
|
virtual uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get debugger widget responsible for accessing the inner workings
|
Get debugger widget responsible for accessing the inner workings
|
||||||
of the cart. This will need to be overridden and implemented by
|
of the cart. This will need to be overridden and implemented by
|
||||||
|
@ -314,12 +314,12 @@ class Cartridge : public Device
|
||||||
Returns true if the image is probably a BUS bankswitching cartridge
|
Returns true if the image is probably a BUS bankswitching cartridge
|
||||||
*/
|
*/
|
||||||
static bool isProbablyBUS(const uInt8* image, uInt32 size);
|
static bool isProbablyBUS(const uInt8* image, uInt32 size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns true if the image is probably a CDF bankswitching cartridge
|
Returns true if the image is probably a CDF bankswitching cartridge
|
||||||
*/
|
*/
|
||||||
static bool isProbablyCDF(const uInt8* image, uInt32 size);
|
static bool isProbablyCDF(const uInt8* image, uInt32 size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns true if the image is probably a CTY bankswitching cartridge
|
Returns true if the image is probably a CTY bankswitching cartridge
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartBUS.cxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -45,14 +43,14 @@ CartridgeBUS::CartridgeBUS(const uInt8* image, uInt32 size,
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image, std::min(32768u, size));
|
memcpy(myImage, image, std::min(32768u, size));
|
||||||
|
|
||||||
// even though the ROM is 32K, only 28K is accessible to the 6507
|
// even though the ROM is 32K, only 28K is accessible to the 6507
|
||||||
createCodeAccessBase(4096 * 7);
|
createCodeAccessBase(4096 * 7);
|
||||||
|
|
||||||
// Pointer to the program ROM (28K @ 0 byte offset)
|
// Pointer to the program ROM (28K @ 0 byte offset)
|
||||||
// which starts after the 2K BUS Driver and 2K C Code
|
// which starts after the 2K BUS Driver and 2K C Code
|
||||||
myProgramImage = myImage + 4096;
|
myProgramImage = myImage + 4096;
|
||||||
|
|
||||||
// Pointer to BUS driver in RAM
|
// Pointer to BUS driver in RAM
|
||||||
myBusDriverImage = myBUSRAM;
|
myBusDriverImage = myBUSRAM;
|
||||||
|
|
||||||
|
@ -61,36 +59,27 @@ CartridgeBUS::CartridgeBUS(const uInt8* image, uInt32 size,
|
||||||
|
|
||||||
#ifdef THUMB_SUPPORT
|
#ifdef THUMB_SUPPORT
|
||||||
// Create Thumbulator ARM emulator
|
// Create Thumbulator ARM emulator
|
||||||
myThumbEmulator = make_ptr<Thumbulator>
|
myThumbEmulator = make_ptr<Thumbulator>((uInt16*)myImage, (uInt16*)myBUSRAM,
|
||||||
((uInt16*)myImage, (uInt16*)myBUSRAM,
|
settings.getBool("thumb.trapfatal"), Thumbulator::ConfigureFor::BUS, this);
|
||||||
settings.getBool("thumb.trapfatal"),
|
|
||||||
Thumbulator::ConfigureFor::BUS,
|
|
||||||
this);
|
|
||||||
#endif
|
#endif
|
||||||
setInitialState();
|
setInitialState();
|
||||||
|
|
||||||
// BUS always starts in bank 6
|
// BUS always starts in bank 6
|
||||||
myStartBank = 6;
|
myStartBank = 6;
|
||||||
|
|
||||||
// bus stuffing is off by default
|
// bus stuffing is off by default
|
||||||
myBusStuff = false;
|
myBusStuff = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeBUS::~CartridgeBUS()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUS::reset()
|
void CartridgeBUS::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM
|
// Initialize RAM
|
||||||
if(mySettings.getBool("ramrandom"))
|
if(mySettings.getBool("ramrandom"))
|
||||||
for(uInt32 t = 2048; t < 8192; ++t)
|
initializeRAM(myBUSRAM+2048, 8192-2048);
|
||||||
myBUSRAM[t] = mySystem->randGenerator().next();
|
|
||||||
else
|
else
|
||||||
memset(myBUSRAM+2048, 0, 8192-2048);
|
memset(myBUSRAM+2048, 0, 8192-2048);
|
||||||
|
|
||||||
// Update cycles to the current system cycles
|
// Update cycles to the current system cycles
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
myFractionalClocks = 0.0;
|
myFractionalClocks = 0.0;
|
||||||
|
@ -106,7 +95,7 @@ void CartridgeBUS::setInitialState()
|
||||||
{
|
{
|
||||||
// Copy initial BUS driver to Harmony RAM
|
// Copy initial BUS driver to Harmony RAM
|
||||||
memcpy(myBusDriverImage, myImage, 0x0800);
|
memcpy(myBusDriverImage, myImage, 0x0800);
|
||||||
|
|
||||||
for (int i=0; i < 3; ++i)
|
for (int i=0; i < 3; ++i)
|
||||||
myMusicWaveformSize[i] = 27;
|
myMusicWaveformSize[i] = 27;
|
||||||
}
|
}
|
||||||
|
@ -135,12 +124,12 @@ void CartridgeBUS::install(System& system)
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
for(uInt32 i = 0x1000; i < 0x1040; i += (1 << System::PAGE_SHIFT))
|
for(uInt32 i = 0x1000; i < 0x1040; i += (1 << System::PAGE_SHIFT))
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
|
|
||||||
// Mirror all access in TIA and RIOT; by doing so we're taking responsibility
|
// Mirror all access in TIA and RIOT; by doing so we're taking responsibility
|
||||||
// for that address space in peek and poke below.
|
// for that address space in peek and poke below.
|
||||||
mySystem->tia().installDelegate(system, *this);
|
mySystem->tia().installDelegate(system, *this);
|
||||||
mySystem->m6532().installDelegate(system, *this);
|
mySystem->m6532().installDelegate(system, *this);
|
||||||
|
|
||||||
// Install pages for the startup bank
|
// Install pages for the startup bank
|
||||||
bank(myStartBank);
|
bank(myStartBank);
|
||||||
}
|
}
|
||||||
|
@ -212,28 +201,28 @@ uInt8 CartridgeBUS::peek(uInt16 address)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
uInt8 peekvalue = myProgramImage[(myCurrentBank << 12) + address];
|
uInt8 peekvalue = myProgramImage[(myCurrentBank << 12) + address];
|
||||||
|
|
||||||
// In debugger/bank-locked mode, we ignore all hotspots and in general
|
// In debugger/bank-locked mode, we ignore all hotspots and in general
|
||||||
// anything that can change the internal state of the cart
|
// anything that can change the internal state of the cart
|
||||||
if(bankLocked())
|
if(bankLocked())
|
||||||
return peekvalue;
|
return peekvalue;
|
||||||
|
|
||||||
// save the STY's zero page address
|
// save the STY's zero page address
|
||||||
if (getBusStuffFlag() && mySTYZeroPage)
|
if (getBusStuffFlag() && mySTYZeroPage)
|
||||||
myBusOverdriveAddress = peekvalue;
|
myBusOverdriveAddress = peekvalue;
|
||||||
|
|
||||||
mySTYZeroPage = false;
|
mySTYZeroPage = false;
|
||||||
|
|
||||||
if(address < 0x20)
|
if(address < 0x20)
|
||||||
{
|
{
|
||||||
uInt8 result = 0;
|
uInt8 result = 0;
|
||||||
|
|
||||||
// Get the index of the data fetcher that's being accessed
|
// Get the index of the data fetcher that's being accessed
|
||||||
uInt32 index = address & 0x0f;
|
uInt32 index = address & 0x0f;
|
||||||
uInt32 function = (address >> 4) & 0x01;
|
uInt32 function = (address >> 4) & 0x01;
|
||||||
|
|
||||||
switch(function)
|
switch(function)
|
||||||
{
|
{
|
||||||
case 0x00: // read from a datastream
|
case 0x00: // read from a datastream
|
||||||
|
@ -257,24 +246,24 @@ uInt8 CartridgeBUS::peek(uInt16 address)
|
||||||
case 0x09: // 0x19 STUFFMODE
|
case 0x09: // 0x19 STUFFMODE
|
||||||
case 0x0a: // 0x1A CALLFN
|
case 0x0a: // 0x1A CALLFN
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: // 0x18 = AMPLITUDE
|
case 0x08: // 0x18 = AMPLITUDE
|
||||||
// Update the music data fetchers (counter & flag)
|
// Update the music data fetchers (counter & flag)
|
||||||
updateMusicModeDataFetchers();
|
updateMusicModeDataFetchers();
|
||||||
|
|
||||||
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
||||||
// can be modified during runtime.
|
// can be modified during runtime.
|
||||||
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
|
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
|
||||||
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
|
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
|
||||||
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
|
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
|
||||||
|
|
||||||
result = uInt8(i);
|
result = uInt8(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -286,48 +275,50 @@ uInt8 CartridgeBUS::peek(uInt16 address)
|
||||||
// Set the current bank to the first 4k bank
|
// Set the current bank to the first 4k bank
|
||||||
bank(0);
|
bank(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF6:
|
case 0x0FF6:
|
||||||
// Set the current bank to the second 4k bank
|
// Set the current bank to the second 4k bank
|
||||||
bank(1);
|
bank(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF7:
|
case 0x0FF7:
|
||||||
// Set the current bank to the third 4k bank
|
// Set the current bank to the third 4k bank
|
||||||
bank(2);
|
bank(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF8:
|
case 0x0FF8:
|
||||||
// Set the current bank to the fourth 4k bank
|
// Set the current bank to the fourth 4k bank
|
||||||
bank(3);
|
bank(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF9:
|
case 0x0FF9:
|
||||||
// Set the current bank to the fifth 4k bank
|
// Set the current bank to the fifth 4k bank
|
||||||
bank(4);
|
bank(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFA:
|
case 0x0FFA:
|
||||||
// Set the current bank to the sixth 4k bank
|
// Set the current bank to the sixth 4k bank
|
||||||
bank(5);
|
bank(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFB:
|
case 0x0FFB:
|
||||||
// Set the current bank to the last 4k bank
|
// Set the current bank to the last 4k bank
|
||||||
bank(6);
|
bank(6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this might not work right for STY $84
|
// this might not work right for STY $84
|
||||||
if (getBusStuffFlag())
|
if (getBusStuffFlag())
|
||||||
mySTYZeroPage = (peekvalue == 0x84);
|
mySTYZeroPage = (peekvalue == 0x84);
|
||||||
|
|
||||||
return peekvalue;
|
return peekvalue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0; // make compiler happy
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -336,25 +327,24 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
|
||||||
if (!(address & 0x1000))
|
if (!(address & 0x1000))
|
||||||
{
|
{
|
||||||
value &= busOverdrive(address);
|
value &= busOverdrive(address);
|
||||||
|
|
||||||
// Check for RAM or TIA mirroring
|
// Check for RAM or TIA mirroring
|
||||||
uInt16 lowAddress = address & 0x3ff;
|
uInt16 lowAddress = address & 0x3ff;
|
||||||
if(lowAddress & 0x80)
|
if(lowAddress & 0x80)
|
||||||
mySystem->m6532().poke(address, value);
|
mySystem->m6532().poke(address, value);
|
||||||
else if(!(lowAddress & 0x200))
|
else if(!(lowAddress & 0x200))
|
||||||
mySystem->tia().poke(address, value);
|
mySystem->tia().poke(address, value);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
if ((address >= 0x10) && (address <= 0x1F))
|
if ((address >= 0x10) && (address <= 0x1F))
|
||||||
{
|
{
|
||||||
// Get the index of the data fetcher that's being accessed
|
// Get the index of the data fetcher that's being accessed
|
||||||
uInt32 index = address & 0x0f;
|
uInt32 index = address & 0x0f;
|
||||||
uInt32 pointer;
|
uInt32 pointer;
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 0x00: // DS0WRITE
|
case 0x00: // DS0WRITE
|
||||||
|
@ -366,13 +356,13 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
|
||||||
//
|
//
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
pointer = getDatastreamPointer(index);
|
pointer = getDatastreamPointer(index);
|
||||||
myDisplayImage[ pointer >> 20 ] = value;
|
myDisplayImage[ pointer >> 20 ] = value;
|
||||||
pointer += 0x100000; // always increment by 1 when writing
|
pointer += 0x100000; // always increment by 1 when writing
|
||||||
setDatastreamPointer(index, pointer);
|
setDatastreamPointer(index, pointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: // 0x14 DS0PTR
|
case 0x04: // 0x14 DS0PTR
|
||||||
case 0x05: // 0x15 DS1PTR
|
case 0x05: // 0x15 DS1PTR
|
||||||
case 0x06: // 0x16 DS2PTR
|
case 0x06: // 0x16 DS2PTR
|
||||||
|
@ -382,7 +372,7 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
|
||||||
//
|
//
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
index &= 0x03;
|
index &= 0x03;
|
||||||
pointer = getDatastreamPointer(index);
|
pointer = getDatastreamPointer(index);
|
||||||
pointer <<=8;
|
pointer <<=8;
|
||||||
|
@ -390,11 +380,11 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
|
||||||
pointer |= (value << 20);
|
pointer |= (value << 20);
|
||||||
setDatastreamPointer(index, pointer);
|
setDatastreamPointer(index, pointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: // 0x19 turn on STY ZP bus stuffing if value is 0
|
case 0x09: // 0x19 turn on STY ZP bus stuffing if value is 0
|
||||||
setBusStuffFlag(value==0);
|
setBusStuffFlag(value==0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0A: // 0x1A CALLFUNCTION
|
case 0x0A: // 0x1A CALLFUNCTION
|
||||||
callFunction(value);
|
callFunction(value);
|
||||||
break;
|
break;
|
||||||
|
@ -409,37 +399,37 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
|
||||||
// Set the current bank to the first 4k bank
|
// Set the current bank to the first 4k bank
|
||||||
bank(0);
|
bank(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF6:
|
case 0x0FF6:
|
||||||
// Set the current bank to the second 4k bank
|
// Set the current bank to the second 4k bank
|
||||||
bank(1);
|
bank(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF7:
|
case 0x0FF7:
|
||||||
// Set the current bank to the third 4k bank
|
// Set the current bank to the third 4k bank
|
||||||
bank(2);
|
bank(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF8:
|
case 0x0FF8:
|
||||||
// Set the current bank to the fourth 4k bank
|
// Set the current bank to the fourth 4k bank
|
||||||
bank(3);
|
bank(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF9:
|
case 0x0FF9:
|
||||||
// Set the current bank to the fifth 4k bank
|
// Set the current bank to the fifth 4k bank
|
||||||
bank(4);
|
bank(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFA:
|
case 0x0FFA:
|
||||||
// Set the current bank to the sixth 4k bank
|
// Set the current bank to the sixth 4k bank
|
||||||
bank(5);
|
bank(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFB:
|
case 0x0FFB:
|
||||||
// Set the current bank to the last 4k bank
|
// Set the current bank to the last 4k bank
|
||||||
bank(6);
|
bank(6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -506,46 +496,43 @@ const uInt8* CartridgeBUS::getImage(int& size) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
uInt8 CartridgeBUS::busOverdrive(uInt16 address)
|
uInt8 CartridgeBUS::busOverdrive(uInt16 address)
|
||||||
{
|
{
|
||||||
uInt8 overdrive = 0xff;
|
uInt8 overdrive = 0xff;
|
||||||
|
|
||||||
// Not sure how to do this, check with stephena.
|
// Not sure how to do this, check with stephena.
|
||||||
//
|
//
|
||||||
// Per discussion with cd-w, have this routine check that the Y register has a
|
// Per discussion with cd-w, have this routine check that the Y register has a
|
||||||
// value of 0xFF. Of it doesn't then "crash the emulation".
|
// value of 0xFF. Of it doesn't then "crash the emulation".
|
||||||
|
|
||||||
|
|
||||||
// only overdrive if the address matches
|
// only overdrive if the address matches
|
||||||
if (address == myBusOverdriveAddress)
|
if (address == myBusOverdriveAddress)
|
||||||
{
|
{
|
||||||
uInt8 map = address & 0x7f;
|
uInt8 map = address & 0x7f;
|
||||||
if (map <= 0x24) // map TIA registers VSYNC thru HMBL inclusive
|
if (map <= 0x24) // map TIA registers VSYNC thru HMBL inclusive
|
||||||
{
|
{
|
||||||
uInt32 alldatastreams = getAddressMap(map);
|
uInt32 alldatastreams = getAddressMap(map);
|
||||||
uInt8 datastream = alldatastreams & 0x0f; // lowest nybble has the current datastream to use
|
uInt8 datastream = alldatastreams & 0x0f; // lowest nybble has the current datastream to use
|
||||||
overdrive = readFromDatastream(datastream);
|
overdrive = readFromDatastream(datastream);
|
||||||
|
|
||||||
// rotate map nybbles for next time
|
// rotate map nybbles for next time
|
||||||
alldatastreams >>= 4;
|
alldatastreams >>= 4;
|
||||||
alldatastreams |= (datastream << 28);
|
alldatastreams |= (datastream << 28);
|
||||||
setAddressMap(map, alldatastreams);
|
setAddressMap(map, alldatastreams);
|
||||||
|
|
||||||
// overdrive |= 0x7c; // breaks bus stuffing to match hobo's system
|
// overdrive |= 0x7c; // breaks bus stuffing to match hobo's system
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
myBusOverdriveAddress = 0xff; // turns off overdrive for next poke event
|
myBusOverdriveAddress = 0xff; // turns off overdrive for next poke event
|
||||||
|
|
||||||
return overdrive;
|
return overdrive;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
uInt32 CartridgeBUS::thumbCallback(uInt8 function, uInt32 value1, uInt32 value2)
|
uInt32 CartridgeBUS::thumbCallback(uInt8 function, uInt32 value1, uInt32 value2)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (function)
|
switch (function)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -558,7 +545,7 @@ uInt32 CartridgeBUS::thumbCallback(uInt8 function, uInt32 value1, uInt32 value2)
|
||||||
case 1:
|
case 1:
|
||||||
myMusicCounters[value1] = 0;
|
myMusicCounters[value1] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// _GetWavePtr - return the counter
|
// _GetWavePtr - return the counter
|
||||||
case 2:
|
case 2:
|
||||||
return myMusicCounters[value1];
|
return myMusicCounters[value1];
|
||||||
|
@ -569,11 +556,10 @@ uInt32 CartridgeBUS::thumbCallback(uInt8 function, uInt32 value1, uInt32 value2)
|
||||||
myMusicWaveformSize[value1] = value2;
|
myMusicWaveformSize[value1] = value2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool CartridgeBUS::save(Serializer& out) const
|
bool CartridgeBUS::save(Serializer& out) const
|
||||||
{
|
{
|
||||||
|
@ -629,16 +615,18 @@ bool CartridgeBUS::load(Serializer& in)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeBUS::getDatastreamPointer(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeBUS::getDatastreamPointer(uInt8 index) const
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
|
|
||||||
return myBUSRAM[DSxPTR + index*4 + 0] + // low byte
|
return myBUSRAM[DSxPTR + index*4 + 0] + // low byte
|
||||||
(myBUSRAM[DSxPTR + index*4 + 1] << 8) +
|
(myBUSRAM[DSxPTR + index*4 + 1] << 8) +
|
||||||
(myBUSRAM[DSxPTR + index*4 + 2] << 16) +
|
(myBUSRAM[DSxPTR + index*4 + 2] << 16) +
|
||||||
(myBUSRAM[DSxPTR + index*4 + 3] << 24) ; // high byte
|
(myBUSRAM[DSxPTR + index*4 + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUS::setDatastreamPointer(uInt8 index, uInt32 value)
|
void CartridgeBUS::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
|
@ -648,7 +636,8 @@ void CartridgeBUS::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
myBUSRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myBUSRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeBUS::getDatastreamIncrement(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeBUS::getDatastreamIncrement(uInt8 index) const
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
return myBUSRAM[DSxINC + index*4 + 0] + // low byte
|
return myBUSRAM[DSxINC + index*4 + 0] + // low byte
|
||||||
|
@ -657,6 +646,7 @@ uInt32 CartridgeBUS::getDatastreamIncrement(uInt8 index)
|
||||||
(myBUSRAM[DSxINC + index*4 + 3] << 24) ; // high byte
|
(myBUSRAM[DSxINC + index*4 + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUS::setDatastreamIncrement(uInt8 index, uInt32 value)
|
void CartridgeBUS::setDatastreamIncrement(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
|
@ -666,7 +656,8 @@ void CartridgeBUS::setDatastreamIncrement(uInt8 index, uInt32 value)
|
||||||
myBUSRAM[DSxINC + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myBUSRAM[DSxINC + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeBUS::getAddressMap(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeBUS::getAddressMap(uInt8 index) const
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
return myBUSRAM[DSMAPS + index*4 + 0] + // low byte
|
return myBUSRAM[DSMAPS + index*4 + 0] + // low byte
|
||||||
|
@ -675,40 +666,43 @@ uInt32 CartridgeBUS::getAddressMap(uInt8 index)
|
||||||
(myBUSRAM[DSMAPS + index*4 + 3] << 24) ; // high byte
|
(myBUSRAM[DSMAPS + index*4 + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeBUS::getWaveform(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeBUS::getWaveform(uInt8 index) const
|
||||||
{
|
{
|
||||||
// instead of 0, 1, 2, etc. this returned
|
// instead of 0, 1, 2, etc. this returned
|
||||||
// 0x40000800 for 0
|
// 0x40000800 for 0
|
||||||
// 0x40000820 for 1
|
// 0x40000820 for 1
|
||||||
// 0x40000840 for 2
|
// 0x40000840 for 2
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
// return myBUSRAM[WAVEFORM + index*4 + 0] + // low byte
|
// return myBUSRAM[WAVEFORM + index*4 + 0] + // low byte
|
||||||
// (myBUSRAM[WAVEFORM + index*4 + 1] << 8) +
|
// (myBUSRAM[WAVEFORM + index*4 + 1] << 8) +
|
||||||
// (myBUSRAM[WAVEFORM + index*4 + 2] << 16) +
|
// (myBUSRAM[WAVEFORM + index*4 + 2] << 16) +
|
||||||
// (myBUSRAM[WAVEFORM + index*4 + 3] << 24) - // high byte
|
// (myBUSRAM[WAVEFORM + index*4 + 3] << 24) - // high byte
|
||||||
// 0x40000800;
|
// 0x40000800;
|
||||||
|
|
||||||
uInt32 result;
|
uInt32 result;
|
||||||
|
|
||||||
result = myBUSRAM[WAVEFORM + index*4 + 0] + // low byte
|
result = myBUSRAM[WAVEFORM + index*4 + 0] + // low byte
|
||||||
(myBUSRAM[WAVEFORM + index*4 + 1] << 8) +
|
(myBUSRAM[WAVEFORM + index*4 + 1] << 8) +
|
||||||
(myBUSRAM[WAVEFORM + index*4 + 2] << 16) +
|
(myBUSRAM[WAVEFORM + index*4 + 2] << 16) +
|
||||||
(myBUSRAM[WAVEFORM + index*4 + 3] << 24);
|
(myBUSRAM[WAVEFORM + index*4 + 3] << 24);
|
||||||
|
|
||||||
result -= 0x40000800;
|
result -= 0x40000800;
|
||||||
|
|
||||||
if (result >= 4096)
|
if (result >= 4096)
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeBUS::getWaveformSize(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeBUS::getWaveformSize(uInt8 index) const
|
||||||
{
|
{
|
||||||
return myMusicWaveformSize[index];
|
return myMusicWaveformSize[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUS::setAddressMap(uInt8 index, uInt32 value)
|
void CartridgeBUS::setAddressMap(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
|
@ -718,16 +712,19 @@ void CartridgeBUS::setAddressMap(uInt8 index, uInt32 value)
|
||||||
myBUSRAM[DSMAPS + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myBUSRAM[DSMAPS + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CartridgeBUS::getBusStuffFlag(void)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool CartridgeBUS::getBusStuffFlag(void) const
|
||||||
{
|
{
|
||||||
return myBusStuff;
|
return myBusStuff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeBUS::setBusStuffFlag(bool value)
|
void CartridgeBUS::setBusStuffFlag(bool value)
|
||||||
{
|
{
|
||||||
myBusStuff = value;
|
myBusStuff = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeBUS::readFromDatastream(uInt8 index)
|
uInt8 CartridgeBUS::readFromDatastream(uInt8 index)
|
||||||
{
|
{
|
||||||
// Pointers are stored as:
|
// Pointers are stored as:
|
||||||
|
@ -739,7 +736,7 @@ uInt8 CartridgeBUS::readFromDatastream(uInt8 index)
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// I = Increment
|
// I = Increment
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
uInt32 pointer = getDatastreamPointer(index);
|
uInt32 pointer = getDatastreamPointer(index);
|
||||||
uInt16 increment = getDatastreamIncrement(index);
|
uInt16 increment = getDatastreamIncrement(index);
|
||||||
uInt8 value = myDisplayImage[ pointer >> 20 ];
|
uInt8 value = myDisplayImage[ pointer >> 20 ];
|
||||||
|
@ -747,4 +744,3 @@ uInt8 CartridgeBUS::readFromDatastream(uInt8 index)
|
||||||
setDatastreamPointer(index, pointer);
|
setDatastreamPointer(index, pointer);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartBUS.hxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef CARTRIDGE_BUS_HXX
|
#ifndef CARTRIDGE_BUS_HXX
|
||||||
|
@ -22,7 +20,7 @@
|
||||||
|
|
||||||
class System;
|
class System;
|
||||||
#ifdef THUMB_SUPPORT
|
#ifdef THUMB_SUPPORT
|
||||||
class Thumbulator;
|
class Thumbulator;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "CartBUSWidget.hxx"
|
#include "CartBUSWidget.hxx"
|
||||||
|
@ -32,22 +30,22 @@ class Thumbulator;
|
||||||
#include "Cart.hxx"
|
#include "Cart.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Cartridge class used for BUS.
|
Cartridge class used for BUS.
|
||||||
|
|
||||||
THIS NEEDS TO BE UPDATED
|
THIS NEEDS TO BE UPDATED
|
||||||
|
|
||||||
|
|
||||||
There are seven 4K program banks, a 4K Display Data RAM,
|
There are seven 4K program banks, a 4K Display Data RAM,
|
||||||
1K C Varaible and Stack, and the BUS chip.
|
1K C Varaible and Stack, and the BUS chip.
|
||||||
BUS chip access is mapped to $1000 - $103F.
|
BUS chip access is mapped to $1000 - $103F.
|
||||||
|
|
||||||
@author Darrell Spice Jr, Chris Walton, Fred Quimby, Stephen Anthony, Bradford W. Mott
|
Authors: Darrell Spice Jr, Chris Walton, Fred Quimby,
|
||||||
@version $Id: CartBUS.hxx 3131 2015-01-01 03:49:32Z stephena $
|
Stephen Anthony, Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
class CartridgeBUS : public Cartridge
|
class CartridgeBUS : public Cartridge
|
||||||
{
|
{
|
||||||
friend class CartridgeBUSWidget;
|
friend class CartridgeBUSWidget;
|
||||||
friend class CartridgeRamBUSWidget;
|
friend class CartridgeRamBUSWidget;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -58,11 +56,7 @@ class CartridgeBUS : public Cartridge
|
||||||
@param settings A reference to the various settings (read-only)
|
@param settings A reference to the various settings (read-only)
|
||||||
*/
|
*/
|
||||||
CartridgeBUS(const uInt8* image, uInt32 size, const Settings& settings);
|
CartridgeBUS(const uInt8* image, uInt32 size, const Settings& settings);
|
||||||
|
virtual ~CartridgeBUS() = default;
|
||||||
/**
|
|
||||||
Destructor
|
|
||||||
*/
|
|
||||||
virtual ~CartridgeBUS();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -74,11 +68,11 @@ class CartridgeBUS : public Cartridge
|
||||||
Notification method invoked by the system when the console type
|
Notification method invoked by the system when the console type
|
||||||
has changed. We need this to inform the Thumbulator that the
|
has changed. We need this to inform the Thumbulator that the
|
||||||
timing has changed.
|
timing has changed.
|
||||||
|
|
||||||
@param timing Enum representing the new console type
|
@param timing Enum representing the new console type
|
||||||
*/
|
*/
|
||||||
void consoleChanged(ConsoleTiming timing) override;
|
void consoleChanged(ConsoleTiming timing) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Notification method invoked by the system right before the
|
Notification method invoked by the system right before the
|
||||||
system resets its cycle counter to zero. It may be necessary
|
system resets its cycle counter to zero. It may be necessary
|
||||||
|
@ -150,14 +144,14 @@ class CartridgeBUS : public Cartridge
|
||||||
@return The name of the object
|
@return The name of the object
|
||||||
*/
|
*/
|
||||||
string name() const override { return "CartridgeBUS"; }
|
string name() const override { return "CartridgeBUS"; }
|
||||||
|
|
||||||
uInt8 busOverdrive(uInt16 address);
|
uInt8 busOverdrive(uInt16 address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Used for Thumbulator to pass values back to the cartridge
|
Used for Thumbulator to pass values back to the cartridge
|
||||||
*/
|
*/
|
||||||
uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override;
|
uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override;
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
/**
|
/**
|
||||||
|
@ -189,49 +183,49 @@ class CartridgeBUS : public Cartridge
|
||||||
bool poke(uInt16 address, uInt8 value) override;
|
bool poke(uInt16 address, uInt8 value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
Sets the initial state of the DPC pointers and RAM
|
Sets the initial state of the DPC pointers and RAM
|
||||||
*/
|
*/
|
||||||
void setInitialState();
|
void setInitialState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Updates any data fetchers in music mode based on the number of
|
Updates any data fetchers in music mode based on the number of
|
||||||
CPU cycles which have passed since the last update.
|
CPU cycles which have passed since the last update.
|
||||||
*/
|
*/
|
||||||
void updateMusicModeDataFetchers();
|
void updateMusicModeDataFetchers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Call Special Functions
|
Call Special Functions
|
||||||
*/
|
*/
|
||||||
void callFunction(uInt8 value);
|
void callFunction(uInt8 value);
|
||||||
|
|
||||||
uInt32 getDatastreamPointer(uInt8 index);
|
uInt32 getDatastreamPointer(uInt8 index) const;
|
||||||
void setDatastreamPointer(uInt8 index, uInt32 value);
|
void setDatastreamPointer(uInt8 index, uInt32 value);
|
||||||
|
|
||||||
uInt32 getDatastreamIncrement(uInt8 index);
|
uInt32 getDatastreamIncrement(uInt8 index) const;
|
||||||
void setDatastreamIncrement(uInt8 index, uInt32 value);
|
void setDatastreamIncrement(uInt8 index, uInt32 value);
|
||||||
|
|
||||||
uInt32 getAddressMap(uInt8 index);
|
uInt32 getAddressMap(uInt8 index) const;
|
||||||
void setAddressMap(uInt8 index, uInt32 value);
|
void setAddressMap(uInt8 index, uInt32 value);
|
||||||
|
|
||||||
bool getBusStuffFlag(void);
|
bool getBusStuffFlag(void) const;
|
||||||
void setBusStuffFlag(bool value);
|
void setBusStuffFlag(bool value);
|
||||||
|
|
||||||
uInt8 readFromDatastream(uInt8 index);
|
uInt8 readFromDatastream(uInt8 index);
|
||||||
|
|
||||||
uInt32 getWaveform(uInt8 index);
|
uInt32 getWaveform(uInt8 index) const;
|
||||||
uInt32 getWaveformSize(uInt8 index);
|
uInt32 getWaveformSize(uInt8 index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The 32K ROM image of the cartridge
|
// The 32K ROM image of the cartridge
|
||||||
uInt8 myImage[32768];
|
uInt8 myImage[32768];
|
||||||
|
|
||||||
// Pointer to the 28K program ROM image of the cartridge
|
// Pointer to the 28K program ROM image of the cartridge
|
||||||
uInt8* myProgramImage;
|
uInt8* myProgramImage;
|
||||||
|
|
||||||
// Pointer to the 4K display ROM image of the cartridge
|
// Pointer to the 4K display ROM image of the cartridge
|
||||||
uInt8* myDisplayImage;
|
uInt8* myDisplayImage;
|
||||||
|
|
||||||
// Pointer to the 2K BUS driver image in RAM
|
// Pointer to the 2K BUS driver image in RAM
|
||||||
uInt8* myBusDriverImage;
|
uInt8* myBusDriverImage;
|
||||||
|
|
||||||
|
@ -248,7 +242,7 @@ class CartridgeBUS : public Cartridge
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates which bank is currently active
|
||||||
uInt16 myCurrentBank;
|
uInt16 myCurrentBank;
|
||||||
|
|
||||||
// Address to override the bus for
|
// Address to override the bus for
|
||||||
uInt16 myBusOverdriveAddress;
|
uInt16 myBusOverdriveAddress;
|
||||||
|
|
||||||
|
@ -257,25 +251,25 @@ class CartridgeBUS : public Cartridge
|
||||||
|
|
||||||
// System cycle count when the last update to music data fetchers occurred
|
// System cycle count when the last update to music data fetchers occurred
|
||||||
Int32 mySystemCycles;
|
Int32 mySystemCycles;
|
||||||
|
|
||||||
uInt8 mySetAddress;
|
uInt8 mySetAddress;
|
||||||
|
|
||||||
// The music mode counters
|
// The music mode counters
|
||||||
uInt32 myMusicCounters[3];
|
uInt32 myMusicCounters[3];
|
||||||
|
|
||||||
// The music frequency
|
// The music frequency
|
||||||
uInt32 myMusicFrequencies[3];
|
uInt32 myMusicFrequencies[3];
|
||||||
|
|
||||||
// The music waveform sizes
|
// The music waveform sizes
|
||||||
uInt8 myMusicWaveformSize[3];
|
uInt8 myMusicWaveformSize[3];
|
||||||
|
|
||||||
// Fractional DPC music OSC clocks unused during the last update
|
// Fractional DPC music OSC clocks unused during the last update
|
||||||
double myFractionalClocks;
|
double myFractionalClocks;
|
||||||
|
|
||||||
// Flags that Bus Stuffing is active
|
// Flags that Bus Stuffing is active
|
||||||
bool myBusStuff;
|
bool myBusStuff;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeBUS() = delete;
|
CartridgeBUS() = delete;
|
||||||
CartridgeBUS(const CartridgeBUS&) = delete;
|
CartridgeBUS(const CartridgeBUS&) = delete;
|
||||||
|
|
|
@ -8,20 +8,19 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartCDF.cxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "Debugger.hxx"
|
#include "Debugger.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "Thumbulator.hxx"
|
#include "Thumbulator.hxx"
|
||||||
#include "CartCDF.hxx"
|
#include "CartCDF.hxx"
|
||||||
|
@ -35,70 +34,60 @@
|
||||||
|
|
||||||
#define FAST_FETCH_ON ((myMode & 0x0F) == 0)
|
#define FAST_FETCH_ON ((myMode & 0x0F) == 0)
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeCDF::CartridgeCDF(const uInt8* image, uInt32 size,
|
CartridgeCDF::CartridgeCDF(const uInt8* image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
mySystemCycles(0),
|
mySystemCycles(0),
|
||||||
myARMCycles(0),
|
myARMCycles(0),
|
||||||
myFractionalClocks(0.0)
|
myFractionalClocks(0.0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
memcpy(myImage, image, std::min(32768u, size));
|
memcpy(myImage, image, std::min(32768u, size));
|
||||||
|
|
||||||
// even though the ROM is 32K, only 28K is accessible to the 6507
|
// even though the ROM is 32K, only 28K is accessible to the 6507
|
||||||
createCodeAccessBase(4096 * 7);
|
createCodeAccessBase(4096 * 7);
|
||||||
|
|
||||||
// Pointer to the program ROM (28K @ 0 byte offset)
|
// Pointer to the program ROM (28K @ 0 byte offset)
|
||||||
// which starts after the 2K CDF Driver and 2K C Code
|
// which starts after the 2K CDF Driver and 2K C Code
|
||||||
myProgramImage = myImage + 4096;
|
myProgramImage = myImage + 4096;
|
||||||
|
|
||||||
// Pointer to CDF driver in RAM
|
// Pointer to CDF driver in RAM
|
||||||
myBusDriverImage = myCDFRAM;
|
myBusDriverImage = myCDFRAM;
|
||||||
|
|
||||||
// Pointer to the display RAM
|
// Pointer to the display RAM
|
||||||
myDisplayImage = myCDFRAM + DSRAM;
|
myDisplayImage = myCDFRAM + DSRAM;
|
||||||
#ifdef THUMB_SUPPORT
|
#ifdef THUMB_SUPPORT
|
||||||
// Create Thumbulator ARM emulator
|
// Create Thumbulator ARM emulator
|
||||||
myThumbEmulator = make_ptr<Thumbulator>
|
myThumbEmulator = make_ptr<Thumbulator>((uInt16*)myImage, (uInt16*)myCDFRAM,
|
||||||
((uInt16*)myImage, (uInt16*)myCDFRAM,
|
settings.getBool("thumb.trapfatal"), Thumbulator::ConfigureFor::CDF, this);
|
||||||
settings.getBool("thumb.trapfatal"),
|
|
||||||
Thumbulator::ConfigureFor::CDF,
|
|
||||||
this);
|
|
||||||
#endif
|
#endif
|
||||||
setInitialState();
|
setInitialState();
|
||||||
|
|
||||||
// CDF always starts in bank 6
|
// CDF always starts in bank 6
|
||||||
myStartBank = 6;
|
myStartBank = 6;
|
||||||
|
|
||||||
// Assuming mode starts out with Fast Fetch off and 3-Voice music,
|
// Assuming mode starts out with Fast Fetch off and 3-Voice music,
|
||||||
// need to confirm with Chris
|
// need to confirm with Chris
|
||||||
myMode = 0xFF;
|
myMode = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeCDF::~CartridgeCDF()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::reset()
|
void CartridgeCDF::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM
|
// Initialize RAM
|
||||||
if(mySettings.getBool("ramrandom"))
|
if(mySettings.getBool("ramrandom"))
|
||||||
for(uInt32 t = 2048; t < 8192; ++t)
|
initializeRAM(myCDFRAM+2048, 8192-2048);
|
||||||
myCDFRAM[t] = mySystem->randGenerator().next();
|
|
||||||
else
|
else
|
||||||
memset(myCDFRAM+2048, 0, 8192-2048);
|
memset(myCDFRAM+2048, 0, 8192-2048);
|
||||||
|
|
||||||
// Update cycles to the current system cycles
|
// Update cycles to the current system cycles
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
myARMCycles = mySystem->cycles();
|
myARMCycles = mySystem->cycles();
|
||||||
myFractionalClocks = 0.0;
|
myFractionalClocks = 0.0;
|
||||||
|
|
||||||
setInitialState();
|
setInitialState();
|
||||||
|
|
||||||
// Upon reset we switch to the startup bank
|
// Upon reset we switch to the startup bank
|
||||||
bank(myStartBank);
|
bank(myStartBank);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +97,7 @@ void CartridgeCDF::setInitialState()
|
||||||
{
|
{
|
||||||
// Copy initial CDF driver to Harmony RAM
|
// Copy initial CDF driver to Harmony RAM
|
||||||
memcpy(myBusDriverImage, myImage, 0x0800);
|
memcpy(myBusDriverImage, myImage, 0x0800);
|
||||||
|
|
||||||
for (int i=0; i < 3; ++i)
|
for (int i=0; i < 3; ++i)
|
||||||
myMusicWaveformSize[i] = 27;
|
myMusicWaveformSize[i] = 27;
|
||||||
}
|
}
|
||||||
|
@ -133,14 +122,14 @@ void CartridgeCDF::systemCyclesReset()
|
||||||
void CartridgeCDF::install(System& system)
|
void CartridgeCDF::install(System& system)
|
||||||
{
|
{
|
||||||
mySystem = &system;
|
mySystem = &system;
|
||||||
|
|
||||||
// Map all of the accesses to call peek and poke
|
// Map all of the accesses to call peek and poke
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
for(uInt32 i = 0x1000; i < 0x1040; i += (1 << System::PAGE_SHIFT))
|
for(uInt32 i = 0x1000; i < 0x1040; i += (1 << System::PAGE_SHIFT))
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
|
|
||||||
// Install pages for the startup bank
|
// Install pages for the startup bank
|
||||||
bank(myStartBank);
|
bank(myStartBank);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -149,17 +138,17 @@ inline void CartridgeCDF::updateMusicModeDataFetchers()
|
||||||
// Calculate the number of cycles since the last update
|
// Calculate the number of cycles since the last update
|
||||||
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
|
|
||||||
// Calculate the number of CDF OSC clocks since the last update
|
// Calculate the number of CDF OSC clocks since the last update
|
||||||
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
|
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
|
||||||
Int32 wholeClocks = Int32(clocks);
|
Int32 wholeClocks = Int32(clocks);
|
||||||
myFractionalClocks = clocks - double(wholeClocks);
|
myFractionalClocks = clocks - double(wholeClocks);
|
||||||
|
|
||||||
if(wholeClocks <= 0)
|
if(wholeClocks <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's update counters and flags of the music mode data fetchers
|
// Let's update counters and flags of the music mode data fetchers
|
||||||
for(int x = 0; x <= 2; ++x)
|
for(int x = 0; x <= 2; ++x)
|
||||||
{
|
{
|
||||||
|
@ -176,11 +165,11 @@ inline void CartridgeCDF::callFunction(uInt8 value)
|
||||||
// Call user written ARM code (will most likely be C compiled for ARM)
|
// Call user written ARM code (will most likely be C compiled for ARM)
|
||||||
case 254: // call with IRQ driven audio, no special handling needed at this
|
case 254: // call with IRQ driven audio, no special handling needed at this
|
||||||
// time for Stella as ARM code "runs in zero 6507 cycles".
|
// time for Stella as ARM code "runs in zero 6507 cycles".
|
||||||
case 255: // call without IRQ driven audio
|
case 255: // call without IRQ driven audio
|
||||||
try {
|
try {
|
||||||
Int32 cycles = mySystem->cycles() - myARMCycles;
|
Int32 cycles = mySystem->cycles() - myARMCycles;
|
||||||
myARMCycles = mySystem->cycles();
|
myARMCycles = mySystem->cycles();
|
||||||
|
|
||||||
myThumbEmulator->run(cycles);
|
myThumbEmulator->run(cycles);
|
||||||
}
|
}
|
||||||
catch(const runtime_error& e) {
|
catch(const runtime_error& e) {
|
||||||
|
@ -202,14 +191,14 @@ inline void CartridgeCDF::callFunction(uInt8 value)
|
||||||
uInt8 CartridgeCDF::peek(uInt16 address)
|
uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
uInt8 peekvalue = myProgramImage[(myCurrentBank << 12) + address];
|
uInt8 peekvalue = myProgramImage[(myCurrentBank << 12) + address];
|
||||||
|
|
||||||
// In debugger/bank-locked mode, we ignore all hotspots and in general
|
// In debugger/bank-locked mode, we ignore all hotspots and in general
|
||||||
// anything that can change the internal state of the cart
|
// anything that can change the internal state of the cart
|
||||||
if(bankLocked())
|
if(bankLocked())
|
||||||
return peekvalue;
|
return peekvalue;
|
||||||
|
|
||||||
// Check if we're in Fast Fetch mode and the prior byte was an A9 (LDA #value)
|
// Check if we're in Fast Fetch mode and the prior byte was an A9 (LDA #value)
|
||||||
if(FAST_FETCH_ON && myLDAimmediateOperandAddress == address)
|
if(FAST_FETCH_ON && myLDAimmediateOperandAddress == address)
|
||||||
{
|
{
|
||||||
|
@ -219,15 +208,14 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
}
|
}
|
||||||
myLDAimmediateOperandAddress = 0;
|
myLDAimmediateOperandAddress = 0;
|
||||||
|
|
||||||
|
|
||||||
if(address <= 0x20)
|
if(address <= 0x20)
|
||||||
{
|
{
|
||||||
uInt8 result = 0;
|
uInt8 result = 0;
|
||||||
|
|
||||||
// Get the index of the data fetcher that's being accessed
|
// Get the index of the data fetcher that's being accessed
|
||||||
uInt32 index = address & 0x1f;
|
uInt32 index = address & 0x1f;
|
||||||
uInt32 function = (address >> 5) & 0x01;
|
uInt32 function = (address >> 5) & 0x01;
|
||||||
|
|
||||||
switch(function)
|
switch(function)
|
||||||
{
|
{
|
||||||
case 0x00: // read from a datastream
|
case 0x00: // read from a datastream
|
||||||
|
@ -240,18 +228,18 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
// index will be 0 for address 0x20 = AMPLITUDE
|
// index will be 0 for address 0x20 = AMPLITUDE
|
||||||
// Update the music data fetchers (counter & flag)
|
// Update the music data fetchers (counter & flag)
|
||||||
updateMusicModeDataFetchers();
|
updateMusicModeDataFetchers();
|
||||||
|
|
||||||
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
||||||
// can be modified during runtime.
|
// can be modified during runtime.
|
||||||
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
|
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
|
||||||
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
|
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
|
||||||
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
|
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
|
||||||
|
|
||||||
result = uInt8(i);
|
result = uInt8(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -263,44 +251,44 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
// Set the current bank to the first 4k bank
|
// Set the current bank to the first 4k bank
|
||||||
bank(0);
|
bank(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF6:
|
case 0x0FF6:
|
||||||
// Set the current bank to the second 4k bank
|
// Set the current bank to the second 4k bank
|
||||||
bank(1);
|
bank(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF7:
|
case 0x0FF7:
|
||||||
// Set the current bank to the third 4k bank
|
// Set the current bank to the third 4k bank
|
||||||
bank(2);
|
bank(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF8:
|
case 0x0FF8:
|
||||||
// Set the current bank to the fourth 4k bank
|
// Set the current bank to the fourth 4k bank
|
||||||
bank(3);
|
bank(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF9:
|
case 0x0FF9:
|
||||||
// Set the current bank to the fifth 4k bank
|
// Set the current bank to the fifth 4k bank
|
||||||
bank(4);
|
bank(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFA:
|
case 0x0FFA:
|
||||||
// Set the current bank to the sixth 4k bank
|
// Set the current bank to the sixth 4k bank
|
||||||
bank(5);
|
bank(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFB:
|
case 0x0FFB:
|
||||||
// Set the current bank to the last 4k bank
|
// Set the current bank to the last 4k bank
|
||||||
bank(6);
|
bank(6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FAST_FETCH_ON && peekvalue == 0xA9)
|
if(FAST_FETCH_ON && peekvalue == 0xA9)
|
||||||
myLDAimmediateOperandAddress = address + 1;
|
myLDAimmediateOperandAddress = address + 1;
|
||||||
|
|
||||||
return peekvalue;
|
return peekvalue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,31 +297,31 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
if ((address >= 0x21) && (address <= 0x2B))
|
if ((address >= 0x21) && (address <= 0x2B))
|
||||||
{
|
{
|
||||||
// Get the index of the data fetcher that's being accessed
|
// Get the index of the data fetcher that's being accessed
|
||||||
uInt32 index = address & 0x0f;
|
uInt32 index = address & 0x0f;
|
||||||
uInt32 pointer;
|
uInt32 pointer;
|
||||||
uInt32 stream = address & 0x03;
|
uInt32 stream = address & 0x03;
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 0x00: // 0x20 AMPLITUDE - read register
|
case 0x00: // 0x20 AMPLITUDE - read register
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x01: // 0x21 SETMODE
|
case 0x01: // 0x21 SETMODE
|
||||||
myMode = value;
|
myMode = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x02: // 0x22 CALLFN
|
case 0x02: // 0x22 CALLFN
|
||||||
callFunction(value);
|
callFunction(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03: // 0x23 RESERVED
|
case 0x03: // 0x23 RESERVED
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0x04: // 0x24 DS0WRITE
|
case 0x04: // 0x24 DS0WRITE
|
||||||
case 0x05: // 0x25 DS1WRITE
|
case 0x05: // 0x25 DS1WRITE
|
||||||
case 0x06: // 0x26 DS2WRITE
|
case 0x06: // 0x26 DS2WRITE
|
||||||
|
@ -343,13 +331,13 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
||||||
//
|
//
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
pointer = getDatastreamPointer(stream);
|
pointer = getDatastreamPointer(stream);
|
||||||
myDisplayImage[ pointer >> 20 ] = value;
|
myDisplayImage[ pointer >> 20 ] = value;
|
||||||
pointer += 0x100000; // always increment by 1 when writing
|
pointer += 0x100000; // always increment by 1 when writing
|
||||||
setDatastreamPointer(stream, pointer);
|
setDatastreamPointer(stream, pointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: // 0x28 DS0PTR
|
case 0x08: // 0x28 DS0PTR
|
||||||
case 0x09: // 0x29 DS1PTR
|
case 0x09: // 0x29 DS1PTR
|
||||||
case 0x0A: // 0x2A DS2PTR
|
case 0x0A: // 0x2A DS2PTR
|
||||||
|
@ -359,7 +347,7 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
||||||
//
|
//
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
pointer = getDatastreamPointer(stream);
|
pointer = getDatastreamPointer(stream);
|
||||||
pointer <<=8;
|
pointer <<=8;
|
||||||
pointer &= 0xf0000000;
|
pointer &= 0xf0000000;
|
||||||
|
@ -377,42 +365,42 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
||||||
// Set the current bank to the first 4k bank
|
// Set the current bank to the first 4k bank
|
||||||
bank(0);
|
bank(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF6:
|
case 0x0FF6:
|
||||||
// Set the current bank to the second 4k bank
|
// Set the current bank to the second 4k bank
|
||||||
bank(1);
|
bank(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF7:
|
case 0x0FF7:
|
||||||
// Set the current bank to the third 4k bank
|
// Set the current bank to the third 4k bank
|
||||||
bank(2);
|
bank(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF8:
|
case 0x0FF8:
|
||||||
// Set the current bank to the fourth 4k bank
|
// Set the current bank to the fourth 4k bank
|
||||||
bank(3);
|
bank(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FF9:
|
case 0x0FF9:
|
||||||
// Set the current bank to the fifth 4k bank
|
// Set the current bank to the fifth 4k bank
|
||||||
bank(4);
|
bank(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFA:
|
case 0x0FFA:
|
||||||
// Set the current bank to the sixth 4k bank
|
// Set the current bank to the sixth 4k bank
|
||||||
bank(5);
|
bank(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0FFB:
|
case 0x0FFB:
|
||||||
// Set the current bank to the last 4k bank
|
// Set the current bank to the last 4k bank
|
||||||
bank(6);
|
bank(6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,14 +408,14 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
||||||
bool CartridgeCDF::bank(uInt16 bank)
|
bool CartridgeCDF::bank(uInt16 bank)
|
||||||
{
|
{
|
||||||
if(bankLocked()) return false;
|
if(bankLocked()) return false;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentBank = bank;
|
myCurrentBank = bank;
|
||||||
uInt16 offset = myCurrentBank << 12;
|
uInt16 offset = myCurrentBank << 12;
|
||||||
|
|
||||||
// Setup the page access methods for the current bank
|
// Setup the page access methods for the current bank
|
||||||
System::PageAccess access(this, System::PA_READ);
|
System::PageAccess access(this, System::PA_READ);
|
||||||
|
|
||||||
// Map Program ROM image into the system
|
// Map Program ROM image into the system
|
||||||
for(uInt32 address = 0x1040; address < 0x2000;
|
for(uInt32 address = 0x1040; address < 0x2000;
|
||||||
address += (1 << System::PAGE_SHIFT))
|
address += (1 << System::PAGE_SHIFT))
|
||||||
|
@ -454,7 +442,7 @@ uInt16 CartridgeCDF::bankCount() const
|
||||||
bool CartridgeCDF::patch(uInt16 address, uInt8 value)
|
bool CartridgeCDF::patch(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
// For now, we ignore attempts to patch the CDF address space
|
// For now, we ignore attempts to patch the CDF address space
|
||||||
if(address >= 0x0040)
|
if(address >= 0x0040)
|
||||||
{
|
{
|
||||||
|
@ -478,31 +466,30 @@ const uInt8* CartridgeCDF::getImage(int& size) const
|
||||||
|
|
||||||
uInt32 CartridgeCDF::thumbCallback(uInt8 function, uInt32 value1, uInt32 value2)
|
uInt32 CartridgeCDF::thumbCallback(uInt8 function, uInt32 value1, uInt32 value2)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (function)
|
switch (function)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
// _SetNote - set the note/frequency
|
// _SetNote - set the note/frequency
|
||||||
myMusicFrequencies[value1] = value2;
|
myMusicFrequencies[value1] = value2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// _ResetWave - reset counter,
|
// _ResetWave - reset counter,
|
||||||
// used to make sure digital samples start from the beginning
|
// used to make sure digital samples start from the beginning
|
||||||
case 1:
|
case 1:
|
||||||
myMusicCounters[value1] = 0;
|
myMusicCounters[value1] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// _GetWavePtr - return the counter
|
// _GetWavePtr - return the counter
|
||||||
case 2:
|
case 2:
|
||||||
return myMusicCounters[value1];
|
return myMusicCounters[value1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// _SetWaveSize - set size of waveform buffer
|
// _SetWaveSize - set size of waveform buffer
|
||||||
case 3:
|
case 3:
|
||||||
myMusicWaveformSize[value1] = value2;
|
myMusicWaveformSize[value1] = value2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,13 +500,13 @@ bool CartridgeCDF::save(Serializer& out) const
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates which bank is currently active
|
||||||
out.putShort(myCurrentBank);
|
out.putShort(myCurrentBank);
|
||||||
|
|
||||||
// Harmony RAM
|
// Harmony RAM
|
||||||
out.putByteArray(myCDFRAM, 8192);
|
out.putByteArray(myCDFRAM, 8192);
|
||||||
|
|
||||||
out.putInt(mySystemCycles);
|
out.putInt(mySystemCycles);
|
||||||
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
||||||
out.putInt(myARMCycles);
|
out.putInt(myARMCycles);
|
||||||
|
@ -529,7 +516,7 @@ bool CartridgeCDF::save(Serializer& out) const
|
||||||
cerr << "ERROR: CartridgeCDF::save" << endl;
|
cerr << "ERROR: CartridgeCDF::save" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,17 +527,17 @@ bool CartridgeCDF::load(Serializer& in)
|
||||||
{
|
{
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates which bank is currently active
|
||||||
myCurrentBank = in.getShort();
|
myCurrentBank = in.getShort();
|
||||||
|
|
||||||
// Harmony RAM
|
// Harmony RAM
|
||||||
in.getByteArray(myCDFRAM, 8192);
|
in.getByteArray(myCDFRAM, 8192);
|
||||||
|
|
||||||
// Get system cycles and fractional clocks
|
// Get system cycles and fractional clocks
|
||||||
mySystemCycles = (Int32)in.getInt();
|
mySystemCycles = (Int32)in.getInt();
|
||||||
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
||||||
|
|
||||||
myARMCycles = (Int32)in.getInt();
|
myARMCycles = (Int32)in.getInt();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -558,23 +545,25 @@ bool CartridgeCDF::load(Serializer& in)
|
||||||
cerr << "ERROR: CartridgeCDF::load" << endl;
|
cerr << "ERROR: CartridgeCDF::load" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, go to the current bank
|
// Now, go to the current bank
|
||||||
bank(myCurrentBank);
|
bank(myCurrentBank);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
// index &= 0x0f;
|
||||||
|
|
||||||
return myCDFRAM[DSxPTR + index*4 + 0] + // low byte
|
return myCDFRAM[DSxPTR + index*4 + 0] + // low byte
|
||||||
(myCDFRAM[DSxPTR + index*4 + 1] << 8) +
|
(myCDFRAM[DSxPTR + index*4 + 1] << 8) +
|
||||||
(myCDFRAM[DSxPTR + index*4 + 2] << 16) +
|
(myCDFRAM[DSxPTR + index*4 + 2] << 16) +
|
||||||
(myCDFRAM[DSxPTR + index*4 + 3] << 24) ; // high byte
|
(myCDFRAM[DSxPTR + index*4 + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
// index &= 0x1f;
|
// index &= 0x1f;
|
||||||
|
@ -584,15 +573,17 @@ void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
myCDFRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myCDFRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const
|
||||||
{
|
{
|
||||||
// index &= 0x1f;
|
// index &= 0x1f;
|
||||||
return myCDFRAM[DSxINC + index*4 + 0] + // low byte
|
return myCDFRAM[DSxINC + index*4 + 0] + // low byte
|
||||||
(myCDFRAM[DSxINC + index*4 + 1] << 8) +
|
(myCDFRAM[DSxINC + index*4 + 1] << 8) +
|
||||||
(myCDFRAM[DSxINC + index*4 + 2] << 16) +
|
(myCDFRAM[DSxINC + index*4 + 2] << 16) +
|
||||||
(myCDFRAM[DSxINC + index*4 + 3] << 24) ; // high byte
|
(myCDFRAM[DSxINC + index*4 + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::setDatastreamIncrement(uInt8 index, uInt32 value)
|
void CartridgeCDF::setDatastreamIncrement(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
// index &= 0x1f;
|
// index &= 0x1f;
|
||||||
|
@ -602,41 +593,43 @@ void CartridgeCDF::setDatastreamIncrement(uInt8 index, uInt32 value)
|
||||||
myCDFRAM[DSxINC + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myCDFRAM[DSxINC + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeCDF::getWaveform(uInt8 index)
|
uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
||||||
{
|
{
|
||||||
// instead of 0, 1, 2, etc. this returned
|
// instead of 0, 1, 2, etc. this returned
|
||||||
// 0x40000800 for 0
|
// 0x40000800 for 0
|
||||||
// 0x40000820 for 1
|
// 0x40000820 for 1
|
||||||
// 0x40000840 for 2
|
// 0x40000840 for 2
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
// return myCDFRAM[WAVEFORM + index*4 + 0] + // low byte
|
// return myCDFRAM[WAVEFORM + index*4 + 0] + // low byte
|
||||||
// (myCDFRAM[WAVEFORM + index*4 + 1] << 8) +
|
// (myCDFRAM[WAVEFORM + index*4 + 1] << 8) +
|
||||||
// (myCDFRAM[WAVEFORM + index*4 + 2] << 16) +
|
// (myCDFRAM[WAVEFORM + index*4 + 2] << 16) +
|
||||||
// (myCDFRAM[WAVEFORM + index*4 + 3] << 24) - // high byte
|
// (myCDFRAM[WAVEFORM + index*4 + 3] << 24) - // high byte
|
||||||
// 0x40000800;
|
// 0x40000800;
|
||||||
|
|
||||||
uInt32 result;
|
uInt32 result;
|
||||||
|
|
||||||
result = myCDFRAM[WAVEFORM + index*4 + 0] + // low byte
|
result = myCDFRAM[WAVEFORM + index*4 + 0] + // low byte
|
||||||
(myCDFRAM[WAVEFORM + index*4 + 1] << 8) +
|
(myCDFRAM[WAVEFORM + index*4 + 1] << 8) +
|
||||||
(myCDFRAM[WAVEFORM + index*4 + 2] << 16) +
|
(myCDFRAM[WAVEFORM + index*4 + 2] << 16) +
|
||||||
(myCDFRAM[WAVEFORM + index*4 + 3] << 24);
|
(myCDFRAM[WAVEFORM + index*4 + 3] << 24);
|
||||||
|
|
||||||
result -= 0x40000800;
|
result -= 0x40000800;
|
||||||
|
|
||||||
if (result >= 4096)
|
if (result >= 4096)
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uInt32 CartridgeCDF::getWaveformSize(uInt8 index)
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
uInt32 CartridgeCDF::getWaveformSize(uInt8 index) const
|
||||||
{
|
{
|
||||||
return myMusicWaveformSize[index];
|
return myMusicWaveformSize[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
|
uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
|
||||||
{
|
{
|
||||||
// Pointers are stored as:
|
// Pointers are stored as:
|
||||||
|
@ -648,7 +641,7 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
|
||||||
// P = Pointer
|
// P = Pointer
|
||||||
// I = Increment
|
// I = Increment
|
||||||
// F = Fractional
|
// F = Fractional
|
||||||
|
|
||||||
uInt32 pointer = getDatastreamPointer(index);
|
uInt32 pointer = getDatastreamPointer(index);
|
||||||
uInt16 increment = getDatastreamIncrement(index);
|
uInt16 increment = getDatastreamIncrement(index);
|
||||||
uInt8 value = myDisplayImage[ pointer >> 20 ];
|
uInt8 value = myDisplayImage[ pointer >> 20 ];
|
||||||
|
@ -656,4 +649,3 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
|
||||||
setDatastreamPointer(index, pointer);
|
setDatastreamPointer(index, pointer);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
// SS SS tt ee ll ll aa aa
|
// SS SS tt ee ll ll aa aa
|
||||||
// SSSS ttt eeeee llll llll aaaaa
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
//
|
//
|
||||||
// Copyright (c) 1995-2015 by Bradford W. Mott, Stephen Anthony
|
// Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony
|
||||||
// and the Stella Team
|
// and the Stella Team
|
||||||
//
|
//
|
||||||
// See the file "License.txt" for information on usage and redistribution of
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
|
||||||
// $Id: CartCDF.hxx 3131 2015-01-01 03:49:32Z stephena $
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#ifndef CARTRIDGE_CDF_HXX
|
#ifndef CARTRIDGE_CDF_HXX
|
||||||
|
@ -22,264 +20,260 @@
|
||||||
|
|
||||||
class System;
|
class System;
|
||||||
#ifdef THUMB_SUPPORT
|
#ifdef THUMB_SUPPORT
|
||||||
class Thumbulator;
|
class Thumbulator;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
#include "CartCDFWidget.hxx"
|
#include "CartCDFWidget.hxx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Cart.hxx"
|
#include "Cart.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Cartridge class used for CDF.
|
Cartridge class used for CDF.
|
||||||
|
|
||||||
THIS NEEDS TO BE UPDATED
|
THIS NEEDS TO BE UPDATED
|
||||||
|
|
||||||
|
|
||||||
There are seven 4K program banks, a 4K Display Data RAM,
|
There are seven 4K program banks, a 4K Display Data RAM,
|
||||||
1K C Varaible and Stack, and the CDF chip.
|
1K C Varaible and Stack, and the CDF chip.
|
||||||
CDF chip access is mapped to $1000 - $103F.
|
CDF chip access is mapped to $1000 - $103F.
|
||||||
|
|
||||||
@author Darrell Spice Jr, Chris Walton, Fred Quimby, Stephen Anthony, Bradford W. Mott
|
Authors: Darrell Spice Jr, Chris Walton, Fred Quimby,
|
||||||
@version $Id: CartCDF.hxx 3131 2015-01-01 03:49:32Z stephena $
|
Stephen Anthony, Bradford W. Mott
|
||||||
*/
|
*/
|
||||||
class CartridgeCDF : public Cartridge
|
class CartridgeCDF : public Cartridge
|
||||||
{
|
{
|
||||||
friend class CartridgeCDFWidget;
|
friend class CartridgeCDFWidget;
|
||||||
friend class CartridgeRamCDFWidget;
|
friend class CartridgeRamCDFWidget;
|
||||||
|
|
||||||
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)
|
|
||||||
*/
|
|
||||||
CartridgeCDF(const uInt8* image, uInt32 size, const Settings& settings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Destructor
|
|
||||||
*/
|
|
||||||
virtual ~CartridgeCDF();
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
Reset device to its power-on state
|
|
||||||
*/
|
|
||||||
void reset() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Notification method invoked by the system when the console type
|
|
||||||
has changed. We need this to inform the Thumbulator that the
|
|
||||||
timing has changed.
|
|
||||||
|
|
||||||
@param timing Enum representing the new console type
|
|
||||||
*/
|
|
||||||
void consoleChanged(ConsoleTiming timing) override;
|
|
||||||
|
|
||||||
/**
|
public:
|
||||||
Notification method invoked by the system right before the
|
/**
|
||||||
system resets its cycle counter to zero. It may be necessary
|
Create a new cartridge using the specified image
|
||||||
to override this method for devices that remember cycle counts.
|
|
||||||
*/
|
@param image Pointer to the ROM image
|
||||||
void systemCyclesReset() override;
|
@param size The size of the ROM image
|
||||||
|
@param settings A reference to the various settings (read-only)
|
||||||
/**
|
*/
|
||||||
Install cartridge in the specified system. Invoked by the system
|
CartridgeCDF(const uInt8* image, uInt32 size, const Settings& settings);
|
||||||
when the cartridge is attached to it.
|
virtual ~CartridgeCDF() = default;
|
||||||
|
|
||||||
@param system The system the device should install itself in
|
public:
|
||||||
*/
|
/**
|
||||||
void install(System& system) override;
|
Reset device to its power-on state
|
||||||
|
*/
|
||||||
/**
|
void reset() override;
|
||||||
Install pages for the specified bank in the system.
|
|
||||||
|
/**
|
||||||
@param bank The bank that should be installed in the system
|
Notification method invoked by the system when the console type
|
||||||
*/
|
has changed. We need this to inform the Thumbulator that the
|
||||||
bool bank(uInt16 bank) override;
|
timing has changed.
|
||||||
|
|
||||||
/**
|
@param timing Enum representing the new console type
|
||||||
Get the current bank.
|
*/
|
||||||
*/
|
void consoleChanged(ConsoleTiming timing) override;
|
||||||
uInt16 getBank() const override;
|
|
||||||
|
/**
|
||||||
/**
|
Notification method invoked by the system right before the
|
||||||
Query the number of banks supported by the cartridge.
|
system resets its cycle counter to zero. It may be necessary
|
||||||
*/
|
to override this method for devices that remember cycle counts.
|
||||||
uInt16 bankCount() const override;
|
*/
|
||||||
|
void systemCyclesReset() override;
|
||||||
/**
|
|
||||||
Patch the cartridge ROM.
|
/**
|
||||||
|
Install cartridge in the specified system. Invoked by the system
|
||||||
@param address The ROM address to patch
|
when the cartridge is attached to it.
|
||||||
@param value The value to place into the address
|
|
||||||
@return Success or failure of the patch operation
|
@param system The system the device should install itself in
|
||||||
*/
|
*/
|
||||||
bool patch(uInt16 address, uInt8 value) override;
|
void install(System& system) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Access the internal ROM image for this cartridge.
|
Install pages for the specified bank in the system.
|
||||||
|
|
||||||
@param size Set to the size of the internal ROM image data
|
@param bank The bank that should be installed in the system
|
||||||
@return A pointer to the internal ROM image data
|
*/
|
||||||
*/
|
bool bank(uInt16 bank) override;
|
||||||
const uInt8* getImage(int& size) const override;
|
|
||||||
|
/**
|
||||||
/**
|
Get the current bank.
|
||||||
Save the current state of this cart to the given Serializer.
|
*/
|
||||||
|
uInt16 getBank() const override;
|
||||||
@param out The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
/**
|
||||||
*/
|
Query the number of banks supported by the cartridge.
|
||||||
bool save(Serializer& out) const override;
|
*/
|
||||||
|
uInt16 bankCount() const override;
|
||||||
/**
|
|
||||||
Load the current state of this cart from the given Serializer.
|
/**
|
||||||
|
Patch the cartridge ROM.
|
||||||
@param in The Serializer object to use
|
|
||||||
@return False on any errors, else true
|
@param address The ROM address to patch
|
||||||
*/
|
@param value The value to place into the address
|
||||||
bool load(Serializer& in) override;
|
@return Success or failure of the patch operation
|
||||||
|
*/
|
||||||
/**
|
bool patch(uInt16 address, uInt8 value) override;
|
||||||
Get a descriptor for the device name (used in error checking).
|
|
||||||
|
/**
|
||||||
@return The name of the object
|
Access the internal ROM image for this cartridge.
|
||||||
*/
|
|
||||||
string name() const override { return "CartridgeCDF"; }
|
@param size Set to the size of the internal ROM image data
|
||||||
|
@return A pointer to the internal ROM image data
|
||||||
// uInt8 busOverdrive(uInt16 address) override;
|
*/
|
||||||
|
const uInt8* getImage(int& size) const override;
|
||||||
/**
|
|
||||||
Used for Thumbulator to pass values back to the cartridge
|
/**
|
||||||
*/
|
Save the current state of this cart to the given Serializer.
|
||||||
uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override;
|
|
||||||
|
@param out The Serializer object to use
|
||||||
|
@return False on any errors, else true
|
||||||
|
*/
|
||||||
|
bool save(Serializer& out) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
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) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get a descriptor for the device name (used in error checking).
|
||||||
|
|
||||||
|
@return The name of the object
|
||||||
|
*/
|
||||||
|
string name() const override { return "CartridgeCDF"; }
|
||||||
|
|
||||||
|
// uInt8 busOverdrive(uInt16 address) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used for Thumbulator to pass values back to the cartridge
|
||||||
|
*/
|
||||||
|
uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override;
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
/**
|
/**
|
||||||
Get debugger widget responsible for accessing the inner workings
|
Get debugger widget responsible for accessing the inner workings
|
||||||
of the cart.
|
of the cart.
|
||||||
*/
|
*/
|
||||||
CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
|
CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
|
||||||
const GUI::Font& nfont, int x, int y, int w, int h) override
|
const GUI::Font& nfont, int x, int y, int w, int h) override
|
||||||
{
|
{
|
||||||
return new CartridgeCDFWidget(boss, lfont, nfont, x, y, w, h, *this);
|
return new CartridgeCDFWidget(boss, lfont, nfont, x, y, w, h, *this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Get the byte at the specified address.
|
Get the byte at the specified address.
|
||||||
|
|
||||||
@return The byte at the specified address
|
@return The byte at the specified address
|
||||||
*/
|
*/
|
||||||
uInt8 peek(uInt16 address) override;
|
uInt8 peek(uInt16 address) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Change the byte at the specified address to the given value
|
Change the byte at the specified address to the given value
|
||||||
|
|
||||||
@param address The address where the value should be stored
|
@param address The address where the value should be stored
|
||||||
@param value The value to be stored at the address
|
@param value The value to be stored at the address
|
||||||
@return True if the poke changed the device address space, else false
|
@return True if the poke changed the device address space, else false
|
||||||
*/
|
*/
|
||||||
bool poke(uInt16 address, uInt8 value) override;
|
bool poke(uInt16 address, uInt8 value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
Sets the initial state of the DPC pointers and RAM
|
Sets the initial state of the DPC pointers and RAM
|
||||||
*/
|
*/
|
||||||
void setInitialState();
|
void setInitialState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Updates any data fetchers in music mode based on the number of
|
Updates any data fetchers in music mode based on the number of
|
||||||
CPU cycles which have passed since the last update.
|
CPU cycles which have passed since the last update.
|
||||||
*/
|
*/
|
||||||
void updateMusicModeDataFetchers();
|
void updateMusicModeDataFetchers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Call Special Functions
|
Call Special Functions
|
||||||
*/
|
*/
|
||||||
void callFunction(uInt8 value);
|
void callFunction(uInt8 value);
|
||||||
|
|
||||||
uInt32 getDatastreamPointer(uInt8 index);
|
uInt32 getDatastreamPointer(uInt8 index) const;
|
||||||
void setDatastreamPointer(uInt8 index, uInt32 value);
|
void setDatastreamPointer(uInt8 index, uInt32 value);
|
||||||
|
|
||||||
uInt32 getDatastreamIncrement(uInt8 index);
|
uInt32 getDatastreamIncrement(uInt8 index) const;
|
||||||
void setDatastreamIncrement(uInt8 index, uInt32 value);
|
void setDatastreamIncrement(uInt8 index, uInt32 value);
|
||||||
|
|
||||||
uInt8 readFromDatastream(uInt8 index);
|
uInt8 readFromDatastream(uInt8 index);
|
||||||
|
|
||||||
uInt32 getWaveform(uInt8 index);
|
uInt32 getWaveform(uInt8 index) const;
|
||||||
uInt32 getWaveformSize(uInt8 index);
|
uInt32 getWaveformSize(uInt8 index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The 32K ROM image of the cartridge
|
// The 32K ROM image of the cartridge
|
||||||
uInt8 myImage[32768];
|
uInt8 myImage[32768];
|
||||||
|
|
||||||
// Pointer to the 28K program ROM image of the cartridge
|
// Pointer to the 28K program ROM image of the cartridge
|
||||||
uInt8* myProgramImage;
|
uInt8* myProgramImage;
|
||||||
|
|
||||||
// Pointer to the 4K display ROM image of the cartridge
|
// Pointer to the 4K display ROM image of the cartridge
|
||||||
uInt8* myDisplayImage;
|
uInt8* myDisplayImage;
|
||||||
|
|
||||||
// Pointer to the 2K CDF driver image in RAM
|
// Pointer to the 2K CDF driver image in RAM
|
||||||
uInt8* myBusDriverImage;
|
uInt8* myBusDriverImage;
|
||||||
|
|
||||||
// The CDF 8k RAM image, used as:
|
// The CDF 8k RAM image, used as:
|
||||||
// $0000 - 2K CDF driver
|
// $0000 - 2K CDF driver
|
||||||
// $0800 - 4K Display Data
|
// $0800 - 4K Display Data
|
||||||
// $1800 - 2K C Variable & Stack
|
// $1800 - 2K C Variable & Stack
|
||||||
uInt8 myCDFRAM[8192];
|
uInt8 myCDFRAM[8192];
|
||||||
|
|
||||||
#ifdef THUMB_SUPPORT
|
#ifdef THUMB_SUPPORT
|
||||||
// Pointer to the Thumb ARM emulator object
|
// Pointer to the Thumb ARM emulator object
|
||||||
unique_ptr<Thumbulator> myThumbEmulator;
|
unique_ptr<Thumbulator> myThumbEmulator;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Indicates which bank is currently active
|
// Indicates which bank is currently active
|
||||||
uInt16 myCurrentBank;
|
uInt16 myCurrentBank;
|
||||||
|
|
||||||
// System cycle count when the last update to music data fetchers occurred
|
// System cycle count when the last update to music data fetchers occurred
|
||||||
Int32 mySystemCycles;
|
Int32 mySystemCycles;
|
||||||
|
|
||||||
Int32 myARMCycles;
|
Int32 myARMCycles;
|
||||||
|
|
||||||
uInt8 mySetAddress;
|
uInt8 mySetAddress;
|
||||||
|
|
||||||
// The music mode counters
|
// The music mode counters
|
||||||
uInt32 myMusicCounters[3];
|
uInt32 myMusicCounters[3];
|
||||||
|
|
||||||
// The music frequency
|
// The music frequency
|
||||||
uInt32 myMusicFrequencies[3];
|
uInt32 myMusicFrequencies[3];
|
||||||
|
|
||||||
// The music waveform sizes
|
// The music waveform sizes
|
||||||
uInt8 myMusicWaveformSize[3];
|
uInt8 myMusicWaveformSize[3];
|
||||||
|
|
||||||
// Fractional DPC music OSC clocks unused during the last update
|
// Fractional DPC music OSC clocks unused during the last update
|
||||||
double myFractionalClocks;
|
double myFractionalClocks;
|
||||||
|
|
||||||
// Controls mode, lower nybble sets Fast Fetch, upper nybble sets audio
|
// Controls mode, lower nybble sets Fast Fetch, upper nybble sets audio
|
||||||
// -0 = Fast Fetch ON
|
// -0 = Fast Fetch ON
|
||||||
// -F = Fast Fetch OFF
|
// -F = Fast Fetch OFF
|
||||||
// 0- = Packed Digital Sample
|
// 0- = Packed Digital Sample
|
||||||
// F- = 3 Voice Music
|
// F- = 3 Voice Music
|
||||||
uInt8 myMode;
|
uInt8 myMode;
|
||||||
|
|
||||||
// set to address of #value if last byte peeked was A9 (LDA #)
|
// set to address of #value if last byte peeked was A9 (LDA #)
|
||||||
uInt16 myLDAimmediateOperandAddress;
|
uInt16 myLDAimmediateOperandAddress;
|
||||||
|
|
||||||
TIA* myTIA;
|
TIA* myTIA;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeCDF() = delete;
|
CartridgeCDF() = delete;
|
||||||
CartridgeCDF(const CartridgeCDF&) = delete;
|
CartridgeCDF(const CartridgeCDF&) = delete;
|
||||||
CartridgeCDF(CartridgeCDF&&) = delete;
|
CartridgeCDF(CartridgeCDF&&) = delete;
|
||||||
CartridgeCDF& operator=(const CartridgeCDF&) = delete;
|
CartridgeCDF& operator=(const CartridgeCDF&) = delete;
|
||||||
CartridgeCDF& operator=(CartridgeCDF&&) = delete;
|
CartridgeCDF& operator=(CartridgeCDF&&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,6 +85,7 @@ string Thumbulator::run()
|
||||||
return statusMsg.str();
|
return statusMsg.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::setConsoleTiming(ConsoleTiming timing)
|
void Thumbulator::setConsoleTiming(ConsoleTiming timing)
|
||||||
{
|
{
|
||||||
// this sets how many ticks of the Harmony/Melody clock
|
// this sets how many ticks of the Harmony/Melody clock
|
||||||
|
@ -92,7 +93,7 @@ void Thumbulator::setConsoleTiming(ConsoleTiming timing)
|
||||||
constexpr double NTSC = 70.0 / 1.193182; // NTSC 6507 clock rate
|
constexpr double NTSC = 70.0 / 1.193182; // NTSC 6507 clock rate
|
||||||
constexpr double PAL = 70.0 / 1.182298; // PAL 6507 clock rate
|
constexpr double PAL = 70.0 / 1.182298; // PAL 6507 clock rate
|
||||||
constexpr double SECAM = 70.0 / 1.187500; // SECAM 6507 clock rate
|
constexpr double SECAM = 70.0 / 1.187500; // SECAM 6507 clock rate
|
||||||
|
|
||||||
switch (timing)
|
switch (timing)
|
||||||
{
|
{
|
||||||
case ConsoleTiming::ntsc: timing_factor = NTSC; break;
|
case ConsoleTiming::ntsc: timing_factor = NTSC; break;
|
||||||
|
@ -104,22 +105,15 @@ void Thumbulator::setConsoleTiming(ConsoleTiming timing)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::updateTimer(uInt32 cycles)
|
void Thumbulator::updateTimer(uInt32 cycles)
|
||||||
{
|
{
|
||||||
double increment;
|
|
||||||
|
|
||||||
increment = cycles * timing_factor;
|
|
||||||
|
|
||||||
if (T1TCR & 1) // bit 0 controls timer on/off
|
if (T1TCR & 1) // bit 0 controls timer on/off
|
||||||
{
|
T1TC += uInt32(cycles * timing_factor);
|
||||||
|
|
||||||
T1TC += uInt32(increment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string Thumbulator::run(uInt32 cycles)
|
string Thumbulator::run(uInt32 cycles)
|
||||||
{
|
{
|
||||||
updateTimer(cycles);
|
updateTimer(cycles);
|
||||||
return this->run();
|
return run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -230,23 +224,23 @@ void Thumbulator::write16(uInt32 addr, uInt32 data)
|
||||||
{
|
{
|
||||||
if((addr > 0x40001fff) && (addr < 0x50000000))
|
if((addr > 0x40001fff) && (addr < 0x50000000))
|
||||||
fatalError("write16", addr, "abort - out of range");
|
fatalError("write16", addr, "abort - out of range");
|
||||||
|
|
||||||
switch(configuration)
|
switch(configuration)
|
||||||
{
|
{
|
||||||
// this protects 2K Harmony/Melody Drivers
|
// this protects 2K Harmony/Melody Drivers
|
||||||
// Initial section of driver is the bootstrap which copies the driver
|
// Initial section of driver is the bootstrap which copies the driver
|
||||||
// from ROM to RAM, so it can safely be used by the custom ARM code
|
// from ROM to RAM, so it can safely be used by the custom ARM code
|
||||||
// as additional RAM
|
// as additional RAM
|
||||||
case ConfigureFor::BUS:
|
case ConfigureFor::BUS:
|
||||||
case ConfigureFor::CDF:
|
case ConfigureFor::CDF:
|
||||||
if((addr > 0x40000028) && (addr < 0x40000800))
|
if((addr > 0x40000028) && (addr < 0x40000800))
|
||||||
fatalError("write16", addr, "to bankswitch code area");
|
fatalError("write16", addr, "to bankswitch code area");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// this protects 3K Harmony/Melody Drivers
|
// this protects 3K Harmony/Melody Drivers
|
||||||
// Initial section of driver is the bootstrap which copies the driver
|
// Initial section of driver is the bootstrap which copies the driver
|
||||||
// from ROM to RAM, so it can safely be used by the custom ARM code
|
// from ROM to RAM, so it can safely be used by the custom ARM code
|
||||||
// as additional RAM
|
// as additional RAM
|
||||||
case ConfigureFor::DPCplus:
|
case ConfigureFor::DPCplus:
|
||||||
if((addr > 0x40000028) && (addr < 0x40000c00))
|
if((addr > 0x40000028) && (addr < 0x40000c00))
|
||||||
fatalError("write16", addr, "to bankswitch code area");
|
fatalError("write16", addr, "to bankswitch code area");
|
||||||
|
@ -299,11 +293,11 @@ void Thumbulator::write32(uInt32 addr, uInt32 data)
|
||||||
case 0xE0000000:
|
case 0xE0000000:
|
||||||
DO_DISS(statusMsg << "uart: [" << char(data&0xFF) << "]" << endl);
|
DO_DISS(statusMsg << "uart: [" << char(data&0xFF) << "]" << endl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
||||||
T1TCR = data;
|
T1TCR = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xE0008008: // T1TC - Timer 1 Counter
|
case 0xE0008008: // T1TC - Timer 1 Counter
|
||||||
T1TC = data;
|
T1TC = data;
|
||||||
break;
|
break;
|
||||||
|
@ -423,11 +417,11 @@ uInt32 Thumbulator::read32(uInt32 addr)
|
||||||
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
case 0xE0008004: // T1TCR - Timer 1 Control Register
|
||||||
data = T1TCR;
|
data = T1TCR;
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
case 0xE0008008: // T1TC - Timer 1 Counter
|
case 0xE0008008: // T1TC - Timer 1 Counter
|
||||||
data = T1TC;
|
data = T1TC;
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
case 0xE000E010:
|
case 0xE000E010:
|
||||||
data = systick_ctrl;
|
data = systick_ctrl;
|
||||||
systick_ctrl &= (~0x00010000);
|
systick_ctrl &= (~0x00010000);
|
||||||
|
@ -1076,9 +1070,9 @@ int Thumbulator::execute()
|
||||||
// branch to even address denotes 32 bit ARM code, which the Thumbulator
|
// branch to even address denotes 32 bit ARM code, which the Thumbulator
|
||||||
// class does not support. So capture relavent information and hand it
|
// class does not support. So capture relavent information and hand it
|
||||||
// off to the Cartridge class for it to handle.
|
// off to the Cartridge class for it to handle.
|
||||||
|
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
switch(configuration)
|
switch(configuration)
|
||||||
{
|
{
|
||||||
case ConfigureFor::BUS:
|
case ConfigureFor::BUS:
|
||||||
|
@ -1097,13 +1091,14 @@ int Thumbulator::execute()
|
||||||
// _SetWaveSize:
|
// _SetWaveSize:
|
||||||
// ldr r4, =WaveSizeStore
|
// ldr r4, =WaveSizeStore
|
||||||
// bx r4 // bx instruction at 0x000006ee
|
// bx r4 // bx instruction at 0x000006ee
|
||||||
|
|
||||||
// address to test for is + 4 due to pipelining
|
// address to test for is + 4 due to pipelining
|
||||||
#define BUS_SetNote (0x000006e2 + 4)
|
|
||||||
#define BUS_ResetWave (0x000006e6 + 4)
|
#define BUS_SetNote (0x000006e2 + 4)
|
||||||
#define BUS_GetWavePtr (0x000006ea + 4)
|
#define BUS_ResetWave (0x000006e6 + 4)
|
||||||
#define BUS_SetWaveSize (0x000006ee + 4)
|
#define BUS_GetWavePtr (0x000006ea + 4)
|
||||||
|
#define BUS_SetWaveSize (0x000006ee + 4)
|
||||||
|
|
||||||
if (pc == BUS_SetNote)
|
if (pc == BUS_SetNote)
|
||||||
{
|
{
|
||||||
myCartridge->thumbCallback(0, read_register(2), read_register(3));
|
myCartridge->thumbCallback(0, read_register(2), read_register(3));
|
||||||
|
@ -1130,22 +1125,23 @@ int Thumbulator::execute()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// just for testing
|
#if 0 // uncomment this for testing
|
||||||
uInt32 r0 = read_register(0);
|
uInt32 r0 = read_register(0);
|
||||||
uInt32 r1 = read_register(1);
|
uInt32 r1 = read_register(1);
|
||||||
uInt32 r2 = read_register(2);
|
uInt32 r2 = read_register(2);
|
||||||
uInt32 r3 = read_register(3);
|
uInt32 r3 = read_register(3);
|
||||||
uInt32 r4 = read_register(4);
|
uInt32 r4 = read_register(4);
|
||||||
myCartridge->thumbCallback(255,0,0);
|
#endif
|
||||||
|
myCartridge->thumbCallback(255, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConfigureFor::DPCplus:
|
case ConfigureFor::DPCplus:
|
||||||
// no 32-bit subroutines in DPC+
|
// no 32-bit subroutines in DPC+
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled)
|
if (handled)
|
||||||
{
|
{
|
||||||
rc = read_register(14); // lr
|
rc = read_register(14); // lr
|
||||||
|
@ -1154,7 +1150,7 @@ int Thumbulator::execute()
|
||||||
write_register(15, rc);
|
write_register(15, rc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2206,20 +2202,20 @@ int Thumbulator::reset()
|
||||||
|
|
||||||
switch(configuration)
|
switch(configuration)
|
||||||
{
|
{
|
||||||
// future 2K Harmony/Melody drivers will most likely use these settings
|
// future 2K Harmony/Melody drivers will most likely use these settings
|
||||||
case ConfigureFor::BUS:
|
case ConfigureFor::BUS:
|
||||||
case ConfigureFor::CDF:
|
case ConfigureFor::CDF:
|
||||||
reg_norm[14] = 0x00000800; // Link Register
|
reg_norm[14] = 0x00000800; // Link Register
|
||||||
reg_norm[15] = 0x0000080B; // Program Counter
|
reg_norm[15] = 0x0000080B; // Program Counter
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// future 3K Harmony/Melody drivers will most likely use these settings
|
// future 3K Harmony/Melody drivers will most likely use these settings
|
||||||
case ConfigureFor::DPCplus:
|
case ConfigureFor::DPCplus:
|
||||||
reg_norm[14] = 0x00000C00; // Link Register
|
reg_norm[14] = 0x00000C00; // Link Register
|
||||||
reg_norm[15] = 0x00000C0B; // Program Counter
|
reg_norm[15] = 0x00000C0B; // Program Counter
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpsr = mamcr = 0;
|
cpsr = mamcr = 0;
|
||||||
handler_mode = false;
|
handler_mode = false;
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Thumbulator
|
||||||
CDF, // cartridges of type CDF
|
CDF, // cartridges of type CDF
|
||||||
DPCplus // cartridges of type DPC+
|
DPCplus // cartridges of type DPC+
|
||||||
};
|
};
|
||||||
|
|
||||||
Thumbulator(const uInt16* rom, uInt16* ram, bool traponfatal,
|
Thumbulator(const uInt16* rom, uInt16* ram, bool traponfatal,
|
||||||
Thumbulator::ConfigureFor configurefor, Cartridge* cartridge);
|
Thumbulator::ConfigureFor configurefor, Cartridge* cartridge);
|
||||||
|
|
||||||
|
@ -80,8 +80,13 @@ class Thumbulator
|
||||||
@param enable Enable (the default) or disable exceptions on fatal errors
|
@param enable Enable (the default) or disable exceptions on fatal errors
|
||||||
*/
|
*/
|
||||||
static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
|
static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
|
||||||
|
|
||||||
void setConsoleTiming(ConsoleTiming timing);
|
/**
|
||||||
|
Inform the Thumbulator class about the console currently in use,
|
||||||
|
which is used to accurately determine how many 6507 cycles have
|
||||||
|
passed while ARM code is being executed.
|
||||||
|
*/
|
||||||
|
void setConsoleTiming(ConsoleTiming timing);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uInt32 read_register(uInt32 reg);
|
uInt32 read_register(uInt32 reg);
|
||||||
|
@ -121,7 +126,7 @@ class Thumbulator
|
||||||
bool handler_mode;
|
bool handler_mode;
|
||||||
uInt32 systick_ctrl, systick_reload, systick_count, systick_calibrate;
|
uInt32 systick_ctrl, systick_reload, systick_count, systick_calibrate;
|
||||||
uInt64 instructions, fetches, reads, writes, systick_ints;
|
uInt64 instructions, fetches, reads, writes, systick_ints;
|
||||||
|
|
||||||
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
// For emulation of LPC2103's timer 1, used for NTSC/PAL/SECAM detection.
|
||||||
// Register names from documentation:
|
// Register names from documentation:
|
||||||
// http://www.nxp.com/documents/user_manual/UM10161.pdf
|
// http://www.nxp.com/documents/user_manual/UM10161.pdf
|
||||||
|
@ -132,9 +137,9 @@ class Thumbulator
|
||||||
ostringstream statusMsg;
|
ostringstream statusMsg;
|
||||||
|
|
||||||
static bool trapOnFatal;
|
static bool trapOnFatal;
|
||||||
|
|
||||||
ConfigureFor configuration;
|
ConfigureFor configuration;
|
||||||
|
|
||||||
Cartridge* myCartridge;
|
Cartridge* myCartridge;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -13,6 +13,8 @@ MODULE_OBJS := \
|
||||||
src/emucore/Cart4K.o \
|
src/emucore/Cart4K.o \
|
||||||
src/emucore/Cart4KSC.o \
|
src/emucore/Cart4KSC.o \
|
||||||
src/emucore/CartAR.o \
|
src/emucore/CartAR.o \
|
||||||
|
src/emucore/CartBUS.o \
|
||||||
|
src/emucore/CartCDF.o \
|
||||||
src/emucore/CartCM.o \
|
src/emucore/CartCM.o \
|
||||||
src/emucore/CartCTY.o \
|
src/emucore/CartCTY.o \
|
||||||
src/emucore/CartCV.o \
|
src/emucore/CartCV.o \
|
||||||
|
|
Loading…
Reference in New Issue