Sample playback update for BUS & CDF.

This commit is contained in:
Stephen Anthony 2017-05-28 14:40:51 -02:30
parent 79d8ed0010
commit e419bbbcab
2 changed files with 66 additions and 56 deletions

View File

@ -99,10 +99,10 @@ void CartridgeBUS::setInitialState()
for (int i=0; i < 3; ++i) for (int i=0; i < 3; ++i)
myMusicWaveformSize[i] = 27; myMusicWaveformSize[i] = 27;
// BUS always starts in bank 6 // BUS always starts in bank 6
myStartBank = 6; myStartBank = 6;
// Assuming mode starts out with Fast Fetch off and 3-Voice music, // Assuming mode starts out with Fast Fetch off and 3-Voice music,
// need to confirm with Chris // need to confirm with Chris
myMode = 0xFF; myMode = 0xFF;
@ -156,15 +156,11 @@ inline void CartridgeBUS::updateMusicModeDataFetchers()
myFractionalClocks = clocks - double(wholeClocks); myFractionalClocks = clocks - double(wholeClocks);
if(wholeClocks <= 0) if(wholeClocks <= 0)
{
return; return;
}
// Let's update counters and flags of the music mode data fetchers // Let's update counters and flags of the music mode data fetchers
for(int x = 0; x <= 2; ++x) for(int x = 0; x <= 2; ++x)
{
myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks; myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -180,7 +176,7 @@ inline void CartridgeBUS::callFunction(uInt8 value)
try { try {
Int32 cycles = mySystem->cycles() - myARMCycles; Int32 cycles = mySystem->cycles() - myARMCycles;
myARMCycles = mySystem->cycles(); myARMCycles = mySystem->cycles();
myThumbEmulator->run(cycles); myThumbEmulator->run(cycles);
} }
catch(const runtime_error& e) { catch(const runtime_error& e) {
@ -220,22 +216,22 @@ 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 17 // implement JMP FASTJMP which fetches the destination address from stream 17
if (myFastJumpActive if (myFastJumpActive
&& myJMPoperandAddress == address) && myJMPoperandAddress == address)
{ {
uInt32 pointer; uInt32 pointer;
uInt8 value; uInt8 value;
myFastJumpActive--; myFastJumpActive--;
myJMPoperandAddress++; myJMPoperandAddress++;
pointer = getDatastreamPointer(JUMPSTREAM); pointer = getDatastreamPointer(JUMPSTREAM);
value = myDisplayImage[ pointer >> 20 ]; value = myDisplayImage[ pointer >> 20 ];
pointer += 0x100000; // always increment by 1 pointer += 0x100000; // always increment by 1
setDatastreamPointer(JUMPSTREAM, pointer); setDatastreamPointer(JUMPSTREAM, pointer);
return value; return value;
} }
@ -261,16 +257,23 @@ uInt8 CartridgeBUS::peek(uInt16 address)
switch(address) switch(address)
{ {
case 0xFEE: // AMPLITUDE case 0xFEE: // AMPLITUDE
// Update the music data fetchers (counter & flag) // Update the music data fetchers (counter & flag)
updateMusicModeDataFetchers(); updateMusicModeDataFetchers();
if DIGITAL_AUDIO_ON if DIGITAL_AUDIO_ON
{ {
// retrieve packed sample (max size is 2K, or 4K of unpacked data) // retrieve packed sample (max size is 2K, or 4K of unpacked data)
peekvalue = myImage[getSample() + (myMusicCounters[0] >> 21)]; uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 21);
// // get sample value from ROM or RAM
if (sampleaddress < 0x8000)
peekvalue = myImage[sampleaddress];
else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40002000) // check for RAM
peekvalue = myBUSRAM[sampleaddress - 0x40000000];
else
peekvalue = 0;
// make sure current volume value is in the lower nybble
if ((myMusicCounters[0] & (1<<20)) == 0) if ((myMusicCounters[0] & (1<<20)) == 0)
peekvalue >>= 4; peekvalue >>= 4;
peekvalue &= 0x0f; peekvalue &= 0x0f;
@ -280,67 +283,67 @@ uInt8 CartridgeBUS::peek(uInt16 address)
// using myDisplayImage[] instead of myProgramImage[] because waveforms // using myDisplayImage[] instead of myProgramImage[] because waveforms
// can be modified during runtime. // can be modified during runtime.
uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] + uInt32 i = myDisplayImage[(getWaveform(0) ) + (myMusicCounters[0] >> myMusicWaveformSize[0])] +
myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] + myDisplayImage[(getWaveform(1) ) + (myMusicCounters[1] >> myMusicWaveformSize[1])] +
myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])]; myDisplayImage[(getWaveform(2) ) + (myMusicCounters[2] >> myMusicWaveformSize[2])];
peekvalue = uInt8(i); peekvalue = uInt8(i);
} }
break; break;
case 0xFEF: // DSREAD case 0xFEF: // DSREAD
peekvalue = readFromDatastream(COMMSTREAM); peekvalue = readFromDatastream(COMMSTREAM);
break; break;
case 0xFF0: // DSWRITE case 0xFF0: // DSWRITE
case 0xFF1: // DSPTR case 0xFF1: // DSPTR
case 0xFF2: // SETMODE case 0xFF2: // SETMODE
case 0xFF3: // CALLFN case 0xFF3: // CALLFN
// these are write-only // these are write-only
break; break;
case 0xFF5: case 0xFF5:
// Set the current bank to the first 4k bank // Set the current bank to the first 4k bank
bank(0); bank(0);
break; break;
case 0x0FF6: case 0x0FF6:
// Set the current bank to the second 4k bank // Set the current bank to the second 4k bank
bank(1); bank(1);
break; break;
case 0x0FF7: case 0x0FF7:
// Set the current bank to the third 4k bank // Set the current bank to the third 4k bank
bank(2); bank(2);
break; break;
case 0x0FF8: case 0x0FF8:
// Set the current bank to the fourth 4k bank // Set the current bank to the fourth 4k bank
bank(3); bank(3);
break; break;
case 0x0FF9: case 0x0FF9:
// Set the current bank to the fifth 4k bank // Set the current bank to the fifth 4k bank
bank(4); bank(4);
break; break;
case 0x0FFA: case 0x0FFA:
// Set the current bank to the sixth 4k bank // Set the current bank to the sixth 4k bank
bank(5); bank(5);
break; break;
case 0x0FFB: case 0x0FFB:
// Set the current bank to the last 4k bank // Set the current bank to the last 4k bank
bank(6); bank(6);
break; break;
default: default:
break; break;
} }
// this might not work right for STY $84 // this might not work right for STY $84
if (BUS_STUFF_ON && peekvalue == 0x84) if (BUS_STUFF_ON && peekvalue == 0x84)
mySTYZeroPageAddress = address + 1; mySTYZeroPageAddress = address + 1;
return peekvalue; return peekvalue;
} }
@ -373,14 +376,14 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
case 0xFEF: // DSREAD case 0xFEF: // DSREAD
// these are read-only // these are read-only
break; break;
case 0xFF0: // DSWRITE case 0xFF0: // DSWRITE
pointer = getDatastreamPointer(COMMSTREAM); 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(COMMSTREAM, pointer); setDatastreamPointer(COMMSTREAM, pointer);
break; break;
case 0xFF1: // DSPTR case 0xFF1: // DSPTR
pointer = getDatastreamPointer(COMMSTREAM); pointer = getDatastreamPointer(COMMSTREAM);
pointer <<=8; pointer <<=8;
@ -388,50 +391,50 @@ bool CartridgeBUS::poke(uInt16 address, uInt8 value)
pointer |= (value << 20); pointer |= (value << 20);
setDatastreamPointer(COMMSTREAM, pointer); setDatastreamPointer(COMMSTREAM, pointer);
break; break;
case 0xFF2: // SETMODE case 0xFF2: // SETMODE
myMode = value; myMode = value;
break; break;
case 0xFF3: // CALLFN case 0xFF3: // CALLFN
callFunction(value); callFunction(value);
break; break;
case 0xFF5: case 0xFF5:
// Set the current bank to the first 4k bank // Set the current bank to the first 4k bank
bank(0); bank(0);
break; break;
case 0x0FF6: case 0x0FF6:
// Set the current bank to the second 4k bank // Set the current bank to the second 4k bank
bank(1); bank(1);
break; break;
case 0x0FF7: case 0x0FF7:
// Set the current bank to the third 4k bank // Set the current bank to the third 4k bank
bank(2); bank(2);
break; break;
case 0x0FF8: case 0x0FF8:
// Set the current bank to the fourth 4k bank // Set the current bank to the fourth 4k bank
bank(3); bank(3);
break; break;
case 0x0FF9: case 0x0FF9:
// Set the current bank to the fifth 4k bank // Set the current bank to the fifth 4k bank
bank(4); bank(4);
break; break;
case 0x0FFA: case 0x0FFA:
// Set the current bank to the sixth 4k bank // Set the current bank to the sixth 4k bank
bank(5); bank(5);
break; break;
case 0x0FFB: case 0x0FFB:
// Set the current bank to the last 4k bank // Set the current bank to the last 4k bank
bank(6); bank(6);
break; break;
default: default:
break; break;
} }
@ -565,17 +568,17 @@ bool CartridgeBUS::save(Serializer& out) const
// Harmony RAM // Harmony RAM
out.putByteArray(myBUSRAM, 8192); out.putByteArray(myBUSRAM, 8192);
// Addresses for bus override logic // Addresses for bus override logic
out.putShort(myBusOverdriveAddress); out.putShort(myBusOverdriveAddress);
out.putShort(mySTYZeroPageAddress); out.putShort(mySTYZeroPageAddress);
out.putShort(myJMPoperandAddress); out.putShort(myJMPoperandAddress);
// Save cycles and clocks // 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); out.putInt(myARMCycles);
// Audio info // Audio info
out.putIntArray(myMusicCounters, 3); out.putIntArray(myMusicCounters, 3);
out.putIntArray(myMusicFrequencies, 3); out.putIntArray(myMusicFrequencies, 3);
@ -609,7 +612,7 @@ bool CartridgeBUS::load(Serializer& in)
// Harmony RAM // Harmony RAM
in.getByteArray(myBUSRAM, 8192); in.getByteArray(myBUSRAM, 8192);
// Addresses for bus override logic // Addresses for bus override logic
myBusOverdriveAddress = in.getShort(); myBusOverdriveAddress = in.getShort();
mySTYZeroPageAddress = in.getShort(); mySTYZeroPageAddress = in.getShort();
@ -619,15 +622,15 @@ bool CartridgeBUS::load(Serializer& in)
mySystemCycles = (Int32)in.getInt(); mySystemCycles = (Int32)in.getInt();
myFractionalClocks = (double)in.getInt() / 100000000.0; myFractionalClocks = (double)in.getInt() / 100000000.0;
myARMCycles = (Int32)in.getInt(); myARMCycles = (Int32)in.getInt();
// Audio info // Audio info
in.getIntArray(myMusicCounters, 3); in.getIntArray(myMusicCounters, 3);
in.getIntArray(myMusicFrequencies, 3); in.getIntArray(myMusicFrequencies, 3);
in.getByteArray(myMusicWaveformSize, 3); in.getByteArray(myMusicWaveformSize, 3);
// Indicates current mode // Indicates current mode
myMode = in.getByte(); myMode = in.getByte();
// Indicates if in the middle of a fast jump // Indicates if in the middle of a fast jump
myFastJumpActive = in.getByte(); myFastJumpActive = in.getByte();
} }
@ -728,12 +731,12 @@ uInt32 CartridgeBUS::getWaveform(uInt8 index) const
uInt32 CartridgeBUS::getSample() uInt32 CartridgeBUS::getSample()
{ {
uInt32 result; uInt32 result;
result = myBUSRAM[WAVEFORM + 0] + // low byte result = myBUSRAM[WAVEFORM + 0] + // low byte
(myBUSRAM[WAVEFORM + 1] << 8) + (myBUSRAM[WAVEFORM + 1] << 8) +
(myBUSRAM[WAVEFORM + 2] << 16) + (myBUSRAM[WAVEFORM + 2] << 16) +
(myBUSRAM[WAVEFORM + 3] << 24); // high byte (myBUSRAM[WAVEFORM + 3] << 24); // high byte
return result; return result;
} }

View File

@ -230,7 +230,7 @@ uInt8 CartridgeCDF::peek(uInt16 address)
myJMPoperandAddress = address + 1; myJMPoperandAddress = address + 1;
return peekvalue; return peekvalue;
} }
myJMPoperandAddress = 0; myJMPoperandAddress = 0;
// Do a FAST FETCH LDA# if: // Do a FAST FETCH LDA# if:
@ -249,10 +249,17 @@ uInt8 CartridgeCDF::peek(uInt16 address)
if DIGITAL_AUDIO_ON if DIGITAL_AUDIO_ON
{ {
// retrieve packed sample (max size is 2K, or 4K of unpacked data) // retrieve packed sample (max size is 2K, or 4K of unpacked data)
address = getSample() + (myMusicCounters[0] >> 21); uInt32 sampleaddress = getSample() + (myMusicCounters[0] >> 21);
peekvalue = myImage[address];
// // get sample value from ROM or RAM
if (sampleaddress < 0x8000)
peekvalue = myImage[sampleaddress];
else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40002000) // check for RAM
peekvalue = myCDFRAM[sampleaddress - 0x40000000];
else
peekvalue = 0;
// make sure current volume value is in the lower nybble
if ((myMusicCounters[0] & (1<<20)) == 0) if ((myMusicCounters[0] & (1<<20)) == 0)
peekvalue >>= 4; peekvalue >>= 4;
peekvalue &= 0x0f; peekvalue &= 0x0f;