'3E' bankswitch scheme now always reports 256+32 banks, even if there

really aren't that many ROM banks.  This is done so that the RAM banks
always start at number 256.

Added latest DPC+ updates from Spiceware.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1983 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-04-02 18:56:50 +00:00
parent fe0e1c757e
commit 8c3ea00bb2
6 changed files with 212 additions and 146 deletions

View File

@ -232,9 +232,12 @@ int Cartridge3E::bank()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Cartridge3E::bankCount() int Cartridge3E::bankCount()
{ {
// In addition to the number of 2K banks in ROM, there are 32 more 1K // Because the RAM banks always start at 256 and above, we require the
// banks for RAM (doubled to 2K because of a read and write port) // number of ROM banks to be 256
return (mySize >> 11) + 32; // If the RAM banks were simply appended to the number of actual
// ROM banks, bank numbers would be ambiguous (ie, would bank 128 be
// the last bank of ROM, or one of the banks of RAM?)
return 256 + 32;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -69,13 +69,11 @@ void Cartridge4A50::install(System& system)
// Map all of the accesses to call peek and poke // Map all of the accesses to call peek and poke
System::PageAccess access; System::PageAccess access;
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift)) for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
{
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
mySystem->setPageAccess(i >> shift, access); mySystem->setPageAccess(i >> 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.

View File

@ -92,14 +92,13 @@ void CartridgeAR::install(System& system)
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert((0x1000 & mask) == 0); assert((0x1000 & mask) == 0);
// Map all of the accesses to call peek and poke
System::PageAccess access; System::PageAccess access;
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift)) for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
{
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
mySystem->setPageAccess(i >> shift, access); mySystem->setPageAccess(i >> shift, access);
}
bankConfiguration(0); bankConfiguration(0);
} }

View File

@ -18,13 +18,14 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <iostream>
#include "System.hxx" #include "System.hxx"
#include "CartDPC.hxx" #include "CartDPC.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDPC::CartridgeDPC(const uInt8* image, uInt32 size) CartridgeDPC::CartridgeDPC(const uInt8* image, uInt32 size)
: mySystemCycles(0),
myFractionalClocks(0.0)
{ {
// Make a copy of the entire image as-is, for use by getImage() // Make a copy of the entire image as-is, for use by getImage()
// (this wastes 12K of RAM, should be controlled by a #ifdef) // (this wastes 12K of RAM, should be controlled by a #ifdef)
@ -46,10 +47,6 @@ CartridgeDPC::CartridgeDPC(const uInt8* image, uInt32 size)
// Initialize the DPC's random number generator register (must be non-zero) // Initialize the DPC's random number generator register (must be non-zero)
myRandomNumber = 1; myRandomNumber = 1;
// Initialize the system cycles counter & fractional clock values
mySystemCycles = 0;
myFractionalClocks = 0.0;
// Remember startup bank // Remember startup bank
myStartBank = 1; myStartBank = 1;
} }
@ -190,6 +187,11 @@ uInt8 CartridgeDPC::peek(uInt16 address)
{ {
address &= 0x0FFF; address &= 0x0FFF;
// In debugger/bank-locked mode, we ignore all hotspots and in general
// anything that can change the internal state of the cart
if(bankLocked())
return myProgramImage[(myCurrentBank << 12) + address];
// Clock the random number generator. This should be done for every // Clock the random number generator. This should be done for every
// cartridge access, however, we're only doing it for the DPC and // cartridge access, however, we're only doing it for the DPC and
// hot-spot accesses to save time. // hot-spot accesses to save time.

View File

@ -26,6 +26,9 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size) CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size)
: myFastFetch(false),
mySystemCycles(0),
myFractionalClocks(0.0)
{ {
// Make a copy of the entire image as-is, for use by getImage() // Make a copy of the entire image as-is, for use by getImage()
// (this wastes 29K of RAM, should be controlled by a #ifdef) // (this wastes 29K of RAM, should be controlled by a #ifdef)
@ -50,10 +53,6 @@ CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size)
// Initialize the DPC's random number generator register (must be non-zero) // Initialize the DPC's random number generator register (must be non-zero)
myRandomNumber = 0x2B435044; // "DPC+" myRandomNumber = 0x2B435044; // "DPC+"
// Initialize the system cycles counter & fractional clock values
mySystemCycles = 0;
myFractionalClocks = 0.0;
// Remember startup bank // Remember startup bank
myStartBank = 5; myStartBank = 5;
} }
@ -90,29 +89,18 @@ void CartridgeDPCPlus::install(System& system)
mySystem = &system; mySystem = &system;
uInt16 shift = mySystem->pageShift(); uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask(); uInt16 mask = mySystem->pageMask();
// Make sure the system we're being installed in has a page size that'll work // Make sure the system we're being installed in has a page size that'll work
assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0)); assert(((0x1080 & mask) == 0) && ((0x1100 & mask) == 0));
// Set the page accessing methods for the hot spots // Map all of the accesses to call peek and poke
System::PageAccess access; System::PageAccess access;
for(uInt32 i = (0x1FF6 & ~mask); i < 0x2000; i += (1 << shift)) access.directPeekBase = 0;
{ access.directPokeBase = 0;
access.directPeekBase = 0; access.device = this;
access.directPokeBase = 0; for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
access.device = this;
mySystem->setPageAccess(i >> shift, access); mySystem->setPageAccess(i >> shift, access);
}
// Set the page accessing method for the DPC reading & writing pages
for(uInt32 j = 0x1000; j < 0x1080; j += (1 << shift))
{
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
mySystem->setPageAccess(j >> shift, access);
}
// Install pages for the startup bank // Install pages for the startup bank
bank(myStartBank); bank(myStartBank);
} }
@ -121,15 +109,14 @@ void CartridgeDPCPlus::install(System& system)
inline void CartridgeDPCPlus::clockRandomNumberGenerator() inline void CartridgeDPCPlus::clockRandomNumberGenerator()
{ {
// Update random number generator (32-bit LFSR) // Update random number generator (32-bit LFSR)
myRandomNumber = ((myRandomNumber & 1) ? 0xa260012b: 0x00) ^ myRandomNumber = ((myRandomNumber & 1) ? 0xa260012b: 0x00) ^ ((myRandomNumber >> 1) & 0x7FFFFFFF);
((myRandomNumber >> 1) & 0x7FFFFFFF);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline void CartridgeDPCPlus::priorClockRandomNumberGenerator() inline void CartridgeDPCPlus::priorClockRandomNumberGenerator()
{ {
// Update random number generator (32-bit LFSR, reversed) // Update random number generator (32-bit LFSR, reversed)
myRandomNumber = ((myRandomNumber & (1<<31)) ? 0x44c00257: 0x00) ^ (myRandomNumber << 1); myRandomNumber = ((myRandomNumber & (1<<31)) ? 0x44c00257: 0x00) ^ (myRandomNumber << 1);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -165,64 +152,76 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
{ {
address &= 0x0FFF; address &= 0x0FFF;
if(address < 0x0040) uInt8 peekvalue = myProgramImage[(myCurrentBank << 12) + address];
// In debugger/bank-locked mode, we ignore all hotspots and in general
// anything that can change the internal state of the cart
if(bankLocked())
return peekvalue;
if(myFastFetch && myLDAimmediate)
{
peekvalue = myProgramImage[(myCurrentBank << 12) + address];
if(peekvalue < 0x0028)
address = peekvalue;
}
myLDAimmediate = false;
if(address < 0x0028)
{ {
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 & 0x07; uInt32 index = address & 0x07;
uInt32 function = (address >> 3) & 0x07; uInt32 function = (address >> 3) & 0x07;
// Update flag register for selected data fetcher // Update flag register for selected data fetcher
if(((myCounters[index] & 0x00ff00) >> 8) == ((myTops[index]+1) & 0xff)) if((myCounters[index] & 0x00ff) == ((myTops[index]+1) & 0xff))
{ {
myFlags[index] = 0xff; myFlags[index] = 0xff;
} }
else if(((myCounters[index] & 0x00ff00) >> 8) == myBottoms[index]) else if((myCounters[index] & 0x00ff) == myBottoms[index])
{ {
myFlags[index] = 0x00; myFlags[index] = 0x00;
} }
switch(function) switch(function)
{ {
case 0x00: case 0x00:
{ {
switch(index) switch(index)
{ {
case 0x00: //advance and return byte 0 of random case 0x00: // advance and return byte 0 of random
clockRandomNumberGenerator(); clockRandomNumberGenerator();
result = myRandomNumber & 0xFF; result = myRandomNumber & 0xFF;
break; break;
case 0x01: // return to prior and return byte 0 of random case 0x01: // return to prior and return byte 0 of random
priorClockRandomNumberGenerator(); priorClockRandomNumberGenerator();
result = myRandomNumber & 0xFF; result = myRandomNumber & 0xFF;
break; break;
case 0x02: case 0x02:
result = (myRandomNumber>>8) & 0xFF; result = (myRandomNumber>>8) & 0xFF;
break; break;
case 0x03: case 0x03:
result = (myRandomNumber>>16) & 0xFF; result = (myRandomNumber>>16) & 0xFF;
break; break;
case 0x04: case 0x04:
result = (myRandomNumber>>24) & 0xFF; result = (myRandomNumber>>24) & 0xFF;
break; break;
case 0x05: case 0x05: // No, it's a music read
case 0x06:
case 0x07:
// No, it's a music read
{ {
static const uInt8 musicAmplitudes[8] = { static const uInt8 musicAmplitudes[8] = {
0x00, 0x04, 0x05, 0x09, 0x06, 0x0a, 0x0b, 0x0f 0x00, 0x04, 0x05, 0x09, 0x06, 0x0a, 0x0b, 0x0f
}; };
// Update the music data fetchers (counter & flag) // Update the music data fetchers (counter & flag)
updateMusicModeDataFetchers(); updateMusicModeDataFetchers();
uInt8 i = 0; uInt8 i = 0;
if(myMusicMode[0] && (myMusicCounter[0]>>31)) if(myMusicMode[0] && (myMusicCounter[0]>>31))
{ {
@ -236,45 +235,69 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
{ {
i |= 0x04; i |= 0x04;
} }
result = musicAmplitudes[i]; result = musicAmplitudes[i];
break;
} }
break;
case 0x06: // reserved
case 0x07: // reserved
break;
} }
break; break;
} }
// DFx display data read // DFx display data read
case 0x01: case 0x01:
{ {
result = myDisplayImage[myCounters[index] >> 8]; result = myDisplayImage[myCounters[index]];
myCounters[index] = (myCounters[index] + 0x100) & 0x0fffff; myCounters[index] = (myCounters[index] + 0x1) & 0x0fff;
break; break;
} }
// DFx display data read AND'd w/flag // DFx display data read AND'd w/flag
case 0x02: case 0x02:
{ {
result = myDisplayImage[myCounters[index] >> 8] & myFlags[index]; result = myDisplayImage[myCounters[index]] & myFlags[index];
myCounters[index] = (myCounters[index] + 0x100) & 0x0fffff; myCounters[index] = (myCounters[index] + 0x1) & 0x0fff;
break; break;
} }
// DFx display data read w/fractional increment // DFx display data read w/fractional increment
case 0x03: case 0x03:
{ {
result = myDisplayImage[myCounters[index] >> 8]; result = myDisplayImage[myFractionalCounters[index] >> 8];
myCounters[index] = (myCounters[index] + myFractionalIncrements[index]) & 0x0fffff; myFractionalCounters[index] = (myFractionalCounters[index] + myFractionalIncrements[index]) & 0x0fffff;
break; break;
} }
case 0x04:
{
switch (index)
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
{
result = myFlags[index];
break;
}
case 0x04: // reserved
case 0x05: // reserved
case 0x06: // reserved
case 0x07: // reserved
break;
}
break;
}
default: default:
{ {
result = 0; result = 0;
break;
} }
} }
return result; return result;
} }
else else
@ -286,36 +309,41 @@ uInt8 CartridgeDPCPlus::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 0x0FF7: case 0x0FF7:
// 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 0x0FF8: case 0x0FF8:
// 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 0x0FF9: case 0x0FF9:
// 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 0x0FFA: case 0x0FFA:
// 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 0x0FFB: case 0x0FFB:
// Set the current bank to the last 4k bank // Set the current bank to the last 4k bank
bank(5); bank(5);
break; break;
default: default:
break; break;
} }
return myProgramImage[(myCurrentBank << 12) + address];
peekvalue = myProgramImage[(myCurrentBank << 12) + address];
if(myFastFetch)
myLDAimmediate = (peekvalue == 0xA9);
return peekvalue;
} }
} }
@ -323,78 +351,103 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value) bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
{ {
address &= 0x0FFF; address &= 0x0FFF;
if((address >= 0x0038) && (address < 0x0080)) if((address >= 0x0028) && (address < 0x0080))
{ {
// 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 & 0x07; uInt32 index = address & 0x07;
uInt32 function = ((address - 0x38) >> 3) & 0x0f; uInt32 function = ((address - 0x28) >> 3) & 0x0f;
switch(function) switch(function)
{ {
//DFxFrac counter low
case 0x00: case 0x00:
{
myFractionalCounters[index] = (myFractionalCounters[index] & 0x0F0000) | ((uInt16)value << 8);
break;
}
// DFxFrac counter high
case 0x01:
{
myFractionalCounters[index] = (((uInt16)value & 0x0F) << 16) | (myFractionalCounters[index] & 0x00ffff);
break;
}
case 0x02:
{ {
myFractionalIncrements[index] = value; myFractionalIncrements[index] = value;
myCounters[index] = myCounters[index] & 0x0FFF00; myFractionalCounters[index] = myFractionalCounters[index] & 0x0FFF00;
break; break;
} }
// DFx top count // DFx top count
case 0x01: case 0x03:
{ {
myTops[index] = value; myTops[index] = value;
myFlags[index] = 0x00; myFlags[index] = 0x00;
break; break;
} }
// DFx bottom count // DFx bottom count
case 0x02: case 0x04:
{ {
myBottoms[index] = value; myBottoms[index] = value;
break; break;
} }
// DFx counter low // DFx counter low
case 0x03: case 0x05:
{ {
myCounters[index] = (myCounters[index] & 0x0F0000) | ((uInt16)value << 8); myCounters[index] = (myCounters[index] & 0x0F00) | value ;
break; break;
} }
// DFx counter high // Control registers
case 0x04: case 0x06:
{ {
myCounters[index] = (((uInt16)value & 0x0F) << 16) | (myCounters[index] & 0x00ffff); switch (index)
// Execute special code for music mode data fetchers
if(index >= 5)
{ {
myMusicMode[index - 5] = (value & 0x10); // FastFetch control
case 0x00:
// NOTE: We are not handling the clock source input for {
// the music mode data fetchers. We're going to assume myFastFetch = (value == 0);
// they always use the OSC input. break;
}
case 0x01: // reserved
case 0x02: // reserved
case 0x03: // reserved
case 0x04: // reserved
break;
case 0x05:
case 0x06:
case 0x07:
{
myMusicMode[index - 5] = (value & 0x10);
break;
}
break;
} }
break; break;
} }
// DF Push // DF Push
case 0x05: case 0x07:
{ {
myCounters[index] = (myCounters[index] - 0x100) & 0x0fffff; myCounters[index] = (myCounters[index] - 0x1) & 0x0fff;
myDisplayImage[myCounters[index] >> 8] = value; myDisplayImage[myCounters[index]] = value;
break; break;
} }
// DFx counter hi, same as counter high, but w/out music mode // DFx counter hi, same as counter high, but w/out music mode
case 0x06: case 0x08:
{ {
myCounters[index] = (((uInt16)value & 0x0F) << 16) | (myCounters[index] & 0x00ffff); myCounters[index] = (((uInt16)value & 0x0F) << 8) | (myCounters[index] & 0x00ff);
break; break;
} }
// Random Number Generator Reset // Random Number Generator Reset
case 0x07: case 0x09:
{ {
switch (index) switch (index)
{ {
@ -428,10 +481,9 @@ bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
case 0x07: case 0x07:
{ {
myMusicFrequency[index-5] = myFrequencyImage[(value<<2)] + myMusicFrequency[index-5] = myFrequencyImage[(value<<2)] +
(myFrequencyImage[(value<<2)+1]<<8) + (myFrequencyImage[(value<<2)+1]<<8) +
(myFrequencyImage[(value<<2)+2]<<16) + (myFrequencyImage[(value<<2)+2]<<16) +
(myFrequencyImage[(value<<2)+3]<<24); (myFrequencyImage[(value<<2)+3]<<24);
break; break;
} }
default: default:
@ -439,17 +491,19 @@ bool CartridgeDPCPlus::poke(uInt16 address, uInt8 value)
} }
break; break;
} }
// DF Write // DF Write
case 0x08: case 0x0a:
{ {
myDisplayImage[myCounters[index] >> 8] = value; myDisplayImage[myCounters[index]] = value;
myCounters[index] = (myCounters[index] + 0x100) & 0x0fffff; myCounters[index] = (myCounters[index] + 0x1) & 0x0fff;
break; break;
} }
default: default:
{
break; break;
}
} }
} }
else else
@ -461,32 +515,32 @@ bool CartridgeDPCPlus::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 0x0FF7: case 0x0FF7:
// 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 0x0FF8: case 0x0FF8:
// 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 0x0FF9: case 0x0FF9:
// 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 0x0FFA: case 0x0FFA:
// 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 0x0FFB: case 0x0FFB:
// Set the current bank to the last 4k bank // Set the current bank to the last 4k bank
bank(5); bank(5);
break; break;
default: default:
break; break;
} }
@ -501,22 +555,7 @@ void CartridgeDPCPlus::bank(uInt16 bank)
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myCurrentBank = bank;
uInt16 offset = myCurrentBank << 12;
uInt16 shift = mySystem->pageShift();
uInt16 mask = mySystem->pageMask();
// Setup the page access methods for the current bank
System::PageAccess access;
access.device = this;
access.directPokeBase = 0;
// Map Program ROM image into the system
for(uInt32 address = 0x1080; address < (0x1FF8U & ~mask);
address += (1 << shift))
{
access.directPeekBase = &myProgramImage[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> shift, access);
}
myBankChanged = true; myBankChanged = true;
} }
@ -583,6 +622,11 @@ bool CartridgeDPCPlus::save(Serializer& out) const
for(i = 0; i < 8; ++i) for(i = 0; i < 8; ++i)
out.putInt(myCounters[i]); out.putInt(myCounters[i]);
// The counter registers for the fractional data fetchers
out.putInt(8);
for(i = 0; i < 8; ++i)
out.putInt(myFractionalCounters[i]);
// The fractional registers for the data fetchers // The fractional registers for the data fetchers
out.putInt(8); out.putInt(8);
for(i = 0; i < 8; ++i) for(i = 0; i < 8; ++i)
@ -593,6 +637,10 @@ bool CartridgeDPCPlus::save(Serializer& out) const
for(i = 0; i < 8; ++i) for(i = 0; i < 8; ++i)
out.putByte((char)myFlags[i]); out.putByte((char)myFlags[i]);
// The Fast Fetcher Enabled flag
out.putBool(myFastFetch);
out.putBool(myLDAimmediate);
// The music mode flags for the data fetchers // The music mode flags for the data fetchers
out.putInt(3); out.putInt(3);
for(i = 0; i < 3; ++i) for(i = 0; i < 3; ++i)
@ -651,7 +699,12 @@ bool CartridgeDPCPlus::load(Serializer& in)
// The counter registers for the data fetchers // The counter registers for the data fetchers
limit = (uInt32) in.getInt(); limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i) for(i = 0; i < limit; ++i)
myCounters[i] = (uInt32) in.getInt(); myCounters[i] = (uInt16) in.getInt();
// The counter registers for the data fetchers
limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i)
myFractionalCounters[i] = (uInt32) in.getInt();
// The fractional registers for the data fetchers // The fractional registers for the data fetchers
limit = (uInt32) in.getInt(); limit = (uInt32) in.getInt();
@ -663,6 +716,10 @@ bool CartridgeDPCPlus::load(Serializer& in)
for(i = 0; i < limit; ++i) for(i = 0; i < limit; ++i)
myFlags[i] = (uInt8) in.getByte(); myFlags[i] = (uInt8) in.getByte();
// The Fast Fetcher Enabled flag
myFastFetch = in.getBool();
myLDAimmediate = in.getBool();
// The music mode flags for the data fetchers // The music mode flags for the data fetchers
limit = (uInt32) in.getInt(); limit = (uInt32) in.getInt();
for(i = 0; i < limit; ++i) for(i = 0; i < limit; ++i)

View File

@ -182,14 +182,21 @@ class CartridgeDPCPlus : public Cartridge
uInt8 myBottoms[8]; uInt8 myBottoms[8];
// The counter registers for the data fetchers // The counter registers for the data fetchers
uInt32 myCounters[8]; uInt16 myCounters[8];
// The counter registers for the fractional data fetchers
uInt32 myFractionalCounters[8];
// The fractional increments for the data fetchers // The fractional increments for the data fetchers
uInt8 myFractionalIncrements[8]; uInt8 myFractionalIncrements[8];
// The flag registers for the data fetchers // The flag registers for the data fetchers
uInt8 myFlags[8]; uInt8 myFlags[8];
// The Fast Fetcher Enabled flag
bool myFastFetch;
bool myLDAimmediate;
// The music mode DF5, DF6, & DF7 enabled flags // The music mode DF5, DF6, & DF7 enabled flags
bool myMusicMode[3]; bool myMusicMode[3];