diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx index 04e308c83..a34899b12 100644 --- a/src/debugger/gui/CartCDFWidget.cxx +++ b/src/debugger/gui/CartCDFWidget.cxx @@ -30,7 +30,7 @@ CartridgeCDFWidget::CartridgeCDFWidget( uInt16 size = 8 * 4096; ostringstream info; - info << "CDF cartridge\n" + info << "CDF cartridge (version " << cart.myVersion << ")\n" << "32K ROM, seven 4K banks are accessible to 2600\n" << "8K CDF RAM\n" << "CDF registers accessible @ $FFF0 - $FFF3\n" diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 3d6c96f74..f0eec204a 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -27,9 +27,10 @@ #include "TIA.hxx" // Location of data within the RAM copy of the CDF Driver. -#define DSxPTR 0x06E0 -#define DSxINC 0x0768 -#define WAVEFORM 0x07F0 +// Version 0 1 +const uInt16 DSxPTR[] = {0x06E0, 0x00A0}; +const uInt16 DSxINC[] = {0x0768, 0x0128}; +const uInt16 WAVEFORM[] = {0x07F0, 0x01B0}; #define DSRAM 0x0800 #define COMMSTREAM 0x20 @@ -62,10 +63,15 @@ CartridgeCDF::CartridgeCDF(const BytePtr& image, uInt32 size, // Pointer to the display RAM myDisplayImage = myCDFRAM + DSRAM; + + setVersion(); + #ifdef THUMB_SUPPORT // Create Thumbulator ARM emulator - myThumbEmulator = make_unique((uInt16*)myImage, (uInt16*)myCDFRAM, - settings.getBool("thumb.trapfatal"), Thumbulator::ConfigureFor::CDF, this); + myThumbEmulator = make_unique( + (uInt16*)myImage, (uInt16*)myCDFRAM, settings.getBool("thumb.trapfatal"), + myVersion ? Thumbulator::ConfigureFor::CDF1 : Thumbulator::ConfigureFor::CDF, + this); #endif setInitialState(); } @@ -576,51 +582,57 @@ bool CartridgeCDF::load(Serializer& in) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const { - // index &= 0x0f; + uInt16 address = DSxPTR[myVersion] + index * 4; - return myCDFRAM[DSxPTR + index*4 + 0] + // low byte - (myCDFRAM[DSxPTR + index*4 + 1] << 8) + - (myCDFRAM[DSxPTR + index*4 + 2] << 16) + - (myCDFRAM[DSxPTR + index*4 + 3] << 24) ; // high byte + return myCDFRAM[address + 0] + // low byte + (myCDFRAM[address + 1] << 8) + + (myCDFRAM[address + 2] << 16) + + (myCDFRAM[address + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value) { - // index &= 0x1f; - myCDFRAM[DSxPTR + index*4 + 0] = value & 0xff; // low byte - myCDFRAM[DSxPTR + index*4 + 1] = (value >> 8) & 0xff; - myCDFRAM[DSxPTR + index*4 + 2] = (value >> 16) & 0xff; - myCDFRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte + uInt16 address = DSxPTR[myVersion] + index * 4; + + myCDFRAM[address + 0] = value & 0xff; // low byte + myCDFRAM[address + 1] = (value >> 8) & 0xff; + myCDFRAM[address + 2] = (value >> 16) & 0xff; + myCDFRAM[address + 3] = (value >> 24) & 0xff; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const { - return myCDFRAM[DSxINC + index*4 + 0] + // low byte - (myCDFRAM[DSxINC + index*4 + 1] << 8) + - (myCDFRAM[DSxINC + index*4 + 2] << 16) + - (myCDFRAM[DSxINC + index*4 + 3] << 24) ; // high byte + uInt16 address = DSxINC[myVersion] + index * 4; + + return myCDFRAM[address + 0] + // low byte + (myCDFRAM[address + 1] << 8) + + (myCDFRAM[address + 2] << 16) + + (myCDFRAM[address + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCDF::setDatastreamIncrement(uInt8 index, uInt32 value) { - myCDFRAM[DSxINC + index*4 + 0] = value & 0xff; // low byte - myCDFRAM[DSxINC + index*4 + 1] = (value >> 8) & 0xff; - myCDFRAM[DSxINC + index*4 + 2] = (value >> 16) & 0xff; - myCDFRAM[DSxINC + index*4 + 3] = (value >> 24) & 0xff; // high byte + uInt16 address = DSxINC[myVersion] + index * 4; + + myCDFRAM[address + 0] = value & 0xff; // low 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 result; + uInt16 address = WAVEFORM[myVersion] + index * 4; - result = myCDFRAM[WAVEFORM + index*4 + 0] + // low byte - (myCDFRAM[WAVEFORM + index*4 + 1] << 8) + - (myCDFRAM[WAVEFORM + index*4 + 2] << 16) + - (myCDFRAM[WAVEFORM + index*4 + 3] << 24); // high byte + result = myCDFRAM[address + 0] + // low byte + (myCDFRAM[address + 1] << 8) + + (myCDFRAM[address + 2] << 16) + + (myCDFRAM[address + 3] << 24); // high byte result -= (0x40000000 + DSRAM); @@ -634,11 +646,12 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const uInt32 CartridgeCDF::getSample() { uInt32 result; + uInt16 address = WAVEFORM[myVersion]; - result = myCDFRAM[WAVEFORM + 0] + // low byte - (myCDFRAM[WAVEFORM + 1] << 8) + - (myCDFRAM[WAVEFORM + 2] << 16) + - (myCDFRAM[WAVEFORM + 3] << 24); // high byte + result = myCDFRAM[address + 0] + // low byte + (myCDFRAM[address + 1] << 8) + + (myCDFRAM[address + 2] << 16) + + (myCDFRAM[address + 3] << 24); // high byte return result; } @@ -669,3 +682,21 @@ uInt8 CartridgeCDF::readFromDatastream(uInt8 index) setDatastreamPointer(index, pointer); 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; + } + } +} diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 0e08b2eae..f5ce5cbf5 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -36,7 +36,7 @@ class System; 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. @authors: Darrell Spice Jr, Chris Walton, Fred Quimby, @@ -209,6 +209,7 @@ class CartridgeCDF : public Cartridge uInt32 getWaveform(uInt8 index) const; uInt32 getWaveformSize(uInt8 index) const; uInt32 getSample(); + void setVersion(); private: // The 32K ROM image of the cartridge @@ -250,16 +251,16 @@ class CartridgeCDF : public Cartridge // Thumbulator will trap these calls and pass the appropriate information to // the Cartridge Class via callFunction() so it can emulate the 32 bit audio routines. - /* Register usage for audio: - r8 = channel0 accumulator - r9 = channel1 accumulator - r10 = channel2 accumulator - r11 = channel0 frequency - r12 = channel1 frequency - r13 = channel2 frequency - r14 = timer base */ + /* Register usage for audio: + r8 = channel0 accumulator + r9 = channel1 accumulator + r10 = channel2 accumulator + r11 = channel0 frequency + r12 = channel1 frequency + r13 = channel2 frequency + r14 = timer base */ - // The music counters, ARM FIQ shadow registers r8, r9, r10 + // The music counters, ARM FIQ shadow registers r8, r9, r10 uInt32 myMusicCounters[3]; // The music frequency, ARM FIQ shadow registers r11, r12, r13 @@ -289,6 +290,9 @@ class CartridgeCDF : public Cartridge uInt8 myFastJumpActive; + // version of CDF + uInt16 myVersion; + private: // Following constructors and assignment operators not supported CartridgeCDF() = delete; diff --git a/src/emucore/Thumbulator.cxx b/src/emucore/Thumbulator.cxx index 9363b642e..84c2e6a29 100644 --- a/src/emucore/Thumbulator.cxx +++ b/src/emucore/Thumbulator.cxx @@ -234,6 +234,7 @@ void Thumbulator::write16(uInt32 addr, uInt32 data) // as additional RAM case ConfigureFor::BUS: case ConfigureFor::CDF: + case ConfigureFor::CDF1: if((addr > 0x40000028) && (addr < 0x40000800)) fatalError("write16", addr, "to bankswitch code area"); break; @@ -1198,6 +1199,67 @@ int Thumbulator::execute() 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: // no 32-bit subroutines in DPC+ break; @@ -2266,6 +2328,7 @@ int Thumbulator::reset() // future 2K Harmony/Melody drivers will most likely use these settings case ConfigureFor::BUS: case ConfigureFor::CDF: + case ConfigureFor::CDF1: reg_norm[14] = 0x00000800; // Link Register reg_norm[15] = 0x0000080B; // Program Counter break; diff --git a/src/emucore/Thumbulator.hxx b/src/emucore/Thumbulator.hxx index 1051c377a..4adf3285b 100644 --- a/src/emucore/Thumbulator.hxx +++ b/src/emucore/Thumbulator.hxx @@ -50,6 +50,7 @@ class Thumbulator enum ConfigureFor { BUS, // cartridges of type BUS CDF, // cartridges of type CDF + CDF1, // cartridges of type CDF version 1 DPCplus // cartridges of type DPC+ };