mirror of https://github.com/stella-emu/stella.git
Support CDFJ / fastjmp2
This commit is contained in:
parent
72932aa09e
commit
59a7cbbc5e
|
@ -30,7 +30,8 @@ CartridgeCDFWidget::CartridgeCDFWidget(
|
||||||
uInt16 size = 8 * 4096;
|
uInt16 size = 8 * 4096;
|
||||||
|
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "CDF cartridge (version " << cart.myVersion << ")\n"
|
info << (cart.myCDFSubtype == CartridgeCDF::CDFSubtype::CDFJ ? "CDFJ" : "CDF")
|
||||||
|
<< " cartridge (version " << cart.myCDFVersion << ")\n"
|
||||||
<< "32K ROM, seven 4K banks are accessible to 2600\n"
|
<< "32K ROM, seven 4K banks are accessible to 2600\n"
|
||||||
<< "8K CDF RAM\n"
|
<< "8K CDF RAM\n"
|
||||||
<< "CDF registers accessible @ $FFF0 - $FFF3\n"
|
<< "CDF registers accessible @ $FFF0 - $FFF3\n"
|
||||||
|
|
|
@ -27,16 +27,18 @@
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
#include "exception/FatalEmulationError.hxx"
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
|
||||||
// Location of data within the RAM copy of the CDF Driver.
|
namespace {
|
||||||
// Version 0 1
|
// Location of data within the RAM copy of the CDF Driver.
|
||||||
const uInt16 DSxPTR[] = {0x06E0, 0x00A0};
|
// Version 0 1
|
||||||
const uInt16 DSxINC[] = {0x0768, 0x0128};
|
const uInt16 DSxPTR[] = {0x06E0, 0x00A0};
|
||||||
const uInt16 WAVEFORM[] = {0x07F0, 0x01B0};
|
const uInt16 DSxINC[] = {0x0768, 0x0128};
|
||||||
|
const uInt16 WAVEFORM[] = {0x07F0, 0x01B0};
|
||||||
|
}
|
||||||
|
|
||||||
#define DSRAM 0x0800
|
#define DSRAM 0x0800
|
||||||
|
|
||||||
#define COMMSTREAM 0x20
|
#define COMMSTREAM 0x20
|
||||||
#define JUMPSTREAM 0x21
|
#define JUMPSTREAM_BASE 0x21
|
||||||
#define AMPLITUDE 0x22
|
|
||||||
|
|
||||||
#define FAST_FETCH_ON ((myMode & 0x0F) == 0)
|
#define FAST_FETCH_ON ((myMode & 0x0F) == 0)
|
||||||
#define DIGITAL_AUDIO_ON ((myMode & 0xF0) == 0)
|
#define DIGITAL_AUDIO_ON ((myMode & 0xF0) == 0)
|
||||||
|
@ -71,7 +73,7 @@ CartridgeCDF::CartridgeCDF(const BytePtr& image, uInt32 size,
|
||||||
bool devSettings = settings.getBool("dev.settings");
|
bool devSettings = settings.getBool("dev.settings");
|
||||||
myThumbEmulator = make_unique<Thumbulator>(
|
myThumbEmulator = make_unique<Thumbulator>(
|
||||||
reinterpret_cast<uInt16*>(myImage), reinterpret_cast<uInt16*>(myCDFRAM), 32768,
|
reinterpret_cast<uInt16*>(myImage), reinterpret_cast<uInt16*>(myCDFRAM), 32768,
|
||||||
devSettings ? settings.getBool("dev.thumb.trapfatal") : false, myVersion ?
|
devSettings ? settings.getBool("dev.thumb.trapfatal") : false, myCDFVersion ?
|
||||||
Thumbulator::ConfigureFor::CDF1 : Thumbulator::ConfigureFor::CDF, this);
|
Thumbulator::ConfigureFor::CDF1 : Thumbulator::ConfigureFor::CDF, this);
|
||||||
|
|
||||||
setInitialState();
|
setInitialState();
|
||||||
|
@ -196,10 +198,10 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
--myFastJumpActive;
|
--myFastJumpActive;
|
||||||
++myJMPoperandAddress;
|
++myJMPoperandAddress;
|
||||||
|
|
||||||
pointer = getDatastreamPointer(JUMPSTREAM);
|
pointer = getDatastreamPointer(myFastJumpStream);
|
||||||
value = myDisplayImage[ pointer >> 20 ];
|
value = myDisplayImage[ pointer >> 20 ];
|
||||||
pointer += 0x100000; // always increment by 1
|
pointer += 0x100000; // always increment by 1
|
||||||
setDatastreamPointer(JUMPSTREAM, pointer);
|
setDatastreamPointer(myFastJumpStream, pointer);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -207,11 +209,12 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
// test for JMP FASTJUMP where FASTJUMP = $0000
|
// test for JMP FASTJUMP where FASTJUMP = $0000
|
||||||
if (FAST_FETCH_ON
|
if (FAST_FETCH_ON
|
||||||
&& peekvalue == 0x4C
|
&& peekvalue == 0x4C
|
||||||
&& myProgramImage[myBankOffset + address+1] == 0
|
&& (myProgramImage[myBankOffset + address+1] & myFastjumpStreamIndexMask) == 0
|
||||||
&& myProgramImage[myBankOffset + address+2] == 0)
|
&& myProgramImage[myBankOffset + address+2] == 0)
|
||||||
{
|
{
|
||||||
myFastJumpActive = 2; // return next two peeks from datastream 31
|
myFastJumpActive = 2; // return next two peeks from datastream 31
|
||||||
myJMPoperandAddress = address + 1;
|
myJMPoperandAddress = address + 1;
|
||||||
|
myFastJumpStream = myProgramImage[myBankOffset + address+1] + JUMPSTREAM_BASE;
|
||||||
return peekvalue;
|
return peekvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,10 +226,10 @@ uInt8 CartridgeCDF::peek(uInt16 address)
|
||||||
// 3) peek value is 0-34
|
// 3) peek value is 0-34
|
||||||
if(FAST_FETCH_ON
|
if(FAST_FETCH_ON
|
||||||
&& myLDAimmediateOperandAddress == address
|
&& myLDAimmediateOperandAddress == address
|
||||||
&& peekvalue <= AMPLITUDE)
|
&& peekvalue <= myAmplitudeStream)
|
||||||
{
|
{
|
||||||
myLDAimmediateOperandAddress = 0;
|
myLDAimmediateOperandAddress = 0;
|
||||||
if (peekvalue == AMPLITUDE)
|
if (peekvalue == myAmplitudeStream)
|
||||||
{
|
{
|
||||||
updateMusicModeDataFetchers();
|
updateMusicModeDataFetchers();
|
||||||
|
|
||||||
|
@ -556,7 +559,7 @@ bool CartridgeCDF::load(Serializer& in)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const
|
uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const
|
||||||
{
|
{
|
||||||
uInt16 address = DSxPTR[myVersion] + index * 4;
|
uInt16 address = myDatastreamBase + index * 4;
|
||||||
|
|
||||||
return myCDFRAM[address + 0] + // low byte
|
return myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[address + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
|
@ -567,7 +570,7 @@ uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
uInt16 address = DSxPTR[myVersion] + index * 4;
|
uInt16 address = myDatastreamBase + index * 4;
|
||||||
|
|
||||||
myCDFRAM[address + 0] = value & 0xff; // low byte
|
myCDFRAM[address + 0] = value & 0xff; // low byte
|
||||||
myCDFRAM[address + 1] = (value >> 8) & 0xff;
|
myCDFRAM[address + 1] = (value >> 8) & 0xff;
|
||||||
|
@ -578,7 +581,7 @@ void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const
|
uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const
|
||||||
{
|
{
|
||||||
uInt16 address = DSxINC[myVersion] + index * 4;
|
uInt16 address = myDatastreamIncrementBase + index * 4;
|
||||||
|
|
||||||
return myCDFRAM[address + 0] + // low byte
|
return myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[address + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
|
@ -590,7 +593,7 @@ uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const
|
||||||
uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
||||||
{
|
{
|
||||||
uInt32 result;
|
uInt32 result;
|
||||||
uInt16 address = WAVEFORM[myVersion] + index * 4;
|
uInt16 address = myWaveformBase + index * 4;
|
||||||
|
|
||||||
result = myCDFRAM[address + 0] + // low byte
|
result = myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[address + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
|
@ -609,7 +612,7 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
||||||
uInt32 CartridgeCDF::getSample()
|
uInt32 CartridgeCDF::getSample()
|
||||||
{
|
{
|
||||||
uInt32 result;
|
uInt32 result;
|
||||||
uInt16 address = WAVEFORM[myVersion];
|
uInt16 address = myWaveformBase;
|
||||||
|
|
||||||
result = myCDFRAM[address + 0] + // low byte
|
result = myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[address + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
|
@ -649,7 +652,7 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::setVersion()
|
void CartridgeCDF::setVersion()
|
||||||
{
|
{
|
||||||
myVersion = 0;
|
uInt8 subversion = 0;
|
||||||
|
|
||||||
for(uInt32 i = 0; i < 2048; i += 4)
|
for(uInt32 i = 0; i < 2048; i += 4)
|
||||||
{
|
{
|
||||||
|
@ -658,8 +661,24 @@ void CartridgeCDF::setVersion()
|
||||||
if ( myImage[i+1] == 0x44 && myImage[i + 5] == 0x44 && myImage[i + 9] == 0x44) // D
|
if ( myImage[i+1] == 0x44 && myImage[i + 5] == 0x44 && myImage[i + 9] == 0x44) // D
|
||||||
if (myImage[i+2] == 0x46 && myImage[i + 6] == 0x46 && myImage[i +10] == 0x46) // F
|
if (myImage[i+2] == 0x46 && myImage[i + 6] == 0x46 && myImage[i +10] == 0x46) // F
|
||||||
{
|
{
|
||||||
myVersion = myImage[i+3];
|
subversion = myImage[i+3];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subversion == 0x4a) {
|
||||||
|
myCDFVersion = 1;
|
||||||
|
myCDFSubtype = CDFSubtype::CDFJ;
|
||||||
|
myAmplitudeStream = 0x23;
|
||||||
|
myFastjumpStreamIndexMask = 0xfe;
|
||||||
|
} else {
|
||||||
|
myCDFVersion = subversion;
|
||||||
|
myCDFSubtype = CDFSubtype::CDF;
|
||||||
|
myAmplitudeStream = 0x22;
|
||||||
|
myFastjumpStreamIndexMask = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
myDatastreamBase = DSxPTR[myCDFVersion];
|
||||||
|
myDatastreamIncrementBase = DSxINC[myCDFVersion];
|
||||||
|
myWaveformBase = WAVEFORM[myCDFVersion];
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,6 +202,13 @@ class CartridgeCDF : public Cartridge
|
||||||
uInt32 getSample();
|
uInt32 getSample();
|
||||||
void setVersion();
|
void setVersion();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum class CDFSubtype {
|
||||||
|
CDF,
|
||||||
|
CDFJ
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The 32K ROM image of the cartridge
|
// The 32K ROM image of the cartridge
|
||||||
uInt8 myImage[32768];
|
uInt8 myImage[32768];
|
||||||
|
@ -277,8 +284,29 @@ class CartridgeCDF : public Cartridge
|
||||||
|
|
||||||
uInt8 myFastJumpActive;
|
uInt8 myFastJumpActive;
|
||||||
|
|
||||||
// version of CDF
|
// Pointer to the array of datastream pointers
|
||||||
uInt16 myVersion;
|
uInt16 myDatastreamBase;
|
||||||
|
|
||||||
|
// Pointer to the array of datastream increments
|
||||||
|
uInt16 myDatastreamIncrementBase;
|
||||||
|
|
||||||
|
// Pointer to the beginning of the waveform data block
|
||||||
|
uInt16 myWaveformBase;
|
||||||
|
|
||||||
|
// Amplitude stream index
|
||||||
|
uInt8 myAmplitudeStream;
|
||||||
|
|
||||||
|
// Mask for determining the index of the datastream during fastjump
|
||||||
|
uInt8 myFastjumpStreamIndexMask;
|
||||||
|
|
||||||
|
// The currently selected fastjump stream
|
||||||
|
uInt8 myFastJumpStream;
|
||||||
|
|
||||||
|
// CDF version
|
||||||
|
uInt8 myCDFVersion;
|
||||||
|
|
||||||
|
// CDF subtype
|
||||||
|
CDFSubtype myCDFSubtype;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
|
|
Loading…
Reference in New Issue