mirror of https://github.com/stella-emu/stella.git
Updated CTY BS scheme to latest version.
This commit is contained in:
parent
e09bc90d17
commit
4e0a941864
|
@ -17,13 +17,9 @@
|
|||
// $Id: CartCTY.cxx 2838 2014-01-17 23:34:03Z stephena $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Serializer.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartCTYTunes.hxx"
|
||||
#include "CartCTY.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -31,32 +27,35 @@ CartridgeCTY::CartridgeCTY(const uInt8* image, uInt32 size, const OSystem& osyst
|
|||
: Cartridge(osystem.settings()),
|
||||
myOSystem(osystem),
|
||||
myOperationType(0),
|
||||
myCounter(0),
|
||||
myTunePosition(0),
|
||||
myLDAimmediate(false),
|
||||
myRandomNumber(0x2B435044),
|
||||
myRamAccessTimeout(0),
|
||||
mySystemCycles(0),
|
||||
myFractionalClocks(0.0)
|
||||
myAudioCycles(0),
|
||||
myFractionalClocks(0.0),
|
||||
myBankOffset(0)
|
||||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, BSPF_min(32768u, size));
|
||||
memcpy(myImage, image, std::min(32768u, size));
|
||||
createCodeAccessBase(32768);
|
||||
|
||||
// This cart contains 64 bytes extended RAM @ 0x1000
|
||||
registerRamArea(0x1000, 64, 0x40, 0x00);
|
||||
// Default to no tune data in case user is utilizing an old ROM
|
||||
memset(myTuneData, 0, 28*1024);
|
||||
|
||||
// Extract tune data if it exists
|
||||
if (size > 32768u)
|
||||
memcpy(myTuneData, image + 32768u, size - 32768u);
|
||||
|
||||
// Point to the first tune
|
||||
myFrequencyImage = CartCTYTunes;
|
||||
myFrequencyImage = myTuneData;
|
||||
|
||||
for(uInt8 i = 0; i < 3; ++i)
|
||||
myMusicCounters[i] = myMusicFrequencies[i] = 0;
|
||||
|
||||
// Remember startup bank (not bank 0, since that's ARM code)
|
||||
myStartBank = 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeCTY::~CartridgeCTY()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeCTY::reset()
|
||||
{
|
||||
|
@ -70,7 +69,7 @@ void CartridgeCTY::reset()
|
|||
myRAM[0] = myRAM[1] = myRAM[2] = myRAM[3] = 0xFF;
|
||||
|
||||
// Update cycles to the current system cycles
|
||||
mySystemCycles = mySystem->cycles();
|
||||
myAudioCycles = mySystem->cycles();
|
||||
myFractionalClocks = 0.0;
|
||||
|
||||
// Upon reset we switch to the startup bank
|
||||
|
@ -81,19 +80,15 @@ void CartridgeCTY::reset()
|
|||
void CartridgeCTY::systemCyclesReset()
|
||||
{
|
||||
// Adjust the cycle counter so that it reflects the new value
|
||||
mySystemCycles -= mySystem->cycles();
|
||||
myAudioCycles -= mySystem->cycles();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeCTY::install(System& system)
|
||||
{
|
||||
mySystem = &system;
|
||||
uInt16 mask = mySystem->pageMask();
|
||||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert(((0x1000 & mask) == 0) && ((0x1080 & mask) == 0));
|
||||
|
||||
// Map all RAM accesses to call peek and poke
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
for(uInt32 i = 0x1000; i < 0x1080; i += (1 << shift))
|
||||
|
@ -108,7 +103,7 @@ uInt8 CartridgeCTY::peek(uInt16 address)
|
|||
{
|
||||
uInt16 peekAddress = address;
|
||||
address &= 0x0FFF;
|
||||
uInt8 peekValue = myImage[myCurrentBank + address];
|
||||
uInt8 peekValue = myImage[myBankOffset + address];
|
||||
|
||||
// In debugger/bank-locked mode, we ignore all hotspots and in general
|
||||
// anything that can change the internal state of the cart
|
||||
|
@ -123,15 +118,23 @@ uInt8 CartridgeCTY::peek(uInt16 address)
|
|||
// Update the music data fetchers (counter & flag)
|
||||
updateMusicModeDataFetchers();
|
||||
|
||||
#if 0
|
||||
// using myDisplayImage[] instead of myProgramImage[] because waveforms
|
||||
// can be modified during runtime.
|
||||
uInt32 i = myDisplayImage[(myMusicWaveforms[0] << 5) + (myMusicCounters[0] >> 27)] +
|
||||
myDisplayImage[(myMusicWaveforms[1] << 5) + (myMusicCounters[1] >> 27)] +
|
||||
myDisplayImage[(myMusicWaveforms[2] << 5) + (myMusicCounters[2] >> 27)];
|
||||
return = (uInt8)i;
|
||||
#endif
|
||||
return 0xF2; // FIXME - return frequency value here
|
||||
uInt8 i = 0;
|
||||
|
||||
/*
|
||||
in the ARM driver registers 8-10 are the music counters 0-2
|
||||
lsr r2, r8, #31
|
||||
add r2, r2, r9, lsr #31
|
||||
add r2, r2, r10, lsr #31
|
||||
lsl r2, r2, #2
|
||||
*/
|
||||
|
||||
i = myMusicCounters[0] >> 31;
|
||||
i = i + (myMusicCounters[1] >> 31);
|
||||
i = i + (myMusicCounters[2] >> 31);
|
||||
i <<= 2;
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
else
|
||||
myLDAimmediate = false;
|
||||
|
@ -161,9 +164,9 @@ uInt8 CartridgeCTY::peek(uInt16 address)
|
|||
((myRandomNumber >> 11) | (myRandomNumber << 21));
|
||||
return myRandomNumber & 0xFF;
|
||||
case 0x02: // Get Tune position (low byte)
|
||||
return myCounter & 0xFF;
|
||||
return myTunePosition & 0xFF;
|
||||
case 0x03: // Get Tune position (high byte)
|
||||
return (myCounter >> 8) & 0xFF;
|
||||
return (myTunePosition >> 8) & 0xFF;
|
||||
default:
|
||||
return myRAM[address];
|
||||
}
|
||||
|
@ -204,7 +207,7 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value)
|
|||
//cerr << "POKE: address=" << HEX4 << address << ", value=" << HEX2 << value << endl;
|
||||
if(address < 0x0040) // Write port is at $1000 - $103F (64 bytes)
|
||||
{
|
||||
switch(address) // FIXME for functionality
|
||||
switch(address)
|
||||
{
|
||||
case 0x00: // Operation type for $1FF4
|
||||
myOperationType = value;
|
||||
|
@ -213,10 +216,16 @@ bool CartridgeCTY::poke(uInt16 address, uInt8 value)
|
|||
myRandomNumber = 0x2B435044;
|
||||
break;
|
||||
case 0x02: // Reset fetcher to beginning of tune
|
||||
myCounter = 0;
|
||||
myTunePosition = 0;
|
||||
myMusicCounters[0] = 0;
|
||||
myMusicCounters[1] = 0;
|
||||
myMusicCounters[2] = 0;
|
||||
myMusicFrequencies[0] = 0;
|
||||
myMusicFrequencies[1] = 0;
|
||||
myMusicFrequencies[2] = 0;
|
||||
break;
|
||||
case 0x03: // Advance fetcher to next tune position
|
||||
myCounter = (myCounter + 3) & 0x0fff;
|
||||
updateTune();
|
||||
break;
|
||||
default:
|
||||
myRAM[address] = value;
|
||||
|
@ -254,14 +263,14 @@ bool CartridgeCTY::bank(uInt16 bank)
|
|||
if(bankLocked()) return false;
|
||||
|
||||
// Remember what bank we're in
|
||||
myCurrentBank = bank << 12;
|
||||
myBankOffset = bank << 12;
|
||||
uInt16 shift = mySystem->pageShift();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access(0, 0, 0, this, System::PA_READ);
|
||||
for(uInt32 address = 0x1080; address < 0x2000; address += (1 << shift))
|
||||
{
|
||||
access.codeAccessBase = &myCodeAccessBase[myCurrentBank + (address & 0x0FFF)];
|
||||
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
return myBankChanged = true;
|
||||
|
@ -270,7 +279,7 @@ bool CartridgeCTY::bank(uInt16 bank)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt16 CartridgeCTY::bank() const
|
||||
{
|
||||
return myCurrentBank >> 12;
|
||||
return myBankOffset >> 12;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -292,7 +301,7 @@ bool CartridgeCTY::patch(uInt16 address, uInt8 value)
|
|||
myRAM[address & 0x003F] = value;
|
||||
}
|
||||
else
|
||||
myImage[myCurrentBank + address] = value;
|
||||
myImage[myBankOffset + address] = value;
|
||||
|
||||
return myBankChanged = true;
|
||||
}
|
||||
|
@ -309,17 +318,18 @@ bool CartridgeCTY::save(Serializer& out) const
|
|||
{
|
||||
try
|
||||
{
|
||||
out.putString(name());
|
||||
out.putShort(bank());
|
||||
out.putByteArray(myRAM, 64);
|
||||
|
||||
out.putByte(myOperationType);
|
||||
out.putShort(myCounter);
|
||||
out.putShort(myTunePosition);
|
||||
out.putBool(myLDAimmediate);
|
||||
out.putInt(myRandomNumber);
|
||||
out.putInt(mySystemCycles);
|
||||
out.putInt((uInt32)(myFractionalClocks * 100000000.0));
|
||||
|
||||
out.putLong(myAudioCycles);
|
||||
out.putDouble(myFractionalClocks);
|
||||
out.putIntArray(myMusicCounters, 3);
|
||||
out.putIntArray(myMusicFrequencies, 3);
|
||||
out.putLong(myFrequencyImage - myTuneData);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -335,19 +345,19 @@ bool CartridgeCTY::load(Serializer& in)
|
|||
{
|
||||
try
|
||||
{
|
||||
if(in.getString() != name())
|
||||
return false;
|
||||
|
||||
// Remember what bank we were in
|
||||
bank(in.getShort());
|
||||
in.getByteArray(myRAM, 64);
|
||||
|
||||
myOperationType = in.getByte();
|
||||
myCounter = in.getShort();
|
||||
myTunePosition = in.getShort();
|
||||
myLDAimmediate = in.getBool();
|
||||
myRandomNumber = in.getInt();
|
||||
mySystemCycles = (Int32)in.getInt();
|
||||
myFractionalClocks = (double)in.getInt() / 100000000.0;
|
||||
myAudioCycles = in.getLong();
|
||||
myFractionalClocks = in.getDouble();
|
||||
in.getIntArray(myMusicCounters, 3);
|
||||
in.getIntArray(myMusicFrequencies, 3);
|
||||
myFrequencyImage = myTuneData + in.getLong();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
@ -424,7 +434,7 @@ uInt8 CartridgeCTY::ramReadWrite()
|
|||
break;
|
||||
}
|
||||
// Bit 6 is 1, busy
|
||||
return myImage[myCurrentBank + 0xFF4] | 0x40;
|
||||
return myImage[myBankOffset + 0xFF4] | 0x40;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -435,11 +445,11 @@ uInt8 CartridgeCTY::ramReadWrite()
|
|||
myRAM[0] = 0; // Successful operation
|
||||
|
||||
// Bit 6 is 0, ready/success
|
||||
return myImage[myCurrentBank + 0xFF4] & ~0x40;
|
||||
return myImage[myBankOffset + 0xFF4] & ~0x40;
|
||||
}
|
||||
else
|
||||
// Bit 6 is 1, busy
|
||||
return myImage[myCurrentBank + 0xFF4] | 0x40;
|
||||
return myImage[myBankOffset + 0xFF4] | 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,10 +459,62 @@ void CartridgeCTY::loadTune(uInt8 index)
|
|||
// Each tune is offset by 4096 bytes
|
||||
// Instead of copying non-modifiable data around (as would happen on the
|
||||
// Harmony), we simply point to the appropriate tune
|
||||
myFrequencyImage = CartCTYTunes + (index << 12);
|
||||
myFrequencyImage = myTuneData + (index << 12);
|
||||
|
||||
// Reset to beginning of tune
|
||||
myCounter = 0;
|
||||
myTunePosition = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeCTY::updateTune()
|
||||
{
|
||||
//UpdateTune:
|
||||
// /* Float data bus */
|
||||
// strb r8, [r0, #+0x01]
|
||||
//
|
||||
// /* Increment song position */
|
||||
// add r7, r7, #1 r7 = songPosition
|
||||
//
|
||||
// /* Read song data (0 = continue) */
|
||||
// msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
|
||||
// ldrb r2, [r14], #1 r14 = myTunePosition, r2 = note
|
||||
// cmp r2, #0
|
||||
// ldrne r11, [r6, +r2, lsl #2] r6 +r2 = ourFrequencyTable[note]. Why lsl #2?
|
||||
// ldrb r2, [r14], #1 r11 = myMusicFrequency[0]
|
||||
// cmp r2, #0
|
||||
// ldrne r12, [r6, +r2, lsl #2] r12 = myMusicFrequency[1]
|
||||
// ldrb r2, [r14], #1
|
||||
// cmp r2, #1
|
||||
// ldrcs r13, [r6, +r2, lsl #2] r13 = myMusicFrequency[2]
|
||||
//
|
||||
// /* Reset tune */
|
||||
// mvneq r7, #0
|
||||
// moveq r14, r4 r4 = start of tune data
|
||||
// msr cpsr_c, #MODE_SYS|I_BIT|F_BIT
|
||||
//
|
||||
// /* Wait until address changes */
|
||||
//WaitAddrChangeA:
|
||||
// ldrh r2, [r0, #+0x16]
|
||||
// cmp r1, r2
|
||||
// beq WaitAddrChangeA
|
||||
// b NewAddress
|
||||
|
||||
myTunePosition += 1;
|
||||
uInt16 songPosition = (myTunePosition - 1) *3;
|
||||
|
||||
uInt8 note = myFrequencyImage[songPosition + 0];
|
||||
if (note)
|
||||
myMusicFrequencies[0] = ourFrequencyTable[note];
|
||||
|
||||
note = myFrequencyImage[songPosition + 1];
|
||||
if (note)
|
||||
myMusicFrequencies[1] = ourFrequencyTable[note];
|
||||
|
||||
note = myFrequencyImage[songPosition + 2];
|
||||
if (note == 1)
|
||||
myTunePosition = 0;
|
||||
else
|
||||
myMusicFrequencies[2] = ourFrequencyTable[note];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -504,7 +566,7 @@ void CartridgeCTY::saveScore(uInt8 index)
|
|||
catch(...)
|
||||
{
|
||||
// Maybe add logging here that save failed?
|
||||
cerr << name() << ": ERROR saving score table " << (int)index << endl;
|
||||
cerr << name() << ": ERROR saving score table " << int(index) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -534,20 +596,150 @@ void CartridgeCTY::wipeAllScores()
|
|||
inline void CartridgeCTY::updateMusicModeDataFetchers()
|
||||
{
|
||||
// Calculate the number of cycles since the last update
|
||||
Int32 cycles = mySystem->cycles() - mySystemCycles;
|
||||
mySystemCycles = mySystem->cycles();
|
||||
uInt32 cycles = uInt32(mySystem->cycles() - myAudioCycles);
|
||||
myAudioCycles = mySystem->cycles();
|
||||
|
||||
// Calculate the number of DPC OSC clocks since the last update
|
||||
// Calculate the number of CTY OSC clocks since the last update
|
||||
double clocks = ((20000.0 * cycles) / 1193191.66666667) + myFractionalClocks;
|
||||
Int32 wholeClocks = (Int32)clocks;
|
||||
myFractionalClocks = clocks - (double)wholeClocks;
|
||||
|
||||
if(wholeClocks <= 0)
|
||||
return;
|
||||
uInt32 wholeClocks = uInt32(clocks);
|
||||
myFractionalClocks = clocks - double(wholeClocks);
|
||||
|
||||
// Let's update counters and flags of the music mode data fetchers
|
||||
for(int x = 0; x <= 2; ++x)
|
||||
{
|
||||
// myMusicCounters[x] += myMusicFrequencies[x];
|
||||
}
|
||||
if(wholeClocks > 0)
|
||||
for(int x = 0; x <= 2; ++x)
|
||||
myMusicCounters[x] += myMusicFrequencies[x] * wholeClocks;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt32 CartridgeCTY::ourFrequencyTable[63] =
|
||||
{
|
||||
// this should really be referenced from within the ROM, but its part of
|
||||
// the Harmony/Melody CTY Driver, which does not appear to be in the ROM.
|
||||
|
||||
0, // CONT 0 Continue Note
|
||||
0, // REPEAT 1 Repeat Song
|
||||
0, // REST 2 Note Rest
|
||||
/*
|
||||
3511350 // C0
|
||||
3720300 // C0s
|
||||
3941491 // D0
|
||||
4175781 // D0s
|
||||
4424031 // E0
|
||||
4687313 // F0
|
||||
4965841 // F0s
|
||||
5261120 // G0
|
||||
5496699 // G0s
|
||||
|
||||
5905580 // A1
|
||||
6256694 // A1s
|
||||
6628853 // B1
|
||||
7022916 // C1
|
||||
7440601 // C1s
|
||||
7882983 // D1
|
||||
8351778 // D1s
|
||||
8848277 // E1
|
||||
9374625 // F1
|
||||
9931897 // F1s
|
||||
10522455 // G1
|
||||
11148232 // G1s
|
||||
*/
|
||||
11811160, // A2
|
||||
12513387, // A2s
|
||||
13257490, // B2
|
||||
14045832, // C2
|
||||
14881203, // C2s
|
||||
15765966, // D2
|
||||
16703557, // D2s
|
||||
17696768, // E2
|
||||
18749035, // F2
|
||||
19864009, // F2s
|
||||
21045125, // G2
|
||||
22296464, // G2s
|
||||
|
||||
23622320, // A3
|
||||
25026989, // A3s
|
||||
26515195, // B3
|
||||
28091878, // C3
|
||||
29762191, // C3s
|
||||
31531932, // D3
|
||||
33406900, // D3s
|
||||
35393537, // E3
|
||||
37498071, // F3
|
||||
39727803, // F3s
|
||||
42090250, // G3
|
||||
44592927, // G3s
|
||||
|
||||
47244640, // A4
|
||||
50053978, // A4s
|
||||
53030391, // B4
|
||||
56183756, // C4 (Middle C)
|
||||
59524596, // C4s
|
||||
63064079, // D4
|
||||
66814014, // D4s
|
||||
70787074, // E4
|
||||
74996142, // F4
|
||||
79455606, // F4s
|
||||
84180285, // G4
|
||||
89186069, // G4s
|
||||
|
||||
94489281, // A5
|
||||
100107957, // A5s
|
||||
106060567, // B5
|
||||
112367297, // C5
|
||||
119048977, // C5s
|
||||
126128157, // D5
|
||||
133628029, // D5s
|
||||
141573933, // E5
|
||||
149992288, // F5
|
||||
158911428, // F5s
|
||||
168360785, // G5
|
||||
178371925, // G5s
|
||||
|
||||
188978561, // A6
|
||||
200215913, // A6s
|
||||
212121348, // B6
|
||||
224734593, // C6
|
||||
238098169, // C6s
|
||||
252256099, // D6
|
||||
267256058, // D6s
|
||||
283147866, // E6
|
||||
299984783, // F6
|
||||
317822855, // F6s
|
||||
336721571, // G6
|
||||
356744064 // G6s
|
||||
/*
|
||||
377957122 // A7
|
||||
400431612 // A7s
|
||||
424242481 // B7
|
||||
449469401 // C7
|
||||
476196124 // C7s
|
||||
504512198 // D7
|
||||
534512116 // D7s
|
||||
566295948 // E7
|
||||
599969565 // F7
|
||||
635645496 // F7s
|
||||
673443141 // G7
|
||||
713488128 // G7s
|
||||
|
||||
755914244 // A8
|
||||
800863224 // A8s
|
||||
848484963 // B8
|
||||
898938588 // C8
|
||||
952392248 // C8s
|
||||
1009024398 // D8
|
||||
1069024232 // D8s
|
||||
1132591895 // E8
|
||||
1199939130 // F8
|
||||
1271290992 // F8s
|
||||
1346886282 // G8
|
||||
1426976255 // G8s
|
||||
|
||||
1511828488 // A9
|
||||
1601726449 // A9s
|
||||
1696969925 // B9
|
||||
1797877176 // C9
|
||||
1904784495 // C9s
|
||||
2018048796 // D9
|
||||
2138048463 // D9s
|
||||
*/
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
|
@ -83,12 +83,10 @@ class System;
|
|||
The tune table functionality is also based on Harmony EEPROM, where
|
||||
7 4K tunes are stored (28K total). The 'index' for operation 1 can
|
||||
therefore be in the range 0 - 6, indicating which tune to load.
|
||||
For this implementation, the 28K tune data is in the 'CartCTYTunes'
|
||||
header file.
|
||||
|
||||
DPC+:
|
||||
The music functionality is quite similar to the DPC+ scheme.
|
||||
|
||||
|
||||
Fast Fetcher
|
||||
The music frequency value is fetched using a fast fetcher operation.
|
||||
This operation is aliased to the instruction "LDA #$F2". Whenever this
|
||||
|
@ -123,11 +121,7 @@ class CartridgeCTY : public Cartridge
|
|||
@param osystem A reference to the OSystem currently in use
|
||||
*/
|
||||
CartridgeCTY(const uInt8* image, uInt32 size, const OSystem& osystem);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~CartridgeCTY();
|
||||
virtual ~CartridgeCTY() = default;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -262,22 +256,24 @@ class CartridgeCTY : public Cartridge
|
|||
void saveScore(uInt8 index);
|
||||
void wipeAllScores();
|
||||
|
||||
/**
|
||||
/**
|
||||
Updates any data fetchers in music mode based on the number of
|
||||
CPU cycles which have passed since the last update.
|
||||
*/
|
||||
void updateMusicModeDataFetchers();
|
||||
|
||||
void updateTune();
|
||||
|
||||
private:
|
||||
// OSsytem currently in use
|
||||
const OSystem& myOSystem;
|
||||
|
||||
// Indicates which bank is currently active
|
||||
uInt16 myCurrentBank;
|
||||
|
||||
// The 32K ROM image of the cartridge
|
||||
uInt8 myImage[32768];
|
||||
|
||||
// The 28K ROM image of the music
|
||||
uInt8 myTuneData[28*1024];
|
||||
|
||||
// The 64 bytes of RAM accessible at $1000 - $1080
|
||||
uInt8 myRAM[64];
|
||||
|
||||
|
@ -285,11 +281,17 @@ class CartridgeCTY : public Cartridge
|
|||
uInt8 myOperationType;
|
||||
|
||||
// Pointer to the 28K frequency table (points to the start of one
|
||||
// of seven 4K tunes in CartCTYTunes)
|
||||
// of seven 4K tunes in myTuneData)
|
||||
const uInt8* myFrequencyImage;
|
||||
|
||||
// The counter register for the data fetcher
|
||||
uInt16 myCounter;
|
||||
uInt16 myTunePosition;
|
||||
|
||||
// The music mode counters
|
||||
uInt32 myMusicCounters[3];
|
||||
|
||||
// The music frequency
|
||||
uInt32 myMusicFrequencies[3];
|
||||
|
||||
// Flags that last byte peeked was A9 (LDA #)
|
||||
bool myLDAimmediate;
|
||||
|
@ -307,11 +309,16 @@ class CartridgeCTY : public Cartridge
|
|||
// of internal RAM to Harmony cart EEPROM
|
||||
string myEEPROMFile;
|
||||
|
||||
// System cycle count when the last update to music data fetchers occurred
|
||||
Int32 mySystemCycles;
|
||||
// System cycle count from when the last update to music data fetchers occurred
|
||||
uInt64 myAudioCycles;
|
||||
|
||||
// Fractional DPC music OSC clocks unused during the last update
|
||||
double myFractionalClocks;
|
||||
|
||||
// Indicates the offset into the ROM image (aligns to current bank)
|
||||
uInt16 myBankOffset;
|
||||
|
||||
static const uInt32 ourFrequencyTable[63];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue