mirror of https://github.com/stella-emu/stella.git
Sample playback update for BUS & CDF.
This commit is contained in:
parent
79d8ed0010
commit
e419bbbcab
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue