mirror of https://github.com/stella-emu/stella.git
CDF updates (with versioning) from Spiceware.
This commit is contained in:
parent
f57d69a023
commit
7a9cde3e4d
|
@ -30,7 +30,7 @@ CartridgeCDFWidget::CartridgeCDFWidget(
|
||||||
uInt16 size = 8 * 4096;
|
uInt16 size = 8 * 4096;
|
||||||
|
|
||||||
ostringstream info;
|
ostringstream info;
|
||||||
info << "CDF cartridge\n"
|
info << "CDF cartridge (version " << cart.myVersion << ")\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,9 +27,10 @@
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
|
|
||||||
// Location of data within the RAM copy of the CDF Driver.
|
// Location of data within the RAM copy of the CDF Driver.
|
||||||
#define DSxPTR 0x06E0
|
// Version 0 1
|
||||||
#define DSxINC 0x0768
|
const uInt16 DSxPTR[] = {0x06E0, 0x00A0};
|
||||||
#define WAVEFORM 0x07F0
|
const uInt16 DSxINC[] = {0x0768, 0x0128};
|
||||||
|
const uInt16 WAVEFORM[] = {0x07F0, 0x01B0};
|
||||||
#define DSRAM 0x0800
|
#define DSRAM 0x0800
|
||||||
|
|
||||||
#define COMMSTREAM 0x20
|
#define COMMSTREAM 0x20
|
||||||
|
@ -62,10 +63,15 @@ CartridgeCDF::CartridgeCDF(const BytePtr& image, uInt32 size,
|
||||||
|
|
||||||
// Pointer to the display RAM
|
// Pointer to the display RAM
|
||||||
myDisplayImage = myCDFRAM + DSRAM;
|
myDisplayImage = myCDFRAM + DSRAM;
|
||||||
|
|
||||||
|
setVersion();
|
||||||
|
|
||||||
#ifdef THUMB_SUPPORT
|
#ifdef THUMB_SUPPORT
|
||||||
// Create Thumbulator ARM emulator
|
// Create Thumbulator ARM emulator
|
||||||
myThumbEmulator = make_unique<Thumbulator>((uInt16*)myImage, (uInt16*)myCDFRAM,
|
myThumbEmulator = make_unique<Thumbulator>(
|
||||||
settings.getBool("thumb.trapfatal"), Thumbulator::ConfigureFor::CDF, this);
|
(uInt16*)myImage, (uInt16*)myCDFRAM, settings.getBool("thumb.trapfatal"),
|
||||||
|
myVersion ? Thumbulator::ConfigureFor::CDF1 : Thumbulator::ConfigureFor::CDF,
|
||||||
|
this);
|
||||||
#endif
|
#endif
|
||||||
setInitialState();
|
setInitialState();
|
||||||
}
|
}
|
||||||
|
@ -576,51 +582,57 @@ bool CartridgeCDF::load(Serializer& in)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const
|
uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const
|
||||||
{
|
{
|
||||||
// index &= 0x0f;
|
uInt16 address = DSxPTR[myVersion] + index * 4;
|
||||||
|
|
||||||
return myCDFRAM[DSxPTR + index*4 + 0] + // low byte
|
return myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[DSxPTR + index*4 + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
(myCDFRAM[DSxPTR + index*4 + 2] << 16) +
|
(myCDFRAM[address + 2] << 16) +
|
||||||
(myCDFRAM[DSxPTR + index*4 + 3] << 24) ; // high byte
|
(myCDFRAM[address + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
// index &= 0x1f;
|
uInt16 address = DSxPTR[myVersion] + index * 4;
|
||||||
myCDFRAM[DSxPTR + index*4 + 0] = value & 0xff; // low byte
|
|
||||||
myCDFRAM[DSxPTR + index*4 + 1] = (value >> 8) & 0xff;
|
myCDFRAM[address + 0] = value & 0xff; // low byte
|
||||||
myCDFRAM[DSxPTR + index*4 + 2] = (value >> 16) & 0xff;
|
myCDFRAM[address + 1] = (value >> 8) & 0xff;
|
||||||
myCDFRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myCDFRAM[address + 2] = (value >> 16) & 0xff;
|
||||||
|
myCDFRAM[address + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const
|
uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const
|
||||||
{
|
{
|
||||||
return myCDFRAM[DSxINC + index*4 + 0] + // low byte
|
uInt16 address = DSxINC[myVersion] + index * 4;
|
||||||
(myCDFRAM[DSxINC + index*4 + 1] << 8) +
|
|
||||||
(myCDFRAM[DSxINC + index*4 + 2] << 16) +
|
return myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[DSxINC + index*4 + 3] << 24) ; // high byte
|
(myCDFRAM[address + 1] << 8) +
|
||||||
|
(myCDFRAM[address + 2] << 16) +
|
||||||
|
(myCDFRAM[address + 3] << 24) ; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeCDF::setDatastreamIncrement(uInt8 index, uInt32 value)
|
void CartridgeCDF::setDatastreamIncrement(uInt8 index, uInt32 value)
|
||||||
{
|
{
|
||||||
myCDFRAM[DSxINC + index*4 + 0] = value & 0xff; // low byte
|
uInt16 address = DSxINC[myVersion] + index * 4;
|
||||||
myCDFRAM[DSxINC + index*4 + 1] = (value >> 8) & 0xff;
|
|
||||||
myCDFRAM[DSxINC + index*4 + 2] = (value >> 16) & 0xff;
|
myCDFRAM[address + 0] = value & 0xff; // low byte
|
||||||
myCDFRAM[DSxINC + index*4 + 3] = (value >> 24) & 0xff; // high byte
|
myCDFRAM[address + 1] = (value >> 8) & 0xff;
|
||||||
|
myCDFRAM[address + 2] = (value >> 16) & 0xff;
|
||||||
|
myCDFRAM[address + 3] = (value >> 24) & 0xff; // high byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
||||||
{
|
{
|
||||||
uInt32 result;
|
uInt32 result;
|
||||||
|
uInt16 address = WAVEFORM[myVersion] + index * 4;
|
||||||
|
|
||||||
result = myCDFRAM[WAVEFORM + index*4 + 0] + // low byte
|
result = myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[WAVEFORM + index*4 + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
(myCDFRAM[WAVEFORM + index*4 + 2] << 16) +
|
(myCDFRAM[address + 2] << 16) +
|
||||||
(myCDFRAM[WAVEFORM + index*4 + 3] << 24); // high byte
|
(myCDFRAM[address + 3] << 24); // high byte
|
||||||
|
|
||||||
result -= (0x40000000 + DSRAM);
|
result -= (0x40000000 + DSRAM);
|
||||||
|
|
||||||
|
@ -634,11 +646,12 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const
|
||||||
uInt32 CartridgeCDF::getSample()
|
uInt32 CartridgeCDF::getSample()
|
||||||
{
|
{
|
||||||
uInt32 result;
|
uInt32 result;
|
||||||
|
uInt16 address = WAVEFORM[myVersion];
|
||||||
|
|
||||||
result = myCDFRAM[WAVEFORM + 0] + // low byte
|
result = myCDFRAM[address + 0] + // low byte
|
||||||
(myCDFRAM[WAVEFORM + 1] << 8) +
|
(myCDFRAM[address + 1] << 8) +
|
||||||
(myCDFRAM[WAVEFORM + 2] << 16) +
|
(myCDFRAM[address + 2] << 16) +
|
||||||
(myCDFRAM[WAVEFORM + 3] << 24); // high byte
|
(myCDFRAM[address + 3] << 24); // high byte
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -669,3 +682,21 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index)
|
||||||
setDatastreamPointer(index, pointer);
|
setDatastreamPointer(index, pointer);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void CartridgeCDF::setVersion()
|
||||||
|
{
|
||||||
|
myVersion = 0;
|
||||||
|
|
||||||
|
for(uInt32 i = 0; i < 2048; i += 4)
|
||||||
|
{
|
||||||
|
// CDF signature occurs 3 times in a row, i+3 (+7 or +11) is version
|
||||||
|
if ( myImage[i+0] == 0x43 && myImage[i + 4] == 0x43 && myImage[i + 8] == 0x43) // C
|
||||||
|
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
|
||||||
|
{
|
||||||
|
myVersion = myImage[i+3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ class System;
|
||||||
|
|
||||||
|
|
||||||
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 Variable and Stack, and the CDF chip.
|
||||||
CDF chip access is mapped to $1000 - $103F.
|
CDF chip access is mapped to $1000 - $103F.
|
||||||
|
|
||||||
@authors: Darrell Spice Jr, Chris Walton, Fred Quimby,
|
@authors: Darrell Spice Jr, Chris Walton, Fred Quimby,
|
||||||
|
@ -209,6 +209,7 @@ class CartridgeCDF : public Cartridge
|
||||||
uInt32 getWaveform(uInt8 index) const;
|
uInt32 getWaveform(uInt8 index) const;
|
||||||
uInt32 getWaveformSize(uInt8 index) const;
|
uInt32 getWaveformSize(uInt8 index) const;
|
||||||
uInt32 getSample();
|
uInt32 getSample();
|
||||||
|
void setVersion();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The 32K ROM image of the cartridge
|
// The 32K ROM image of the cartridge
|
||||||
|
@ -289,6 +290,9 @@ class CartridgeCDF : public Cartridge
|
||||||
|
|
||||||
uInt8 myFastJumpActive;
|
uInt8 myFastJumpActive;
|
||||||
|
|
||||||
|
// version of CDF
|
||||||
|
uInt16 myVersion;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
CartridgeCDF() = delete;
|
CartridgeCDF() = delete;
|
||||||
|
|
|
@ -234,6 +234,7 @@ void Thumbulator::write16(uInt32 addr, uInt32 data)
|
||||||
// as additional RAM
|
// as additional RAM
|
||||||
case ConfigureFor::BUS:
|
case ConfigureFor::BUS:
|
||||||
case ConfigureFor::CDF:
|
case ConfigureFor::CDF:
|
||||||
|
case ConfigureFor::CDF1:
|
||||||
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;
|
||||||
|
@ -1198,6 +1199,67 @@ int Thumbulator::execute()
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ConfigureFor::CDF1:
|
||||||
|
// this subroutine interface is used in the CDF driver,
|
||||||
|
// it starts at address 0x00000750
|
||||||
|
// _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 CDF1_SetNote (0x00000752 + 4)
|
||||||
|
#define CDF1_ResetWave (0x00000756 + 4)
|
||||||
|
#define CDF1_GetWavePtr (0x0000075a + 4)
|
||||||
|
#define CDF1_SetWaveSize (0x0000075e + 4)
|
||||||
|
|
||||||
|
if (pc == CDF1_SetNote)
|
||||||
|
{
|
||||||
|
myCartridge->thumbCallback(0, read_register(2), read_register(3));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == CDF1_ResetWave)
|
||||||
|
{
|
||||||
|
myCartridge->thumbCallback(1, read_register(2), 0);
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == CDF1_GetWavePtr)
|
||||||
|
{
|
||||||
|
write_register(2, myCartridge->thumbCallback(2, read_register(2), 0));
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
else if (pc == CDF1_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
|
||||||
|
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::DPCplus:
|
case ConfigureFor::DPCplus:
|
||||||
// no 32-bit subroutines in DPC+
|
// no 32-bit subroutines in DPC+
|
||||||
break;
|
break;
|
||||||
|
@ -2266,6 +2328,7 @@ int Thumbulator::reset()
|
||||||
// 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:
|
||||||
|
case ConfigureFor::CDF1:
|
||||||
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;
|
||||||
|
|
|
@ -50,6 +50,7 @@ class Thumbulator
|
||||||
enum ConfigureFor {
|
enum ConfigureFor {
|
||||||
BUS, // cartridges of type BUS
|
BUS, // cartridges of type BUS
|
||||||
CDF, // cartridges of type CDF
|
CDF, // cartridges of type CDF
|
||||||
|
CDF1, // cartridges of type CDF version 1
|
||||||
DPCplus // cartridges of type DPC+
|
DPCplus // cartridges of type DPC+
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue