mirror of https://github.com/stella-emu/stella.git
Merge branch 'SpiceWare-master'
This commit is contained in:
commit
1cb83f4a68
|
@ -33,8 +33,8 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
info << "BUS Stuffing cartridge\n"
|
info << "BUS Stuffing cartridge\n"
|
||||||
<< "32K ROM, seven 4K banks are accessible to 2600\n"
|
<< "32K ROM, seven 4K banks are accessible to 2600\n"
|
||||||
<< "8K BUS RAM\n"
|
<< "8K BUS RAM\n"
|
||||||
<< "BUS registers accessible @ $F000 - $F03F\n"
|
<< "BUS registers accessible @ $FFEE - $FFF3\n"
|
||||||
<< "Banks accessible at hotspots $FFF5 to $FFFB\n"
|
<< "Banks accessible at hotspots $FFFF to $FFFB\n"
|
||||||
<< "Startup bank = " << cart.myStartBank << "\n";
|
<< "Startup bank = " << cart.myStartBank << "\n";
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -49,7 +49,7 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int xpos = 10,
|
int xpos = 10,
|
||||||
ypos = addBaseInformation(size, "AtariAge", info.str()) +
|
ypos = addBaseInformation(size, "AtariAge", info.str(), 4) +
|
||||||
myLineHeight;
|
myLineHeight;
|
||||||
|
|
||||||
VariantList items;
|
VariantList items;
|
||||||
|
@ -70,28 +70,57 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
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;
|
#define DS_X 30
|
||||||
|
xpos = DS_X;
|
||||||
|
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, 4, 6, 32, Common::Base::F_16_3_2);
|
myDatastreamPointers = new DataGridWidget(boss, _nfont, DS_X, 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);
|
||||||
|
|
||||||
|
myDatastreamPointers2 = new DataGridWidget(boss, _nfont, DS_X + myDatastreamPointers->getWidth() * 3 / 4, ypos+myLineHeight-2 + 4*myLineHeight, 1, 2, 6, 32, Common::Base::F_16_3_2);
|
||||||
|
myDatastreamPointers2->setTarget(this);
|
||||||
|
myDatastreamPointers2->setEditable(false);
|
||||||
|
|
||||||
|
uInt32 row;
|
||||||
|
for(row = 0; row < 4; ++row)
|
||||||
|
{
|
||||||
|
myDatastreamLabels[row] =
|
||||||
|
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
||||||
|
ypos+myLineHeight-2 + row*myLineHeight + 2,
|
||||||
|
myFontWidth*2, myFontHeight, "", kTextAlignLeft);
|
||||||
|
myDatastreamLabels[row]->setLabel(Common::Base::toString(row * 4, Common::Base::F_16_2));
|
||||||
|
}
|
||||||
|
lwidth = _font.getStringWidth("Write Data (stream 16)");
|
||||||
|
myDatastreamLabels[4] =
|
||||||
|
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
||||||
|
ypos+myLineHeight-2 + 4*myLineHeight + 2,
|
||||||
|
lwidth, myFontHeight, "Write Data (stream 16)", kTextAlignLeft);
|
||||||
|
myDatastreamLabels[5] =
|
||||||
|
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
||||||
|
ypos+myLineHeight-2 + 5*myLineHeight + 2,
|
||||||
|
lwidth, myFontHeight, "Jump Data (stream 17)", kTextAlignLeft);
|
||||||
|
|
||||||
// Datastream Increments
|
// Datastream Increments
|
||||||
xpos = 0 + myDatastreamPointers->getWidth();
|
xpos = DS_X + myDatastreamPointers->getWidth() + 20;
|
||||||
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);
|
||||||
|
|
||||||
|
myDatastreamIncrements2 = new DataGridWidget(boss, _nfont, xpos, ypos+myLineHeight-2 + 4*myLineHeight, 1, 2, 5, 32, Common::Base::F_16_2_2);
|
||||||
|
myDatastreamIncrements2->setTarget(this);
|
||||||
|
myDatastreamIncrements2->setEditable(false);
|
||||||
|
|
||||||
// Datastream Maps
|
// Datastream Maps
|
||||||
xpos = 0; ypos += myLineHeight*5 + 4;
|
xpos = 0; ypos += myLineHeight*7 + 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);
|
||||||
|
@ -100,7 +129,7 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
// 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,
|
||||||
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);
|
||||||
|
@ -110,7 +139,7 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
// 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);
|
||||||
|
@ -120,17 +149,26 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
// 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);
|
||||||
|
|
||||||
|
int xpossp = xpos + myMusicWaveforms->getWidth() + 20;
|
||||||
|
int lwidth2 = _font.getStringWidth("Sample Pointer ");
|
||||||
|
new StaticTextWidget(boss, _font, xpossp, ypos, lwidth2,
|
||||||
|
myFontHeight, "Sample Pointer ", kTextAlignLeft);
|
||||||
|
|
||||||
|
mySamplePointer = new DataGridWidget(boss, _nfont, xpossp + lwidth2, ypos-2, 1, 1, 8, 32, Common::Base::F_16_8);
|
||||||
|
mySamplePointer->setTarget(this);
|
||||||
|
mySamplePointer->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);
|
||||||
|
@ -138,15 +176,15 @@ CartridgeBUSWidget::CartridgeBUSWidget(
|
||||||
myMusicWaveformSizes->setEditable(false);
|
myMusicWaveformSizes->setEditable(false);
|
||||||
|
|
||||||
|
|
||||||
// BUS stuff and ZP STY flags
|
// BUS stuff and Digital Audio 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");
|
||||||
myBusOverdrive->setTarget(this);
|
myBusOverdrive->setTarget(this);
|
||||||
myBusOverdrive->setEditable(false);
|
myBusOverdrive->setEditable(false);
|
||||||
xpos = _font.getStringWidth("CHECKBOX BUS Overdrive enabled");
|
|
||||||
myZPSTY = new CheckboxWidget(boss, _font, xpos, ypos, "Zero Page STY");
|
myDigitalSample = new CheckboxWidget(boss, _font, xpossp, ypos, "Digital Sample mode");
|
||||||
myZPSTY->setTarget(this);
|
myDigitalSample->setTarget(this);
|
||||||
myZPSTY->setEditable(false);
|
myDigitalSample->setEditable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -162,8 +200,9 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
myOldState.mwaves.clear();
|
myOldState.mwaves.clear();
|
||||||
myOldState.mwavesizes.clear();
|
myOldState.mwavesizes.clear();
|
||||||
myOldState.internalram.clear();
|
myOldState.internalram.clear();
|
||||||
|
myOldState.samplepointer.clear();
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 16; i++)
|
for(uInt32 i = 0; i < 18; i++)
|
||||||
{
|
{
|
||||||
// Pointers are stored as:
|
// Pointers are stored as:
|
||||||
// PPPFF---
|
// PPPFF---
|
||||||
|
@ -176,13 +215,21 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
// 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));
|
if (i < 16)
|
||||||
|
myOldState.datastreamincrements.push_back(myCart.getDatastreamIncrement(i));
|
||||||
|
else
|
||||||
|
myOldState.datastreamincrements.push_back(0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 40; i++)
|
for(uInt32 i = 0; i < 37; i++) // only 37 map values
|
||||||
{
|
{
|
||||||
myOldState.addressmaps.push_back(myCart.getAddressMap(i));
|
myOldState.addressmaps.push_back(myCart.getAddressMap(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(uInt32 i = 37; i < 40; i++) // but need 40 for the grid
|
||||||
|
{
|
||||||
|
myOldState.addressmaps.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 3; ++i)
|
for(uInt32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
|
@ -198,6 +245,8 @@ void CartridgeBUSWidget::saveOldState()
|
||||||
|
|
||||||
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]);
|
||||||
|
|
||||||
|
myOldState.samplepointer.push_back(myCart.getSample());
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -228,7 +277,16 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
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();
|
||||||
|
for(int i = 16; i < 18; ++i)
|
||||||
|
{
|
||||||
|
Int32 pointervalue = myCart.getDatastreamPointer(i) >> 12;
|
||||||
|
alist.push_back(0); vlist.push_back(pointervalue);
|
||||||
|
changed.push_back(pointervalue != myOldState.datastreampointers[i]);
|
||||||
|
}
|
||||||
|
myDatastreamPointers2->setList(alist, vlist, changed);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -237,14 +295,29 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
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();
|
||||||
|
for(int i = 16; i < 18; ++i)
|
||||||
|
{
|
||||||
|
Int32 incrementvalue = 0x100;
|
||||||
|
alist.push_back(0); vlist.push_back(incrementvalue);
|
||||||
|
changed.push_back(incrementvalue != myOldState.datastreamincrements[i]);
|
||||||
|
}
|
||||||
|
myDatastreamIncrements2->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 < 37; ++i) // only 37 map values
|
||||||
{
|
{
|
||||||
Int32 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]);
|
||||||
}
|
}
|
||||||
|
for(int i = 37; i < 40; ++i) // but need 40 for the grid
|
||||||
|
{
|
||||||
|
Int32 mapvalue = 0;
|
||||||
|
alist.push_back(0); vlist.push_back(mapvalue);
|
||||||
|
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();
|
||||||
|
@ -279,8 +352,26 @@ void CartridgeBUSWidget::loadConfig()
|
||||||
}
|
}
|
||||||
myMusicWaveformSizes->setList(alist, vlist, changed);
|
myMusicWaveformSizes->setList(alist, vlist, changed);
|
||||||
|
|
||||||
// myBusOverdrive->setState(myCart.getBusStuffFlag());
|
alist.clear(); vlist.clear(); changed.clear();
|
||||||
// myZPSTY->setState(myCart.mySTYZeroPage);
|
alist.push_back(0); vlist.push_back(myCart.getSample());
|
||||||
|
changed.push_back((myCart.getSample()) != uInt32(myOldState.samplepointer[0]));
|
||||||
|
mySamplePointer->setList(alist, vlist, changed);
|
||||||
|
|
||||||
|
myBusOverdrive->setState((myCart.myMode & 0x0f) == 0);
|
||||||
|
myDigitalSample->setState((myCart.myMode & 0xf0) == 0);
|
||||||
|
|
||||||
|
if ((myCart.myMode & 0xf0) == 0)
|
||||||
|
{
|
||||||
|
myMusicWaveforms->setCrossed(true);
|
||||||
|
myMusicWaveformSizes->setCrossed(true);
|
||||||
|
mySamplePointer->setCrossed(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myMusicWaveforms->setCrossed(false);
|
||||||
|
myMusicWaveformSizes->setCrossed(false);
|
||||||
|
mySamplePointer->setCrossed(true);
|
||||||
|
}
|
||||||
|
|
||||||
CartDebugWidget::loadConfig();
|
CartDebugWidget::loadConfig();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class CartridgeBUSWidget : public CartDebugWidget
|
||||||
IntArray mfreqs;
|
IntArray mfreqs;
|
||||||
IntArray mwaves;
|
IntArray mwaves;
|
||||||
IntArray mwavesizes;
|
IntArray mwavesizes;
|
||||||
|
IntArray samplepointer;
|
||||||
uInt32 random;
|
uInt32 random;
|
||||||
ByteArray internalram;
|
ByteArray internalram;
|
||||||
};
|
};
|
||||||
|
@ -54,13 +55,17 @@ class CartridgeBUSWidget : public CartDebugWidget
|
||||||
|
|
||||||
DataGridWidget* myDatastreamPointers;
|
DataGridWidget* myDatastreamPointers;
|
||||||
DataGridWidget* myDatastreamIncrements;
|
DataGridWidget* myDatastreamIncrements;
|
||||||
|
DataGridWidget* myDatastreamPointers2;
|
||||||
|
DataGridWidget* myDatastreamIncrements2;
|
||||||
DataGridWidget* myAddressMaps;
|
DataGridWidget* myAddressMaps;
|
||||||
DataGridWidget* myMusicCounters;
|
DataGridWidget* myMusicCounters;
|
||||||
DataGridWidget* myMusicFrequencies;
|
DataGridWidget* myMusicFrequencies;
|
||||||
DataGridWidget* myMusicWaveforms;
|
DataGridWidget* myMusicWaveforms;
|
||||||
DataGridWidget* myMusicWaveformSizes;
|
DataGridWidget* myMusicWaveformSizes;
|
||||||
|
DataGridWidget* mySamplePointer;
|
||||||
|
StaticTextWidget* myDatastreamLabels[6];
|
||||||
CheckboxWidget* myBusOverdrive;
|
CheckboxWidget* myBusOverdrive;
|
||||||
CheckboxWidget* myZPSTY;
|
CheckboxWidget* myDigitalSample;
|
||||||
CartState myOldState;
|
CartState myOldState;
|
||||||
|
|
||||||
enum { kBankChanged = 'bkCH' };
|
enum { kBankChanged = 'bkCH' };
|
||||||
|
|
|
@ -96,16 +96,14 @@ CartridgeCDFWidget::CartridgeCDFWidget(
|
||||||
myDatastreamLabels[row]->setLabel(Common::Base::toString(row * 4, Common::Base::F_16_2));
|
myDatastreamLabels[row]->setLabel(Common::Base::toString(row * 4, Common::Base::F_16_2));
|
||||||
}
|
}
|
||||||
lwidth = _font.getStringWidth("Write Data (stream 20)");
|
lwidth = _font.getStringWidth("Write Data (stream 20)");
|
||||||
myDatastreamLabels[row] =
|
myDatastreamLabels[8] =
|
||||||
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
||||||
ypos+myLineHeight-2 + 8*myLineHeight + 2,
|
ypos+myLineHeight-2 + 8*myLineHeight + 2,
|
||||||
lwidth, myFontHeight, "Write Data (stream 20)", kTextAlignLeft);
|
lwidth, myFontHeight, "Write Data (stream 20)", kTextAlignLeft);
|
||||||
// myDatastreamLabels[row]->setLabel(Common::Base::toString(row * 4, Common::Base::F_16_2));
|
myDatastreamLabels[9] =
|
||||||
myDatastreamLabels[row] =
|
|
||||||
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
new StaticTextWidget(_boss, _font, DS_X - _font.getStringWidth("xx "),
|
||||||
ypos+myLineHeight-2 + 9*myLineHeight + 2,
|
ypos+myLineHeight-2 + 9*myLineHeight + 2,
|
||||||
lwidth, myFontHeight, "Jump Data (stream 21)", kTextAlignLeft);
|
lwidth, myFontHeight, "Jump Data (stream 21)", kTextAlignLeft);
|
||||||
// myDatastreamLabels[row]->setLabel(Common::Base::toString(row * 4, Common::Base::F_16_2));
|
|
||||||
|
|
||||||
// Datastream Increments
|
// Datastream Increments
|
||||||
xpos = DS_X + myDatastreamPointers->getWidth() + 20;
|
xpos = DS_X + myDatastreamPointers->getWidth() + 20;
|
||||||
|
|
|
@ -65,7 +65,6 @@ class CartridgeCDFWidget : public CartDebugWidget
|
||||||
DataGridWidget* mySamplePointer;
|
DataGridWidget* mySamplePointer;
|
||||||
StaticTextWidget* myDatastreamLabels[10];
|
StaticTextWidget* myDatastreamLabels[10];
|
||||||
|
|
||||||
// done differently than in DPC+, need to rethink debugger support
|
|
||||||
CheckboxWidget* myFastFetch;
|
CheckboxWidget* myFastFetch;
|
||||||
CheckboxWidget* myDigitalSample;
|
CheckboxWidget* myDigitalSample;
|
||||||
CartState myOldState;
|
CartState myOldState;
|
||||||
|
|
|
@ -27,12 +27,15 @@
|
||||||
#include "CartBUS.hxx"
|
#include "CartBUS.hxx"
|
||||||
|
|
||||||
// Location of data within the RAM copy of the BUS Driver.
|
// Location of data within the RAM copy of the BUS Driver.
|
||||||
#define DSxPTR 0x06E0
|
#define DSxPTR 0x06D8
|
||||||
#define DSxINC 0x0720
|
#define DSxINC 0x0720
|
||||||
#define DSMAPS 0x0760
|
#define DSMAPS 0x0760
|
||||||
#define WAVEFORM 0x07F4
|
#define WAVEFORM 0x07F4
|
||||||
#define DSRAM 0x0800
|
#define DSRAM 0x0800
|
||||||
|
|
||||||
|
#define COMMSTREAM 0x10
|
||||||
|
#define JUMPSTREAM 0x11
|
||||||
|
|
||||||
#define BUS_STUFF_ON ((myMode & 0x0F) == 0)
|
#define BUS_STUFF_ON ((myMode & 0x0F) == 0)
|
||||||
#define DIGITAL_AUDIO_ON ((myMode & 0xF0) == 0)
|
#define DIGITAL_AUDIO_ON ((myMode & 0xF0) == 0)
|
||||||
|
|
||||||
|
@ -41,6 +44,7 @@ CartridgeBUS::CartridgeBUS(const uInt8* image, uInt32 size,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings),
|
: Cartridge(settings),
|
||||||
mySystemCycles(0),
|
mySystemCycles(0),
|
||||||
|
myARMCycles(0),
|
||||||
myFractionalClocks(0.0)
|
myFractionalClocks(0.0)
|
||||||
{
|
{
|
||||||
// Copy the ROM image into my buffer
|
// Copy the ROM image into my buffer
|
||||||
|
@ -78,6 +82,7 @@ void CartridgeBUS::reset()
|
||||||
|
|
||||||
// Update cycles to the current system cycles
|
// Update cycles to the current system cycles
|
||||||
mySystemCycles = mySystem->cycles();
|
mySystemCycles = mySystem->cycles();
|
||||||
|
myARMCycles = mySystem->cycles();
|
||||||
myFractionalClocks = 0.0;
|
myFractionalClocks = 0.0;
|
||||||
|
|
||||||
setInitialState();
|
setInitialState();
|
||||||
|
@ -116,6 +121,7 @@ void CartridgeBUS::systemCyclesReset()
|
||||||
{
|
{
|
||||||
// Adjust the cycle counter so that it reflects the new value
|
// Adjust the cycle counter so that it reflects the new value
|
||||||
mySystemCycles -= mySystem->cycles();
|
mySystemCycles -= mySystem->cycles();
|
||||||
|
myARMCycles -= mySystem->cycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -172,7 +178,10 @@ inline void CartridgeBUS::callFunction(uInt8 value)
|
||||||
// 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 {
|
||||||
myThumbEmulator->run();
|
Int32 cycles = mySystem->cycles() - myARMCycles;
|
||||||
|
myARMCycles = mySystem->cycles();
|
||||||
|
|
||||||
|
myThumbEmulator->run(cycles);
|
||||||
}
|
}
|
||||||
catch(const runtime_error& e) {
|
catch(const runtime_error& e) {
|
||||||
if(!mySystem->autodetectMode())
|
if(!mySystem->autodetectMode())
|
||||||
|
@ -211,6 +220,32 @@ uInt8 CartridgeBUS::peek(uInt16 address)
|
||||||
// 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;
|
||||||
|
|
||||||
|
// implement JMP FASTJMP which fetches the destination address from stream 33
|
||||||
|
if (myFastJumpActive)
|
||||||
|
{
|
||||||
|
uInt32 pointer;
|
||||||
|
uInt8 value;
|
||||||
|
|
||||||
|
myFastJumpActive--;
|
||||||
|
|
||||||
|
pointer = getDatastreamPointer(JUMPSTREAM);
|
||||||
|
value = myDisplayImage[ pointer >> 20 ];
|
||||||
|
pointer += 0x100000; // always increment by 1
|
||||||
|
setDatastreamPointer(JUMPSTREAM, pointer);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// test for JMP FASTJUMP where FASTJUMP = $0000
|
||||||
|
if (BUS_STUFF_ON
|
||||||
|
&& peekvalue == 0x4C
|
||||||
|
&& myProgramImage[(myCurrentBank << 12) + address+1] == 0
|
||||||
|
&& myProgramImage[(myCurrentBank << 12) + address+2] == 0)
|
||||||
|
{
|
||||||
|
myFastJumpActive = 2; // return next two peeks from datastream 31
|
||||||
|
return peekvalue;
|
||||||
|
}
|
||||||
|
|
||||||
// save the STY's zero page address
|
// save the STY's zero page address
|
||||||
if (BUS_STUFF_ON && mySTYZeroPageAddress == address)
|
if (BUS_STUFF_ON && mySTYZeroPageAddress == address)
|
||||||
|
@ -218,120 +253,90 @@ uInt8 CartridgeBUS::peek(uInt16 address)
|
||||||
|
|
||||||
mySTYZeroPageAddress = 0;
|
mySTYZeroPageAddress = 0;
|
||||||
|
|
||||||
if(address < 0x20)
|
switch(address)
|
||||||
{
|
{
|
||||||
uInt8 result = 0;
|
case 0xFEE: // AMPLITUDE
|
||||||
|
|
||||||
// Get the index of the data fetcher that's being accessed
|
// Update the music data fetchers (counter & flag)
|
||||||
uInt32 index = address & 0x0f;
|
updateMusicModeDataFetchers();
|
||||||
uInt32 function = (address >> 4) & 0x01;
|
|
||||||
|
if DIGITAL_AUDIO_ON
|
||||||
switch(function)
|
|
||||||
{
|
|
||||||
case 0x00: // read from a datastream
|
|
||||||
{
|
{
|
||||||
result = readFromDatastream(index);
|
// retrieve packed sample (max size is 2K, or 4K of unpacked data)
|
||||||
break;
|
peekvalue = myImage[getSample() + (myMusicCounters[0] >> 21)];
|
||||||
|
|
||||||
|
//
|
||||||
|
if ((myMusicCounters[0] & (1<<20)) == 0)
|
||||||
|
peekvalue >>= 4;
|
||||||
|
peekvalue &= 0x0f;
|
||||||
}
|
}
|
||||||
case 0x01: // misc read registers
|
else
|
||||||
{
|
{
|
||||||
switch(index)
|
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
||||||
{
|
// can be modified during runtime.
|
||||||
// the following are POKE ONLY
|
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
|
||||||
case 0x00: // 0x10 DF0WRITE
|
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
|
||||||
case 0x01: // 0x11 DF1WRITE
|
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
|
||||||
case 0x02: // 0x12 DF2WRITE
|
|
||||||
case 0x03: // 0x13 DF3WRITE
|
peekvalue = uInt8(i);
|
||||||
case 0x04: // 0x14 DF0PTR
|
|
||||||
case 0x05: // 0x15 DF1PTR
|
|
||||||
case 0x06: // 0x16 DF2PTR
|
|
||||||
case 0x07: // 0x17 DF3PTR
|
|
||||||
case 0x09: // 0x19 STUFFMODE
|
|
||||||
case 0x0a: // 0x1A CALLFN
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x08: // 0x18 = AMPLITUDE
|
|
||||||
// Update the music data fetchers (counter & flag)
|
|
||||||
updateMusicModeDataFetchers();
|
|
||||||
|
|
||||||
if DIGITAL_AUDIO_ON
|
|
||||||
{
|
|
||||||
// retrieve packed sample (max size is 2K, or 4K of unpacked data)
|
|
||||||
result = myImage[getSample() + (myMusicCounters[0] >> 21)];
|
|
||||||
|
|
||||||
//
|
|
||||||
if ((myMusicCounters[0] & (1<<20)) == 0)
|
|
||||||
result >>= 4;
|
|
||||||
result &= 0x0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
|
||||||
// can be modified during runtime.
|
|
||||||
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
|
|
||||||
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
|
|
||||||
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
|
|
||||||
|
|
||||||
result = uInt8(i);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
return result;
|
case 0xFEF: // DSREAD
|
||||||
}
|
peekvalue = readFromDatastream(COMMSTREAM);
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
// Switch banks if necessary
|
case 0xFF0: // DSWRITE
|
||||||
switch(address)
|
case 0xFF1: // DSPTR
|
||||||
{
|
case 0xFF2: // SETMODE
|
||||||
case 0xFF5:
|
case 0xFF3: // CALLFN
|
||||||
// Set the current bank to the first 4k bank
|
// these are write-only
|
||||||
bank(0);
|
break;
|
||||||
break;
|
|
||||||
|
case 0xFF5:
|
||||||
case 0x0FF6:
|
// Set the current bank to the first 4k bank
|
||||||
// Set the current bank to the second 4k bank
|
bank(0);
|
||||||
bank(1);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FF6:
|
||||||
case 0x0FF7:
|
// Set the current bank to the second 4k bank
|
||||||
// Set the current bank to the third 4k bank
|
bank(1);
|
||||||
bank(2);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FF7:
|
||||||
case 0x0FF8:
|
// Set the current bank to the third 4k bank
|
||||||
// Set the current bank to the fourth 4k bank
|
bank(2);
|
||||||
bank(3);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FF8:
|
||||||
case 0x0FF9:
|
// Set the current bank to the fourth 4k bank
|
||||||
// Set the current bank to the fifth 4k bank
|
bank(3);
|
||||||
bank(4);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FF9:
|
||||||
case 0x0FFA:
|
// Set the current bank to the fifth 4k bank
|
||||||
// Set the current bank to the sixth 4k bank
|
bank(4);
|
||||||
bank(5);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FFA:
|
||||||
case 0x0FFB:
|
// Set the current bank to the sixth 4k bank
|
||||||
// Set the current bank to the last 4k bank
|
bank(5);
|
||||||
bank(6);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FFB:
|
||||||
default:
|
// Set the current bank to the last 4k bank
|
||||||
break;
|
bank(6);
|
||||||
}
|
break;
|
||||||
|
|
||||||
// this might not work right for STY $84
|
default:
|
||||||
if (BUS_STUFF_ON && peekvalue == 0x84)
|
break;
|
||||||
mySTYZeroPageAddress = address + 1;
|
|
||||||
|
|
||||||
return peekvalue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this might not work right for STY $84
|
||||||
|
if (BUS_STUFF_ON && peekvalue == 0x84)
|
||||||
|
mySTYZeroPageAddress = address + 1;
|
||||||
|
|
||||||
|
return peekvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; // make compiler happy
|
return 0; // make compiler happy
|
||||||
|
@ -353,102 +358,77 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
uInt32 pointer;
|
||||||
|
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
if ((address >= 0x10) && (address <= 0x1F))
|
switch(address)
|
||||||
{
|
{
|
||||||
// Get the index of the data fetcher that's being accessed
|
case 0xFEE: // AMPLITUDE
|
||||||
uInt32 index = address & 0x0f;
|
case 0xFEF: // DSREAD
|
||||||
uInt32 pointer;
|
// these are read-only
|
||||||
|
break;
|
||||||
switch (index)
|
|
||||||
{
|
case 0xFF0: // DSWRITE
|
||||||
case 0x00: // DS0WRITE
|
pointer = getDatastreamPointer(COMMSTREAM);
|
||||||
case 0x01: // DS1WRITE
|
myDisplayImage[ pointer >> 20 ] = value;
|
||||||
case 0x02: // DS2WRITE
|
pointer += 0x100000; // always increment by 1 when writing
|
||||||
case 0x03: // DS3WRITE
|
setDatastreamPointer(COMMSTREAM, pointer);
|
||||||
// Pointers are stored as:
|
break;
|
||||||
// PPPFF---
|
|
||||||
//
|
case 0xFF1: // DSPTR
|
||||||
// P = Pointer
|
pointer = getDatastreamPointer(COMMSTREAM);
|
||||||
// F = Fractional
|
pointer <<=8;
|
||||||
|
pointer &= 0xf0000000;
|
||||||
pointer = getDatastreamPointer(index);
|
pointer |= (value << 20);
|
||||||
myDisplayImage[ pointer >> 20 ] = value;
|
setDatastreamPointer(COMMSTREAM, pointer);
|
||||||
pointer += 0x100000; // always increment by 1 when writing
|
break;
|
||||||
setDatastreamPointer(index, pointer);
|
|
||||||
break;
|
case 0xFF2: // SETMODE
|
||||||
|
myMode = value;
|
||||||
case 0x04: // 0x14 DS0PTR
|
break;
|
||||||
case 0x05: // 0x15 DS1PTR
|
|
||||||
case 0x06: // 0x16 DS2PTR
|
case 0xFF3: // CALLFN
|
||||||
case 0x07: // 0x17 DS3PTR
|
callFunction(value);
|
||||||
// Pointers are stored as:
|
break;
|
||||||
// PPPFF---
|
|
||||||
//
|
case 0xFF5:
|
||||||
// P = Pointer
|
// Set the current bank to the first 4k bank
|
||||||
// F = Fractional
|
bank(0);
|
||||||
|
break;
|
||||||
index &= 0x03;
|
|
||||||
pointer = getDatastreamPointer(index);
|
case 0x0FF6:
|
||||||
pointer <<=8;
|
// Set the current bank to the second 4k bank
|
||||||
pointer &= 0xf0000000;
|
bank(1);
|
||||||
pointer |= (value << 20);
|
break;
|
||||||
setDatastreamPointer(index, pointer);
|
|
||||||
break;
|
case 0x0FF7:
|
||||||
|
// Set the current bank to the third 4k bank
|
||||||
case 0x09: // 0x19 SETMODE
|
bank(2);
|
||||||
myMode = value;
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FF8:
|
||||||
case 0x0A: // 0x1A CALLFUNCTION
|
// Set the current bank to the fourth 4k bank
|
||||||
callFunction(value);
|
bank(3);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
case 0x0FF9:
|
||||||
else
|
// Set the current bank to the fifth 4k bank
|
||||||
{
|
bank(4);
|
||||||
// Switch banks if necessary
|
break;
|
||||||
switch(address)
|
|
||||||
{
|
case 0x0FFA:
|
||||||
case 0xFF5:
|
// Set the current bank to the sixth 4k bank
|
||||||
// Set the current bank to the first 4k bank
|
bank(5);
|
||||||
bank(0);
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0FFB:
|
||||||
case 0x0FF6:
|
// Set the current bank to the last 4k bank
|
||||||
// Set the current bank to the second 4k bank
|
bank(6);
|
||||||
bank(1);
|
break;
|
||||||
break;
|
|
||||||
|
default:
|
||||||
case 0x0FF7:
|
break;
|
||||||
// Set the current bank to the third 4k bank
|
|
||||||
bank(2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0FF8:
|
|
||||||
// Set the current bank to the fourth 4k bank
|
|
||||||
bank(3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0FF9:
|
|
||||||
// Set the current bank to the fifth 4k bank
|
|
||||||
bank(4);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0FFA:
|
|
||||||
// Set the current bank to the sixth 4k bank
|
|
||||||
bank(5);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0FFB:
|
|
||||||
// Set the current bank to the last 4k bank
|
|
||||||
bank(6);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,12 +496,6 @@ uInt8 CartridgeBUS::busOverdrive(uInt16 address)
|
||||||
{
|
{
|
||||||
uInt8 overdrive = 0xff;
|
uInt8 overdrive = 0xff;
|
||||||
|
|
||||||
// Not sure how to do this, check with stephena.
|
|
||||||
//
|
|
||||||
// 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".
|
|
||||||
|
|
||||||
|
|
||||||
// only overdrive if the address matches
|
// only overdrive if the address matches
|
||||||
if (address == myBusOverdriveAddress)
|
if (address == myBusOverdriveAddress)
|
||||||
{
|
{
|
||||||
|
@ -536,8 +510,6 @@ uInt8 CartridgeBUS::busOverdrive(uInt16 address)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,9 +560,26 @@ bool CartridgeBUS::save(Serializer& out) const
|
||||||
|
|
||||||
// Harmony RAM
|
// Harmony RAM
|
||||||
out.putByteArray(myBUSRAM, 8192);
|
out.putByteArray(myBUSRAM, 8192);
|
||||||
|
|
||||||
|
// Addresses for bus override logic
|
||||||
|
out.putShort(myBusOverdriveAddress);
|
||||||
|
out.putShort(mySTYZeroPageAddress);
|
||||||
|
|
||||||
|
// Save cycles and clocks
|
||||||
out.putInt(mySystemCycles);
|
out.putInt(mySystemCycles);
|
||||||
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
||||||
|
out.putInt(myARMCycles);
|
||||||
|
|
||||||
|
// Audio info
|
||||||
|
out.putIntArray(myMusicCounters, 3);
|
||||||
|
out.putIntArray(myMusicFrequencies, 3);
|
||||||
|
out.putByteArray(myMusicWaveformSize, 3);
|
||||||
|
|
||||||
|
// Indicates current mode
|
||||||
|
out.putByte(myMode);
|
||||||
|
|
||||||
|
// Indicates if in the middle of a fast jump
|
||||||
|
out.putByte(myFastJumpActive);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -614,10 +603,26 @@ bool CartridgeBUS::load(Serializer& in)
|
||||||
|
|
||||||
// Harmony RAM
|
// Harmony RAM
|
||||||
in.getByteArray(myBUSRAM, 8192);
|
in.getByteArray(myBUSRAM, 8192);
|
||||||
|
|
||||||
|
// Addresses for bus override logic
|
||||||
|
myBusOverdriveAddress = in.getShort();
|
||||||
|
mySTYZeroPageAddress = in.getShort();
|
||||||
|
|
||||||
// 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();
|
||||||
|
|
||||||
|
// Audio info
|
||||||
|
in.getIntArray(myMusicCounters, 3);
|
||||||
|
in.getIntArray(myMusicFrequencies, 3);
|
||||||
|
in.getByteArray(myMusicWaveformSize, 3);
|
||||||
|
|
||||||
|
// Indicates current mode
|
||||||
|
myMode = in.getByte();
|
||||||
|
|
||||||
|
// Indicates if in the middle of a fast jump
|
||||||
|
myFastJumpActive = in.getByte();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -249,8 +249,9 @@ 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;
|
// ARM cycle count from when the last callFunction() occurred
|
||||||
|
Int32 myARMCycles;
|
||||||
|
|
||||||
// The music mode counters
|
// The music mode counters
|
||||||
uInt32 myMusicCounters[3];
|
uInt32 myMusicCounters[3];
|
||||||
|
@ -270,6 +271,8 @@ class CartridgeBUS : public Cartridge
|
||||||
// 0- = Packed Digital Sample
|
// 0- = Packed Digital Sample
|
||||||
// F- = 3 Voice Music
|
// F- = 3 Voice Music
|
||||||
uInt8 myMode;
|
uInt8 myMode;
|
||||||
|
|
||||||
|
uInt8 myFastJumpActive;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#define WAVEFORM 0x07F0
|
#define WAVEFORM 0x07F0
|
||||||
#define DSRAM 0x0800
|
#define DSRAM 0x0800
|
||||||
|
|
||||||
#define WRITESTREAM 0x20
|
#define COMMSTREAM 0x20
|
||||||
#define JUMPSTREAM 0x21
|
#define JUMPSTREAM 0x21
|
||||||
#define AMPLITUDE 0x22
|
#define AMPLITUDE 0x22
|
||||||
|
|
||||||
|
@ -228,11 +228,15 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
return peekvalue;
|
return peekvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we're in Fast Fetch mode and the prior byte was an A9 (LDA #value)
|
// Do a FAST FETCH LDA# if:
|
||||||
|
// 1) in Fast Fetch mode
|
||||||
|
// 2) peeking the operand of an LDA # instruction
|
||||||
|
// 3) peek value is 0-34
|
||||||
if(FAST_FETCH_ON
|
if(FAST_FETCH_ON
|
||||||
&& myLDAimmediateOperandAddress == address
|
&& myLDAimmediateOperandAddress == address
|
||||||
&& peekvalue <= AMPLITUDE)
|
&& peekvalue <= AMPLITUDE)
|
||||||
{
|
{
|
||||||
|
myLDAimmediateOperandAddress = 0;
|
||||||
if (peekvalue == AMPLITUDE)
|
if (peekvalue == AMPLITUDE)
|
||||||
{
|
{
|
||||||
updateMusicModeDataFetchers();
|
updateMusicModeDataFetchers();
|
||||||
|
@ -318,22 +322,21 @@ bool CartridgeCDF::poke(uInt16 address, uInt8 value)
|
||||||
|
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
// Switch banks if necessary
|
|
||||||
switch(address)
|
switch(address)
|
||||||
{
|
{
|
||||||
case 0xFF0: // DSWRITE
|
case 0xFF0: // DSWRITE
|
||||||
pointer = getDatastreamPointer(WRITESTREAM);
|
pointer = getDatastreamPointer(COMMSTREAM);
|
||||||
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(WRITESTREAM, pointer);
|
setDatastreamPointer(COMMSTREAM, pointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF1: // DSPTR
|
case 0xFF1: // DSPTR
|
||||||
pointer = getDatastreamPointer(WRITESTREAM);
|
pointer = getDatastreamPointer(COMMSTREAM);
|
||||||
pointer <<=8;
|
pointer <<=8;
|
||||||
pointer &= 0xf0000000;
|
pointer &= 0xf0000000;
|
||||||
pointer |= (value << 20);
|
pointer |= (value << 20);
|
||||||
setDatastreamPointer(WRITESTREAM, pointer);
|
setDatastreamPointer(COMMSTREAM, pointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFF2: // SETMODE
|
case 0xFF2: // SETMODE
|
||||||
|
|
|
@ -1076,29 +1076,28 @@ int Thumbulator::execute()
|
||||||
switch(configuration)
|
switch(configuration)
|
||||||
{
|
{
|
||||||
case ConfigureFor::BUS:
|
case ConfigureFor::BUS:
|
||||||
case ConfigureFor::CDF:
|
// this subroutine interface is used in the BUS driver,
|
||||||
// this subroutine interface is used in BUS and CDF drivers,
|
// it starts at address 0x000006d8
|
||||||
// and starts at address 0x000006e0 in both.
|
|
||||||
// _SetNote:
|
// _SetNote:
|
||||||
// ldr r4, =NoteStore
|
// ldr r4, =NoteStore
|
||||||
// bx r4 // bx instruction at 0x000006e2
|
// bx r4 // bx instruction at 0x000006da
|
||||||
// _ResetWave:
|
// _ResetWave:
|
||||||
// ldr r4, =ResetWaveStore
|
// ldr r4, =ResetWaveStore
|
||||||
// bx r4 // bx instruction at 0x000006e6
|
// bx r4 // bx instruction at 0x000006de
|
||||||
// _GetWavePtr:
|
// _GetWavePtr:
|
||||||
// ldr r4, =WavePtrFetch
|
// ldr r4, =WavePtrFetch
|
||||||
// bx r4 // bx instruction at 0x000006ea
|
// bx r4 // bx instruction at 0x000006e2
|
||||||
// _SetWaveSize:
|
// _SetWaveSize:
|
||||||
// ldr r4, =WaveSizeStore
|
// ldr r4, =WaveSizeStore
|
||||||
// bx r4 // bx instruction at 0x000006ee
|
// bx r4 // bx instruction at 0x000006e6
|
||||||
|
|
||||||
// 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_SetNote (0x000006da + 4)
|
||||||
#define BUS_ResetWave (0x000006e6 + 4)
|
#define BUS_ResetWave (0x000006de + 4)
|
||||||
#define BUS_GetWavePtr (0x000006ea + 4)
|
#define BUS_GetWavePtr (0x000006e2 + 4)
|
||||||
#define BUS_SetWaveSize (0x000006ee + 4)
|
#define BUS_SetWaveSize (0x000006e6 + 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));
|
||||||
|
@ -1125,6 +1124,67 @@ int Thumbulator::execute()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if 0 // uncomment this for testing
|
||||||
|
uInt32 r0 = read_register(0);
|
||||||
|
uInt32 r1 = read_register(1);
|
||||||
|
uInt32 r2 = read_register(2);
|
||||||
|
uInt32 r3 = read_register(3);
|
||||||
|
uInt32 r4 = read_register(4);
|
||||||
|
#endif
|
||||||
|
myCartridge->thumbCallback(255, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConfigureFor::CDF:
|
||||||
|
// this subroutine interface is used in the CDF driver,
|
||||||
|
// it starts at address 0x000006e0
|
||||||
|
// _SetNote:
|
||||||
|
// ldr r4, =NoteStore
|
||||||
|
// bx r4 // bx instruction at 0x000006e2
|
||||||
|
// _ResetWave:
|
||||||
|
// ldr r4, =ResetWaveStore
|
||||||
|
// bx r4 // bx instruction at 0x000006e6
|
||||||
|
// _GetWavePtr:
|
||||||
|
// ldr r4, =WavePtrFetch
|
||||||
|
// bx r4 // bx instruction at 0x000006ea
|
||||||
|
// _SetWaveSize:
|
||||||
|
// ldr r4, =WaveSizeStore
|
||||||
|
// bx r4 // bx instruction at 0x000006ee
|
||||||
|
|
||||||
|
// address to test for is + 4 due to pipelining
|
||||||
|
|
||||||
|
#define CDF_SetNote (0x000006e2 + 4)
|
||||||
|
#define CDF_ResetWave (0x000006e6 + 4)
|
||||||
|
#define CDF_GetWavePtr (0x000006ea + 4)
|
||||||
|
#define CDF_SetWaveSize (0x000006ee + 4)
|
||||||
|
|
||||||
|
if (pc == CDF_SetNote)
|
||||||
|
{
|
||||||
|
myCartridge->thumbCallback(0, read_register(2), read_register(3));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == CDF_ResetWave)
|
||||||
|
{
|
||||||
|
myCartridge->thumbCallback(1, read_register(2), 0);
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == CDF_GetWavePtr)
|
||||||
|
{
|
||||||
|
write_register(2, myCartridge->thumbCallback(2, read_register(2), 0));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == CDF_SetWaveSize)
|
||||||
|
{
|
||||||
|
myCartridge->thumbCallback(3, read_register(2), read_register(3));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == 0x0000083a)
|
||||||
|
{
|
||||||
|
// exiting Custom ARM code, returning to BUS Driver control
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if 0 // uncomment this 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);
|
||||||
|
|
Loading…
Reference in New Issue