From 2db1ea172b693f0f9d39de6f54b7067234596239 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 3 Apr 2020 17:08:42 +0200 Subject: [PATCH 01/52] initial commit --- src/common/bspf.hxx | 1 + src/debugger/gui/CartE0Widget.cxx | 18 +- src/emucore/CartE0.cxx | 101 ++----- src/emucore/CartE0.hxx | 20 +- src/emucore/CartEnhanced.cxx | 259 ++++++++++++++++++ src/emucore/CartEnhanced.hxx | 204 ++++++++++++++ src/emucore/CartF0.cxx | 152 +--------- src/emucore/CartF0.hxx | 104 +------ src/emucore/CartF4.cxx | 139 +--------- src/emucore/CartF4.hxx | 101 +------ src/emucore/CartF4SC.cxx | 204 +------------- src/emucore/CartF4SC.hxx | 102 +------ src/emucore/CartF6.cxx | 182 +----------- src/emucore/CartF6.hxx | 99 +------ src/emucore/CartF6SC.cxx | 244 +---------------- src/emucore/CartF6SC.hxx | 102 +------ src/emucore/CartF8.cxx | 151 +--------- src/emucore/CartF8.hxx | 98 +------ src/emucore/CartF8SC.cxx | 224 +-------------- src/emucore/CartF8SC.hxx | 102 +------ src/emucore/CartFC.cxx | 133 +-------- src/emucore/CartFC.hxx | 90 +----- src/emucore/CartFE.cxx | 100 ++----- src/emucore/CartFE.hxx | 50 +--- src/emucore/CartMNetwork.hxx | 2 +- src/emucore/CartUA.cxx | 133 +-------- src/emucore/CartUA.hxx | 72 +---- src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 + {profile => test/roms/profile}/128.bin | Bin {profile => test/roms/profile}/README.md | 0 .../roms/profile}/catharsis_theory.bin | Bin 32 files changed, 656 insertions(+), 2539 deletions(-) create mode 100644 src/emucore/CartEnhanced.cxx create mode 100644 src/emucore/CartEnhanced.hxx rename {profile => test/roms/profile}/128.bin (100%) rename {profile => test/roms/profile}/README.md (100%) rename {profile => test/roms/profile}/catharsis_theory.bin (100%) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index e7cc60024..06333b13c 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -84,6 +84,7 @@ using ByteArray = std::vector; using ShortArray = std::vector; using StringList = std::vector; using ByteBuffer = std::unique_ptr; // NOLINT +using WordBuffer = std::unique_ptr; // NOLINT // We use KB a lot; let's make a literal for it constexpr uInt32 operator "" _KB(unsigned long long size) diff --git a/src/debugger/gui/CartE0Widget.cxx b/src/debugger/gui/CartE0Widget.cxx index 9413ce5c0..de845b197 100644 --- a/src/debugger/gui/CartE0Widget.cxx +++ b/src/debugger/gui/CartE0Widget.cxx @@ -98,9 +98,9 @@ CartridgeE0Widget::CartridgeE0Widget( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeE0Widget::loadConfig() { - mySlice0->setSelectedIndex(myCart.myCurrentSlice[0]); - mySlice1->setSelectedIndex(myCart.myCurrentSlice[1]); - mySlice2->setSelectedIndex(myCart.myCurrentSlice[2]); + mySlice0->setSelectedIndex(myCart.myCurrentBank[0]); + mySlice1->setSelectedIndex(myCart.myCurrentBank[1]); + mySlice2->setSelectedIndex(myCart.myCurrentBank[2]); CartDebugWidget::loadConfig(); } @@ -114,13 +114,13 @@ void CartridgeE0Widget::handleCommand(CommandSender* sender, switch(cmd) { case kSlice0Changed: - myCart.segmentZero(mySlice0->getSelected()); + myCart.bank(mySlice0->getSelected(), 0); break; case kSlice1Changed: - myCart.segmentOne(mySlice1->getSelected()); + myCart.bank(mySlice1->getSelected(), 1); break; case kSlice2Changed: - myCart.segmentTwo(mySlice2->getSelected()); + myCart.bank(mySlice2->getSelected(), 2); break; default: break; @@ -136,9 +136,9 @@ string CartridgeE0Widget::bankState() ostringstream& buf = buffer(); buf << "Slices: " << std::dec - << seg0[myCart.myCurrentSlice[0]] << " / " - << seg1[myCart.myCurrentSlice[1]] << " / " - << seg2[myCart.myCurrentSlice[2]]; + << seg0[myCart.myCurrentBank[0]] << " / " + << seg1[myCart.myCurrentBank[1]] << " / " + << seg2[myCart.myCurrentBank[2]]; return buf.str(); } diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index ff3a9b52c..3788a95bc 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -34,17 +34,17 @@ void CartridgeE0::reset() // Setup segments to some default slices if(randomStartBank()) { - segmentZero(mySystem->randGenerator().next() % 8); - segmentOne(mySystem->randGenerator().next() % 8); - segmentTwo(mySystem->randGenerator().next() % 8); + bank(mySystem->randGenerator().next() % 8, 0); + bank(mySystem->randGenerator().next() % 8, 1); + bank(mySystem->randGenerator().next() % 8, 2); } else { - segmentZero(4); - segmentOne(5); - segmentTwo(6); + bank(4, 0); + bank(5, 1); + bank(6, 2); } - myCurrentSlice[3] = 7; // fixed + myCurrentBank[3] = bankCount() - 1; // fixed myBankChanged = true; } @@ -69,7 +69,7 @@ void CartridgeE0::install(System& system) // Set the page accessing methods for the hot spots in the last segment access.directPeekBase = nullptr; - access.romAccessBase = &myRomAccessBase[0x1FC0]; // TJ: is this the correct address (or 0x1FE0)? + access.romAccessBase = &myRomAccessBase[0x1FC0]; access.romPeekCounter = &myRomAccessCounter[0x1FC0]; access.romPokeCounter = &myRomAccessCounter[0x1FC0 + myAccessSize]; access.type = System::PageAccessType::READ; @@ -81,7 +81,7 @@ void CartridgeE0::install(System& system) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeE0::getBank(uInt16 address) const { - return myCurrentSlice[(address & 0xFFF) >> 10]; // 1K slices + return myCurrentBank[(address & 0xFFF) >> 10]; // 1K slices } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -98,18 +98,18 @@ uInt8 CartridgeE0::peek(uInt16 address) // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FE7)) { - segmentZero(address & 0x0007); + bank(address & 0x0007, 0); } else if((address >= 0x0FE8) && (address <= 0x0FEF)) { - segmentOne(address & 0x0007); + bank(address & 0x0007, 1); } else if((address >= 0x0FF0) && (address <= 0x0FF7)) { - segmentTwo(address & 0x0007); + bank(address & 0x0007, 2); } - return myImage[(myCurrentSlice[address >> 10] << 10) + (address & 0x03FF)]; + return myImage[(myCurrentBank[address >> 10] << 10) + (address & 0x03FF)]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -120,83 +120,38 @@ bool CartridgeE0::poke(uInt16 address, uInt8) // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FE7)) { - segmentZero(address & 0x0007); + bank(address & 0x0007, 0); } else if((address >= 0x0FE8) && (address <= 0x0FEF)) { - segmentOne(address & 0x0007); + bank(address & 0x0007, 1); } else if((address >= 0x0FF0) && (address <= 0x0FF7)) { - segmentTwo(address & 0x0007); + bank(address & 0x0007, 2); } return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0::segmentZero(uInt16 slice) +void CartridgeE0::bank(uInt16 bank, uInt16 slice) { if(bankLocked()) return; // Remember the new slice - myCurrentSlice[0] = slice; - uInt16 offset = slice << 10; + myCurrentBank[slice] = bank; + uInt16 sliceOffset = slice * (1 << 10); + uInt16 bankOffset = bank << 10; // Setup the page access methods for the current bank System::PageAccess access(this, System::PageAccessType::READ); - for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE) + for(uInt16 addr = 0x1000 + sliceOffset; addr < 0x1000 + sliceOffset + 0x400; addr += System::PAGE_SIZE) { - access.directPeekBase = &myImage[offset + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0::segmentOne(uInt16 slice) -{ - if(bankLocked()) return; - - // Remember the new slice - myCurrentSlice[1] = slice; - uInt16 offset = slice << 10; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0::segmentTwo(uInt16 slice) -{ - if(bankLocked()) return; - - // Remember the new slice - myCurrentSlice[2] = slice; - uInt16 offset = slice << 10; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - for(uInt16 addr = 0x1800; addr < 0x1C00; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + myAccessSize]; + access.directPeekBase = &myImage[bankOffset + (addr & 0x03FF)]; + access.romAccessBase = &myRomAccessBase[bankOffset + (addr & 0x03FF)]; + access.romPeekCounter = &myRomAccessCounter[bankOffset + (addr & 0x03FF)]; + access.romPokeCounter = &myRomAccessCounter[bankOffset + (addr & 0x03FF) + myAccessSize]; mySystem->setPageAccess(addr, access); } myBankChanged = true; @@ -206,7 +161,7 @@ void CartridgeE0::segmentTwo(uInt16 slice) bool CartridgeE0::patch(uInt16 address, uInt8 value) { address &= 0x0FFF; - myImage[(myCurrentSlice[address >> 10] << 10) + (address & 0x03FF)] = value; + myImage[(myCurrentBank[address >> 10] << 10) + (address & 0x03FF)] = value; return true; } @@ -222,7 +177,7 @@ bool CartridgeE0::save(Serializer& out) const { try { - out.putShortArray(myCurrentSlice.data(), myCurrentSlice.size()); + out.putShortArray(myCurrentBank.data(), myCurrentBank.size()); } catch(...) { @@ -238,7 +193,7 @@ bool CartridgeE0::load(Serializer& in) { try { - in.getShortArray(myCurrentSlice.data(), myCurrentSlice.size()); + in.getShortArray(myCurrentBank.data(), myCurrentBank.size()); } catch(...) { diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 0a9453ab2..35513be85 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -156,32 +156,18 @@ class CartridgeE0 : public Cartridge private: /** - Install the specified slice for segment zero + Install the specified slice for segment (bank) 0..2 @param slice The slice to map into the segment */ - void segmentZero(uInt16 slice); - - /** - Install the specified slice for segment one - - @param slice The slice to map into the segment - */ - void segmentOne(uInt16 slice); - - /** - Install the specified slice for segment two - - @param slice The slice to map into the segment - */ - void segmentTwo(uInt16 slice); + void bank(uInt16 bank, uInt16 slice); private: // The 8K ROM image of the cartridge std::array myImage; // Indicates the slice mapped into each of the four segments - std::array myCurrentSlice; + std::array myCurrentBank; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx new file mode 100644 index 000000000..ff4113ad4 --- /dev/null +++ b/src/emucore/CartEnhanced.cxx @@ -0,0 +1,259 @@ +//============================================================================ +// +// 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 +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "System.hxx" +#include "CartEnhanced.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, + const string& md5, const Settings& settings) + : Cartridge(settings, md5), + mySize(size) +{ + // Allocate array for the ROM image + myImage = make_unique(mySize); + + // Copy the ROM image into my buffer + std::copy_n(image.get(), mySize, myImage.get()); + + // Copy the ROM image into my buffer + createRomAccessArrays(mySize); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeEnhanced::install(System& system) +{ + // Allocate array for the current bank segments slices + myCurrentBankOffset = make_unique(BANK_SEGS); + std::fill_n(myCurrentBankOffset.get(), BANK_SEGS, 0); + + // Allocate array for the RAM area + myRAM = make_unique(myRamSize); + + // Setup page access + mySystem = &system; + + System::PageAccess access(this, System::PageAccessType::READ); + + // Set the page accessing method for the RAM writing pages + // Map access to this class, since we need to inspect all accesses to + // check if RWP happens + access.type = System::PageAccessType::WRITE; + for(uInt16 addr = 0x1000; addr < 0x1000 + myRamSize; addr += System::PAGE_SIZE) + { + uInt16 offset = addr & myRamMask; + access.romAccessBase = &myRomAccessBase[offset]; + access.romPeekCounter = &myRomAccessCounter[offset]; + access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + + // Set the page accessing method for the RAM reading pages + access.type = System::PageAccessType::READ; + for(uInt16 addr = 0x1000 + myRamSize; addr < 0x1000 + myRamSize * 2; addr += System::PAGE_SIZE) + { + uInt16 offset = addr & myRamMask; + access.directPeekBase = &myRAM[offset]; + access.romAccessBase = &myRomAccessBase[myRamSize + offset]; + access.romPeekCounter = &myRomAccessCounter[myRamSize + offset]; + access.romPokeCounter = &myRomAccessCounter[myRamSize + offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + + // Install pages for the startup bank + bank(startBank()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeEnhanced::reset() +{ + initializeRAM(myRAM.get(), myRamSize); + + initializeStartBank(getStartBank()); + + // Upon reset we switch to the reset bank + bank(startBank()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt8 CartridgeEnhanced::peek(uInt16 address) +{ + uInt16 peekAddress = address; + address &= myBankMask; + + checkSwitchBank(address); + + if(address < myRamSize) // Write port is at 0xF000 - 0xF07F (128 bytes) + return peekRAM(myRAM[address], peekAddress); + else + return myImage[myBankOffset + address]; + return myImage[myCurrentBankOffset[address >> BANK_SHIFT] + (address & BANK_MASK)]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) +{ + address &= myBankMask; + + // Switch banks if necessary + if (checkSwitchBank(address & myBankMask)) + return false; + + if(myRamSize) + { + if(!(address & myRamSize)) + { + pokeRAM(myRAM[address & myRamMask], address, value); + return true; + } + else + { + // Writing to the read port should be ignored, but trigger a break if option enabled + uInt8 dummy; + + pokeRAM(dummy, address, value); + myRamWriteAccess = address; + } + } + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeEnhanced::bank(uInt16 bank, uInt16 slice) +{ + if(bankLocked()) return false; + + // Remember what bank we're in + myBankOffset = bank << myBankShift; + + uInt16 romHotspot = this->romHotspot(); + uInt16 fromAddr = 0x1000 + myRamSize * 2; + uInt16 toAddr; + + if(romHotspot) + { + System::PageAccess access(this, System::PageAccessType::READ); + + // Set the page accessing methods for the hot spots + for(uInt16 addr = (romHotspot & ~System::PAGE_MASK); addr < 0x1000 + myBankSize; + addr += System::PAGE_SIZE) + { + uInt16 offset = myBankOffset + (addr & myBankMask); + access.romAccessBase = &myRomAccessBase[offset]; + access.romPeekCounter = &myRomAccessCounter[offset]; + access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + toAddr = romHotspot; + } + else + toAddr = 0x1000 + myBankSize; + + System::PageAccess access(this, System::PageAccessType::READ); + + // Setup the page access methods for the current bank + for(uInt16 addr = (fromAddr & ~System::PAGE_MASK); addr < (toAddr & ~System::PAGE_MASK); + addr += System::PAGE_SIZE) + { + uInt16 offset = myBankOffset + (addr & myBankMask); + if(myDirectPeek) + access.directPeekBase = &myImage[offset]; + access.romAccessBase = &myRomAccessBase[offset]; + access.romPeekCounter = &myRomAccessCounter[offset]; + access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + + return myBankChanged = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 CartridgeEnhanced::getBank(uInt16) const +{ + return myBankOffset >> myBankShift; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 CartridgeEnhanced::bankCount() const +{ + return uInt16(mySize >> myBankShift); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) +{ + address &= myBankMask; + + if(address < myRamSize * 2) + { + // Normally, a write to the read port won't do anything + // However, the patch command is special in that ignores such + // cart restrictions + myRAM[address & myRamMask] = value; + } + else + myImage[myBankOffset + address] = value; + + return myBankChanged = true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const uInt8* CartridgeEnhanced::getImage(size_t& size) const +{ + size = mySize; + return myImage.get(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeEnhanced::save(Serializer& out) const +{ + try + { + out.putShort(myBankOffset); + if(myRamSize) + out.putByteArray(myRAM.get(), myRamSize); + + } + catch(...) + { + cerr << "ERROR: << " << name() << "::save" << endl; + return false; + } + + return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeEnhanced::load(Serializer& in) +{ + try + { + myBankOffset = in.getShort(); + if(myRamSize) + in.getByteArray(myRAM.get(), myRamSize); + } + catch(...) + { + cerr << "ERROR: " << name() << "::load" << endl; + return false; + } + + // Remember what bank we were in + bank(myBankOffset >> myBankShift); + + return true; +} diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx new file mode 100644 index 000000000..22d253b6a --- /dev/null +++ b/src/emucore/CartEnhanced.hxx @@ -0,0 +1,204 @@ +//============================================================================ +// +// 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 +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CARTRIDGEENHANCED_HXX +#define CARTRIDGEENHANCED_HXX + +class System; + +#include "bspf.hxx" +#include "Cart.hxx" + +/** + Enhanced cartridge base class used for multiple cart types. + + @author Thomas Jentzsch +*/ +class CartridgeEnhanced : public Cartridge +{ + public: + /** + Create a new cartridge using the specified image + + @param image Pointer to the ROM image + @param size The size of the ROM image + @param md5 The md5sum of the ROM image + @param settings A reference to the various settings (read-only) + */ + CartridgeEnhanced(const ByteBuffer& image, size_t size, const string& md5, + const Settings& settings); + virtual ~CartridgeEnhanced() = default; + + public: + /** + Install cartridge in the specified system. Invoked by the system + when the cartridge is attached to it. + + @param system The system the device should install itself in + */ + void install(System& system) override; + + /** + Reset device to its power-on state + */ + void reset() override; + + + /** + Install pages for the specified bank in the system. + + @param bank The bank that should be installed in the system + */ + bool bank(uInt16 bank, uInt16 slice); + + /** + Install pages for the specified bank in the system. + + @param bank The bank that should be installed in the system + */ + bool bank(uInt16 bank) override { return this->bank(bank, 0); } + + /** + Get the current bank. + + @param address The address to use when querying the bank + */ + uInt16 getBank(uInt16 address = 0) const override; + + /** + Query the number of banks supported by the cartridge. + */ + uInt16 bankCount() const override; + + /** + Patch the cartridge ROM. + + @param address The ROM address to patch + @param value The value to place into the address + @return Success or failure of the patch operation + */ + bool patch(uInt16 address, uInt8 value) override; + + /** + Access the internal ROM image for this cartridge. + + @param size Set to the size of the internal ROM image data + @return A pointer to the internal ROM image data + */ + const uInt8* getImage(size_t& size) const override; + + /** + Save the current state of this cart to the given Serializer. + + @param out The Serializer object to use + @return False on any errors, else true + */ + bool save(Serializer& out) const override; + + /** + Load the current state of this cart from the given Serializer. + + @param in The Serializer object to use + @return False on any errors, else true + */ + bool load(Serializer& in) override; + + public: + /** + Get the byte at the specified address. + + @return The byte at the specified address + */ + uInt8 peek(uInt16 address) override; + + /** + Change the byte at the specified address to the given value + + @param address The address where the value should be stored + @param value The value to be stored at the address + @return True if the poke changed the device address space, else false + */ + bool poke(uInt16 address, uInt8 value) override; + + protected: + // Pointer to a dynamically allocated ROM image of the cartridge + ByteBuffer myImage{nullptr}; + + // Pointer to a dynamically allocated RAM area of the cartridge + ByteBuffer myRAM{nullptr}; + + uInt16 myBankShift{BANK_SHIFT}; + + uInt16 myBankSize{BANK_SIZE}; + + uInt16 myBankMask{BANK_MASK}; + + uInt16 myRamSize{RAM_SIZE}; + + uInt16 myRamMask{RAM_MASK}; + + bool myDirectPeek{true}; + + // Indicates the offset into the ROM image (aligns to current bank) + uInt16 myBankOffset{0}; + + // Indicates the slice mapped into each of the bank segments + WordBuffer myCurrentBankOffset{nullptr}; + + private: + // log(ROM bank size) / log(2) + static constexpr uInt16 BANK_SHIFT = 12; + + // bank size + static constexpr uInt16 BANK_SIZE = 1 << BANK_SHIFT; // 2 ^ 12 = 4K + + // bank mask + static constexpr uInt16 BANK_MASK = BANK_SIZE - 1; + + // bank segments + static constexpr uInt16 BANK_SEGS = 1; + + // RAM size + static constexpr uInt16 RAM_SIZE = 0; + + // RAM mask + static constexpr uInt16 RAM_MASK = 0; + + // Size of the ROM image + size_t mySize{0}; + + protected: + /** + Check hotspots and switch bank if triggered. + */ + virtual bool checkSwitchBank(uInt16 address, uInt8 value = 0) = 0; + + private: + virtual uInt16 getStartBank() const { return 0; } + + virtual uInt16 romHotspot() const { return 0; } + + private: + // Following constructors and assignment operators not supported + CartridgeEnhanced() = delete; + CartridgeEnhanced(const CartridgeEnhanced&) = delete; + CartridgeEnhanced(CartridgeEnhanced&&) = delete; + CartridgeEnhanced& operator=(const CartridgeEnhanced&) = delete; + CartridgeEnhanced& operator=(CartridgeEnhanced&&) = delete; +}; + +#endif diff --git a/src/emucore/CartF0.cxx b/src/emucore/CartF0.cxx index a69c3c8ed..9f021a685 100644 --- a/src/emucore/CartF0.cxx +++ b/src/emucore/CartF0.cxx @@ -15,159 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "System.hxx" #include "CartF0.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF0::CartridgeF0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF0::reset() +bool CartridgeF0::checkSwitchBank(uInt16 address, uInt8) { - // Upon reset we switch to the startup bank - initializeStartBank(15); - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF0::install(System& system) -{ - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF0::peek(uInt16 address) -{ - address &= 0x0FFF; - - // Switch to next bank + // Switch banks if necessary if(address == 0x0FF0) - incbank(); - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF0::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch to next bank - if(address == 0x0FF0) - incbank(); - + { + // Switch to next bank + uInt8 nextBank = ((getBank()) + 1) & 0x0F; + bank(nextBank); + return true; + } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF0::incbank() -{ - // Determine current bank, and increment to the next one - uInt8 nextBank = ((myBankOffset >> 12) + 1) & 0x0F; - bank(nextBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF0::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1FF0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF0::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF0::bankCount() const -{ - return 16; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF0::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF0::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF0::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeF0::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF0::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: CartridgeF0::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index d4733a784..07123bf34 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF0_HXX #define CARTRIDGEF0_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF0Widget.hxx" #endif @@ -31,9 +28,9 @@ class System; There are 16 4K banks. Accessing $1FF0 switches to next bank. - @author Eckhard Stolberg + @author Eckhard Stolberg, Thomas Jentzsch */ -class CartridgeF0 : public Cartridge +class CartridgeF0 : public CartridgeEnhanced { friend class CartridgeF0Widget; @@ -51,71 +48,6 @@ class CartridgeF0 : public Cartridge virtual ~CartridgeF0() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,35 +67,13 @@ class CartridgeF0 : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + protected: + bool checkSwitchBank(uInt16 address, uInt8 value = 0); - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + uInt16 romHotspot() const override { return 0x1FF0; } private: - /** - Install pages for the next bank in the system - */ - void incbank(); - - private: - // The 64K ROM image of the cartridge - std::array myImage; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + uInt16 getStartBank() const override { return 15; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF4.cxx b/src/emucore/CartF4.cxx index 8111bb1a0..0cb689228 100644 --- a/src/emucore/CartF4.cxx +++ b/src/emucore/CartF4.cxx @@ -15,155 +15,24 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Random.hxx" -#include "System.hxx" #include "CartF4.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4::CartridgeF4(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4::reset() +bool CartridgeF4::checkSwitchBank(uInt16 address, uInt8) { - // Upon reset we switch to the startup bank - initializeStartBank(0); - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4::install(System& system) -{ - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF4::peek(uInt16 address) -{ - address &= 0x0FFF; - // Switch banks if necessary + // Note: addresses could be calculated from hotspot and bank count if((address >= 0x0FF4) && (address <= 0x0FFB)) { bank(address - 0x0FF4); + return true; } - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FF4) && (address <= 0x0FFB)) - { - bank(address - 0x0FF4); - } - return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF4 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1FF4U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF4::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF4::bankCount() const -{ - return 8; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF4::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeF4::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: CartridgeF4::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index d9c8fd346..3b4f0f141 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF4_HXX #define CARTRIDGEF4_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF4Widget.hxx" #endif @@ -30,9 +27,9 @@ class System; Cartridge class used for Atari's 32K bankswitched games. There are eight 4K banks, accessible by read/write to $1FF4 - $1FFB. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeF4 : public Cartridge +class CartridgeF4 : public CartridgeEnhanced { friend class CartridgeF4Widget; @@ -50,71 +47,6 @@ class CartridgeF4 : public Cartridge virtual ~CartridgeF4() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -134,31 +66,12 @@ class CartridgeF4 : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + protected: + bool checkSwitchBank(uInt16 address, uInt8 value = 0); - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; + uInt16 romHotspot() const override { return 0x1FF4; } - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - - private: - // The 32K ROM image of the cartridge - std::array myImage; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - - private: +private: // Following constructors and assignment operators not supported CartridgeF4() = delete; CartridgeF4(const CartridgeF4&) = delete; diff --git a/src/emucore/CartF4SC.cxx b/src/emucore/CartF4SC.cxx index 24496b161..5364f2eb4 100644 --- a/src/emucore/CartF4SC.cxx +++ b/src/emucore/CartF4SC.cxx @@ -15,211 +15,13 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "System.hxx" #include "CartF4SC.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4SC::CartridgeF4SC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeF4(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4SC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4SC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x007F]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x07F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - access.romPeekCounter = &myRomAccessCounter[0x80 + (addr & 0x007F)]; - access.romPokeCounter = &myRomAccessCounter[0x80 + (addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF4SC::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FF4) && (address <= 0x0FFB)) - bank(address - 0x0FF4); - - if(address < 0x0080) // Write port is at 0xF000 - 0xF07F (128 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4SC::poke(uInt16 address, uInt8 value) -{ - uInt16 pokeAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FF4) && (address <= 0x0FFB)) - { - bank(address - 0x0FF4); - return false; - } - - if(!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], pokeAddress, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4SC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF4 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1100; addr < static_cast(0x1FF4U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF4SC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF4SC::bankCount() const -{ - return 8; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4SC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF4SC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4SC::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeF4SC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF4SC::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeF4SC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + myRamSize = RAM_SIZE; + myRamMask = RAM_MASK; } diff --git a/src/emucore/CartF4SC.hxx b/src/emucore/CartF4SC.hxx index 20c003970..5f49a33a6 100644 --- a/src/emucore/CartF4SC.hxx +++ b/src/emucore/CartF4SC.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF4SC_HXX #define CARTRIDGEF4SC_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartF4.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF4SCWidget.hxx" #endif @@ -31,9 +28,9 @@ class System; RAM. There are eight 4K banks, accessible by read/write to $1FF4 - $1FFB. RAM read port is $1080 - $10FF, write port is $1000 - $107F. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeF4SC : public Cartridge +class CartridgeF4SC : public CartridgeF4 { friend class CartridgeF4SCWidget; @@ -51,71 +48,6 @@ class CartridgeF4SC : public Cartridge virtual ~CartridgeF4SC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,32 +67,12 @@ class CartridgeF4SC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 32K ROM image of the cartridge - std::array myImage; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; - // The 128 bytes of RAM - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + // RAM mask + static constexpr uInt16 RAM_MASK = RAM_SIZE - 1; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index a7a8dec2b..567424d7a 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -15,195 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "System.hxx" #include "CartF6.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6::CartridgeF6(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6::reset() +bool CartridgeF6::checkSwitchBank(uInt16 address, uInt8) { - // Upon reset we switch to the startup bank - initializeStartBank(0); - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6::install(System& system) -{ - mySystem = &system; - - // Upon install we'll setup the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF6::peek(uInt16 address) -{ - address &= 0x0FFF; - // Switch banks if necessary - switch(address) + // Note: addresses could be calculated from hotspot and bank count + if((address >= 0x0FF6) && (address <= 0x0FF9)) { - case 0x0FF6: - // Set the current bank to the first 4k bank - bank(0); - break; - - case 0x0FF7: - // Set the current bank to the second 4k bank - bank(1); - break; - - case 0x0FF8: - // Set the current bank to the third 4k bank - bank(2); - break; - - case 0x0FF9: - // Set the current bank to the forth 4k bank - bank(3); - break; - - default: - break; - } - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch banks if necessary - switch(address) - { - case 0x0FF6: - // Set the current bank to the first 4k bank - bank(0); - break; - - case 0x0FF7: - // Set the current bank to the second 4k bank - bank(1); - break; - - case 0x0FF8: - // Set the current bank to the third 4k bank - bank(2); - break; - - case 0x0FF9: - // Set the current bank to the forth 4k bank - bank(3); - break; - - default: - break; + bank(address - 0x0FF6); + return true; } return false; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF6 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1FF6U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF6::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF6::bankCount() const -{ - return 4; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF6::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeF6::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: CartridgeF6::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartF6.hxx b/src/emucore/CartF6.hxx index 4dc2c62b5..275727786 100644 --- a/src/emucore/CartF6.hxx +++ b/src/emucore/CartF6.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF6_HXX #define CARTRIDGEF6_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF6Widget.hxx" #endif @@ -30,9 +27,9 @@ class System; Cartridge class used for Atari's 16K bankswitched games. There are four 4K banks, accessible by read/write to $1FF6 - $1FF9. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeF6 : public Cartridge +class CartridgeF6 : public CartridgeEnhanced { friend class CartridgeF6Widget; @@ -50,71 +47,6 @@ class CartridgeF6 : public Cartridge virtual ~CartridgeF6() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -134,29 +66,10 @@ class CartridgeF6 : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + protected: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - - private: - // The 16K ROM image of the cartridge - std::array myImage; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + uInt16 romHotspot() const override { return 0x1FF6; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF6SC.cxx b/src/emucore/CartF6SC.cxx index 60b998182..034f02bce 100644 --- a/src/emucore/CartF6SC.cxx +++ b/src/emucore/CartF6SC.cxx @@ -15,251 +15,13 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "System.hxx" #include "CartF6SC.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6SC::CartridgeF6SC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeF6(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6SC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6SC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x007F]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x07F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - access.romPeekCounter = &myRomAccessCounter[0x80 + (addr & 0x007F)]; - access.romPokeCounter = &myRomAccessCounter[0x80 + (addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF6SC::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - switch(address) - { - case 0x0FF6: - // Set the current bank to the first 4k bank - bank(0); - break; - - case 0x0FF7: - // Set the current bank to the second 4k bank - bank(1); - break; - - case 0x0FF8: - // Set the current bank to the third 4k bank - bank(2); - break; - - case 0x0FF9: - // Set the current bank to the forth 4k bank - bank(3); - break; - - default: - break; - } - - if(address < 0x0080) // Write port is at 0xF000 - 0xF07F (128 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6SC::poke(uInt16 address, uInt8 value) -{ - // Switch banks if necessary - switch(address & 0x0FFF) - { - case 0x0FF6: - // Set the current bank to the first 4k bank - bank(0); - return false; - - case 0x0FF7: - // Set the current bank to the second 4k bank - bank(1); - return false; - - case 0x0FF8: - // Set the current bank to the third 4k bank - bank(2); - return false; - - case 0x0FF9: - // Set the current bank to the forth 4k bank - bank(3); - return false; - - default: - break; - } - - if(!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6SC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF6 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1100; addr < static_cast(0x1FF6U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF6SC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF6SC::bankCount() const -{ - return 4; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6SC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF6SC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6SC::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeF6SC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF6SC::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeF6SC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + myRamSize = RAM_SIZE; + myRamMask = RAM_MASK; } diff --git a/src/emucore/CartF6SC.hxx b/src/emucore/CartF6SC.hxx index 45a7c5ac3..a791a538d 100644 --- a/src/emucore/CartF6SC.hxx +++ b/src/emucore/CartF6SC.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF6SC_HXX #define CARTRIDGEF6SC_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartF6.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF6SCWidget.hxx" #endif @@ -31,9 +28,9 @@ class System; RAM. There are four 4K banks, accessible by read/write to $1FF6 - $1FF9. RAM read port is $1080 - $10FF, write port is $1000 - $107F. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeF6SC : public Cartridge +class CartridgeF6SC : public CartridgeF6 { friend class CartridgeF6SCWidget; @@ -51,71 +48,6 @@ class CartridgeF6SC : public Cartridge virtual ~CartridgeF6SC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,32 +67,12 @@ class CartridgeF6SC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 16K ROM image of the cartridge - std::array myImage; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; - // The 128 bytes of RAM - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + // RAM mask + static constexpr uInt16 RAM_MASK = RAM_SIZE - 1; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF8.cxx b/src/emucore/CartF8.cxx index b23ed802e..79b4708c4 100644 --- a/src/emucore/CartF8.cxx +++ b/src/emucore/CartF8.cxx @@ -15,176 +15,33 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "System.hxx" #include "CartF8.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8::CartridgeF8(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8::reset() +bool CartridgeF8::checkSwitchBank(uInt16 address, uInt8) { - initializeStartBank(1); - - // Upon reset we switch to the reset bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8::install(System& system) -{ - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF8::peek(uInt16 address) -{ - address &= 0x0FFF; - // Switch banks if necessary switch(address) { case 0x0FF8: // Set the current bank to the lower 4k bank bank(0); - break; + return true; case 0x0FF9: // Set the current bank to the upper 4k bank bank(1); - break; - - default: - break; - } - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch banks if necessary - switch(address) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0FF9: - // Set the current bank to the upper 4k bank - bank(1); - break; + return true; default: break; } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF8 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1FF8U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF8::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF8::bankCount() const -{ - return 2; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF8::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeF8::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: CartridgeF8::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartF8.hxx b/src/emucore/CartF8.hxx index b586d70ff..71e4d6e72 100644 --- a/src/emucore/CartF8.hxx +++ b/src/emucore/CartF8.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF8_HXX #define CARTRIDGEF8_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF8Widget.hxx" #endif @@ -30,9 +27,9 @@ class System; Cartridge class used for Atari's 8K bankswitched games. There are two 4K banks, accessible by read/write to $1FF8 - $1FF9. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeF8 : public Cartridge +class CartridgeF8 : public CartridgeEnhanced { friend class CartridgeF8Widget; @@ -50,71 +47,6 @@ class CartridgeF8 : public Cartridge virtual ~CartridgeF8() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -134,29 +66,13 @@ class CartridgeF8 : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + protected: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + uInt16 romHotspot() const override { return 0x1FF8; } private: - // The 8K ROM image of the cartridge - std::array myImage; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + uInt16 getStartBank() const override { return 1; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF8SC.cxx b/src/emucore/CartF8SC.cxx index c885a9c83..e9dd5bd5c 100644 --- a/src/emucore/CartF8SC.cxx +++ b/src/emucore/CartF8SC.cxx @@ -15,231 +15,13 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "System.hxx" #include "CartF8SC.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8SC::CartridgeF8SC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeF8(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8SC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(1); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8SC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x007F]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x07F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - access.romPeekCounter = &myRomAccessCounter[0x80 + (addr & 0x007F)]; - access.romPokeCounter = &myRomAccessCounter[0x80 + (addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF8SC::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - switch(address) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0FF9: - // Set the current bank to the upper 4k bank - bank(1); - break; - - default: - break; - } - - if(address < 0x0080) // Write port is at 0xF000 - 0xF07F (128 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8SC::poke(uInt16 address, uInt8 value) -{ - // Switch banks if necessary - switch(address & 0x0FFF) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - return false; - - case 0x0FF9: - // Set the current bank to the upper 4k bank - bank(1); - return false; - - default: - break; - } - - if (!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8SC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF8 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1100; addr < static_cast(0x1FF8U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF8SC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeF8SC::bankCount() const -{ - return 2; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8SC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeF8SC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8SC::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeF8SC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeF8SC::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeF8SC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + myRamSize = RAM_SIZE; + myRamMask = RAM_MASK; } diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index 592637d3d..9ec8209c4 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGEF8SC_HXX #define CARTRIDGEF8SC_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartF8.hxx" #ifdef DEBUGGER_SUPPORT #include "CartF8SCWidget.hxx" #endif @@ -31,9 +28,9 @@ class System; RAM. There are two 4K banks, accessible by read/write to $1FF8 - $1FF9. RAM read port is $1080 - $10FF, write port is $1000 - $107F. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeF8SC : public Cartridge +class CartridgeF8SC : public CartridgeF8 { friend class CartridgeF8SCWidget; @@ -51,71 +48,6 @@ class CartridgeF8SC : public Cartridge virtual ~CartridgeF8SC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,32 +67,12 @@ class CartridgeF8SC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 8K ROM image of the cartridge - std::array myImage; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; - // The 128 bytes of RAM - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + // RAM mask + static constexpr uInt16 RAM_MASK = RAM_SIZE - 1; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartFC.cxx b/src/emucore/CartFC.cxx index 565e577cf..741935c06 100644 --- a/src/emucore/CartFC.cxx +++ b/src/emucore/CartFC.cxx @@ -21,52 +21,35 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFC::CartridgeFC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeFC::reset() { - initializeStartBank(0); + CartridgeEnhanced::reset(); + myTargetBank = 0; - - // Upon reset we switch to the reset bank - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFC::install(System& system) +bool CartridgeFC::checkSwitchBank(uInt16 address, uInt8) { - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeFC::peek(uInt16 address) -{ - address &= 0x0FFF; - // Switch banks if necessary if(address == 0x0FFC) { // Trigger the bank switch bank(myTargetBank); + return true; } - - return myImage[myBankOffset + address]; + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFC::poke(uInt16 address, uInt8 value) { - address &= 0x0FFF; + address &= myBankMask; // Switch banks if necessary switch (address) @@ -88,108 +71,8 @@ bool CartridgeFC::poke(uInt16 address, uInt8 value) myTargetBank = value % bankCount(); break; - case 0x0FFC: - // Trigger the bank switch - bank(myTargetBank); - break; - default: - break; + checkSwitchBank(address); } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFC::bank(uInt16 bank) -{ - if (bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for (uInt16 addr = (0x1FF8 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for (uInt16 addr = 0x1000; addr < static_cast(0x1FF8U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - myCurrentBank = myTargetBank; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFC::bankCount() const -{ - return uInt16(mySize >> 12); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFC::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeFC::getImage(size_t& size) const -{ - size = mySize; - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFC::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch (...) - { - cerr << "ERROR: CartridgeFC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFC::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch (...) - { - cerr << "ERROR: CartridgeFC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartFC.hxx b/src/emucore/CartFC.hxx index cc96d0131..c1987a189 100644 --- a/src/emucore/CartFC.hxx +++ b/src/emucore/CartFC.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartFCWidget.hxx" @@ -30,12 +30,12 @@ class System; /** Cartridge class used for Amiga's 32K Power Play Arcade Video Game Album. There are eight 4K banks, writing to $1FF8 definies the two lowest bits - of the wanted bank, writeing to $1FF9 defines the high bits. Reading from + of the wanted bank, writeing to $1FF9 defines the high bits. Accessing $1FFC triggers the bank switching @author Thomas Jentzsch */ -class CartridgeFC : public Cartridge +class CartridgeFC : public CartridgeEnhanced { friend class CartridgeFCWidget; @@ -58,66 +58,6 @@ class CartridgeFC : public Cartridge */ void reset() override; - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -138,13 +78,6 @@ class CartridgeFC : public Cartridge #endif public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - /** Change the byte at the specified address to the given value @@ -154,19 +87,12 @@ class CartridgeFC : public Cartridge */ bool poke(uInt16 address, uInt8 value) override; + protected: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + + uInt16 romHotspot() const override { return 0x1FF8; } + private: - // The 32K ROM image of the cartridge - std::array myImage; - - // Size of the ROM image - size_t mySize{0}; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - - // Indicates which bank is currently active for the first segment - uInt16 myCurrentBank{0}; - // Target bank defined by writing to $1FF8/9 uInt16 myTargetBank{0}; diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 36cfa7c84..1837c7b88 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -22,20 +22,15 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFE::CartridgeFE(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); + myDirectPeek = false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeFE::reset() { - // Decathlon requires this, since there is no startup vector in bank 1 - initializeStartBank(0); - - bank(startBank()); + CartridgeEnhanced::reset(); myLastAccessWasFE = false; } @@ -51,14 +46,27 @@ void CartridgeFE::install(System& system) mySystem->setPageAccess(addr, access); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeFE::checkSwitchBank(uInt16 address, uInt8 value) +{ + if(myLastAccessWasFE) + { + bank((value & 0x20) ? 0 : 1); + myLastAccessWasFE = false; // was: address == 0x01FE; + return true; + } + myLastAccessWasFE = address == 0x01FE; + return false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeFE::peek(uInt16 address) { uInt8 value = (address < 0x200) ? mySystem->m6532().peek(address) : - myImage[myBankOffset + (address & 0x0FFF)]; + myImage[myBankOffset + (address & myBankMask)]; // Check if we hit hotspot - checkBankSwitch(address, value); + checkSwitchBank(address, value); return value; } @@ -70,83 +78,17 @@ bool CartridgeFE::poke(uInt16 address, uInt8 value) mySystem->m6532().poke(address, value); // Check if we hit hotspot - checkBankSwitch(address, value); + checkSwitchBank(address, value); return false; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFE::checkBankSwitch(uInt16 address, uInt8 value) -{ - if(bankLocked()) - return; - - // Did we detect $01FE on the last address bus access? - // If so, we bankswitch according to the upper 3 bits of the data bus - // NOTE: see the header file for the significance of 'value & 0x20' - if(myLastAccessWasFE) - bank((value & 0x20) ? 0 : 1); - - // On the next cycle, we use the (then) current data bus value to decode - // the bank to use - myLastAccessWasFE = address == 0x01FE; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFE::bank(uInt16 bank) -{ - if(bankLocked()) - return false; - - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Setup the page access methods for the current bank - // Map all of the cart accesses to call peek and poke - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFE::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFE::bankCount() const -{ - return 2; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFE::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeFE::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFE::save(Serializer& out) const { + CartridgeEnhanced::save(out); try { - out.putShort(myBankOffset); out.putBool(myLastAccessWasFE); } catch(...) @@ -161,9 +103,9 @@ bool CartridgeFE::save(Serializer& out) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFE::load(Serializer& in) { + CartridgeEnhanced::load(in); try { - myBankOffset = in.getShort(); myLastAccessWasFE = in.getBool(); } catch(...) diff --git a/src/emucore/CartFE.hxx b/src/emucore/CartFE.hxx index dabfafdf4..18361faf0 100644 --- a/src/emucore/CartFE.hxx +++ b/src/emucore/CartFE.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartFEWidget.hxx" #endif @@ -75,7 +75,7 @@ class System; @author Stephen Anthony; with ideas/research from Christian Speckner and alex_79 and TomSon (of AtariAge) */ -class CartridgeFE : public Cartridge +class CartridgeFE : public CartridgeEnhanced { friend class CartridgeFEWidget; @@ -106,42 +106,6 @@ class CartridgeFE : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - /** Save the current state of this cart to the given Serializer. @@ -194,20 +158,14 @@ class CartridgeFE : public Cartridge */ bool poke(uInt16 address, uInt8 value) override; - private: + protected: /** Perform bankswitch when necessary, by monitoring for $01FE on the address bus and getting the bank number from the data bus. */ - void checkBankSwitch(uInt16 address, uInt8 value); + bool checkSwitchBank(uInt16 address, uInt8 value) override; private: - // The 8K ROM image of the cartridge - std::array myImage; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - // Whether previous address by peek/poke equals $01FE (hotspot) bool myLastAccessWasFE{false}; diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index ad0decad9..ef06aae57 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -106,7 +106,7 @@ class CartridgeMNetwork : public Cartridge uInt16 getBank(uInt16 address = 0) const override; /** - Query the number of banks supported by the cartridge. + Query the number of banks supported by the cartridge. */ uInt16 bankCount() const override; diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index bfa1321bb..4fd5a5410 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -22,20 +22,9 @@ CartridgeUA::CartridgeUA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings, bool swapHotspots) - : Cartridge(settings, md5), + : CartridgeEnhanced(image, size, md5, settings), mySwappedHotspots(swapHotspots) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeUA::reset() -{ - // Upon reset we switch to the startup bank - initializeStartBank(0); - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,26 +49,33 @@ void CartridgeUA::install(System& system) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeUA::peek(uInt16 address) +bool CartridgeUA::checkSwitchBank(uInt16 address, uInt8) { - address &= 0x1FFF; - // Switch banks if necessary switch(address & 0x1260) { case 0x0220: // Set the current bank to the lower 4k bank bank(mySwappedHotspots ? 1 : 0); - break; + return true; case 0x0240: // Set the current bank to the upper 4k bank bank(mySwappedHotspots ? 0 : 1); - break; + return true; default: break; } + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt8 CartridgeUA::peek(uInt16 address) +{ + address &= myBankMask; + + checkSwitchBank(address); // Because of the way accessing is set up, we will only get here // when doing a TIA read @@ -90,24 +86,9 @@ uInt8 CartridgeUA::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeUA::poke(uInt16 address, uInt8 value) { - address &= 0x1FFF; + address &= myBankMask; - // Switch banks if necessary - switch(address & 0x1260) - { - case 0x0220: - // Set the current bank to the lower 4k bank - bank(mySwappedHotspots ? 1 : 0); - break; - - case 0x0240: - // Set the current bank to the upper 4k bank - bank(mySwappedHotspots ? 0 : 1); - break; - - default: - break; - } + checkSwitchBank(address); // Because of the way accessing is set up, we will may get here by // doing a write to TIA or cart; we ignore the cart write @@ -119,87 +100,3 @@ bool CartridgeUA::poke(uInt16 address, uInt8 value) return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeUA::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeUA::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeUA::bankCount() const -{ - return 2; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeUA::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeUA::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeUA::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: " << name() << "::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeUA::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: " << name() << "::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 38588e4a9..66fe82ec8 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -19,7 +19,7 @@ #define CARTRIDGEUA_HXX #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #include "System.hxx" #ifdef DEBUGGER_SUPPORT #include "CartUAWidget.hxx" @@ -30,9 +30,9 @@ are two 4K banks, which are switched by accessing $0220 (bank 0) and $0240 (bank 1). - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeUA : public Cartridge +class CartridgeUA : public CartridgeEnhanced { friend class CartridgeUAWidget; @@ -51,11 +51,6 @@ class CartridgeUA : public Cartridge virtual ~CartridgeUA() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -64,57 +59,6 @@ class CartridgeUA : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; /** Get a descriptor for the device name (used in error checking). @@ -152,16 +96,14 @@ class CartridgeUA : public Cartridge */ bool poke(uInt16 address, uInt8 value) override; - private: - // The 8K ROM image of the cartridge - std::array myImage; + protected: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + + private: // Previous Device's page access std::array myHotSpotPageAccess; - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - // Indicates if banks are swapped ("Mickey" cart) bool mySwappedHotspots{false}; diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 9aa49cb84..fcd2b85fb 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -717,6 +717,7 @@ + @@ -1739,6 +1740,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 4a2fe6691..ef41cf662 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -1005,6 +1005,9 @@ Source Files\gui + + Source Files\emucore + @@ -2063,6 +2066,9 @@ Header Files\gui + + Header Files\emucore + diff --git a/profile/128.bin b/test/roms/profile/128.bin similarity index 100% rename from profile/128.bin rename to test/roms/profile/128.bin diff --git a/profile/README.md b/test/roms/profile/README.md similarity index 100% rename from profile/README.md rename to test/roms/profile/README.md diff --git a/profile/catharsis_theory.bin b/test/roms/profile/catharsis_theory.bin similarity index 100% rename from profile/catharsis_theory.bin rename to test/roms/profile/catharsis_theory.bin From 8352a36401203af7473ab06db12936028ae4e39d Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 4 Apr 2020 10:53:14 +0200 Subject: [PATCH 02/52] add support for multi segment banking into CartEnhanced class refactor more cart classes --- src/common/bspf.hxx | 2 +- src/debugger/gui/CartE0Widget.cxx | 12 +- src/debugger/gui/DebuggerDialog.cxx | 2 +- src/emucore/CartBF.cxx | 133 +----------------- src/emucore/CartBF.hxx | 96 +------------ src/emucore/CartBFSC.cxx | 194 +------------------------- src/emucore/CartBFSC.hxx | 100 +------------- src/emucore/CartDF.cxx | 135 +------------------ src/emucore/CartDF.hxx | 96 +------------ src/emucore/CartDFSC.cxx | 202 +--------------------------- src/emucore/CartDFSC.hxx | 100 +------------- src/emucore/CartE0.cxx | 128 ++---------------- src/emucore/CartE0.hxx | 85 ++---------- src/emucore/CartEF.cxx | 135 +------------------ src/emucore/CartEF.hxx | 96 +------------ src/emucore/CartEFSC.cxx | 202 +--------------------------- src/emucore/CartEFSC.hxx | 99 +------------- src/emucore/CartEnhanced.cxx | 80 +++++------ src/emucore/CartEnhanced.hxx | 81 ++++++----- src/emucore/CartF0.hxx | 3 +- src/emucore/CartF4.hxx | 2 +- src/emucore/CartF4SC.cxx | 2 +- src/emucore/CartF6.hxx | 2 +- src/emucore/CartF6SC.cxx | 2 +- src/emucore/CartF8.hxx | 3 +- src/emucore/CartF8SC.cxx | 1 - src/emucore/CartF8SC.hxx | 3 - src/emucore/CartFC.hxx | 3 +- src/emucore/CartFE.cxx | 4 +- src/emucore/CartFE.hxx | 4 +- src/emucore/CartUA.cxx | 2 +- src/emucore/CartUA.hxx | 2 +- 32 files changed, 183 insertions(+), 1828 deletions(-) diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 06333b13c..7312783b3 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -84,7 +84,7 @@ using ByteArray = std::vector; using ShortArray = std::vector; using StringList = std::vector; using ByteBuffer = std::unique_ptr; // NOLINT -using WordBuffer = std::unique_ptr; // NOLINT +using DWordBuffer = std::unique_ptr; // NOLINT // We use KB a lot; let's make a literal for it constexpr uInt32 operator "" _KB(unsigned long long size) diff --git a/src/debugger/gui/CartE0Widget.cxx b/src/debugger/gui/CartE0Widget.cxx index de845b197..bdce56fdb 100644 --- a/src/debugger/gui/CartE0Widget.cxx +++ b/src/debugger/gui/CartE0Widget.cxx @@ -98,9 +98,9 @@ CartridgeE0Widget::CartridgeE0Widget( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeE0Widget::loadConfig() { - mySlice0->setSelectedIndex(myCart.myCurrentBank[0]); - mySlice1->setSelectedIndex(myCart.myCurrentBank[1]); - mySlice2->setSelectedIndex(myCart.myCurrentBank[2]); + mySlice0->setSelectedIndex(myCart.myCurrentSegOffset[0] >> myCart.myBankShift); + mySlice1->setSelectedIndex(myCart.myCurrentSegOffset[1] >> myCart.myBankShift); + mySlice2->setSelectedIndex(myCart.myCurrentSegOffset[2] >> myCart.myBankShift); CartDebugWidget::loadConfig(); } @@ -136,9 +136,9 @@ string CartridgeE0Widget::bankState() ostringstream& buf = buffer(); buf << "Slices: " << std::dec - << seg0[myCart.myCurrentBank[0]] << " / " - << seg1[myCart.myCurrentBank[1]] << " / " - << seg2[myCart.myCurrentBank[2]]; + << seg0[myCart.myCurrentSegOffset[0] >> myCart.myBankShift] << " / " + << seg1[myCart.myCurrentSegOffset[1] >> myCart.myBankShift] << " / " + << seg2[myCart.myCurrentSegOffset[2] >> myCart.myBankShift]; return buf.str(); } diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index 47e05da04..3143dbc10 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -617,7 +617,7 @@ void DebuggerDialog::addRomArea() // The 'cart-specific' information tab (optional) - tabID = myRomTab->addTab(" " + instance().console().cartridge().name() + " ", TabWidget::AUTO_WIDTH); + tabID = myRomTab->addTab(" " + instance().console().cartridge().name() + " ", TabWidget::AUTO_WIDTH); myCartInfo = instance().console().cartridge().infoWidget( myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1, tabHeight - myRomTab->getTabHeight() - 2); diff --git a/src/emucore/CartBF.cxx b/src/emucore/CartBF.cxx index 91d13cbb7..0d1921c17 100644 --- a/src/emucore/CartBF.cxx +++ b/src/emucore/CartBF.cxx @@ -21,33 +21,12 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBF::CartridgeBF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBF::reset() -{ - initializeStartBank(1); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBF::install(System& system) -{ - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeBF::peek(uInt16 address) +bool CartridgeBF::checkSwitchBank(uInt16 address, uInt8) { // Due to the way addressing is set up, we will only get here if the // address is in the hotspot range ($1F80 - $1FFF) @@ -55,111 +34,9 @@ uInt8 CartridgeBF::peek(uInt16 address) // Switch banks if necessary if((address >= 0x0F80) && (address <= 0x0FBF)) + { bank(address - 0x0F80); - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBF::poke(uInt16 address, uInt8) -{ - // Due to the way addressing is set up, we will only get here if the - // address is in the hotspot range ($1F80 - $1FFF) - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0F80) && (address <= 0x0FBF)) - bank(address - 0x0F80); - + return true; + } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBF::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1F80 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1F80U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeBF::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeBF::bankCount() const -{ - return 64; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBF::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeBF::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBF::save(Serializer& out) const -{ - try - { - out.putInt(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeBF::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBF::load(Serializer& in) -{ - try - { - myBankOffset = in.getInt(); - } - catch(...) - { - cerr << "ERROR: CartridgeBF::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartBF.hxx b/src/emucore/CartBF.hxx index 158f43a45..08b54d731 100644 --- a/src/emucore/CartBF.hxx +++ b/src/emucore/CartBF.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartBFWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; There are 64 4K banks (total of 256K ROM). Accessing $1F80 - $1FBF switches to each bank. - @author Mike Saarna + @author Mike Saarna, Thomas Jentzsch */ -class CartridgeBF : public Cartridge +class CartridgeBF : public CartridgeEnhanced { friend class CartridgeBFWidget; @@ -51,71 +51,6 @@ class CartridgeBF : public Cartridge virtual ~CartridgeBF() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,29 +70,12 @@ class CartridgeBF : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 256K ROM image of the cartridge - std::array myImage; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - // Indicates the offset into the ROM image (aligns to current bank) - uInt32 myBankOffset{0}; + uInt16 romHotspot() const override { return 0x1F80; } + + uInt16 getStartBank() const override { return 1; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartBFSC.cxx b/src/emucore/CartBFSC.cxx index d0d33c79f..bd9793893 100644 --- a/src/emucore/CartBFSC.cxx +++ b/src/emucore/CartBFSC.cxx @@ -21,197 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBFSC::CartridgeBFSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeBF(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFSC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(15); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFSC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeBFSC::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0F80) && (address <= 0x0FBF)) - bank(address - 0x0F80); - - if(address < 0x0080) // Write port is at 0xF000 - 0xF07F (128 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBFSC::poke(uInt16 address, uInt8 value) -{ - uInt16 pokeAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0F80) && (address <= 0x0FBF)) - { - bank(address - 0x0F80); - return false; - } - - if (!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], pokeAddress, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBFSC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1F80 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1100; addr < static_cast(0x1F80U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeBFSC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeBFSC::bankCount() const -{ - return 64; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBFSC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeBFSC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBFSC::save(Serializer& out) const -{ - try - { - out.putInt(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeBFSC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeBFSC::load(Serializer& in) -{ - try - { - myBankOffset = in.getInt(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeBFSC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartBFSC.hxx b/src/emucore/CartBFSC.hxx index b4cb72aad..35c4b84ca 100644 --- a/src/emucore/CartBFSC.hxx +++ b/src/emucore/CartBFSC.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartBF.hxx" #ifdef DEBUGGER_SUPPORT #include "CartBFSCWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; Accessing $1F80 - $1FBF switches to each bank. RAM read port is $1080 - $10FF, write port is $1000 - $107F. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ -class CartridgeBFSC : public Cartridge +class CartridgeBFSC : public CartridgeBF { friend class CartridgeBFSCWidget; @@ -50,72 +50,6 @@ class CartridgeBFSC : public Cartridge const Settings& settings); virtual ~CartridgeBFSC() = default; - public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,32 +69,12 @@ class CartridgeBFSC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + private: + uInt16 getStartBank() const override { return 15; } private: - // The 256K ROM image of the cartridge - std::array myImage; - - // The 128 bytes of RAM - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt32 myBankOffset{0}; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartDF.cxx b/src/emucore/CartDF.cxx index b43bc0837..db9ab62d2 100644 --- a/src/emucore/CartDF.cxx +++ b/src/emucore/CartDF.cxx @@ -21,145 +21,20 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDF::CartridgeDF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDF::reset() -{ - initializeStartBank(1); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDF::install(System& system) -{ - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeDF::peek(uInt16 address) +bool CartridgeDF::checkSwitchBank(uInt16 address, uInt8) { address &= 0x0FFF; // Switch banks if necessary if((address >= 0x0FC0) && (address <= 0x0FDF)) + { bank(address - 0x0FC0); - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDF::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FC0) && (address <= 0x0FDF)) - bank(address - 0x0FC0); - + return true; + } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDF::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FC0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1FC0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDF::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDF::bankCount() const -{ - return 32; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDF::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeDF::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDF::save(Serializer& out) const -{ - try - { - out.putInt(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeDF::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDF::load(Serializer& in) -{ - try - { - myBankOffset = in.getInt(); - } - catch(...) - { - cerr << "ERROR: CartridgeDF::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartDF.hxx b/src/emucore/CartDF.hxx index 04804b957..5b2025285 100644 --- a/src/emucore/CartDF.hxx +++ b/src/emucore/CartDF.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartDFWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; There are 32 4K banks (total of 128K ROM). Accessing $1FC0 - $1FDF switches to each bank. - @author Mike Saarna + @author Mike Saarna, Thomas Jentzsch */ -class CartridgeDF : public Cartridge +class CartridgeDF : public CartridgeEnhanced { friend class CartridgeDFWidget; @@ -51,71 +51,6 @@ class CartridgeDF : public Cartridge virtual ~CartridgeDF() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,29 +70,12 @@ class CartridgeDF : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 128K ROM image of the cartridge - std::array myImage; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - // Indicates the offset into the ROM image (aligns to current bank) - uInt32 myBankOffset{0}; + uInt16 romHotspot() const override { return 0x1FC0; } + + uInt16 getStartBank() const override { return 15; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartDFSC.cxx b/src/emucore/CartDFSC.cxx index 3661459fa..f759136a7 100644 --- a/src/emucore/CartDFSC.cxx +++ b/src/emucore/CartDFSC.cxx @@ -21,205 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDFSC::CartridgeDFSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeDF(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFSC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(15); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFSC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x007F]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - access.romPeekCounter = &myRomAccessCounter[0x80 + (addr & 0x007F)]; - access.romPokeCounter = &myRomAccessCounter[0x80 + (addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeDFSC::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FC0) && (address <= 0x0FDF)) - bank(address - 0x0FC0); - - if(address < 0x0080) // Write port is at 0xF000 - 0xF07F (128 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDFSC::poke(uInt16 address, uInt8 value) -{ - uInt16 pokeAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FC0) && (address <= 0x0FDF)) - { - bank(address - 0x0FC0); - return false; - } - - if(!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], pokeAddress, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDFSC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FC0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1100; addr < static_cast(0x1FC0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDFSC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDFSC::bankCount() const -{ - return 32; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDFSC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeDFSC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDFSC::save(Serializer& out) const -{ - try - { - out.putInt(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeDFSC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDFSC::load(Serializer& in) -{ - try - { - myBankOffset = in.getInt(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeDFSC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartDFSC.hxx b/src/emucore/CartDFSC.hxx index af35f476b..cf3661039 100644 --- a/src/emucore/CartDFSC.hxx +++ b/src/emucore/CartDFSC.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartDF.hxx" #ifdef DEBUGGER_SUPPORT #include "CartDFSCWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; Accessing $1FC0 - $1FDF switches to each bank. RAM read port is $1080 - $10FF, write port is $1000 - $107F. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ -class CartridgeDFSC : public Cartridge +class CartridgeDFSC : public CartridgeDF { friend class CartridgeDFSCWidget; @@ -51,71 +51,6 @@ class CartridgeDFSC : public Cartridge virtual ~CartridgeDFSC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,34 +70,11 @@ class CartridgeDFSC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 128K ROM image of the cartridge - std::array myImage; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; - // The 128 bytes of RAM - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt32 myBankOffset{0}; - - private: +private: // Following constructors and assignment operators not supported CartridgeDFSC() = delete; CartridgeDFSC(const CartridgeDFSC&) = delete; diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index 3788a95bc..e35917993 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -21,11 +21,9 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE0::CartridgeE0(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); + myBankShift = BANK_SHIFT; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -44,7 +42,7 @@ void CartridgeE0::reset() bank(5, 1); bank(6, 2); } - myCurrentBank[3] = bankCount() - 1; // fixed + myCurrentSegOffset[3] = (bankCount() - 1) << myBankShift; // fixed myBankChanged = true; } @@ -52,7 +50,13 @@ void CartridgeE0::reset() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeE0::install(System& system) { - mySystem = &system; + //// Allocate array for the current bank segments slices + //myCurrentSegOffset = make_unique(myBankSegs); + + //// Setup page access + //mySystem = &system; + + CartridgeEnhanced::install(system); System::PageAccess access(this, System::PageAccessType::READ); @@ -79,127 +83,23 @@ void CartridgeE0::install(System& system) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeE0::getBank(uInt16 address) const +bool CartridgeE0::checkSwitchBank(uInt16 address, uInt8) { - return myCurrentBank[(address & 0xFFF) >> 10]; // 1K slices -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeE0::bankCount() const -{ - return 8; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeE0::peek(uInt16 address) -{ - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FE0) && (address <= 0x0FE7)) - { - bank(address & 0x0007, 0); - } - else if((address >= 0x0FE8) && (address <= 0x0FEF)) - { - bank(address & 0x0007, 1); - } - else if((address >= 0x0FF0) && (address <= 0x0FF7)) - { - bank(address & 0x0007, 2); - } - - return myImage[(myCurrentBank[address >> 10] << 10) + (address & 0x03FF)]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE0::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FE7)) { bank(address & 0x0007, 0); + return true; } else if((address >= 0x0FE8) && (address <= 0x0FEF)) { bank(address & 0x0007, 1); + return true; } else if((address >= 0x0FF0) && (address <= 0x0FF7)) { bank(address & 0x0007, 2); + return true; } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0::bank(uInt16 bank, uInt16 slice) -{ - if(bankLocked()) return; - - // Remember the new slice - myCurrentBank[slice] = bank; - uInt16 sliceOffset = slice * (1 << 10); - uInt16 bankOffset = bank << 10; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - for(uInt16 addr = 0x1000 + sliceOffset; addr < 0x1000 + sliceOffset + 0x400; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[bankOffset + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[bankOffset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[bankOffset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[bankOffset + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE0::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - myImage[(myCurrentBank[address >> 10] << 10) + (address & 0x03FF)] = value; - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeE0::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE0::save(Serializer& out) const -{ - try - { - out.putShortArray(myCurrentBank.data(), myCurrentBank.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeE0::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeE0::load(Serializer& in) -{ - try - { - in.getShortArray(myCurrentBank.data(), myCurrentBank.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeE0::load" << endl; - return false; - } - - return true; -} diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 35513be85..66dbbba6a 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartE0Widget.hxx" #endif @@ -39,9 +39,9 @@ class System; only one actual bank, in which pieces of it can be swapped out in many different ways. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeE0 : public Cartridge +class CartridgeE0 : public CartridgeEnhanced { friend class CartridgeE0Widget; @@ -72,52 +72,6 @@ class CartridgeE0 : public Cartridge */ void install(System& system) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -137,37 +91,14 @@ class CartridgeE0 : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + private: + bool checkSwitchBank(uInt16 address, uInt8 = 0) override; - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + uInt16 romHotspot() const override { return 0x1FE0; } private: - /** - Install the specified slice for segment (bank) 0..2 - - @param slice The slice to map into the segment - */ - void bank(uInt16 bank, uInt16 slice); - - private: - // The 8K ROM image of the cartridge - std::array myImage; - - // Indicates the slice mapped into each of the four segments - std::array myCurrentBank; + // log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 10; // = 1K = 0x0400 private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index 16635200b..70cd8236b 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -21,145 +21,20 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEF::reset() -{ - initializeStartBank(1); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEF::install(System& system) -{ - mySystem = &system; - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeEF::peek(uInt16 address) +bool CartridgeEF::checkSwitchBank(uInt16 address, uInt8) { address &= 0x0FFF; // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FEF)) + { bank(address - 0x0FE0); - - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEF::poke(uInt16 address, uInt8) -{ - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FE0) && (address <= 0x0FEF)) - bank(address - 0x0FE0); - + return true; + } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEF::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1000; addr < static_cast(0x1FE0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEF::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEF::bankCount() const -{ - return 16; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEF::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeEF::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEF::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeEF::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEF::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: CartridgeEF::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartEF.hxx b/src/emucore/CartEF.hxx index 62a10975d..1461e954d 100644 --- a/src/emucore/CartEF.hxx +++ b/src/emucore/CartEF.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartEFWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; There are 16 4K banks (total of 64K ROM). Accessing $1FE0 - $1FEF switches to each bank. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ -class CartridgeEF : public Cartridge +class CartridgeEF : public CartridgeEnhanced { friend class CartridgeEFWidget; @@ -51,71 +51,6 @@ class CartridgeEF : public Cartridge virtual ~CartridgeEF() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,29 +70,12 @@ class CartridgeEF : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 64K ROM image of the cartridge - std::array myImage; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + uInt16 romHotspot() const override { return 0x1FE0; } + + uInt16 getStartBank() const override { return 1; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEFSC.cxx b/src/emucore/CartEFSC.cxx index 3502be7a0..c70cff194 100644 --- a/src/emucore/CartEFSC.cxx +++ b/src/emucore/CartEFSC.cxx @@ -21,205 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEFSC::CartridgeEFSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEF(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFSC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(15); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFSC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x007F]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - access.romPeekCounter = &myRomAccessCounter[0x80 + (addr & 0x007F)]; - access.romPokeCounter = &myRomAccessCounter[0x80 + (addr & 0x007F) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeEFSC::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FE0) && (address <= 0x0FEF)) - bank(address - 0x0FE0); - - if(address < 0x0080) // Write port is at 0xF000 - 0xF07F (128 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEFSC::poke(uInt16 address, uInt8 value) -{ - uInt16 pokeAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - if((address >= 0x0FE0) && (address <= 0x0FEF)) - { - bank(address - 0x0FE0); - return false; - } - - if (!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], pokeAddress, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEFSC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1100; addr < static_cast(0x1FE0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEFSC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEFSC::bankCount() const -{ - return 16; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEFSC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeEFSC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEFSC::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeEFSC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEFSC::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeEFSC::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + myRamSize = RAM_SIZE; } diff --git a/src/emucore/CartEFSC.hxx b/src/emucore/CartEFSC.hxx index 810b27b22..d204d1ef5 100644 --- a/src/emucore/CartEFSC.hxx +++ b/src/emucore/CartEFSC.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEF.hxx" #ifdef DEBUGGER_SUPPORT #include "CartEFSCWidget.hxx" #endif @@ -32,9 +32,9 @@ class System; Accessing $1FE0 - $1FEF switches to each bank. RAM read port is $1080 - $10FF, write port is $1000 - $107F. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ -class CartridgeEFSC : public Cartridge +class CartridgeEFSC : public CartridgeEF { friend class CartridgeEFSCWidget; @@ -52,71 +52,6 @@ class CartridgeEFSC : public Cartridge virtual ~CartridgeEFSC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -136,32 +71,12 @@ class CartridgeEFSC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + private: + uInt16 getStartBank() const override { return 15; } private: - // The 64K ROM image of the cartridge - std::array myImage; - - // The 128 bytes of RAM - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index ff4113ad4..0f0472392 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -37,9 +37,14 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeEnhanced::install(System& system) { + // calculate bank switching and RAM sizes and masks + myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 + myBankMask = myBankSize - 1; // e.g. = 0x0FFF + myBankSegs = 1 << (12 - myBankShift); // e.g. = 1 + myRamMask = myRamSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) + // Allocate array for the current bank segments slices - myCurrentBankOffset = make_unique(BANK_SEGS); - std::fill_n(myCurrentBankOffset.get(), BANK_SEGS, 0); + myCurrentSegOffset = make_unique(myBankSegs); // Allocate array for the RAM area myRAM = make_unique(myRamSize); @@ -93,24 +98,22 @@ void CartridgeEnhanced::reset() uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - address &= myBankMask; - checkSwitchBank(address); + checkSwitchBank(address & 0x0FFF); + address &= myBankMask; if(address < myRamSize) // Write port is at 0xF000 - 0xF07F (128 bytes) return peekRAM(myRAM[address], peekAddress); else - return myImage[myBankOffset + address]; - return myImage[myCurrentBankOffset[address >> BANK_SHIFT] + (address & BANK_MASK)]; + //return myImage[myBankOffset + address]; + return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { - address &= myBankMask; - // Switch banks if necessary - if (checkSwitchBank(address & myBankMask)) + if (checkSwitchBank(address & 0x0FFF)) return false; if(myRamSize) @@ -133,45 +136,34 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEnhanced::bank(uInt16 bank, uInt16 slice) +bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) { if(bankLocked()) return false; - // Remember what bank we're in - myBankOffset = bank << myBankShift; - + // Remember what bank is in which segment + uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; + uInt16 segmentOffset = segment << myBankShift; uInt16 romHotspot = this->romHotspot(); - uInt16 fromAddr = 0x1000 + myRamSize * 2; - uInt16 toAddr; + uInt16 hotSpotAddr; + uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK; + uInt16 toAddr = (segmentOffset + 0x1000 + myBankSize) & ~System::PAGE_MASK; if(romHotspot) - { - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (romHotspot & ~System::PAGE_MASK); addr < 0x1000 + myBankSize; - addr += System::PAGE_SIZE) - { - uInt16 offset = myBankOffset + (addr & myBankMask); - access.romAccessBase = &myRomAccessBase[offset]; - access.romPeekCounter = &myRomAccessCounter[offset]; - access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - toAddr = romHotspot; - } + hotSpotAddr = segmentOffset + (romHotspot & ~System::PAGE_MASK); else - toAddr = 0x1000 + myBankSize; + hotSpotAddr = 0xFFFF; // none System::PageAccess access(this, System::PageAccessType::READ); // Setup the page access methods for the current bank - for(uInt16 addr = (fromAddr & ~System::PAGE_MASK); addr < (toAddr & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) + for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) { - uInt16 offset = myBankOffset + (addr & myBankMask); - if(myDirectPeek) + uInt32 offset = bankOffset + (addr & myBankMask); + + if(myDirectPeek && addr != hotSpotAddr) access.directPeekBase = &myImage[offset]; + else + access.directPeekBase = nullptr; access.romAccessBase = &myRomAccessBase[offset]; access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; @@ -182,9 +174,9 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 slice) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEnhanced::getBank(uInt16) const +uInt16 CartridgeEnhanced::getBank(uInt16 address) const { - return myBankOffset >> myBankShift; + return myCurrentSegOffset[(address & 0xFFF) >> myBankShift] >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -196,9 +188,7 @@ uInt16 CartridgeEnhanced::bankCount() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) { - address &= myBankMask; - - if(address < myRamSize * 2) + if((address & myBankMask) < myRamSize * 2) { // Normally, a write to the read port won't do anything // However, the patch command is special in that ignores such @@ -206,7 +196,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) myRAM[address & myRamMask] = value; } else - myImage[myBankOffset + address] = value; + myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value; return myBankChanged = true; } @@ -223,7 +213,7 @@ bool CartridgeEnhanced::save(Serializer& out) const { try { - out.putShort(myBankOffset); + out.putIntArray(myCurrentSegOffset.get(), myBankSegs); if(myRamSize) out.putByteArray(myRAM.get(), myRamSize); @@ -242,7 +232,7 @@ bool CartridgeEnhanced::load(Serializer& in) { try { - myBankOffset = in.getShort(); + in.getIntArray(myCurrentSegOffset.get(), myBankSegs); if(myRamSize) in.getByteArray(myRAM.get(), myRamSize); } @@ -251,9 +241,5 @@ bool CartridgeEnhanced::load(Serializer& in) cerr << "ERROR: " << name() << "::load" << endl; return false; } - - // Remember what bank we were in - bank(myBankOffset >> myBankShift); - return true; } diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 22d253b6a..b8511ac29 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -63,7 +63,7 @@ class CartridgeEnhanced : public Cartridge @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank, uInt16 slice); + bool bank(uInt16 bank, uInt16 segment); /** Install pages for the specified bank in the system. @@ -135,62 +135,71 @@ class CartridgeEnhanced : public Cartridge bool poke(uInt16 address, uInt8 value) override; protected: + // The '2 ^ N = bank segment size' exponent + uInt16 myBankShift{BANK_SHIFT}; // default 12 (-> one 4K segment) + + // The size of a bank's segment + uInt16 myBankSize{0}; + + // The mask for a bank segment + uInt16 myBankMask{0}; + + // The number of segments a bank is split into + uInt16 myBankSegs{0}; + + // The extra RAM size + uInt16 myRamSize{RAM_SIZE}; // default 0 + + // The mask for the extra RAM + uInt16 myRamMask{0}; // RAM_SIZE - 1, but doesn't matter when RAM_SIZE is 0 + // Pointer to a dynamically allocated ROM image of the cartridge ByteBuffer myImage{nullptr}; + // Contains the offset into the ROM image for each of the bank segments + DWordBuffer myCurrentSegOffset{nullptr}; + + // Indicates whether to use direct ROM peeks or not + bool myDirectPeek{true}; + // Pointer to a dynamically allocated RAM area of the cartridge ByteBuffer myRAM{nullptr}; - uInt16 myBankShift{BANK_SHIFT}; - - uInt16 myBankSize{BANK_SIZE}; - - uInt16 myBankMask{BANK_MASK}; - - uInt16 myRamSize{RAM_SIZE}; - - uInt16 myRamMask{RAM_MASK}; - - bool myDirectPeek{true}; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - - // Indicates the slice mapped into each of the bank segments - WordBuffer myCurrentBankOffset{nullptr}; - private: - // log(ROM bank size) / log(2) - static constexpr uInt16 BANK_SHIFT = 12; + // Calculated as: log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 12; // default = 4K - // bank size - static constexpr uInt16 BANK_SIZE = 1 << BANK_SHIFT; // 2 ^ 12 = 4K + // The size of extra RAM in ROM address space + static constexpr uInt16 RAM_SIZE = 0; // default = none - // bank mask - static constexpr uInt16 BANK_MASK = BANK_SIZE - 1; - - // bank segments - static constexpr uInt16 BANK_SEGS = 1; - - // RAM size - static constexpr uInt16 RAM_SIZE = 0; - - // RAM mask - static constexpr uInt16 RAM_MASK = 0; - - // Size of the ROM image + // The size of the ROM image size_t mySize{0}; protected: /** Check hotspots and switch bank if triggered. + + @param address The address to check + @param value The optional value used to determine the bank switched to + @return True if a bank switch happened. */ virtual bool checkSwitchBank(uInt16 address, uInt8 value = 0) = 0; private: + /** + Get the ROM's startup bank. + + @return The bank the ROM will start in + */ virtual uInt16 getStartBank() const { return 0; } + /** + Get the hotspot in ROM address space. + + @return The first hotspot address in ROM space or 0 + */ virtual uInt16 romHotspot() const { return 0; } + // TODO: handle cases where there the hotspots cover multiple pages private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index 07123bf34..fc8d62939 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -67,12 +67,11 @@ class CartridgeF0 : public CartridgeEnhanced } #endif - protected: + private: bool checkSwitchBank(uInt16 address, uInt8 value = 0); uInt16 romHotspot() const override { return 0x1FF0; } - private: uInt16 getStartBank() const override { return 15; } private: diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index 3b4f0f141..afe81d0e0 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -66,7 +66,7 @@ class CartridgeF4 : public CartridgeEnhanced } #endif - protected: + private: bool checkSwitchBank(uInt16 address, uInt8 value = 0); uInt16 romHotspot() const override { return 0x1FF4; } diff --git a/src/emucore/CartF4SC.cxx b/src/emucore/CartF4SC.cxx index 5364f2eb4..4fe6e13eb 100644 --- a/src/emucore/CartF4SC.cxx +++ b/src/emucore/CartF4SC.cxx @@ -23,5 +23,5 @@ CartridgeF4SC::CartridgeF4SC(const ByteBuffer& image, size_t size, : CartridgeF4(image, size, md5, settings) { myRamSize = RAM_SIZE; - myRamMask = RAM_MASK; + myRamMask = RAM_SIZE - 1; } diff --git a/src/emucore/CartF6.hxx b/src/emucore/CartF6.hxx index 275727786..2f183ad7b 100644 --- a/src/emucore/CartF6.hxx +++ b/src/emucore/CartF6.hxx @@ -66,7 +66,7 @@ class CartridgeF6 : public CartridgeEnhanced } #endif - protected: + private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; uInt16 romHotspot() const override { return 0x1FF6; } diff --git a/src/emucore/CartF6SC.cxx b/src/emucore/CartF6SC.cxx index 034f02bce..15613a357 100644 --- a/src/emucore/CartF6SC.cxx +++ b/src/emucore/CartF6SC.cxx @@ -23,5 +23,5 @@ CartridgeF6SC::CartridgeF6SC(const ByteBuffer& image, size_t size, : CartridgeF6(image, size, md5, settings) { myRamSize = RAM_SIZE; - myRamMask = RAM_MASK; + myRamMask = RAM_SIZE - 1; } diff --git a/src/emucore/CartF8.hxx b/src/emucore/CartF8.hxx index 71e4d6e72..23863fa57 100644 --- a/src/emucore/CartF8.hxx +++ b/src/emucore/CartF8.hxx @@ -66,12 +66,11 @@ class CartridgeF8 : public CartridgeEnhanced } #endif - protected: + private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; uInt16 romHotspot() const override { return 0x1FF8; } - private: uInt16 getStartBank() const override { return 1; } private: diff --git a/src/emucore/CartF8SC.cxx b/src/emucore/CartF8SC.cxx index e9dd5bd5c..98ce4357f 100644 --- a/src/emucore/CartF8SC.cxx +++ b/src/emucore/CartF8SC.cxx @@ -23,5 +23,4 @@ CartridgeF8SC::CartridgeF8SC(const ByteBuffer& image, size_t size, : CartridgeF8(image, size, md5, settings) { myRamSize = RAM_SIZE; - myRamMask = RAM_MASK; } diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index 9ec8209c4..25fe0dfe3 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -71,9 +71,6 @@ class CartridgeF8SC : public CartridgeF8 // RAM size static constexpr uInt16 RAM_SIZE = 0x80; - // RAM mask - static constexpr uInt16 RAM_MASK = RAM_SIZE - 1; - private: // Following constructors and assignment operators not supported CartridgeF8SC() = delete; diff --git a/src/emucore/CartFC.hxx b/src/emucore/CartFC.hxx index c1987a189..b08f2085c 100644 --- a/src/emucore/CartFC.hxx +++ b/src/emucore/CartFC.hxx @@ -87,12 +87,11 @@ class CartridgeFC : public CartridgeEnhanced */ bool poke(uInt16 address, uInt8 value) override; - protected: + private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; uInt16 romHotspot() const override { return 0x1FF8; } - private: // Target bank defined by writing to $1FF8/9 uInt16 myTargetBank{0}; diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 1837c7b88..3a07730e0 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -37,7 +37,7 @@ void CartridgeFE::reset() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeFE::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); // The hotspot $01FE is in a mirror of zero-page RAM // We need to claim access to it here, and deal with it in peek/poke below @@ -63,7 +63,7 @@ bool CartridgeFE::checkSwitchBank(uInt16 address, uInt8 value) uInt8 CartridgeFE::peek(uInt16 address) { uInt8 value = (address < 0x200) ? mySystem->m6532().peek(address) : - myImage[myBankOffset + (address & myBankMask)]; + myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)]; // Check if we hit hotspot checkSwitchBank(address, value); diff --git a/src/emucore/CartFE.hxx b/src/emucore/CartFE.hxx index 18361faf0..3132704cd 100644 --- a/src/emucore/CartFE.hxx +++ b/src/emucore/CartFE.hxx @@ -72,8 +72,8 @@ class System; particular *why* the address $01FE will be placed on the address bus after both the JSR and RTS opcodes. - @author Stephen Anthony; with ideas/research from Christian Speckner and - alex_79 and TomSon (of AtariAge) + @author Stephen Anthony, Thomas Jentzsch; with ideas/research from Christian + Speckner and alex_79 and TomSon (of AtariAge) */ class CartridgeFE : public CartridgeEnhanced { diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index 4fd5a5410..74ccc3773 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -30,7 +30,7 @@ CartridgeUA::CartridgeUA(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeUA::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); // Get the page accessing methods for the hot spots since they overlap // areas within the TIA we'll need to forward requests to the TIA diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 66fe82ec8..94dcb4a98 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -97,7 +97,7 @@ class CartridgeUA : public CartridgeEnhanced bool poke(uInt16 address, uInt8 value) override; - protected: + private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; private: From 7e2ccf6d99223910c1dd16bb13871a1671fbc0d8 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 4 Apr 2020 17:28:30 +0200 Subject: [PATCH 03/52] refactor Cart3F improve CartEnhanced for segmented types --- src/debugger/gui/Cart3FWidget.cxx | 2 +- src/emucore/Cart3F.cxx | 163 ++---------------------------- src/emucore/Cart3F.hxx | 88 ++-------------- src/emucore/CartE0.cxx | 37 ------- src/emucore/CartE0.hxx | 8 -- src/emucore/CartEnhanced.cxx | 15 +-- src/emucore/CartEnhanced.hxx | 6 +- 7 files changed, 28 insertions(+), 291 deletions(-) diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index 223e56cc0..ab5a48761 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -88,7 +88,7 @@ string Cartridge3FWidget::bankState() { ostringstream& buf = buffer(); - buf << "Bank = #" << std::dec << myCart.myCurrentBank << ", hotspot = $3F"; + buf << "Bank = #" << std::dec << (myCart.myCurrentSegOffset[0] >> myCart.myBankShift) << ", hotspot = $3F"; return buf.str(); } diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 2989e88ff..7c3701c16 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -22,177 +22,32 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3F::Cartridge3F(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeEnhanced(image, size, md5, settings) { - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3F::reset() -{ - initializeStartBank(bankCount() - 1); - - bank(startBank()); + myBankShift = BANK_SHIFT; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3F::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); System::PageAccess access(this, System::PageAccessType::READWRITE); // The hotspot ($3F) is in TIA address space, so we claim it here for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); - - // Setup the second segment to always point to the last ROM slice - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[(mySize - 2048) + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[(mySize - 2048) + (addr & 0x07FF)]; - access.romPeekCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF)]; - access.romPokeCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge3F::peek(uInt16 address) +bool Cartridge3F::checkSwitchBank(uInt16 address, uInt8 value) { - address &= 0x0FFF; - - if(address < 0x0800) - return myImage[(address & 0x07FF) + (myCurrentBank << 11)]; - else - return myImage[(address & 0x07FF) + mySize - 2048]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::poke(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - // Switch banks if necessary if(address <= 0x003F) - bank(value); - - // Handle TIA space that we claimed above - mySystem->tia().poke(address, value); - + { + // Make sure the bank they're asking for is reasonable + bank(value % bankCount(), 0); + return true; + } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::bank(uInt16 bank) -{ - if(bankLocked()) - return false; - - // Make sure the bank they're asking for is reasonable - if((uInt32(bank) << 11) < mySize) - { - myCurrentBank = bank; - } - else - { - // Oops, the bank they're asking for isn't valid so let's wrap it - // around to a valid bank number - myCurrentBank = bank % (mySize >> 11); - } - - uInt32 offset = myCurrentBank << 11; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x07FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x07FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3F::getBank(uInt16 address) const -{ - if (address & 0x800) - return uInt16((mySize >> 11) - 1); // 2K slices, fixed bank - else - return myCurrentBank; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3F::bankCount() const -{ - return uInt16(mySize >> 11); // 2K slices -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0800) - myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value; - else - myImage[(address & 0x07FF) + mySize - 2048] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge3F::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::save(Serializer& out) const -{ - try - { - out.putShort(myCurrentBank); - } - catch(...) - { - cerr << "ERROR: Cartridge3F::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3F::load(Serializer& in) -{ - try - { - myCurrentBank = in.getShort(); - } - catch(...) - { - cerr << "ERROR: Cartridge3F::load" << endl; - return false; - } - - // Now, go to the current bank - bank(myCurrentBank); - - return true; -} diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index cb75bcd88..53b71427a 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart3FWidget.hxx" #endif @@ -38,7 +38,7 @@ class System; @author Bradford W. Mott */ -class Cartridge3F : public Cartridge +class Cartridge3F : public CartridgeEnhanced { friend class Cartridge3FWidget; @@ -56,11 +56,6 @@ class Cartridge3F : public Cartridge virtual ~Cartridge3F() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -69,57 +64,6 @@ class Cartridge3F : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; /** Get a descriptor for the device name (used in error checking). @@ -140,32 +84,12 @@ class Cartridge3F : public Cartridge } #endif - public: - /** - Get the byte at the specified address - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + private: + bool checkSwitchBank(uInt16 address, uInt8 value) override; private: - // Pointer to a dynamically allocated ROM image of the cartridge - ByteBuffer myImage; - - // Size of the ROM image - size_t mySize{0}; - - // Indicates which bank is currently active for the first segment - uInt16 myCurrentBank{0}; + // log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800 private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index e35917993..97752e447 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -42,46 +42,9 @@ void CartridgeE0::reset() bank(5, 1); bank(6, 2); } - myCurrentSegOffset[3] = (bankCount() - 1) << myBankShift; // fixed - myBankChanged = true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0::install(System& system) -{ - //// Allocate array for the current bank segments slices - //myCurrentSegOffset = make_unique(myBankSegs); - - //// Setup page access - //mySystem = &system; - - CartridgeEnhanced::install(system); - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page acessing methods for the first part of the last segment - for(uInt16 addr = 0x1C00; addr < static_cast(0x1FE0U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[0x1C00 + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[0x1C00 + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[0x1C00 + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[0x1C00 + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing methods for the hot spots in the last segment - access.directPeekBase = nullptr; - access.romAccessBase = &myRomAccessBase[0x1FC0]; - access.romPeekCounter = &myRomAccessCounter[0x1FC0]; - access.romPokeCounter = &myRomAccessCounter[0x1FC0 + myAccessSize]; - access.type = System::PageAccessType::READ; - for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeE0::checkSwitchBank(uInt16 address, uInt8) { diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 66dbbba6a..08fc82806 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -64,14 +64,6 @@ class CartridgeE0 : public CartridgeEnhanced */ void reset() override; - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - /** Get a descriptor for the device name (used in error checking). diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 0f0472392..0ac9ffadd 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -79,8 +79,11 @@ void CartridgeEnhanced::install(System& system) mySystem->setPageAccess(addr, access); } - // Install pages for the startup bank - bank(startBank()); + // Install pages for the startup bank (TODO: currently only in first bank segment) + bank(startBank(), 0); + if(myBankSegs > 1) + // Setup the last bank segment to always point to the last ROM segment + bank(bankCount() - 1, myBankSegs - 1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -99,13 +102,13 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - checkSwitchBank(address & 0x0FFF); + if (romHotspot()) + checkSwitchBank(address & 0x0FFF); address &= myBankMask; if(address < myRamSize) // Write port is at 0xF000 - 0xF07F (128 bytes) return peekRAM(myRAM[address], peekAddress); else - //return myImage[myBankOffset + address]; return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; } @@ -113,7 +116,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { // Switch banks if necessary - if (checkSwitchBank(address & 0x0FFF)) + if (checkSwitchBank(address & 0x0FFF, value)) return false; if(myRamSize) @@ -149,7 +152,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt16 toAddr = (segmentOffset + 0x1000 + myBankSize) & ~System::PAGE_MASK; if(romHotspot) - hotSpotAddr = segmentOffset + (romHotspot & ~System::PAGE_MASK); + hotSpotAddr = (romHotspot & ~System::PAGE_MASK); else hotSpotAddr = 0xFFFF; // none diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index b8511ac29..4bd45fadd 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -165,6 +165,9 @@ class CartridgeEnhanced : public Cartridge // Pointer to a dynamically allocated RAM area of the cartridge ByteBuffer myRAM{nullptr}; + // The size of the ROM image + size_t mySize{0}; + private: // Calculated as: log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 12; // default = 4K @@ -172,9 +175,6 @@ class CartridgeEnhanced : public Cartridge // The size of extra RAM in ROM address space static constexpr uInt16 RAM_SIZE = 0; // default = none - // The size of the ROM image - size_t mySize{0}; - protected: /** Check hotspots and switch bank if triggered. From ac5b46ee9746773bb0da3d3569a255bcce5cb704 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sat, 4 Apr 2020 13:39:38 -0230 Subject: [PATCH 04/52] Fixed compilation in Linux. --- src/emucore/CartF0.hxx | 2 +- src/emucore/CartF4.hxx | 2 +- src/emucore/module.mk | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index fc8d62939..e885cd934 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -68,7 +68,7 @@ class CartridgeF0 : public CartridgeEnhanced #endif private: - bool checkSwitchBank(uInt16 address, uInt8 value = 0); + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; uInt16 romHotspot() const override { return 0x1FF0; } diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index afe81d0e0..5b54af54d 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -67,7 +67,7 @@ class CartridgeF4 : public CartridgeEnhanced #endif private: - bool checkSwitchBank(uInt16 address, uInt8 value = 0); + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; uInt16 romHotspot() const override { return 0x1FF4; } diff --git a/src/emucore/module.mk b/src/emucore/module.mk index e02fcdc2d..bbdd5eaab 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS := \ src/emucore/Booster.o \ src/emucore/Cart.o \ src/emucore/CartDetector.o \ + src/emucore/CartEnhanced.o \ src/emucore/Cart0840.o \ src/emucore/Cart2K.o \ src/emucore/Cart3E.o \ From 6e06da11618bd4c7a02c7db25ed8fbe05fa10d5b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 4 Apr 2020 18:29:05 +0200 Subject: [PATCH 05/52] add get current segment from cart for debug widgets --- src/debugger/gui/Cart3FWidget.cxx | 7 ++++--- src/debugger/gui/CartE0Widget.cxx | 12 ++++++------ src/emucore/Cart3F.hxx | 2 +- src/emucore/CartEnhanced.cxx | 6 ++++++ src/emucore/CartEnhanced.hxx | 13 ++++++++++--- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index ab5a48761..86d43177b 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -26,9 +26,10 @@ Cartridge3FWidget::Cartridge3FWidget( : CartDebugWidget(boss, lfont, nfont, x, y, w, h), myCart(cart) { - size_t size = cart.mySize; - ostringstream info; + size_t size; + + cart.getImage(size); info << "Tigervision 3F cartridge, 2-256 2K banks\n" << "Startup bank = " << cart.startBank() << " or undetermined\n" << "First 2K bank selected by writing to $3F\n" @@ -88,7 +89,7 @@ string Cartridge3FWidget::bankState() { ostringstream& buf = buffer(); - buf << "Bank = #" << std::dec << (myCart.myCurrentSegOffset[0] >> myCart.myBankShift) << ", hotspot = $3F"; + buf << "Bank = #" << std::dec << myCart.getSegmentBank() << ", hotspot = $3F"; return buf.str(); } diff --git a/src/debugger/gui/CartE0Widget.cxx b/src/debugger/gui/CartE0Widget.cxx index bdce56fdb..861c99228 100644 --- a/src/debugger/gui/CartE0Widget.cxx +++ b/src/debugger/gui/CartE0Widget.cxx @@ -98,9 +98,9 @@ CartridgeE0Widget::CartridgeE0Widget( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeE0Widget::loadConfig() { - mySlice0->setSelectedIndex(myCart.myCurrentSegOffset[0] >> myCart.myBankShift); - mySlice1->setSelectedIndex(myCart.myCurrentSegOffset[1] >> myCart.myBankShift); - mySlice2->setSelectedIndex(myCart.myCurrentSegOffset[2] >> myCart.myBankShift); + mySlice0->setSelectedIndex(myCart.getSegmentBank(0)); + mySlice1->setSelectedIndex(myCart.getSegmentBank(1)); + mySlice2->setSelectedIndex(myCart.getSegmentBank(2)); CartDebugWidget::loadConfig(); } @@ -136,9 +136,9 @@ string CartridgeE0Widget::bankState() ostringstream& buf = buffer(); buf << "Slices: " << std::dec - << seg0[myCart.myCurrentSegOffset[0] >> myCart.myBankShift] << " / " - << seg1[myCart.myCurrentSegOffset[1] >> myCart.myBankShift] << " / " - << seg2[myCart.myCurrentSegOffset[2] >> myCart.myBankShift]; + << seg0[myCart.getSegmentBank(0)] << " / " + << seg1[myCart.getSegmentBank(1)] << " / " + << seg2[myCart.getSegmentBank(2)]; return buf.str(); } diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index 53b71427a..d9f3e9fa6 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -36,7 +36,7 @@ class System; $00 to $3F will change banks. Although, the Tigervision games only used 8K this bankswitching scheme supports up to 512K. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ class Cartridge3F : public CartridgeEnhanced { diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 0ac9ffadd..adcd8bc0e 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -182,6 +182,12 @@ uInt16 CartridgeEnhanced::getBank(uInt16 address) const return myCurrentSegOffset[(address & 0xFFF) >> myBankShift] >> myBankShift; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 CartridgeEnhanced::getSegmentBank(uInt16 segment) const +{ + return myCurrentSegOffset[segment % myBankSegs] >> myBankShift; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::bankCount() const { diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 4bd45fadd..703cd320f 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -79,6 +79,13 @@ class CartridgeEnhanced : public Cartridge */ uInt16 getBank(uInt16 address = 0) const override; + /** + Get the current bank for a bank segment. + + @param segment The segment to get the bank for + */ + uInt16 getSegmentBank(uInt16 segment = 0) const; + /** Query the number of banks supported by the cartridge. */ @@ -165,9 +172,6 @@ class CartridgeEnhanced : public Cartridge // Pointer to a dynamically allocated RAM area of the cartridge ByteBuffer myRAM{nullptr}; - // The size of the ROM image - size_t mySize{0}; - private: // Calculated as: log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 12; // default = 4K @@ -175,6 +179,9 @@ class CartridgeEnhanced : public Cartridge // The size of extra RAM in ROM address space static constexpr uInt16 RAM_SIZE = 0; // default = none + // The size of the ROM image + size_t mySize{0}; + protected: /** Check hotspots and switch bank if triggered. From 706d82e75c4dd9334e863255e28874f326c6f982 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 4 Apr 2020 23:04:41 +0200 Subject: [PATCH 06/52] refactor Cart0840 --- src/emucore/Cart0840.cxx | 158 ++++++----------------------------- src/emucore/Cart0840.hxx | 70 ++-------------- src/emucore/CartBF.hxx | 2 +- src/emucore/CartDF.hxx | 2 +- src/emucore/CartE0.hxx | 2 +- src/emucore/CartEF.hxx | 2 +- src/emucore/CartEnhanced.cxx | 8 +- src/emucore/CartEnhanced.hxx | 4 +- src/emucore/CartF0.hxx | 2 +- src/emucore/CartF4.hxx | 2 +- src/emucore/CartF6.hxx | 2 +- src/emucore/CartF8.hxx | 2 +- 12 files changed, 45 insertions(+), 211 deletions(-) diff --git a/src/emucore/Cart0840.cxx b/src/emucore/Cart0840.cxx index f10dbb7b2..e071f61a2 100644 --- a/src/emucore/Cart0840.cxx +++ b/src/emucore/Cart0840.cxx @@ -21,25 +21,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge0840::Cartridge0840(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge0840::reset() -{ - // Upon reset we switch to the startup bank - initializeStartBank(0); - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge0840::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); // Get the page accessing methods for the hot spots since they overlap // areas within the TIA we'll need to forward requests to the TIA @@ -56,32 +45,34 @@ void Cartridge0840::install(System& system) System::PageAccess access(this, System::PageAccessType::READ); for(uInt16 addr = 0x0800; addr < 0x0FFF; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); +} - // Install pages for bank 0 - bank(startBank()); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Cartridge0840::checkSwitchBank(uInt16 address, uInt8) +{ + // Switch banks if necessary + switch(address & 0x1840) + { + case 0x0800: + // Set the current bank to the lower 4k bank + bank(0); + return true; + + case 0x0840: + // Set the current bank to the upper 4k bank + bank(1); + return true; + + default: + break; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 Cartridge0840::peek(uInt16 address) { - address &= 0x1840; - - // Switch banks if necessary - switch(address) - { - case 0x0800: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0840: - // Set the current bank to the upper 4k bank - bank(1); - break; - - default: - break; - } + checkSwitchBank(address); // Because of the way we've set up accessing above, we can only // get here when the addresses are from 0x800 - 0xFFF @@ -92,24 +83,7 @@ uInt8 Cartridge0840::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge0840::poke(uInt16 address, uInt8 value) { - address &= 0x1840; - - // Switch banks if necessary - switch(address) - { - case 0x0800: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0840: - // Set the current bank to the upper 4k bank - bank(1); - break; - - default: - break; - } + checkSwitchBank(address); // Because of the way accessing is set up, we will may get here by // doing a write to 0x800 - 0xFFF or cart; we ignore the cart write @@ -121,85 +95,3 @@ bool Cartridge0840::poke(uInt16 address, uInt8 value) return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge0840::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge0840::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge0840::bankCount() const -{ - return 2; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge0840::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0fff)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge0840::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge0840::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - } - catch(...) - { - cerr << "ERROR: Cartridge0840::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge0840::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - } - catch(...) - { - cerr << "ERROR: Cartridge0840::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset); - - return true; -} diff --git a/src/emucore/Cart0840.hxx b/src/emucore/Cart0840.hxx index 87d372f59..af1977485 100644 --- a/src/emucore/Cart0840.hxx +++ b/src/emucore/Cart0840.hxx @@ -19,7 +19,7 @@ #define CARTRIDGE0840_HXX #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #include "System.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart0840Widget.hxx" @@ -30,9 +30,9 @@ are two 4K banks, which are switched by accessing $0800 (bank 0) and $0840 (bank 1). - @author Fred X. Quimby + @author Fred X. Quimby, Thomas Jentzsch */ -class Cartridge0840 : public Cartridge +class Cartridge0840 : public CartridgeEnhanced { friend class Cartridge0840Widget; @@ -50,11 +50,6 @@ class Cartridge0840 : public Cartridge virtual ~Cartridge0840() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -63,58 +58,6 @@ class Cartridge0840 : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -152,12 +95,11 @@ class Cartridge0840 : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: - // The 8K ROM image of the cartridge - std::array myImage; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + uInt16 hotspot() const override { return 0x0840; } + private: // Previous Device's page access std::array myHotSpotPageAccess; diff --git a/src/emucore/CartBF.hxx b/src/emucore/CartBF.hxx index 08b54d731..23c51f760 100644 --- a/src/emucore/CartBF.hxx +++ b/src/emucore/CartBF.hxx @@ -73,7 +73,7 @@ class CartridgeBF : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1F80; } + uInt16 hotspot() const override { return 0x1F80; } uInt16 getStartBank() const override { return 1; } diff --git a/src/emucore/CartDF.hxx b/src/emucore/CartDF.hxx index 5b2025285..3c33e8bff 100644 --- a/src/emucore/CartDF.hxx +++ b/src/emucore/CartDF.hxx @@ -73,7 +73,7 @@ class CartridgeDF : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FC0; } + uInt16 hotspot() const override { return 0x1FC0; } uInt16 getStartBank() const override { return 15; } diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 08fc82806..7c1fe18e3 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -86,7 +86,7 @@ class CartridgeE0 : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 = 0) override; - uInt16 romHotspot() const override { return 0x1FE0; } + uInt16 hotspot() const override { return 0x1FE0; } private: // log(ROM bank segment size) / log(2) diff --git a/src/emucore/CartEF.hxx b/src/emucore/CartEF.hxx index 1461e954d..ff71b9909 100644 --- a/src/emucore/CartEF.hxx +++ b/src/emucore/CartEF.hxx @@ -73,7 +73,7 @@ class CartridgeEF : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FE0; } + uInt16 hotspot() const override { return 0x1FE0; } uInt16 getStartBank() const override { return 1; } diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index adcd8bc0e..a29cdcb6f 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -102,7 +102,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - if (romHotspot()) + if (hotspot()) checkSwitchBank(address & 0x0FFF); address &= myBankMask; @@ -146,13 +146,13 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) // Remember what bank is in which segment uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; uInt16 segmentOffset = segment << myBankShift; - uInt16 romHotspot = this->romHotspot(); + uInt16 hotspot = this->hotspot(); uInt16 hotSpotAddr; uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK; uInt16 toAddr = (segmentOffset + 0x1000 + myBankSize) & ~System::PAGE_MASK; - if(romHotspot) - hotSpotAddr = (romHotspot & ~System::PAGE_MASK); + if(hotspot) + hotSpotAddr = (hotspot & ~System::PAGE_MASK); else hotSpotAddr = 0xFFFF; // none diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 703cd320f..a78b725e7 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -203,9 +203,9 @@ class CartridgeEnhanced : public Cartridge /** Get the hotspot in ROM address space. - @return The first hotspot address in ROM space or 0 + @return The first hotspot address (ususally in ROM) space or 0 */ - virtual uInt16 romHotspot() const { return 0; } + virtual uInt16 hotspot() const { return 0; } // TODO: handle cases where there the hotspots cover multiple pages private: diff --git a/src/emucore/CartF0.hxx b/src/emucore/CartF0.hxx index e885cd934..0d5837066 100644 --- a/src/emucore/CartF0.hxx +++ b/src/emucore/CartF0.hxx @@ -70,7 +70,7 @@ class CartridgeF0 : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FF0; } + uInt16 hotspot() const override { return 0x1FF0; } uInt16 getStartBank() const override { return 15; } diff --git a/src/emucore/CartF4.hxx b/src/emucore/CartF4.hxx index 5b54af54d..d44e96640 100644 --- a/src/emucore/CartF4.hxx +++ b/src/emucore/CartF4.hxx @@ -69,7 +69,7 @@ class CartridgeF4 : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FF4; } + uInt16 hotspot() const override { return 0x1FF4; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF6.hxx b/src/emucore/CartF6.hxx index 2f183ad7b..16faeebab 100644 --- a/src/emucore/CartF6.hxx +++ b/src/emucore/CartF6.hxx @@ -69,7 +69,7 @@ class CartridgeF6 : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FF6; } + uInt16 hotspot() const override { return 0x1FF6; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartF8.hxx b/src/emucore/CartF8.hxx index 23863fa57..29b308808 100644 --- a/src/emucore/CartF8.hxx +++ b/src/emucore/CartF8.hxx @@ -69,7 +69,7 @@ class CartridgeF8 : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FF8; } + uInt16 hotspot() const override { return 0x1FF8; } uInt16 getStartBank() const override { return 1; } From f2c464a71faca8bd48c8cf0facc9a2bc87b674aa Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 4 Apr 2020 23:05:09 +0200 Subject: [PATCH 07/52] one missing file --- src/emucore/CartFC.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/CartFC.hxx b/src/emucore/CartFC.hxx index b08f2085c..5858ae85a 100644 --- a/src/emucore/CartFC.hxx +++ b/src/emucore/CartFC.hxx @@ -90,7 +90,7 @@ class CartridgeFC : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 romHotspot() const override { return 0x1FF8; } + uInt16 hotspot() const override { return 0x1FF8; } // Target bank defined by writing to $1FF8/9 uInt16 myTargetBank{0}; From db522623751f400227074e0399fb5504a99953ca Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 6 Apr 2020 09:21:32 +0200 Subject: [PATCH 08/52] refactor CartMDM make sure the banks are updated when stepping back --- src/debugger/gui/CartMDMWidget.cxx | 5 +- src/emucore/CartEnhanced.cxx | 4 ++ src/emucore/CartMDM.cxx | 90 +++++++----------------------- src/emucore/CartMDM.hxx | 50 ++--------------- 4 files changed, 31 insertions(+), 118 deletions(-) diff --git a/src/debugger/gui/CartMDMWidget.cxx b/src/debugger/gui/CartMDMWidget.cxx index 7b0f799e4..2ba603168 100644 --- a/src/debugger/gui/CartMDMWidget.cxx +++ b/src/debugger/gui/CartMDMWidget.cxx @@ -27,9 +27,10 @@ CartridgeMDMWidget::CartridgeMDMWidget( : CartDebugWidget(boss, lfont, nfont, x, y, w, h), myCart(cart) { - size_t size = myCart.mySize; - ostringstream info; + size_t size; + + myCart.getImage(size); info << "Menu Driven Megacart, containing up to 128 4K banks\n" << "Startup bank = " << cart.startBank() << "\n" << "\nBanks are selected by reading from $800 - $BFF, where the lower " diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index a29cdcb6f..4cbf61eca 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -250,5 +250,9 @@ bool CartridgeEnhanced::load(Serializer& in) cerr << "ERROR: " << name() << "::load" << endl; return false; } + // Restore bank sewgments + for(uInt16 i = 0; i < myBankSegs; ++i) + bank(getSegmentBank(i), i); + return true; } diff --git a/src/emucore/CartMDM.cxx b/src/emucore/CartMDM.cxx index 4c69f7c7c..decb634ec 100644 --- a/src/emucore/CartMDM.cxx +++ b/src/emucore/CartMDM.cxx @@ -21,30 +21,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeMDM::CartridgeMDM(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeEnhanced(image, size, md5, settings) { - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeMDM::reset() -{ - initializeStartBank(0); - - // Upon reset we switch to the startup bank - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeMDM::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); // Get the page accessing methods for the hot spots since they overlap // areas within the TIA we'll need to forward requests to the TIA @@ -61,9 +45,18 @@ void CartridgeMDM::install(System& system) System::PageAccess access(this, System::PageAccessType::READWRITE); for(uInt16 addr = 0x0800; addr < 0x0BFF; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); +} - // Install pages for bank 0 - bank(startBank()); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeMDM::checkSwitchBank(uInt16 address, uInt8) +{ + // Switch banks if necessary + if((address & 0x1C00) == 0x0800) + { + bank(address & 0x0FF); + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -71,8 +64,8 @@ uInt8 CartridgeMDM::peek(uInt16 address) { // Because of the way we've set up accessing above, we can only // get here when the addresses are from 0x800 - 0xBFF - if((address & 0x1C00) == 0x0800) - bank(address & 0x0FF); + + checkSwitchBank(address); int hotspot = ((address & 0x0F00) >> 8) - 8; return myHotSpotPageAccess[hotspot].device->peek(address); @@ -85,8 +78,7 @@ bool CartridgeMDM::poke(uInt16 address, uInt8 value) // about those below $1000 if(!(address & 0x1000)) { - if((address & 0x1C00) == 0x0800) - bank(address & 0x0FF); + checkSwitchBank(address); int hotspot = ((address & 0x0F00) >> 8) - 8; myHotSpotPageAccess[hotspot].device->poke(address, value); @@ -100,22 +92,7 @@ bool CartridgeMDM::bank(uInt16 bank) { if(bankLocked() || myBankingDisabled) return false; - // Remember what bank we're in - // Wrap around to a valid bank number if necessary - myBankOffset = (bank % bankCount()) << 12; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } + CartridgeEnhanced::bank(bank); // Accesses above bank 127 disable further bankswitching; we're only // concerned with the lower byte @@ -123,38 +100,12 @@ bool CartridgeMDM::bank(uInt16 bank) return myBankChanged = true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeMDM::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeMDM::bankCount() const -{ - return uInt16(mySize >> 12); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMDM::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeMDM::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeMDM::save(Serializer& out) const { + CartridgeEnhanced::save(out); try { - out.putInt(myBankOffset); out.putBool(myBankingDisabled); } catch(...) @@ -169,9 +120,9 @@ bool CartridgeMDM::save(Serializer& out) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeMDM::load(Serializer& in) { + CartridgeEnhanced::load(in); try { - myBankOffset = in.getInt(); myBankingDisabled = in.getBool(); } catch(...) @@ -180,8 +131,5 @@ bool CartridgeMDM::load(Serializer& in) return false; } - // Remember what bank we were in - bank(myBankOffset >> 12); - return true; } diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index 1c2a34cb6..6fd7435a3 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -19,7 +19,7 @@ #define CARTRIDGEMDM_HXX #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #include "System.hxx" #ifdef DEBUGGER_SUPPORT #include "CartMDMWidget.hxx" @@ -42,9 +42,9 @@ Therefore, there are 128 banks / 512K possible in total. - @author Stephen Anthony, based on 0840 scheme by Fred X. Quimby + @author Stephen Anthony, Thomas Jentzsch, based on 0840 scheme by Fred X. Quimby */ -class CartridgeMDM : public Cartridge +class CartridgeMDM : public CartridgeEnhanced { friend class CartridgeMDMWidget; @@ -62,11 +62,6 @@ class CartridgeMDM : public Cartridge virtual ~CartridgeMDM() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -82,35 +77,6 @@ class CartridgeMDM : public Cartridge */ bool bank(uInt16 bank) override; - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - /** Save the current state of this cart to the given Serializer. @@ -164,18 +130,12 @@ class CartridgeMDM : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: - // Pointer to a dynamically allocated ROM image of the cartridge - ByteBuffer myImage; - - // Size of the ROM image - size_t mySize{0}; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + private: // Previous Device's page access std::array myHotSpotPageAccess; - // Indicates the offset into the ROM image (aligns to current bank) - uInt32 myBankOffset{0}; - // Indicates whether banking has been disabled due to a bankswitch // above bank 127 bool myBankingDisabled{false}; From 4b89f335d0c924e6c54b9406f70c8e541b51e60f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 6 Apr 2020 09:42:13 +0200 Subject: [PATCH 09/52] refactor CartSB --- src/debugger/gui/CartSBWidget.cxx | 5 +- src/emucore/CartSB.cxx | 132 +++++------------------------- src/emucore/CartSB.hxx | 73 ++--------------- 3 files changed, 30 insertions(+), 180 deletions(-) diff --git a/src/debugger/gui/CartSBWidget.cxx b/src/debugger/gui/CartSBWidget.cxx index a7bf7e5b2..78d352879 100644 --- a/src/debugger/gui/CartSBWidget.cxx +++ b/src/debugger/gui/CartSBWidget.cxx @@ -26,10 +26,11 @@ CartridgeSBWidget::CartridgeSBWidget( : CartDebugWidget(boss, lfont, nfont, x, y, w, h), myCart(cart) { - size_t size = myCart.mySize; - VariantList items; ostringstream info, bank; + size_t size; + + myCart.getImage(size); info << "SB SUPERbanking, 32 or 64 4K banks\n" << "Hotspots are from $800 to $" << Common::Base::HEX2 << (0x800 + myCart.bankCount() - 1) << ", including\n" diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 44ff9381f..58dd94522 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -21,30 +21,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeSB::CartridgeSB(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeEnhanced(image, size, md5, settings) { - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeSB::reset() -{ - initializeStartBank(bankCount() - 1); - - // Upon reset we switch to the startup bank - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeSB::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); // Get the page accessing methods for the hot spots since they overlap // areas within the TIA we'll need to forward requests to the TIA @@ -62,19 +46,27 @@ void CartridgeSB::install(System& system) // Set the page accessing methods for the hot spots for(uInt16 addr = 0x0800; addr < 0x0FFF; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); - - // Install pages for startup bank - bank(startBank()); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeSB::checkSwitchBank(uInt16 address, uInt8) +{ + // Switch banks if necessary + if((address & 0x1800) == 0x0800) + { + bank(address & startBank()); + return true; + } + return false; +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeSB::peek(uInt16 address) { - address &= (0x17FF + (mySize >> 12)); + address &= (0x17FF + bankCount()); - // Switch banks if necessary - if ((address & 0x1800) == 0x0800) - bank(address & startBank()); + checkSwitchBank(address); if(!(address & 0x1000)) { @@ -90,11 +82,9 @@ uInt8 CartridgeSB::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeSB::poke(uInt16 address, uInt8 value) { - address &= (0x17FF + (mySize >> 12)); + address &= (0x17FF + bankCount()); - // Switch banks if necessary - if((address & 0x1800) == 0x0800) - bank(address & startBank()); + checkSwitchBank(address); if(!(address & 0x1000)) { @@ -105,87 +95,3 @@ bool CartridgeSB::poke(uInt16 address, uInt8 value) } return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeSB::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeSB::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeSB::bankCount() const -{ - return uInt16(mySize >> 12); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeSB::patch(uInt16 address, uInt8 value) -{ - myImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeSB::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeSB::save(Serializer& out) const -{ - try - { - out.putInt(myBankOffset); - } - catch(...) - { - cerr << "ERROR: CartridgeSB::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeSB::load(Serializer& in) -{ - try - { - myBankOffset = in.getInt(); - } - catch(...) - { - cerr << "ERROR: CartridgeSB::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; -} diff --git a/src/emucore/CartSB.hxx b/src/emucore/CartSB.hxx index fe8f8b75d..3682dbb04 100644 --- a/src/emucore/CartSB.hxx +++ b/src/emucore/CartSB.hxx @@ -19,7 +19,7 @@ #define CARTRIDGESB_HXX #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #include "System.hxx" #ifdef DEBUGGER_SUPPORT #include "CartSBWidget.hxx" @@ -31,9 +31,9 @@ (32 banks) and $800 - $83F (64 banks). All mirrors up to $FFF are also used ($900, $A00, ...). - @author Fred X. Quimby + @author Fred X. Quimby, Thomas Jentzsch */ -class CartridgeSB : public Cartridge +class CartridgeSB : public CartridgeEnhanced { friend class CartridgeSBWidget; @@ -51,11 +51,6 @@ class CartridgeSB : public Cartridge virtual ~CartridgeSB() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -64,58 +59,6 @@ class CartridgeSB : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -153,13 +96,13 @@ class CartridgeSB : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: - // The 128-256K ROM image and size of the cartridge - ByteBuffer myImage; - size_t mySize{0}; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - // Indicates the offset into the ROM image (aligns to current bank) - uInt32 myBankOffset{0}; + uInt16 hotspot() const override { return 0x0840; } + uInt16 getStartBank() const override { return bankCount() - 1; } + + private: // Previous Device's page access std::array myHotSpotPageAccess; From fdabb6fe1cbb5bed1d9a6cf9da65d11e2c3ee0a9 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 7 Apr 2020 08:24:06 +0200 Subject: [PATCH 10/52] refactor Cart2K and Cart4K(SC) --- src/debugger/gui/Cart2KWidget.cxx | 5 +- src/emucore/Cart2K.cxx | 68 +++------------ src/emucore/Cart2K.hxx | 68 +-------------- src/emucore/Cart4K.cxx | 45 +--------- src/emucore/Cart4K.hxx | 62 +------------- src/emucore/Cart4KSC.cxx | 134 +----------------------------- src/emucore/Cart4KSC.hxx | 76 ++--------------- src/emucore/CartEnhanced.cxx | 15 ++-- src/emucore/CartEnhanced.hxx | 6 +- 9 files changed, 44 insertions(+), 435 deletions(-) diff --git a/src/debugger/gui/Cart2KWidget.cxx b/src/debugger/gui/Cart2KWidget.cxx index e90ed67f2..745c52316 100644 --- a/src/debugger/gui/Cart2KWidget.cxx +++ b/src/debugger/gui/Cart2KWidget.cxx @@ -25,7 +25,10 @@ Cartridge2KWidget::Cartridge2KWidget( : CartDebugWidget(boss, lfont, nfont, x, y, w, h) { // Eventually, we should query this from the debugger/disassembler - size_t size = cart.mySize; + size_t size; + + cart.getImage(size); + uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; start -= start % size; diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index ee9f2b334..24a328736 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -21,15 +21,19 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { // Size can be a maximum of 2K - if(size > 2_KB) size = 2_KB; + if(size > 2_KB) + size = 2_KB; // Set image size to closest power-of-two for the given size - mySize = 1; + mySize = 1; myBankShift = 0; while(mySize < size) + { mySize <<= 1; + myBankShift++; + } // Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam size_t bufSize = std::max(mySize, System::PAGE_SIZE); @@ -49,62 +53,12 @@ Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, for(size_t i = 0; i < System::PAGE_SIZE; i += mySize) std::copy_n(image.get(), mySize, myImage.get() + i); mySize = System::PAGE_SIZE; + myBankShift = 6; } + // update access arrays, bank size and mask based on new size createRomAccessArrays(mySize); - // Set mask for accessing the image buffer - // This is guaranteed to work, as mySize is a power of two - myMask = static_cast(mySize) - 1; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge2K::reset() -{ - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge2K::install(System& system) -{ - mySystem = &system; - - // Map ROM image into the system - // Note that we don't need our own peek/poke methods, since the mapping - // takes care of the entire address space - System::PageAccess access(this, System::PageAccessType::READ); - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[addr & myMask]; - access.romAccessBase = &myRomAccessBase[addr & myMask]; - access.romPeekCounter = &myRomAccessCounter[addr & myMask]; - access.romPokeCounter = &myRomAccessCounter[(addr & myMask) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge2K::patch(uInt16 address, uInt8 value) -{ - myImage[address & myMask] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge2K::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge2K::save(Serializer&) const -{ - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge2K::load(Serializer&) -{ - return true; + myBankSize = 1 << myBankShift; // e.g. = 2 ^ 11 = 2048 = 0x0800 + myBankMask = myBankSize - 1; // e.g. = 0x07FF } diff --git a/src/emucore/Cart2K.hxx b/src/emucore/Cart2K.hxx index 22f08fbf5..1ef2ee250 100644 --- a/src/emucore/Cart2K.hxx +++ b/src/emucore/Cart2K.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart2KWidget.hxx" #endif @@ -33,9 +33,9 @@ class System; data repeats in intervals based on the size of the ROM (which will always be a power of 2). - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ -class Cartridge2K : public Cartridge +class Cartridge2K : public CartridgeEnhanced { friend class Cartridge2KWidget; @@ -53,52 +53,6 @@ class Cartridge2K : public Cartridge virtual ~Cartridge2K() = default; public: - /** - Reset cartridge to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -118,22 +72,8 @@ class Cartridge2K : public Cartridge } #endif - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override { return myImage[address & myMask]; } - private: - // Pointer to a dynamically allocated ROM image of the cartridge - ByteBuffer myImage; - - // Size of the ROM image - size_t mySize{0}; - - // Mask to use for mirroring - uInt16 myMask{0}; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; }; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Cart4K.cxx b/src/emucore/Cart4K.cxx index 4f4aab979..d26ccfec0 100644 --- a/src/emucore/Cart4K.cxx +++ b/src/emucore/Cart4K.cxx @@ -21,48 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4K::Cartridge4K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge4K::reset() -{ - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge4K::install(System& system) -{ - mySystem = &system; - - // Map ROM image into the system - // Note that we don't need our own peek/poke methods, since the mapping - // takes care of the entire address space - System::PageAccess access(this, System::PageAccessType::READ); - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[addr & 0x0FFF]; - access.romAccessBase = &myRomAccessBase[addr & 0x0FFF]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x0FFF]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge4K::patch(uInt16 address, uInt8 value) -{ - myImage[address & 0x0FFF] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge4K::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); + cerr << "Cartridge4K" << endl; } diff --git a/src/emucore/Cart4K.hxx b/src/emucore/Cart4K.hxx index 2b42516f5..70819c5b2 100644 --- a/src/emucore/Cart4K.hxx +++ b/src/emucore/Cart4K.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart4KWidget.hxx" #endif @@ -30,9 +30,9 @@ class System; This is the standard Atari 4K cartridge. These cartridges are not bankswitched. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class Cartridge4K : public Cartridge +class Cartridge4K : public CartridgeEnhanced { friend class Cartridge4KWidget; @@ -50,52 +50,6 @@ class Cartridge4K : public Cartridge virtual ~Cartridge4K() = default; public: - /** - Reset cartridge to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override { return true; } - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override { return true; } - /** Get a descriptor for the device name (used in error checking). @@ -115,16 +69,8 @@ class Cartridge4K : public Cartridge } #endif - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override { return myImage[address & 0x0FFF]; } - private: - // The 4K ROM image for the cartridge - std::array myImage; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; }; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Cart4KSC.cxx b/src/emucore/Cart4KSC.cxx index 09e043c94..92d2e946e 100644 --- a/src/emucore/Cart4KSC.cxx +++ b/src/emucore/Cart4KSC.cxx @@ -21,137 +21,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge4KSC::Cartridge4KSC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : Cartridge4K(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge4KSC::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - - myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge4KSC::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x007F]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1080; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x007F]; - access.romAccessBase = &myRomAccessBase[0x80 + (addr & 0x007F)]; - mySystem->setPageAccess(addr, access); - } - - // Map ROM image into the system - for(uInt16 addr = 0x1100; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[addr & 0x0FFF]; - access.romAccessBase = &myRomAccessBase[addr & 0x0FFF]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge4KSC::peek(uInt16 address) -{ - // The only way we can get to this method is if we attempt to read from - // the write port (0xF000 - 0xF07F, 128 bytes), in which case an - // unwanted write is potentially triggered - return peekRAM(myRAM[address & 0x007F], address); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge4KSC::poke(uInt16 address, uInt8 value) -{ - if (!(address & 0x080)) - { - pokeRAM(myRAM[address & 0x007F], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge4KSC::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0100) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x007F] = value; - } - else - myImage[address & 0xFFF] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge4KSC::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge4KSC::save(Serializer& out) const -{ - try - { - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: Cartridge4KSC::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge4KSC::load(Serializer& in) -{ - try - { - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: Cartridge4KSC::load" << endl; - return false; - } - - return true; + myRamSize = RAM_SIZE; } diff --git a/src/emucore/Cart4KSC.hxx b/src/emucore/Cart4KSC.hxx index 4d596f47a..64dde3c39 100644 --- a/src/emucore/Cart4KSC.hxx +++ b/src/emucore/Cart4KSC.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "Cart4K.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart4KSCWidget.hxx" #endif @@ -29,9 +29,11 @@ class System; /** Cartridge class used for 4K games with 128 bytes of RAM. RAM read port is $1080 - $10FF, write port is $1000 - $107F. + + @author Stephen Anthony, Thomas Jentzsch */ -class Cartridge4KSC : public Cartridge +class Cartridge4KSC : public Cartridge4K { friend class Cartridge4KSCWidget; @@ -49,52 +51,6 @@ class Cartridge4KSC : public Cartridge virtual ~Cartridge4KSC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -114,29 +70,9 @@ class Cartridge4KSC : public Cartridge } #endif - public: - /** - Get the byte at the specified address. - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - private: - // The 4K ROM image of the cartridge - std::array myImage; - - // The 128 bytes of RAM - std::array myRAM; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 4cbf61eca..8efab740a 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -24,19 +24,19 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, : Cartridge(settings, md5), mySize(size) { - // Allocate array for the ROM image - myImage = make_unique(mySize); + // Allocate array for the ROM image (at least 64 bytzes) + myImage = make_unique(std::max(uInt16(mySize), System::PAGE_SIZE)); // Copy the ROM image into my buffer std::copy_n(image.get(), mySize, myImage.get()); - - // Copy the ROM image into my buffer - createRomAccessArrays(mySize); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeEnhanced::install(System& system) { + // Copy the ROM image into my buffer + createRomAccessArrays(mySize); + // calculate bank switching and RAM sizes and masks myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 myBankMask = myBankSize - 1; // e.g. = 0x0FFF @@ -81,7 +81,7 @@ void CartridgeEnhanced::install(System& system) // Install pages for the startup bank (TODO: currently only in first bank segment) bank(startBank(), 0); - if(myBankSegs > 1) + if(mySize >= 4_KB && myBankSegs > 1) // Setup the last bank segment to always point to the last ROM segment bank(bankCount() - 1, myBankSegs - 1); } @@ -149,7 +149,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt16 hotspot = this->hotspot(); uInt16 hotSpotAddr; uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK; - uInt16 toAddr = (segmentOffset + 0x1000 + myBankSize) & ~System::PAGE_MASK; + // for ROMs < 4_KB, the whole address space will be mapped. + uInt16 toAddr = (segmentOffset + 0x1000 + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; if(hotspot) hotSpotAddr = (hotspot & ~System::PAGE_MASK); diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index a78b725e7..6437c362e 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -172,6 +172,9 @@ class CartridgeEnhanced : public Cartridge // Pointer to a dynamically allocated RAM area of the cartridge ByteBuffer myRAM{nullptr}; + // The size of the ROM image + size_t mySize{0}; + private: // Calculated as: log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 12; // default = 4K @@ -179,9 +182,6 @@ class CartridgeEnhanced : public Cartridge // The size of extra RAM in ROM address space static constexpr uInt16 RAM_SIZE = 0; // default = none - // The size of the ROM image - size_t mySize{0}; - protected: /** Check hotspots and switch bank if triggered. From a1ded47af3cf842c2271d534394f4fb1e3bcf5aa Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 8 Apr 2020 22:02:01 +0200 Subject: [PATCH 11/52] fix carts >= 64K --- src/emucore/CartEnhanced.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 8efab740a..6752d3153 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -25,7 +25,7 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, mySize(size) { // Allocate array for the ROM image (at least 64 bytzes) - myImage = make_unique(std::max(uInt16(mySize), System::PAGE_SIZE)); + myImage = make_unique(std::max(uInt32(mySize), uInt32(System::PAGE_SIZE))); // Copy the ROM image into my buffer std::copy_n(image.get(), mySize, myImage.get()); @@ -251,7 +251,7 @@ bool CartridgeEnhanced::load(Serializer& in) cerr << "ERROR: " << name() << "::load" << endl; return false; } - // Restore bank sewgments + // Restore bank segments for(uInt16 i = 0; i < myBankSegs; ++i) bank(getSegmentBank(i), i); From 60cd8739b41f6c8d8e1e0bf14304b6bc11f5dfb6 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 9 Apr 2020 16:07:38 +0200 Subject: [PATCH 12/52] refactor CartX07 --- src/debugger/gui/CartX07Widget.cxx | 2 +- src/emucore/CartX07.cxx | 146 ++++++----------------------- src/emucore/CartX07.hxx | 69 +------------- 3 files changed, 33 insertions(+), 184 deletions(-) diff --git a/src/debugger/gui/CartX07Widget.cxx b/src/debugger/gui/CartX07Widget.cxx index 78fd70d3b..0c6bc5b95 100644 --- a/src/debugger/gui/CartX07Widget.cxx +++ b/src/debugger/gui/CartX07Widget.cxx @@ -103,7 +103,7 @@ string CartridgeX07Widget::bankState() { ostringstream& buf = buffer(); - buf << "Bank = " << std::dec << myCart.myCurrentBank; + buf << "Bank = " << std::dec << myCart.getBank(); return buf.str(); } diff --git a/src/emucore/CartX07.cxx b/src/emucore/CartX07.cxx index 96bf5e4ed..ac40b6ac6 100644 --- a/src/emucore/CartX07.cxx +++ b/src/emucore/CartX07.cxx @@ -23,25 +23,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeX07::CartridgeX07(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeX07::reset() -{ - // Upon reset we switch to the startup bank - initializeStartBank(0); - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeX07::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); // Set the page accessing methods for the hot spots // The hotspots use almost all addresses below 0x1000, so we simply grab them @@ -49,31 +38,42 @@ void CartridgeX07::install(System& system) System::PageAccess access(this, System::PageAccessType::READWRITE); for(uInt16 addr = 0x00; addr < 0x1000; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); +} - // Install pages for the startup bank - bank(startBank()); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeX07::checkSwitchBank(uInt16 address, uInt8) +{ + // Switch banks if necessary + if((address & 0x180f) == 0x080d) + { + bank((address & 0xf0) >> 4); + return true; + } + else if((address & 0x1880) == 0) + { + if((getBank() & 0xe) == 0xe) + { + bank(((address & 0x40) >> 6) | 0xe); + return true; + } + } + + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeX07::peek(uInt16 address) { - uInt8 value = 0; - + uInt8 value = 0; // JTZ: is this correct? // Check for RAM or TIA mirroring uInt16 lowAddress = address & 0x3ff; + if(lowAddress & 0x80) value = mySystem->m6532().peek(address); else if(!(lowAddress & 0x200)) value = mySystem->tia().peek(address); - // Switch banks if necessary - if((address & 0x180f) == 0x080d) - bank((address & 0xf0) >> 4); - else if((address & 0x1880) == 0) - { - if((myCurrentBank & 0xe) == 0xe) - bank(((address & 0x40) >> 6) | (myCurrentBank & 0xe)); - } + checkSwitchBank(address); return value; } @@ -83,103 +83,13 @@ bool CartridgeX07::poke(uInt16 address, uInt8 value) { // Check for RAM or TIA mirroring uInt16 lowAddress = address & 0x3ff; + if(lowAddress & 0x80) mySystem->m6532().poke(address, value); else if(!(lowAddress & 0x200)) mySystem->tia().poke(address, value); - // Switch banks if necessary - if((address & 0x180f) == 0x080d) - bank((address & 0xf0) >> 4); - else if((address & 0x1880) == 0) - { - if((myCurrentBank & 0xe) == 0xe) - bank(((address & 0x40) >> 6) | (myCurrentBank & 0xe)); - } + checkSwitchBank(address); + return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeX07::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myCurrentBank = (bank & 0x0f); - uInt32 offset = myCurrentBank << 12; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeX07::getBank(uInt16) const -{ - return myCurrentBank; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeX07::bankCount() const -{ - return 16; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeX07::patch(uInt16 address, uInt8 value) -{ - myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value; - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeX07::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeX07::save(Serializer& out) const -{ - try - { - out.putShort(myCurrentBank); - } - catch(...) - { - cerr << "ERROR: CartridgeX07::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeX07::load(Serializer& in) -{ - try - { - myCurrentBank = in.getShort(); - } - catch(...) - { - cerr << "ERROR: CartridgeX07::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myCurrentBank); - - return true; -} diff --git a/src/emucore/CartX07.hxx b/src/emucore/CartX07.hxx index 0beff0e0b..3cde4efdf 100644 --- a/src/emucore/CartX07.hxx +++ b/src/emucore/CartX07.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartX07Widget.hxx" #endif @@ -40,9 +40,9 @@ class System; Note that the latter will hit on almost any TIA access. - @author Eckhard Stolberg + @author Eckhard Stolberg, Thomas Jentzsch */ -class CartridgeX07 : public Cartridge +class CartridgeX07 : public CartridgeEnhanced { friend class CartridgeX07Widget; @@ -60,11 +60,6 @@ class CartridgeX07 : public Cartridge virtual ~CartridgeX07() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -73,58 +68,6 @@ class CartridgeX07 : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -162,11 +105,7 @@ class CartridgeX07 : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: - // The 64K ROM image of the cartridge - std::array myImage; - - // Indicates which bank is currently active - uInt16 myCurrentBank{0}; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; private: // Following constructors and assignment operators not supported From ebc097a01618470dcaa86dca04c11c9fa3029bee Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 11 Apr 2020 14:12:27 +0200 Subject: [PATCH 13/52] refactor CartFA(2).cxx --- src/emucore/CartFA.cxx | 228 +---------------------------- src/emucore/CartFA.hxx | 99 ++----------- src/emucore/CartFA2.cxx | 309 +++++----------------------------------- src/emucore/CartFA2.hxx | 89 ++---------- 4 files changed, 58 insertions(+), 667 deletions(-) diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index 5a4ecb6bd..3f1062f41 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -21,235 +21,19 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA::CartridgeFA(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeEnhanced(image, size, md5, settings) { - // Copy the ROM image into my buffer - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(myImage.size()); + myRamSize = RAM_SIZE; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(2); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[addr & 0x00FF]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x00FF]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1100; addr < 0x1200; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x00FF]; - access.romAccessBase = &myRomAccessBase[0x100 + (addr & 0x00FF)]; - access.romPeekCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF)]; - access.romPokeCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeFA::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary - switch(address) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0FF9: - // Set the current bank to the middle 4k bank - bank(1); - break; - - case 0x0FFA: - // Set the current bank to the upper 4k bank - bank(2); - break; - - default: - break; - } - - if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::poke(uInt16 address, uInt8 value) +bool CartridgeFA::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary - switch(address & 0x0FFF) + if((address >= 0x0FF8) && (address <= 0x0FFA)) { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - return false; - - case 0x0FF9: - // Set the current bank to the middle 4k bank - bank(1); - return false; - - case 0x0FFA: - // Set the current bank to the upper 4k bank - bank(2); - return false; - - default: - break; - } - - if (!(address & 0x100)) - { - pokeRAM(myRAM[address & 0x00FF], address, value); + bank(address - 0x0FF8); return true; } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF8 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1200; addr < static_cast(0x1FF8U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA::bankCount() const -{ - return 3; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0200) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x00FF] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeFA::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + return false; } diff --git a/src/emucore/CartFA.hxx b/src/emucore/CartFA.hxx index 9729a366f..920f2bdec 100644 --- a/src/emucore/CartFA.hxx +++ b/src/emucore/CartFA.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartFAWidget.hxx" #endif @@ -31,9 +31,9 @@ class System; banks, accessible by read/write at $1FF8 - $1FFA, and 256 bytes of RAM. RAM read port is $1100 - $11FF, write port is $1000 - $10FF. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeFA : public Cartridge +class CartridgeFA : public CartridgeEnhanced { friend class CartridgeFAWidget; @@ -51,71 +51,6 @@ class CartridgeFA : public Cartridge virtual ~CartridgeFA() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -135,32 +70,16 @@ class CartridgeFA : public Cartridge } #endif - public: - /** - Get the byte at the specified address. + private: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; + uInt16 hotspot() const override { return 0x1FF8; } - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + uInt16 getStartBank() const override { return 2; } private: - // The 12K ROM image of the cartridge - std::array myImage; - - // The 256 bytes of RAM on the cartridge - std::array myRAM; - - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x100; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 1630f216e..0d892c9b3 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -15,308 +15,67 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "OSystem.hxx" -#include "Serializer.hxx" -#include "System.hxx" #include "TimerManager.hxx" #include "CartFA2.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA2::CartridgeFA2(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5) + : CartridgeFA(image, size, md5, settings) { // 29/32K version of FA2 has valid data @ 1K - 29K const uInt8* img_ptr = image.get(); if(size >= 29_KB) + { img_ptr += 1_KB; - else if(size < mySize) - mySize = size; + mySize = 28_KB; + } + + // Allocate array for the ROM image + myImage = make_unique(mySize); // Copy the ROM image into my buffer - std::copy_n(img_ptr, mySize, myImage.begin()); - createRomAccessArrays(mySize); + std::copy_n(image.get(), mySize, myImage.get()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2::reset() +bool CartridgeFA2::checkSwitchBank(uInt16 address, uInt8) { - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); - - // Upon reset we switch to the startup bank - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1100; addr += System::PAGE_SIZE) + // Switch banks if necessary + if((address >= 0x0FF5) && (address <= 0x0FFB)) { - access.romAccessBase = &myRomAccessBase[addr & 0x00FF]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x00FF]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); + bank(address - 0x0FF5); + return true; } - - // Set the page accessing method for the RAM reading pages - access.directPokeBase = nullptr; - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1100; addr < 0x1200; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x00FF]; - access.romAccessBase = &myRomAccessBase[0x100 + (addr & 0x00FF)]; - access.romPeekCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF)]; - access.romPokeCounter = &myRomAccessCounter[0x100 + (addr & 0x00FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank - bank(startBank()); + return false; } - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeFA2::peek(uInt16 address) { - uInt16 peekAddress = address; - address &= 0x0FFF; - // Switch banks if necessary - switch(address) + if((address & 0x0FFF) == 0x0FF4) { - case 0x0FF4: - // Load/save RAM to/from Harmony cart flash - if(mySize == 28_KB && !bankLocked()) - return ramReadWrite(); - break; - - case 0x0FF5: - // Set the current bank to the first 4k bank - bank(0); - break; - - case 0x0FF6: - // Set the current bank to the second 4k bank - bank(1); - break; - - case 0x0FF7: - // Set the current bank to the third 4k bank - bank(2); - break; - - case 0x0FF8: - // Set the current bank to the fourth 4k bank - bank(3); - break; - - case 0x0FF9: - // Set the current bank to the fifth 4k bank - bank(4); - break; - - case 0x0FFA: - // Set the current bank to the sixth 4k bank - bank(5); - break; - - case 0x0FFB: - // Set the current bank to the seventh 4k bank - // This is only available on 28K ROMs - if(mySize == 28_KB) bank(6); - break; - - default: - break; + // Load/save RAM to/from Harmony cart flash + if(mySize == 28_KB && !bankLocked()) + return ramReadWrite(); } - if(address < 0x0100) // Write port is at 0xF000 - 0xF0FF (256 bytes) - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myBankOffset + address]; + return CartridgeEnhanced::peek(address); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFA2::poke(uInt16 address, uInt8 value) { - // Switch banks if necessary - switch(address & 0x0FFF) + if((address & 0x0FFF) == 0x0FF4) { - case 0x0FF4: - // Load/save RAM to/from Harmony cart flash - if(mySize == 28_KB && !bankLocked()) - ramReadWrite(); - return false; - - case 0x0FF5: - // Set the current bank to the first 4k bank - bank(0); - return false; - - case 0x0FF6: - // Set the current bank to the second 4k bank - bank(1); - return false; - - case 0x0FF7: - // Set the current bank to the third 4k bank - bank(2); - return false; - - case 0x0FF8: - // Set the current bank to the fourth 4k bank - bank(3); - return false; - - case 0x0FF9: - // Set the current bank to the fifth 4k bank - bank(4); - return false; - - case 0x0FFA: - // Set the current bank to the sixth 4k bank - bank(5); - return false; - - case 0x0FFB: - // Set the current bank to the seventh 4k bank - // This is only available on 28K ROMs - if(mySize == 28_KB) bank(6); - return false; - - default: - break; - } - - if(!(address & 0x100)) - { - pokeRAM(myRAM[address & 0x00FF], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF4 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1200; addr < static_cast(0x1FF4U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA2::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeFA2::bankCount() const -{ - return uInt16(mySize / 4_KB); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0200) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & 0x00FF] = value; - } - else - myImage[myBankOffset + address] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeFA2::getImage(size_t& size) const -{ - size = mySize; - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::save(Serializer& out) const -{ - try - { - out.putShort(myBankOffset); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA2::save" << endl; + // Load/save RAM to/from Harmony cart flash + if(mySize == 28_KB && !bankLocked()) + ramReadWrite(); return false; } - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeFA2::load(Serializer& in) -{ - try - { - myBankOffset = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeFA2::load" << endl; - return false; - } - - // Remember what bank we were in - bank(myBankOffset >> 12); - - return true; + return CartridgeEnhanced::poke(address, value); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -361,11 +120,11 @@ uInt8 CartridgeFA2::ramReadWrite() { try { - serializer.getByteArray(myRAM.data(), myRAM.size()); + serializer.getByteArray(myRAM.get(), myRamSize); } catch(...) { - myRAM.fill(0); + std::fill_n(myRAM.get(), myRamSize, 0); } myRamAccessTimeout += 500; // Add 0.5 ms delay for read } @@ -373,7 +132,7 @@ uInt8 CartridgeFA2::ramReadWrite() { try { - serializer.putByteArray(myRAM.data(), myRAM.size()); + serializer.putByteArray(myRAM.get(), myRamSize); } catch(...) { @@ -384,7 +143,7 @@ uInt8 CartridgeFA2::ramReadWrite() } } // Bit 6 is 1, busy - return myImage[myBankOffset + 0xFF4] | 0x40; + return myImage[myCurrentSegOffset[0] + 0xFF4] | 0x40; } else { @@ -395,11 +154,11 @@ uInt8 CartridgeFA2::ramReadWrite() myRAM[255] = 0; // Successful operation // Bit 6 is 0, ready/success - return myImage[myBankOffset + 0xFF4] & ~0x40; + return myImage[myCurrentSegOffset[0] + 0xFF4] & ~0x40; } else // Bit 6 is 1, busy - return myImage[myBankOffset + 0xFF4] | 0x40; + return myImage[myCurrentSegOffset[0] + 0xFF4] | 0x40; } } @@ -424,18 +183,18 @@ void CartridgeFA2::flash(uInt8 operation) { try { - serializer.getByteArray(myRAM.data(), myRAM.size()); + serializer.getByteArray(myRAM.get(), myRamSize); } catch(...) { - myRAM.fill(0); + std::fill_n(myRAM.get(), myRamSize, 0); } } else if(operation == 2) // write { try { - serializer.putByteArray(myRAM.data(), myRAM.size()); + serializer.putByteArray(myRAM.get(), myRamSize); } catch(...) { diff --git a/src/emucore/CartFA2.hxx b/src/emucore/CartFA2.hxx index ea19b0d43..8175f4cdc 100644 --- a/src/emucore/CartFA2.hxx +++ b/src/emucore/CartFA2.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartFA.hxx" #ifdef DEBUGGER_SUPPORT #include "CartFA2Widget.hxx" #endif @@ -43,9 +43,9 @@ class System; by the emulator. Also supported is a 32K variant. In any event, only data at 1K - 29K of the ROM is used. - @author Chris D. Walton + @author Chris D. Walton, Thomas Jentzsch */ -class CartridgeFA2 : public Cartridge +class CartridgeFA2 : public CartridgeFA { friend class CartridgeFA2Widget; @@ -63,71 +63,6 @@ class CartridgeFA2 : public Cartridge virtual ~CartridgeFA2() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -173,6 +108,12 @@ class CartridgeFA2 : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + + uInt16 hotspot() const override { return 0x1FF4; } + + uInt16 getStartBank() const override { return 0; } + /** Either load or save internal RAM to Harmony flash (represented by a file in emulation). @@ -192,15 +133,6 @@ class CartridgeFA2 : public Cartridge void flash(uInt8 operation); private: - // The 24K/28K ROM image of the cartridge - std::array myImage; - - // Actual usable size of the ROM image - size_t mySize{28_KB}; - - // The 256 bytes of RAM on the cartridge - std::array myRAM; - // The time after which the first request of a load/save operation // will actually be completed // Due to flash RAM constraints, a read/write isn't instantaneous, @@ -211,9 +143,6 @@ class CartridgeFA2 : public Cartridge // of internal RAM to Harmony cart flash string myFlashFile; - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - private: // Following constructors and assignment operators not supported CartridgeFA2() = delete; From 40f0c2f6a0e185bea687ba2a3fea0caf1aa5619a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 12 Apr 2020 09:02:28 +0200 Subject: [PATCH 14/52] remove superfluous code in Cart2K --- src/emucore/Cart2K.cxx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/emucore/Cart2K.cxx b/src/emucore/Cart2K.cxx index 24a328736..f4d4ef7bd 100644 --- a/src/emucore/Cart2K.cxx +++ b/src/emucore/Cart2K.cxx @@ -55,10 +55,4 @@ Cartridge2K::Cartridge2K(const ByteBuffer& image, size_t size, mySize = System::PAGE_SIZE; myBankShift = 6; } - - // update access arrays, bank size and mask based on new size - createRomAccessArrays(mySize); - - myBankSize = 1 << myBankShift; // e.g. = 2 ^ 11 = 2048 = 0x0800 - myBankMask = myBankSize - 1; // e.g. = 0x07FF } From eae35042fa61a61465d706cb263d69f570c07cfd Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 12 Apr 2020 11:35:41 +0200 Subject: [PATCH 15/52] improve CartEnhanced to allow swapped RAM read/write ports refactor CartCV add more CV test ROMs --- src/emucore/CartCV.cxx | 160 +++++------------------------------ src/emucore/CartCV.hxx | 82 +++--------------- src/emucore/CartEnhanced.cxx | 33 +++++--- src/emucore/CartEnhanced.hxx | 20 ++++- 4 files changed, 72 insertions(+), 223 deletions(-) diff --git a/src/emucore/CartCV.cxx b/src/emucore/CartCV.cxx index 42c74a808..136e817c3 100644 --- a/src/emucore/CartCV.cxx +++ b/src/emucore/CartCV.cxx @@ -21,164 +21,42 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeCV::CartridgeCV(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeEnhanced(image, size, md5, settings) { - if(mySize == myImage.size()) - { - // Copy the ROM data into my buffer - std::copy_n(image.get(), myImage.size(), myImage.begin()); - } - else if(mySize == 4_KB) + myBankShift = BANK_SHIFT; + myRamSize = RAM_SIZE; + myRamWpHigh = RAM_HIGH_WP; + + + if(mySize == 4_KB) { // The game has something saved in the RAM // Useful for MagiCard program listings - // Copy the ROM data into my buffer - std::copy_n(image.get() + myImage.size(), myImage.size(), myImage.begin()); + // Allocate array for the ROM image + mySize = 2_KB; + myImage = make_unique(mySize); + // Copy the ROM image into my buffer + std::copy_n(image.get() + mySize, mySize, myImage.get()); + + + myInitialRAM = make_unique(1_KB); // Copy the RAM image into a buffer for use in reset() - std::copy_n(image.get(), myInitialRAM.size(), myInitialRAM.begin()); + std::copy_n(image.get(), 1_KB, myInitialRAM.get()); } - createRomAccessArrays(myImage.size() + myRAM.size()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCV::reset() { - if(mySize == 4_KB) + if(myInitialRAM != nullptr) { // Copy the RAM image into my buffer - myRAM = myInitialRAM; + std::copy_n(myInitialRAM.get(), 1_KB, myRAM.get()); } else - initializeRAM(myRAM.data(), myRAM.size()); + initializeRAM(myRAM.get(), myRamSize); myBankChanged = true; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCV::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[addr & 0x07FF]; - access.romAccessBase = &myRomAccessBase[addr & 0x07FF]; - access.romPeekCounter = &myRomAccessCounter[addr & 0x07FF]; - access.romPokeCounter = &myRomAccessCounter[(addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.directPeekBase = nullptr; - access.romAccessBase = nullptr; - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); - - // Set the page accessing method for the RAM reading pages - access.directPokeBase = nullptr; - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x03FF]; - access.romAccessBase = &myRomAccessBase[2048 + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[2048 + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[2048 + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeCV::peek(uInt16 address) -{ - // The only way we can get to this method is if we attempt to read from - // the write port (0xF400 - 0xF7FF, 1024 bytes), in which case an - // unwanted write is potentially triggered - return peekRAM(myRAM[address & 0x03FF], address); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCV::poke(uInt16 address, uInt8 value) -{ - - if(address & 0x0400) - { - pokeRAM(myRAM[address & 0x03FF], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCV::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0800) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - // The following will work for both reads and writes - myRAM[address & 0x03FF] = value; - } - else - myImage[address & 0x07FF] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeCV::getImage(size_t& size) const -{ - size = myImage.size(); - return myImage.data(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCV::save(Serializer& out) const -{ - try - { - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeCV::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCV::load(Serializer& in) -{ - try - { - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeCV::load" << endl; - return false; - } - - return true; -} diff --git a/src/emucore/CartCV.hxx b/src/emucore/CartCV.hxx index 3b872ce9d..4e18040a6 100644 --- a/src/emucore/CartCV.hxx +++ b/src/emucore/CartCV.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartCVWidget.hxx" #endif @@ -33,9 +33,9 @@ class System; $F400-$F7FF write to RAM $F800-$FFFF ROM - @author Eckhard Stolberg + @author Eckhard Stolberg, Thomas Jentzsch */ -class CartridgeCV : public Cartridge +class CartridgeCV : public CartridgeEnhanced { friend class CartridgeCVWidget; @@ -58,47 +58,6 @@ class CartridgeCV : public Cartridge */ void reset() override; - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -118,35 +77,22 @@ class CartridgeCV : public Cartridge } #endif - public: - /** - Get the byte at the specified address + private: + bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; }; - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + protected: + // Initial RAM data from the cart (doesn't always exist) + ByteBuffer myInitialRAM{nullptr}; private: - // The 2k ROM image for the cartridge - std::array myImage; + // Calculated as: log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 11; // 2K - // Initial size of the cart data - size_t mySize{0}; + // RAM size + static constexpr uInt16 RAM_SIZE = 0x400; // 1K - // The 1024 bytes of RAM - std::array myRAM; - - // Initial RAM data from the cart (doesn't always exist) - std::array myInitialRAM; + // Write port for extra RAM is at high address + static constexpr bool RAM_HIGH_WP = true; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 6752d3153..c479ddd92 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -42,6 +42,8 @@ void CartridgeEnhanced::install(System& system) myBankMask = myBankSize - 1; // e.g. = 0x0FFF myBankSegs = 1 << (12 - myBankShift); // e.g. = 1 myRamMask = myRamSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) + myWriteOffset = myRamWpHigh ? myRamSize : 0; + myReadOffset = myRamWpHigh ? 0 : myRamSize; // Allocate array for the current bank segments slices myCurrentSegOffset = make_unique(myBankSegs); @@ -58,24 +60,24 @@ void CartridgeEnhanced::install(System& system) // Map access to this class, since we need to inspect all accesses to // check if RWP happens access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000; addr < 0x1000 + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = 0x1000 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; - access.romAccessBase = &myRomAccessBase[offset]; - access.romPeekCounter = &myRomAccessCounter[offset]; - access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; + access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset]; + access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize]; mySystem->setPageAccess(addr, access); } // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1000 + myRamSize; addr < 0x1000 + myRamSize * 2; addr += System::PAGE_SIZE) + for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; access.directPeekBase = &myRAM[offset]; - access.romAccessBase = &myRomAccessBase[myRamSize + offset]; - access.romPeekCounter = &myRomAccessCounter[myRamSize + offset]; - access.romPokeCounter = &myRomAccessCounter[myRamSize + offset + myAccessSize]; + access.romAccessBase = &myRomAccessBase[myReadOffset + offset]; + access.romPeekCounter = &myRomAccessCounter[myReadOffset + offset]; + access.romPokeCounter = &myRomAccessCounter[myReadOffset + offset + myAccessSize]; mySystem->setPageAccess(addr, access); } @@ -106,7 +108,9 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) checkSwitchBank(address & 0x0FFF); address &= myBankMask; - if(address < myRamSize) // Write port is at 0xF000 - 0xF07F (128 bytes) + // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) + if(address < myReadOffset + myRamSize && address >= myReadOffset) + // This is a read accees to a write port! return peekRAM(myRAM[address], peekAddress); else return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; @@ -115,15 +119,18 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { + uInt16 pokeAddress = address; + // Switch banks if necessary if (checkSwitchBank(address & 0x0FFF, value)) return false; + address &= myBankMask; if(myRamSize) { - if(!(address & myRamSize)) + if(bool(address & myRamSize) == myRamWpHigh) { - pokeRAM(myRAM[address & myRamMask], address, value); + pokeRAM(myRAM[address & myRamMask], pokeAddress, value); return true; } else @@ -131,8 +138,8 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) // Writing to the read port should be ignored, but trigger a break if option enabled uInt8 dummy; - pokeRAM(dummy, address, value); - myRamWriteAccess = address; + pokeRAM(dummy, pokeAddress, value); + myRamWriteAccess = pokeAddress; } } return false; diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 6437c362e..6c67b6eaf 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -40,7 +40,7 @@ class CartridgeEnhanced : public Cartridge @param settings A reference to the various settings (read-only) */ CartridgeEnhanced(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); + const Settings& settings); virtual ~CartridgeEnhanced() = default; public: @@ -160,6 +160,21 @@ class CartridgeEnhanced : public Cartridge // The mask for the extra RAM uInt16 myRamMask{0}; // RAM_SIZE - 1, but doesn't matter when RAM_SIZE is 0 + // The offset into ROM space for writing to RAM + // - xxSC = 0x0000 + // - FA(2) = 0x0000 + // - CV = 0x0400 + uInt16 myWriteOffset{0}; + + // The offset into ROM space for reading from RAM + // - xxSC = 0x0080 + // - FA(2) = 0x0100 + // - CV = 0x0000 + uInt16 myReadOffset{0}; + + // Flag, true if write port is at high and read port is at low address + bool myRamWpHigh{RAM_HIGH_WP}; + // Pointer to a dynamically allocated ROM image of the cartridge ByteBuffer myImage{nullptr}; @@ -182,6 +197,9 @@ class CartridgeEnhanced : public Cartridge // The size of extra RAM in ROM address space static constexpr uInt16 RAM_SIZE = 0; // default = none + // Write port for extra RAM is at low address by default + static constexpr bool RAM_HIGH_WP = false; + protected: /** Check hotspots and switch bank if triggered. From 3e6780d6bb2084f33eb6589b5c622e335112c19e Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 12 Apr 2020 19:15:07 -0230 Subject: [PATCH 16/52] Fixed some warnings from clang. Just checking on the progress; looking good so far. --- src/emucore/Cart2K.hxx | 2 +- src/emucore/Cart4K.hxx | 2 +- src/emucore/CartCV.cxx | 2 -- src/emucore/CartCV.hxx | 2 +- src/emucore/CartDetector.cxx | 6 ++---- src/emucore/CartEnhanced.cxx | 3 +-- src/emucore/CartEnhanced.hxx | 1 - src/emucore/CartFA2.cxx | 3 +-- src/emucore/CartUA.hxx | 6 +++--- 9 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/emucore/Cart2K.hxx b/src/emucore/Cart2K.hxx index 1ef2ee250..0ed6fedef 100644 --- a/src/emucore/Cart2K.hxx +++ b/src/emucore/Cart2K.hxx @@ -73,7 +73,7 @@ class Cartridge2K : public CartridgeEnhanced #endif private: - bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; }; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Cart4K.hxx b/src/emucore/Cart4K.hxx index 70819c5b2..1a7c428f4 100644 --- a/src/emucore/Cart4K.hxx +++ b/src/emucore/Cart4K.hxx @@ -70,7 +70,7 @@ class Cartridge4K : public CartridgeEnhanced #endif private: - bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; }; + bool checkSwitchBank(uInt16 address, uInt8 value = 0) override { return false; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartCV.cxx b/src/emucore/CartCV.cxx index 136e817c3..8d7ac9d89 100644 --- a/src/emucore/CartCV.cxx +++ b/src/emucore/CartCV.cxx @@ -27,7 +27,6 @@ CartridgeCV::CartridgeCV(const ByteBuffer& image, size_t size, myRamSize = RAM_SIZE; myRamWpHigh = RAM_HIGH_WP; - if(mySize == 4_KB) { // The game has something saved in the RAM @@ -40,7 +39,6 @@ CartridgeCV::CartridgeCV(const ByteBuffer& image, size_t size, // Copy the ROM image into my buffer std::copy_n(image.get() + mySize, mySize, myImage.get()); - myInitialRAM = make_unique(1_KB); // Copy the RAM image into a buffer for use in reset() std::copy_n(image.get(), 1_KB, myInitialRAM.get()); diff --git a/src/emucore/CartCV.hxx b/src/emucore/CartCV.hxx index 4e18040a6..1b4773e5e 100644 --- a/src/emucore/CartCV.hxx +++ b/src/emucore/CartCV.hxx @@ -78,7 +78,7 @@ class CartridgeCV : public CartridgeEnhanced #endif private: - bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; }; + bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; } protected: // Initial RAM data from the cart (doesn't always exist) diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index b6e6f150a..9fe79314f 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -951,14 +951,13 @@ bool CartDetector::isProbablyFC(const ByteBuffer& image, size_t size) { 0x8d, 0xf8, 0xff, 0x8d, 0xfc, 0xff }, // STA $FFF8, STA $FFFC Surf's Up (4K) { 0x8c, 0xf9, 0xff, 0xad, 0xfc, 0xff } // STY $FFF9, LDA $FFFC 3-D Havoc }; - for (uInt32 i = 0; i < 3; ++i) - if (searchForBytes(image.get(), size, signature[i], 6, 1)) + for(uInt32 i = 0; i < 3; ++i) + if(searchForBytes(image.get(), size, signature[i], 6, 1)) return true; return false; } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyFE(const ByteBuffer& image, size_t size) { @@ -1032,7 +1031,6 @@ bool CartDetector::isProbablyWD(const ByteBuffer& image, size_t size) return searchForBytes(image.get(), size, signature[0], 3, 1); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyX07(const ByteBuffer& image, size_t size) { diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index c479ddd92..db2768ed0 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -110,7 +110,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) if(address < myReadOffset + myRamSize && address >= myReadOffset) - // This is a read accees to a write port! + // This is a read access to a write port! return peekRAM(myRAM[address], peekAddress); else return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; @@ -233,7 +233,6 @@ bool CartridgeEnhanced::save(Serializer& out) const out.putIntArray(myCurrentSegOffset.get(), myBankSegs); if(myRamSize) out.putByteArray(myRAM.get(), myRamSize); - } catch(...) { diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 6c67b6eaf..dd8bd4322 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -57,7 +57,6 @@ class CartridgeEnhanced : public Cartridge */ void reset() override; - /** Install pages for the specified bank in the system. diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 0d892c9b3..1e4251988 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -49,11 +49,10 @@ bool CartridgeFA2::checkSwitchBank(uInt16 address, uInt8) } return false; } - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeFA2::peek(uInt16 address) { - if((address & 0x0FFF) == 0x0FF4) { // Load/save RAM to/from Harmony cart flash diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 94dcb4a98..97569dd76 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -59,13 +59,14 @@ class CartridgeUA : public CartridgeEnhanced */ void install(System& system) override; - /** Get a descriptor for the device name (used in error checking). @return The name of the object */ - string name() const override { return mySwappedHotspots ? "CartridgeUASW" : "CartridgeUA"; } + string name() const override { + return mySwappedHotspots ? "CartridgeUASW" : "CartridgeUA"; + } #ifdef DEBUGGER_SUPPORT /** @@ -96,7 +97,6 @@ class CartridgeUA : public CartridgeEnhanced */ bool poke(uInt16 address, uInt8 value) override; - private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; From ac3ce8cb595357beb9a90fee90b32fd5b1c50d0e Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 13 Apr 2020 18:05:44 +0200 Subject: [PATCH 17/52] intermediate commit for refactoring 3E (something got broken in disassembly before) --- src/emucore/Cart3E.cxx | 29 ++++++----- src/emucore/Cart3E.hxx | 6 +++ src/emucore/CartEnhanced.cxx | 99 +++++++++++++++++++++++++++--------- src/emucore/CartEnhanced.hxx | 16 ++++-- 4 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index 0947d783e..f5f37febc 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -23,7 +23,8 @@ Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) : Cartridge(settings, md5), - mySize(size) + mySize(size), + myRomBanks(256/*uInt16(size) >> 11*/) { // Allocate array for the ROM image myImage = make_unique(mySize); @@ -80,10 +81,10 @@ uInt8 Cartridge3E::peek(uInt16 address) if(address < 0x0040) // TIA access return mySystem->tia().peek(address); - else if(myCurrentBank >= 256) + else if(myCurrentBank >= myRomBanks) { // Reading from the write port triggers an unwanted write - return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], peekAddress); + return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)], peekAddress); } // Make compiler happy; should never get here @@ -103,15 +104,15 @@ bool Cartridge3E::poke(uInt16 address, uInt8 value) if(address == 0x003F) bank(value); else if(address == 0x003E) - bank(value + 256); + bank(value + myRomBanks); return mySystem->tia().poke(address, value); } - else if(myCurrentBank >= 256) + else if(myCurrentBank >= myRomBanks) { if(address & 0x0400) { - pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)], + pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)], pokeAddress, value); return true; } @@ -133,7 +134,7 @@ bool Cartridge3E::bank(uInt16 bank) { if(bankLocked()) return false; - if(bank < 256) + if(bank < myRomBanks) { // Make sure the bank they're asking for is reasonable if((uInt32(bank) << 11) < mySize) @@ -164,9 +165,9 @@ bool Cartridge3E::bank(uInt16 bank) } else { - bank -= 256; - bank %= 32; - myCurrentBank = bank + 256; + bank -= myRomBanks; + bank %= myRamBanks; + myCurrentBank = bank + myRomBanks; uInt32 offset = bank << 10; @@ -204,7 +205,7 @@ bool Cartridge3E::bank(uInt16 bank) uInt16 Cartridge3E::getBank(uInt16 address) const { if (address & 0x800) - return 255; // 256 - 1 // 2K slices, fixed bank + return myRomBanks - 1; // 2K slices, fixed bank else return myCurrentBank; } @@ -217,7 +218,7 @@ uInt16 Cartridge3E::bankCount() const // 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; + return myRomBanks + myRamBanks; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -227,10 +228,10 @@ bool Cartridge3E::patch(uInt16 address, uInt8 value) if(address < 0x0800) { - if(myCurrentBank < 256) + if(myCurrentBank < myRomBanks) myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value; else - myRAM[(address & 0x03FF) + ((myCurrentBank - 256) << 10)] = value; + myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)] = value; } else myImage[(address & 0x07FF) + mySize - 2048] = value; diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index 554560fd5..6b2ea0b88 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -190,6 +190,12 @@ class Cartridge3E : public Cartridge // Size of the ROM image size_t mySize{0}; + // Size of the ROM image + uInt16 myRomBanks{0}; + + // Size of the ROM image + uInt16 myRamBanks{32}; + // Indicates which bank is currently active for the first segment uInt16 myCurrentBank{0}; diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index db2768ed0..1a446a9a8 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -146,40 +146,89 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) +bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM) { if(bankLocked()) return false; - // Remember what bank is in which segment - uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; uInt16 segmentOffset = segment << myBankShift; - uInt16 hotspot = this->hotspot(); - uInt16 hotSpotAddr; - uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK; - // for ROMs < 4_KB, the whole address space will be mapped. - uInt16 toAddr = (segmentOffset + 0x1000 + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; - if(hotspot) - hotSpotAddr = (hotspot & ~System::PAGE_MASK); - else - hotSpotAddr = 0xFFFF; // none - - System::PageAccess access(this, System::PageAccessType::READ); - - // Setup the page access methods for the current bank - for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) + if(!isRAM) { - uInt32 offset = bankOffset + (addr & myBankMask); + // Setup ROM bank + // Remember what bank is in which segment + uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; - if(myDirectPeek && addr != hotSpotAddr) - access.directPeekBase = &myImage[offset]; + uInt16 hotspot = this->hotspot(); + uInt16 hotSpotAddr; + uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK; + // for ROMs < 4_KB, the whole address space will be mapped. + uInt16 toAddr = (segmentOffset + 0x1000 + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; + + if(hotspot) + hotSpotAddr = (hotspot & ~System::PAGE_MASK); else - access.directPeekBase = nullptr; - access.romAccessBase = &myRomAccessBase[offset]; - access.romPeekCounter = &myRomAccessCounter[offset]; - access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; - mySystem->setPageAccess(addr, access); + hotSpotAddr = 0xFFFF; // none + + System::PageAccess access(this, System::PageAccessType::READ); + // Setup the page access methods for the current bank + for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) + { + uInt32 offset = bankOffset + (addr & myBankMask); + + if(myDirectPeek && addr != hotSpotAddr) + access.directPeekBase = &myImage[offset]; + else + access.directPeekBase = nullptr; + access.romAccessBase = &myRomAccessBase[offset]; + access.romPeekCounter = &myRomAccessCounter[offset]; + access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } } + /*else + { + // Setup RAM bank + // TODO: define offsets on init + uInt16 myWriteBankOffset = myBankSize >> 1; + uInt16 myReadBankOffset = 0; + + // Remember what bank is in which segment + uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; + + // Set the page accessing method for the RAM writing pages + uInt16 fromAddr = (segmentOffset + myWriteBankOffset + 0x1000) & ~System::PAGE_MASK; + uInt16 toAddr = (segmentOffset + myWriteBankOffset + 0x1000 + myBankSize >> 1) & ~System::PAGE_MASK; + System::PageAccess access(this, System::PageAccessType::WRITE); + + for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) + { + uInt32 offset = bankOffset + (addr & myBankMask); + + access.romAccessBase = &myRomAccessBase[offset]; + access.romPeekCounter = &myRomAccessCounter[offset]; + access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + + // Set the page accessing method for the RAM reading pages + fromAddr = (segmentOffset + myReadBankOffset + 0x1000) & ~System::PAGE_MASK; + toAddr = (segmentOffset + myReadBankOffset + 0x1000 + myBankSize >> 1) & ~System::PAGE_MASK; + + access.type = System::PageAccessType::READ; + for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) + { + uInt32 offset = bankOffset + (addr & myBankMask); + + + + uInt16 offset = addr & myRamMask; + access.directPeekBase = &myBankRAM[offset]; + access.romAccessBase = &myRomAccessBase[offset]; + access.romPeekCounter = &myRomAccessCounter[offset]; + access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + }*/ return myBankChanged = true; } diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index dd8bd4322..29046f0ea 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -60,28 +60,34 @@ class CartridgeEnhanced : public Cartridge /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + @param segment The segment the bank should be using + @param isRAM True if the bank is a RAM bank + + @return true, if bank has changed */ - bool bank(uInt16 bank, uInt16 segment); + bool bank(uInt16 bank, uInt16 segment, bool isRAM = false); /** Install pages for the specified bank in the system. - @param bank The bank that should be installed in the system + @param bank The bank that should be installed in the system + + @return true, if bank has changed */ bool bank(uInt16 bank) override { return this->bank(bank, 0); } /** Get the current bank. - @param address The address to use when querying the bank + @param address The address to use when querying the bank */ uInt16 getBank(uInt16 address = 0) const override; /** Get the current bank for a bank segment. - @param segment The segment to get the bank for + @param segment The segment to get the bank for */ uInt16 getSegmentBank(uInt16 segment = 0) const; From 7fb2d096b967272751effb0d02e6a648bb720d8a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 13 Apr 2020 21:58:16 +0200 Subject: [PATCH 18/52] removed CV+ type (incl. doc update) --- Changes.txt | 4 +- docs/index.html | 23 ++- src/debugger/gui/CartCVPlusWidget.cxx | 157 ----------------- src/debugger/gui/CartCVPlusWidget.hxx | 73 -------- src/debugger/gui/module.mk | 3 +- src/emucore/Bankswitch.cxx | 3 - src/emucore/Bankswitch.hxx | 16 +- src/emucore/CartCVPlus.cxx | 235 -------------------------- src/emucore/CartCVPlus.hxx | 188 --------------------- src/emucore/CartDetector.cxx | 19 +-- src/emucore/CartDetector.hxx | 5 - src/emucore/module.mk | 3 +- src/windows/Stella.vcxproj | 8 - src/windows/Stella.vcxproj.filters | 12 -- 14 files changed, 31 insertions(+), 718 deletions(-) delete mode 100644 src/debugger/gui/CartCVPlusWidget.cxx delete mode 100644 src/debugger/gui/CartCVPlusWidget.hxx delete mode 100644 src/emucore/CartCVPlus.cxx delete mode 100644 src/emucore/CartCVPlus.hxx diff --git a/Changes.txt b/Changes.txt index 60fd29f4e..7a6b7bc3d 100644 --- a/Changes.txt +++ b/Changes.txt @@ -22,7 +22,7 @@ a game. This allows the user to save high scores for these games. For each game and variation, the top 10 scores can be saved. (TODO: Doc) - * Add option which lets default ROM path follow launcher navigation (TODO: Doc) + * Added option which lets default ROM path follow launcher navigation (TODO: Doc) * Added displaying last write address in the debugger. @@ -30,6 +30,8 @@ * Restored 'cfg' directory for Distella config files. + * Removed unused CV+ bank switching type. + -Have fun! diff --git a/docs/index.html b/docs/index.html index 68be48e0d..b0065878b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3756,7 +3756,9 @@ Ms Pac-Man (Stella extended codes):

Each block in a property file consists of a set of properties for a single game. Stella supports the properties described below:

- +

+ +

@@ -3791,8 +3793,7 @@ Ms Pac-Man (Stella extended codes): - - + @@ -3875,11 +3876,15 @@ Ms Pac-Man (Stella extended codes):
CDF Chris, Darrell, Fred (includes CDFJ).CDF
CM ¹Spectravideo CompuMate .CM
CTY ²CDW - Chetiry .CTY
CV Commavid extra RAM .CV
CV+ Extended Commavid extra RAM.CVP
CV CommaVid extra RAM .CV
DASH Boulder Dash 2 .DAS, .DASH
DF CPUWIZ 128K .DF
DFSC CPUWIZ 128K + RAM.DFS, .DFSC
+
- +

+ +

+ @@ -3899,8 +3904,11 @@ Ms Pac-Man (Stella extended codes): right player. The value must be A or B.
Console.TelevisionType:
+
- +

+ +

@@ -3975,8 +3983,11 @@ Ms Pac-Man (Stella extended codes): how to use the X/Y axis (ie, 02 is paddle0/paddle2). -->
Controller.Left:
Controller.Right:
+
- +

+ +

diff --git a/src/debugger/gui/CartCVPlusWidget.cxx b/src/debugger/gui/CartCVPlusWidget.cxx deleted file mode 100644 index cab27d3e5..000000000 --- a/src/debugger/gui/CartCVPlusWidget.cxx +++ /dev/null @@ -1,157 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#include "Debugger.hxx" -#include "CartDebug.hxx" -#include "CartCVPlus.hxx" -#include "PopUpWidget.hxx" -#include "CartCVPlusWidget.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartridgeCVPlusWidget::CartridgeCVPlusWidget( - GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, - int x, int y, int w, int h, CartridgeCVPlus& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) -{ - size_t size = cart.mySize; - - ostringstream info; - info << "LS_Dracon CV+ cartridge, 1K RAM, 2-256 2K ROM\n" - << "1024 bytes RAM @ $F000 - $F7FF\n" - << " $F000 - $F3FF (R), $F400 - $F7FF (W)\n" - << "2048 bytes ROM @ $F800 - $FFFF, by writing to $3D\n" - << "Startup bank = " << cart.startBank() << "\n"; - - int xpos = 2, - ypos = addBaseInformation(size, "LS_Dracon / Stephen Anthony", - info.str()) + myLineHeight; - - VariantList items; - for(uInt16 i = 0; i < cart.bankCount(); ++i) - VarList::push_back(items, Variant(i).toString() + " ($3D)"); - - ostringstream label; - label << "Set bank ($F800 - $FFFF) "; - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("xxx ($3D)"), - myLineHeight, items, label.str(), - _font.getStringWidth(label.str()), kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVPlusWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVPlusWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeCVPlusWidget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Bank = " << std::dec << myCart.myCurrentBank << ", hotspot = $3D"; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVPlusWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeCVPlusWidget::internalRamSize() -{ - return 1024; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeCVPlusWidget::internalRamRPort(int start) -{ - return 0xF000 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeCVPlusWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F3FF used for Read Access\n" - << "$F400 - $F7FF used for Write Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeCVPlusWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeCVPlusWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVPlusWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeCVPlusWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeCVPlusWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF000, false); -} diff --git a/src/debugger/gui/CartCVPlusWidget.hxx b/src/debugger/gui/CartCVPlusWidget.hxx deleted file mode 100644 index b1401b07c..000000000 --- a/src/debugger/gui/CartCVPlusWidget.hxx +++ /dev/null @@ -1,73 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#ifndef CARTRIDGECVPlus_WIDGET_HXX -#define CARTRIDGECVPlus_WIDGET_HXX - -class CartridgeCVPlus; -class PopUpWidget; - -#include "CartDebugWidget.hxx" - -class CartridgeCVPlusWidget : public CartDebugWidget -{ - public: - CartridgeCVPlusWidget(GuiObject* boss, const GUI::Font& lfont, - const GUI::Font& nfont, - int x, int y, int w, int h, - CartridgeCVPlus& cart); - virtual ~CartridgeCVPlusWidget() = default; - - private: - CartridgeCVPlus& myCart; - PopUpWidget* myBank{nullptr}; - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - enum { kBankChanged = 'bkCH' }; - - private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - void saveOldState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - - // Following constructors and assignment operators not supported - CartridgeCVPlusWidget() = delete; - CartridgeCVPlusWidget(const CartridgeCVPlusWidget&) = delete; - CartridgeCVPlusWidget(CartridgeCVPlusWidget&&) = delete; - CartridgeCVPlusWidget& operator=(const CartridgeCVPlusWidget&) = delete; - CartridgeCVPlusWidget& operator=(CartridgeCVPlusWidget&&) = delete; -}; - -#endif diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index d80408a60..522d31cf4 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -21,8 +21,7 @@ MODULE_OBJS := \ src/debugger/gui/CartCDFWidget.o \ src/debugger/gui/CartCDFInfoWidget.o \ src/debugger/gui/CartCMWidget.o \ - src/debugger/gui/CartCTYWidget.o \ - src/debugger/gui/CartCVPlusWidget.o \ + src/debugger/gui/CartCTYWidget.o \ src/debugger/gui/CartCVWidget.o \ src/debugger/gui/CartDASHWidget.o \ src/debugger/gui/CartDFSCWidget.o \ diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx index 231d6f73f..9726dc6aa 100644 --- a/src/emucore/Bankswitch.cxx +++ b/src/emucore/Bankswitch.cxx @@ -118,7 +118,6 @@ Bankswitch::BSList = {{ { "CM" , "CM (SpectraVideo CompuMate)" }, { "CTY" , "CTY (CDW - Chetiry)" }, { "CV" , "CV (Commavid extra RAM)" }, - { "CV+" , "CV+ (Extended Commavid)" }, { "DASH" , "DASH (Experimental)" }, { "DF" , "DF (CPUWIZ 128K)" }, { "DFSC" , "DFSC (CPUWIZ 128K + RAM)" }, @@ -197,7 +196,6 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = { { "CM" , Bankswitch::Type::_CM }, { "CTY" , Bankswitch::Type::_CTY }, { "CV" , Bankswitch::Type::_CV }, - { "CVP" , Bankswitch::Type::_CVP }, { "DAS" , Bankswitch::Type::_DASH }, { "DASH" , Bankswitch::Type::_DASH }, { "DF" , Bankswitch::Type::_DF }, @@ -262,7 +260,6 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = { { "CM" , Bankswitch::Type::_CM }, { "CTY" , Bankswitch::Type::_CTY }, { "CV" , Bankswitch::Type::_CV }, - { "CV+" , Bankswitch::Type::_CVP }, { "DASH" , Bankswitch::Type::_DASH }, { "DF" , Bankswitch::Type::_DF }, { "DFSC" , Bankswitch::Type::_DFSC }, diff --git a/src/emucore/Bankswitch.hxx b/src/emucore/Bankswitch.hxx index c57f81609..4ed7cc445 100644 --- a/src/emucore/Bankswitch.hxx +++ b/src/emucore/Bankswitch.hxx @@ -38,14 +38,14 @@ class Bankswitch public: // Currently supported bankswitch schemes enum class Type { - _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, - _64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50, - _4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF, - _CM, _CTY, _CV, _CVP, _DASH, _DF, _DFSC, - _DPC, _DPCP, _E0, _E7, _E78K, _EF, _EFSC, - _F0, _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, - _FA, _FA2, _FC, _FE, _MDM, _SB, _UA, - _UASW, _WD, _WDSW, _X07, + _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, + _64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50, + _4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF, + _CM, _CTY, _CV, _DASH, _DF, _DFSC, _DPC, + _DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0, + _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, + _FA2, _FC, _FE, _MDM, _SB, _UA, _UASW, + _WD, _WDSW, _X07, #ifdef CUSTOM_ARM _CUSTOM, #endif diff --git a/src/emucore/CartCVPlus.cxx b/src/emucore/CartCVPlus.cxx deleted file mode 100644 index a3258e53c..000000000 --- a/src/emucore/CartCVPlus.cxx +++ /dev/null @@ -1,235 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#include "System.hxx" -#include "TIA.hxx" -#include "CartCVPlus.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartridgeCVPlus::CartridgeCVPlus(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) -{ - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize + myRAM.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVPlus::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); - - // We'll map the startup bank into the first segment upon reset - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVPlus::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READWRITE); - - // The hotspot ($3D) is in TIA address space, so we claim it here - for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.directPeekBase = access.directPokeBase = nullptr; - access.romAccessBase = nullptr; - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[mySize + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[mySize + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[mySize + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[addr & 0x03FF]; - access.romAccessBase = &myRomAccessBase[mySize + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[mySize + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[mySize + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Install pages for the startup bank into the first segment - bank(startBank()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeCVPlus::peek(uInt16 address) -{ - if((address & 0x0FFF) < 0x0800) // Write port is at 0xF400 - 0xF7FF (1024 bytes) - return peekRAM(myRAM[address & 0x03FF], address); - else - return myImage[(address & 0x07FF) + (myCurrentBank << 11)]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCVPlus::poke(uInt16 address, uInt8 value) -{ - uInt16 pokeAddress = address; - address &= 0x0FFF; - - if(address < 0x0040) - { - // Switch banks if necessary - if(address == 0x003D) - bank(value); - - // Handle TIA space that we claimed above - return mySystem->tia().poke(address, value); - } - else - { - if(address & 0x0400) - { - pokeRAM(myRAM[address & 0x03FF], pokeAddress, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - return false; - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCVPlus::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Make sure the bank they're asking for is reasonable - if((uInt32(bank) << 11) < mySize) - { - myCurrentBank = bank; - } - else - { - // Oops, the bank they're asking for isn't valid so let's wrap it - // around to a valid bank number - myCurrentBank = bank % (mySize >> 11); - } - - uInt32 offset = myCurrentBank << 11; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x07FF)]; - mySystem->setPageAccess(addr, access); - } - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeCVPlus::getBank(uInt16) const -{ - return myCurrentBank; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeCVPlus::bankCount() const -{ - return uInt16(mySize >> 11); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCVPlus::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0800) - { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - // The following will work for both reads and writes - myRAM[address & 0x03FF] = value; - } - else - myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeCVPlus::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCVPlus::save(Serializer& out) const -{ - try - { - out.putShort(myCurrentBank); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeCVPlus::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeCVPlus::load(Serializer& in) -{ - try - { - myCurrentBank = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: CartridgeCVPlus::load" << endl; - return false; - } - - // Now, go to the current bank - bank(myCurrentBank); - - return true; -} diff --git a/src/emucore/CartCVPlus.hxx b/src/emucore/CartCVPlus.hxx deleted file mode 100644 index 63fcb62da..000000000 --- a/src/emucore/CartCVPlus.hxx +++ /dev/null @@ -1,188 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#ifndef CARTRIDGECVPlus_HXX -#define CARTRIDGECVPlus_HXX - -class System; - -#include "bspf.hxx" -#include "Cart.hxx" -#ifdef DEBUGGER_SUPPORT - #include "CartCVPlusWidget.hxx" -#endif - -/** - Cartridge class based on both Commavid and 3F/3E schemes: - - Commavid (RAM): - $F000-$F3FF read from RAM - $F400-$F7FF write to RAM - - 3F/3E (ROM): - $F800-$FFFF ROM - - In this bankswitching scheme the 2600's 4K cartridge - address space is broken into two 2K segments. The lower 2K - is RAM, as decribed above (same as CV/Commavid scheme). - To map ROM, the desired bank number of the upper 2K segment is - selected by storing its value into $3D. - - @author Stephen Anthony, LS_Dracon -*/ - -class CartridgeCVPlus : public Cartridge -{ - friend class CartridgeCVPlusWidget; - - public: - /** - Create a new cartridge using the specified image and size - - @param image Pointer to the ROM image - @param size The size of the ROM image - @param settings A reference to the various settings (read-only) - */ - CartridgeCVPlus(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); - virtual ~CartridgeCVPlus() = default; - - public: - /** - Reset device to its power-on state - */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - - /** - Get a descriptor for the device name (used in error checking). - - @return The name of the object - */ - string name() const override { return "CartridgeCV+"; } - - #ifdef DEBUGGER_SUPPORT - /** - Get debugger widget responsible for accessing the inner workings - of the cart. - */ - CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, - const GUI::Font& nfont, int x, int y, int w, int h) override - { - return new CartridgeCVPlusWidget(boss, lfont, nfont, x, y, w, h, *this); - } - #endif - - public: - /** - Get the byte at the specified address - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - - private: - // Pointer to a dynamically allocated ROM image of the cartridge - ByteBuffer myImage; - - // The 1024 bytes of RAM - std::array myRAM; - - // Size of the ROM image - size_t mySize{0}; - - // Indicates which bank is currently active for the first segment - uInt16 myCurrentBank{0}; - - private: - // Following constructors and assignment operators not supported - CartridgeCVPlus() = delete; - CartridgeCVPlus(const CartridgeCVPlus&) = delete; - CartridgeCVPlus(CartridgeCVPlus&&) = delete; - CartridgeCVPlus& operator=(const CartridgeCVPlus&) = delete; - CartridgeCVPlus& operator=(CartridgeCVPlus&&) = delete; -}; - -#endif diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 9fe79314f..09e0def71 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -33,7 +33,6 @@ #include "CartCM.hxx" #include "CartCTY.hxx" #include "CartCV.hxx" -#include "CartCVPlus.hxx" #include "CartDASH.hxx" #include "CartDF.hxx" #include "CartDFSC.hxx" @@ -278,8 +277,6 @@ CartDetector::createFromImage(const ByteBuffer& image, size_t size, Bankswitch:: return make_unique(image, size, md5, settings); case Bankswitch::Type::_CV: return make_unique(image, size, md5, settings); - case Bankswitch::Type::_CVP: - return make_unique(image, size, md5, settings); case Bankswitch::Type::_DASH: return make_unique(image, size, md5, settings); case Bankswitch::Type::_DF: @@ -346,11 +343,7 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si // Guess type based on size Bankswitch::Type type = Bankswitch::Type::_AUTO; - if(isProbablyCVPlus(image, size)) - { - type = Bankswitch::Type::_CVP; - } - else if((size % 8448) == 0 || size == 6144) + if((size % 8448) == 0 || size == 6144) { type = Bankswitch::Type::_AR; } @@ -757,16 +750,6 @@ bool CartDetector::isProbablyCV(const ByteBuffer& image, size_t size) return searchForBytes(image.get(), size, signature[1], 3, 1); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartDetector::isProbablyCVPlus(const ByteBuffer& image, size_t) -{ - // CV+ cart is identified key 'commavidplus' @ $04 in the ROM - // We inspect only this area to speed up the search - uInt8 cvp[12] = { 'c', 'o', 'm', 'm', 'a', 'v', 'i', 'd', - 'p', 'l', 'u', 's' }; - return searchForBytes(image.get()+4, 24, cvp, 12, 1); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyDASH(const ByteBuffer& image, size_t size) { diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 5f6a60674..8f9d04ac9 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -175,11 +175,6 @@ class CartDetector */ static bool isProbablyCV(const ByteBuffer& image, size_t size); - /** - Returns true if the image is probably a CV+ bankswitching cartridge - */ - static bool isProbablyCVPlus(const ByteBuffer& image, size_t size); - /** Returns true if the image is probably a DASH bankswitching cartridge */ diff --git a/src/emucore/module.mk b/src/emucore/module.mk index bbdd5eaab..4b72d3b22 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -20,8 +20,7 @@ MODULE_OBJS := \ src/emucore/CartCDF.o \ src/emucore/CartCM.o \ src/emucore/CartCTY.o \ - src/emucore/CartCV.o \ - src/emucore/CartCVPlus.o \ + src/emucore/CartCV.o \ src/emucore/CartDASH.o \ src/emucore/CartDPC.o \ src/emucore/CartDPCPlus.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index fcd2b85fb..46fd9a877 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -585,9 +585,6 @@ true - - true - true @@ -724,7 +721,6 @@ - @@ -1596,9 +1592,6 @@ true - - true - true @@ -1747,7 +1740,6 @@ - diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index ef41cf662..8f9d893f8 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -759,12 +759,6 @@ Source Files\debugger - - Source Files\emucore - - - Source Files\debugger - Source Files\debugger @@ -1748,12 +1742,6 @@ Header Files\debugger - - Header Files\debugger - - - Header Files\emucore - Header Files\debugger From db0d92eb2c948040fe37a8fbc132c7c1428252fa Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 15 Apr 2020 14:53:05 +0200 Subject: [PATCH 19/52] add RAM bank support to CartEnhanced refactor Cart3E differentiate between ROM and RAM banks (TODO: check debugger) --- src/debugger/CartDebug.cxx | 45 ++-- src/debugger/CartDebug.hxx | 4 +- src/debugger/DebuggerParser.cxx | 14 +- src/debugger/gui/Cart3EWidget.cxx | 24 +-- src/debugger/gui/Cart3FWidget.cxx | 2 +- src/debugger/gui/CartFA2Widget.cxx | 4 +- src/debugger/gui/CartFCWidget.cxx | 4 +- src/debugger/gui/CartMDMWidget.cxx | 2 +- src/debugger/gui/CartMNetworkWidget.cxx | 4 +- src/debugger/gui/CartSBWidget.cxx | 4 +- src/debugger/gui/RomWidget.cxx | 2 +- src/emucore/Cart.cxx | 14 +- src/emucore/Cart.hxx | 12 +- src/emucore/Cart3E.cxx | 263 +++--------------------- src/emucore/Cart3E.hxx | 108 ++-------- src/emucore/Cart3EPlus.cxx | 2 +- src/emucore/Cart3EPlus.hxx | 2 +- src/emucore/Cart3F.cxx | 2 +- src/emucore/CartAR.cxx | 2 +- src/emucore/CartAR.hxx | 2 +- src/emucore/CartBUS.cxx | 2 +- src/emucore/CartBUS.hxx | 2 +- src/emucore/CartCDF.cxx | 2 +- src/emucore/CartCDF.hxx | 2 +- src/emucore/CartCM.cxx | 2 +- src/emucore/CartCM.hxx | 2 +- src/emucore/CartCTY.cxx | 2 +- src/emucore/CartCTY.hxx | 2 +- src/emucore/CartDPC.cxx | 2 +- src/emucore/CartDPC.hxx | 2 +- src/emucore/CartDPCPlus.cxx | 2 +- src/emucore/CartDPCPlus.hxx | 2 +- src/emucore/CartEnhanced.cxx | 217 ++++++++++++------- src/emucore/CartEnhanced.hxx | 32 ++- src/emucore/CartFC.cxx | 6 +- src/emucore/CartMNetwork.cxx | 8 +- src/emucore/CartMNetwork.hxx | 2 +- src/emucore/CartSB.cxx | 4 +- src/emucore/CartSB.hxx | 2 +- src/emucore/CartWD.cxx | 2 +- src/emucore/CartWD.hxx | 2 +- src/gui/GameInfoDialog.cxx | 2 +- 42 files changed, 313 insertions(+), 504 deletions(-) diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index a52732cfe..ef6924187 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -72,12 +72,18 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem) // Create bank information for each potential bank, and an extra one for ZP RAM BankInfo info; - for(uInt32 i = 0; i < myConsole.cartridge().bankCount(); ++i) + for(uInt32 i = 0; i < myConsole.cartridge().romBankCount(); ++i) { info.size = myConsole.cartridge().bankSize(i); myBankInfo.push_back(info); } + for(uInt32 i = 0; i < myConsole.cartridge().ramBankCount(); ++i) + { + info.size = myConsole.cartridge().bankSize(i) >> 1; + myBankInfo.push_back(info); + } + info.size = 128; // ZP RAM myBankInfo.push_back(info); @@ -235,9 +241,10 @@ string CartDebug::toString() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartDebug::disassemble(bool force) +bool CartDebug::disassemblePC(bool force) { uInt16 PC = myDebugger.cpuDebug().pc(); + // ROM/RAM bank or ZP-RAM? int bank = (PC & 0x1000) ? getBank(PC) : int(myBankInfo.size()) - 1; return disassemble(bank, PC, force); @@ -414,7 +421,7 @@ bool CartDebug::addDirective(Device::AccessType type, bank = (myDebugger.cpuDebug().pc() & 0x1000) ? getBank(myDebugger.cpuDebug().pc()) : int(myBankInfo.size())-1; - bank = std::min(bank, bankCount()); + bank = std::min(bank, romBankCount()); BankInfo& info = myBankInfo[bank]; DirectiveList& list = info.directiveList; @@ -546,9 +553,9 @@ int CartDebug::getPCBank() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int CartDebug::bankCount() const +int CartDebug::romBankCount() const { - return myConsole.cartridge().bankCount(); + return myConsole.cartridge().romBankCount(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -955,7 +962,7 @@ string CartDebug::loadConfigFile() myDebugger.rom().invalidate(); stringstream retVal; - if(myConsole.cartridge().bankCount() > 1) + if(myConsole.cartridge().romBankCount() > 1) retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n"); retVal << "config file '" << node.getShortPath() << "' loaded OK"; return retVal.str(); @@ -990,14 +997,14 @@ string CartDebug::saveConfigFile() out << "// Stella.pro: \"" << name << "\"" << endl << "// MD5: " << md5 << endl << endl; - for(uInt32 b = 0; b < myConsole.cartridge().bankCount(); ++b) + for(uInt32 b = 0; b < myConsole.cartridge().romBankCount(); ++b) { out << "[" << b << "]" << endl; getBankDirectives(out, myBankInfo[b]); } stringstream retVal; - if(myConsole.cartridge().bankCount() > 1) + if(myConsole.cartridge().romBankCount() > 1) retVal << DebuggerParser::red("config file for multi-bank ROM not fully supported\n"); retVal << "config file '" << cfg.getShortPath() << "' saved OK"; return retVal.str(); @@ -1058,14 +1065,14 @@ string CartDebug::saveDisassembly() Disassembly disasm; disasm.list.reserve(2048); - uInt16 bankCount = myConsole.cartridge().bankCount(); + uInt16 romBankCount = myConsole.cartridge().romBankCount(); uInt16 oldBank = myConsole.cartridge().getBank(); // prepare for switching banks myConsole.cartridge().unlockBank(); uInt32 origin = 0; - for(int bank = 0; bank < bankCount; ++bank) + for(int bank = 0; bank < romBankCount; ++bank) { // TODO: not every CartDebugWidget does it like that, we need a method myConsole.cartridge().unlockBank(); @@ -1082,8 +1089,8 @@ string CartDebug::saveDisassembly() buf << "\n\n;***********************************************************\n" << "; Bank " << bank; - if (bankCount > 1) - buf << " / 0.." << bankCount - 1; + if (romBankCount > 1) + buf << " / 0.." << romBankCount - 1; buf << "\n;***********************************************************\n\n"; @@ -1097,7 +1104,7 @@ string CartDebug::saveDisassembly() buf << " SEG CODE\n"; - if(bankCount == 1) + if(romBankCount == 1) buf << " ORG $" << Base::HEX4 << info.offset << "\n\n"; else buf << " ORG $" << Base::HEX4 << origin << "\n" @@ -1327,7 +1334,7 @@ string CartDebug::saveDisassembly() out << buf.str(); stringstream retVal; - if(myConsole.cartridge().bankCount() > 1) + if(myConsole.cartridge().romBankCount() > 1) retVal << DebuggerParser::red("disassembly for multi-bank ROM not fully supported\n"); retVal << "saved " << node.getShortPath() << " OK"; return retVal.str(); @@ -1367,8 +1374,8 @@ string CartDebug::saveAccessFile() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartDebug::listConfig(int bank) { - uInt32 startbank = 0, endbank = bankCount(); - if(bank >= 0 && bank < bankCount()) + uInt32 startbank = 0, endbank = romBankCount(); + if(bank >= 0 && bank < romBankCount()) { startbank = bank; endbank = startbank + 1; @@ -1392,7 +1399,7 @@ string CartDebug::listConfig(int bank) getBankDirectives(buf, info); } - if(myConsole.cartridge().bankCount() > 1) + if(myConsole.cartridge().romBankCount() > 1) buf << DebuggerParser::red("config file for multi-bank ROM not fully supported") << endl; return buf.str(); @@ -1401,8 +1408,8 @@ string CartDebug::listConfig(int bank) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartDebug::clearConfig(int bank) { - uInt32 startbank = 0, endbank = bankCount(); - if(bank >= 0 && bank < bankCount()) + uInt32 startbank = 0, endbank = romBankCount(); + if(bank >= 0 && bank < romBankCount()) { startbank = bank; endbank = startbank + 1; diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index c2bd03cae..486eedd79 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -95,7 +95,7 @@ class CartDebug : public DebuggerSystem int lastWriteBaseAddress(); // TODO - bool disassemble(bool force = false); + bool disassemblePC(bool force = false); bool disassembleBank(int bank); // First, a call is made to disassemble(), which updates the disassembly @@ -159,7 +159,7 @@ class CartDebug : public DebuggerSystem /** Get the total number of banks supported by the cartridge. */ - int bankCount() const; + int romBankCount() const; /** Add a label and associated address. diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 4f50be800..da3b0bc5f 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -763,7 +763,7 @@ void DebuggerParser::executeBreak() { uInt16 addr; uInt8 bank; - uInt32 bankCount = debugger.cartDebug().bankCount(); + uInt32 romBankCount = debugger.cartDebug().romBankCount(); if(argCount == 0) addr = debugger.cpuDebug().pc(); @@ -775,7 +775,7 @@ void DebuggerParser::executeBreak() else { bank = args[1]; - if(bank >= bankCount && bank != 0xff) + if(bank >= romBankCount && bank != 0xff) { commandResult << red("invalid bank"); return; @@ -791,12 +791,12 @@ void DebuggerParser::executeBreak() commandResult << "cleared"; commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors"; - if(bankCount > 1) + if(romBankCount > 1) commandResult << " in bank #" << std::dec << int(bank); } else { - for(int i = 0; i < debugger.cartDebug().bankCount(); ++i) + for(int i = 0; i < debugger.cartDebug().romBankCount(); ++i) { bool set = debugger.toggleBreakPoint(addr, i); @@ -809,7 +809,7 @@ void DebuggerParser::executeBreak() commandResult << "cleared"; commandResult << " breakpoint at $" << Base::HEX4 << addr << " + mirrors"; - if(bankCount > 1) + if(romBankCount > 1) commandResult << " in bank #" << std::dec << int(bank); } } @@ -1459,11 +1459,11 @@ void DebuggerParser::executeListbreaks() { stringstream buf; int count = 0; - uInt32 bankCount = debugger.cartDebug().bankCount(); + uInt32 romBankCount = debugger.cartDebug().romBankCount(); for(const auto& bp : debugger.breakPoints().getBreakpoints()) { - if(bankCount == 1) + if(romBankCount == 1) { buf << debugger.cartDebug().getLabel(bp.addr, true, 4) << " "; if(!(++count % 8)) buf << endl; diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx index 3880f2026..e91b268ab 100644 --- a/src/debugger/gui/Cart3EWidget.cxx +++ b/src/debugger/gui/Cart3EWidget.cxx @@ -25,8 +25,8 @@ Cartridge3EWidget::Cartridge3EWidget( int x, int y, int w, int h, Cartridge3E& cart) : CartDebugWidget(boss, lfont, nfont, x, y, w, h), myCart(cart), - myNumRomBanks(uInt32(cart.mySize >> 11)), - myNumRamBanks(32) + myNumRomBanks(myCart.romBankCount()), + myNumRamBanks(myCart.ramBankCount()) { size_t size = cart.mySize; @@ -93,21 +93,21 @@ void Cartridge3EWidget::saveOldState() for(uInt32 i = 0; i < internalRamSize(); ++i) myOldState.internalram.push_back(myCart.myRAM[i]); - myOldState.bank = myCart.myCurrentBank; + myOldState.bank = myCart.getBank(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EWidget::loadConfig() { - if(myCart.myCurrentBank < 256) + if(myCart.getBank() < myCart.romBankCount()) { - myROMBank->setSelectedIndex(myCart.myCurrentBank % myNumRomBanks, myOldState.bank != myCart.myCurrentBank); - myRAMBank->setSelectedMax(myOldState.bank >= 256); + myROMBank->setSelectedIndex(myCart.getBank() % myNumRomBanks, myOldState.bank != myCart.getBank()); + myRAMBank->setSelectedMax(myOldState.bank >= myCart.romBankCount()); } else { - myROMBank->setSelectedMax(myOldState.bank < 256); - myRAMBank->setSelectedIndex(myCart.myCurrentBank - 256, myOldState.bank != myCart.myCurrentBank); + myROMBank->setSelectedMax(myOldState.bank < myCart.romBankCount()); + myRAMBank->setSelectedIndex(myCart.getBank() - myCart.romBankCount(), myOldState.bank != myCart.getBank()); } CartDebugWidget::loadConfig(); @@ -128,7 +128,7 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender, } else { - bank = 256; // default to first RAM bank + bank = myCart.romBankCount(); // default to first RAM bank myRAMBank->setSelectedIndex(0); } } @@ -137,7 +137,7 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender, if(myRAMBank->getSelected() < int(myNumRamBanks)) { myROMBank->setSelectedMax(); - bank = myRAMBank->getSelected() + 256; + bank = myRAMBank->getSelected() + myCart.romBankCount(); } else { @@ -157,8 +157,8 @@ string Cartridge3EWidget::bankState() { ostringstream& buf = buffer(); - uInt16& bank = myCart.myCurrentBank; - if(bank < 256) + uInt16 bank = myCart.getBank(); + if(bank < myCart.romBankCount()) buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive"; else buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRomBanks; diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index 86d43177b..13cd851bd 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -44,7 +44,7 @@ Cartridge3FWidget::Cartridge3FWidget( ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight; VariantList items; - for(uInt16 i = 0; i < cart.bankCount(); ++i) + for(uInt16 i = 0; i < cart.romBankCount(); ++i) VarList::push_back(items, Variant(i).toString() + " ($3F)"); ostringstream label; diff --git a/src/debugger/gui/CartFA2Widget.cxx b/src/debugger/gui/CartFA2Widget.cxx index eb2bf4d07..9a24eb5a7 100644 --- a/src/debugger/gui/CartFA2Widget.cxx +++ b/src/debugger/gui/CartFA2Widget.cxx @@ -38,7 +38,7 @@ CartridgeFA2Widget::CartridgeFA2Widget( << "Startup bank = " << cart.startBank() << " or undetermined\n"; // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < cart.bankCount(); + for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < cart.romBankCount(); ++i, offset += 0x1000) { uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; @@ -58,7 +58,7 @@ CartridgeFA2Widget::CartridgeFA2Widget( VarList::push_back(items, "3 ($FFF8)"); VarList::push_back(items, "4 ($FFF9)"); VarList::push_back(items, "5 ($FFFA)"); - if(cart.bankCount() == 7) + if(cart.romBankCount() == 7) VarList::push_back(items, "6 ($FFFB)"); myBank = diff --git a/src/debugger/gui/CartFCWidget.cxx b/src/debugger/gui/CartFCWidget.cxx index ce1bf9403..a034b56e3 100644 --- a/src/debugger/gui/CartFCWidget.cxx +++ b/src/debugger/gui/CartFCWidget.cxx @@ -26,7 +26,7 @@ CartridgeFCWidget::CartridgeFCWidget( : CartDebugWidget(boss, lfont, nfont, x, y, w, h), myCart(cart) { - uInt16 size = cart.bankCount() * 4096; + uInt16 size = cart.romBankCount() * 4096; ostringstream info; info << "FC cartridge, up to eight 4K banks\n" @@ -42,7 +42,7 @@ CartridgeFCWidget::CartridgeFCWidget( ypos = addBaseInformation(size, "Amiga Corp.", info.str()) + myLineHeight; VariantList items; - for (uInt16 i = 0; i < cart.bankCount(); ++i) + for (uInt16 i = 0; i < cart.romBankCount(); ++i) VarList::push_back(items, Variant(i).toString() + " ($FFF8 = " + Variant(i & 0b11).toString() + "/$FFF9 = " + Variant(i >> 2).toString() +")"); diff --git a/src/debugger/gui/CartMDMWidget.cxx b/src/debugger/gui/CartMDMWidget.cxx index 2ba603168..48afbaf77 100644 --- a/src/debugger/gui/CartMDMWidget.cxx +++ b/src/debugger/gui/CartMDMWidget.cxx @@ -40,7 +40,7 @@ CartridgeMDMWidget::CartridgeMDMWidget( ypos = addBaseInformation(size, "Edwin Blink", info.str(), 15) + myLineHeight; VariantList items; - for(uInt32 i = 0x800; i < (0x800U + myCart.bankCount()); ++i) + for(uInt32 i = 0x800; i < (0x800U + myCart.romBankCount()); ++i) { info.str(""); info << std::dec << (i & 0xFF) << " ($" << Common::Base::HEX4 << i << ")"; diff --git a/src/debugger/gui/CartMNetworkWidget.cxx b/src/debugger/gui/CartMNetworkWidget.cxx index cdc1f9bce..37d382a7e 100644 --- a/src/debugger/gui/CartMNetworkWidget.cxx +++ b/src/debugger/gui/CartMNetworkWidget.cxx @@ -35,14 +35,14 @@ CartridgeMNetworkWidget::CartridgeMNetworkWidget( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& cart, ostringstream& info) { - uInt32 size = cart.bankCount() * cart.BANK_SIZE; + uInt32 size = cart.romBankCount() * cart.BANK_SIZE; int xpos = 2, ypos = addBaseInformation(size, "M-Network", info.str(), 15) + myLineHeight; VariantList items0, items1; - for(int i = 0; i < cart.bankCount(); ++i) + for(int i = 0; i < cart.romBankCount(); ++i) VarList::push_back(items0, getSpotLower(i)); for(int i = 0; i < 4; ++i) VarList::push_back(items1, getSpotUpper(i)); diff --git a/src/debugger/gui/CartSBWidget.cxx b/src/debugger/gui/CartSBWidget.cxx index 78d352879..7a82ba8e0 100644 --- a/src/debugger/gui/CartSBWidget.cxx +++ b/src/debugger/gui/CartSBWidget.cxx @@ -33,12 +33,12 @@ CartridgeSBWidget::CartridgeSBWidget( myCart.getImage(size); info << "SB SUPERbanking, 32 or 64 4K banks\n" << "Hotspots are from $800 to $" - << Common::Base::HEX2 << (0x800 + myCart.bankCount() - 1) << ", including\n" + << Common::Base::HEX2 << (0x800 + myCart.romBankCount() - 1) << ", including\n" << "mirrors ($900, $A00, $B00, ...)\n" << "Startup bank = " << std::dec << cart.startBank() << "\n"; // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < myCart.bankCount(); + for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < myCart.romBankCount(); ++i, offset += 0x1000, ++spot) { uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index 18c8b0b78..e62fe0a17 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -68,7 +68,7 @@ void RomWidget::loadConfig() const CartState& oldstate = static_cast(cart.getOldState()); // Fill romlist the current bank of source or disassembly - myListIsDirty |= cart.disassemble(myListIsDirty); + myListIsDirty |= cart.disassemblePC(myListIsDirty); if(myListIsDirty) { myRomList->setList(cart.disassembly()); diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx index f85850ba2..7639101ff 100644 --- a/src/emucore/Cart.cxx +++ b/src/emucore/Cart.cxx @@ -83,7 +83,7 @@ uInt16 Cartridge::bankSize(uInt16 bank) const getImage(size); - return std::min(uInt32(size) / bankCount(), 4_KB); // assuming that each bank has the same size + return std::min(uInt32(size) / romBankCount(), 4_KB); // assuming that each bank has the same size } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -145,13 +145,13 @@ string Cartridge::getAccessCounters() const ostringstream out; uInt32 offset = 0; - for(uInt16 bank = 0; bank < bankCount(); ++bank) + for(uInt16 bank = 0; bank < romBankCount(); ++bank) { uInt16 origin = bankOrigin(bank); uInt16 bankSize = this->bankSize(bank); out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.." - << Common::Base::toString(bankCount() - 1, Common::Base::Fmt::_10_8) << " reads:\n"; + << Common::Base::toString(romBankCount() - 1, Common::Base::Fmt::_10_8) << " reads:\n"; for(uInt16 addr = 0; addr < bankSize; ++addr) { out << Common::Base::HEX4 << (addr | origin) << "," @@ -159,7 +159,7 @@ string Cartridge::getAccessCounters() const } out << "\n"; out << "Bank " << Common::Base::toString(bank, Common::Base::Fmt::_10_8) << " / 0.." - << Common::Base::toString(bankCount() - 1, Common::Base::Fmt::_10_8) << " writes:\n"; + << Common::Base::toString(romBankCount() - 1, Common::Base::Fmt::_10_8) << " writes:\n"; for(uInt16 addr = 0; addr < bankSize; ++addr) { out << Common::Base::HEX4 << (addr | origin) << "," @@ -230,11 +230,11 @@ uInt16 Cartridge::initializeStartBank(uInt16 defaultBank) int propsBank = myStartBankFromPropsFunc(); if(randomStartBank()) - return myStartBank = mySystem->randGenerator().next() % bankCount(); + return myStartBank = mySystem->randGenerator().next() % romBankCount(); else if(propsBank >= 0) - return myStartBank = BSPF::clamp(propsBank, 0, bankCount() - 1); + return myStartBank = BSPF::clamp(propsBank, 0, romBankCount() - 1); else - return myStartBank = BSPF::clamp(int(defaultBank), 0, bankCount() - 1); + return myStartBank = BSPF::clamp(int(defaultBank), 0, romBankCount() - 1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index ce7d66a8b..a7488f551 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -180,7 +180,7 @@ class Cartridge : public Device virtual uInt16 getBank(uInt16 address = 0) const { return 0; } /** - Query the number of 'banks' supported by the cartridge. Note that + Query the number of ROM 'banks' supported by the cartridge. Note that this information is cart-specific, where each cart basically defines what a 'bank' is. @@ -192,7 +192,15 @@ class Cartridge : public Device RAM slices at multiple access points) is so complicated that the cart will report having only one 'virtual' bank. */ - virtual uInt16 bankCount() const { return 1; } + virtual uInt16 romBankCount() const { return 1; } + + + /** + Query the number of RAM 'banks' supported by the cartridge. Note that + this information is cart-specific, where each cart basically defines + what a 'bank' is. + */ + virtual uInt16 ramBankCount() const { return 0; } /** Get the size of a bank. diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index f1ccd2957..a927ddd2d 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -22,52 +22,42 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3E::Cartridge3E(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size), - myRomBanks(256/*uInt16(size) >> 11*/) + : CartridgeEnhanced(image, size, md5, settings) { - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize + myRAM.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3E::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); - - // We'll map the startup bank into the first segment upon reset - bank(startBank()); + myBankShift = BANK_SHIFT; + myRamSize = RAM_SIZE; + myRamBankCount = RAM_BANKS; + myRamWpHigh = RAM_HIGH_WP; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3E::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); System::PageAccess access(this, System::PageAccessType::READWRITE); // The hotspots ($3E and $3F) are in TIA address space, so we claim it here for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); +} - // Setup the second segment to always point to the last ROM slice - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1800; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[(mySize - 2048) + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[(mySize - 2048) + (addr & 0x07FF)]; - access.romPeekCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF)]; - access.romPokeCounter = &myRomAccessCounter[(mySize - 2048) + (addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value) +{ + // Switch banks if necessary + if(address == 0x003F) { + // Switch ROM bank into segment 0 + bank(value); + return true; } - - // Install pages for the startup bank into the first segment - bank(startBank()); + else if(address == 0x003E) + { + // Switch RAM bank into segment 0 + bank(value + romBankCount()); + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -76,215 +66,8 @@ uInt8 Cartridge3E::peek(uInt16 address) uInt16 peekAddress = address; address &= 0x0FFF; - // Due to the way paging is set up, the only way to get here is a TIA read or - // attempting to read from the RAM write port - if(address < 0x0040) // TIA access return mySystem->tia().peek(address); - else if(myCurrentBank >= myRomBanks) - { - // Reading from the write port triggers an unwanted write - return peekRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)], peekAddress); - } - // Make compiler happy; should never get here - return myImage[(address & 0x07FF) + mySize - 2048]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3E::poke(uInt16 address, uInt8 value) -{ - uInt16 pokeAddress = address; - address &= 0x0FFF; - - // Switch banks if necessary. Armin (Kroko) says there are no mirrored - // hotspots. - if(address < 0x0040) - { - if(address == 0x003F) - bank(value); - else if(address == 0x003E) - bank(value + myRomBanks); - - return mySystem->tia().poke(address, value); - } - else if(myCurrentBank >= myRomBanks) - { - if(address & 0x0400) - { - pokeRAM(myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)], - pokeAddress, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - return false; - } - } - return false; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3E::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - if(bank < myRomBanks) - { - // Make sure the bank they're asking for is reasonable - if((uInt32(bank) << 11) < mySize) - { - myCurrentBank = bank; - } - else - { - // Oops, the bank they're asking for isn't valid so let's wrap it - // around to a valid bank number - myCurrentBank = bank % (mySize >> 11); - } - - uInt32 offset = myCurrentBank << 11; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map ROM image into the system - for(uInt16 addr = 0x1000; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[offset + (addr & 0x07FF)]; - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x07FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x07FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x07FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - } - else - { - bank -= myRomBanks; - bank %= myRamBanks; - myCurrentBank = bank + myRomBanks; - - uInt32 offset = bank << 10; - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - // Map read-port RAM image into the system - // Writes are mapped to poke(), to check for write to the read port - for(uInt16 addr = 0x1000; addr < 0x1400; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myRAM[offset + (addr & 0x03FF)]; - access.romAccessBase = &myRomAccessBase[mySize + offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - access.directPeekBase = nullptr; - access.type = System::PageAccessType::WRITE; - - // Map write-port RAM image into the system - // Reads are mapped to peek(), to check for read from write port - for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[mySize + offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[mySize + offset + (addr & 0x03FF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3E::getBank(uInt16 address) const -{ - if (address & 0x800) - return myRomBanks - 1; // 2K slices, fixed bank - else - return myCurrentBank; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3E::bankCount() const -{ - // Because the RAM banks always start at 256 and above, we require the - // number of ROM banks to be 256 - // 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 myRomBanks + myRamBanks; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3E::bankSize(uInt16 bank) const -{ - return 2_KB; // we cannot use bankCount() here, because it delivers wrong numbers -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3E::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - if(address < 0x0800) - { - if(myCurrentBank < myRomBanks) - myImage[(address & 0x07FF) + (myCurrentBank << 11)] = value; - else - myRAM[(address & 0x03FF) + ((myCurrentBank - myRomBanks) << 10)] = value; - } - else - myImage[(address & 0x07FF) + mySize - 2048] = value; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge3E::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3E::save(Serializer& out) const -{ - try - { - out.putShort(myCurrentBank); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: Cartridge3E::save" << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3E::load(Serializer& in) -{ - try - { - myCurrentBank = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch(...) - { - cerr << "ERROR: Cartridge3E::load" << endl; - return false; - } - - // Now, go to the current bank - bank(myCurrentBank); - - return true; + return CartridgeEnhanced::peek(peekAddress); } diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index d78cb3bb0..4871c67a6 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "Cart3EWidget.hxx" #endif @@ -47,10 +47,8 @@ class System; by storing its value into $3F. To map RAM in the first 2K segment instead, store the RAM bank number into $3E. - This implementation of 3E bankswitching numbers the ROM banks 0 to - 255, and the RAM banks 256 to 287. This is done because the public - bankswitching interface requires us to use one bank number, not one - bank number plus the knowledge of whether it's RAM or ROM. + This implementation of 3E bankswitching numbers the RAM banks (up to 32) + after the ROM banks (up to 256). All 32K of potential RAM is available to a game using this class, even though real cartridges might not have the full 32K: We have no way to @@ -58,10 +56,10 @@ class System; may add a stella.pro property for this), but for now it shouldn't cause any problems. (Famous last words...) - @author B. Watson + @author B. Watson, Thomas Jentzsch */ -class Cartridge3E : public Cartridge +class Cartridge3E : public CartridgeEnhanced { friend class Cartridge3EWidget; @@ -79,10 +77,6 @@ class Cartridge3E : public Cartridge virtual ~Cartridge3E() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; /** Install cartridge in the specified system. Invoked by the system @@ -92,66 +86,6 @@ class Cartridge3E : public Cartridge */ void install(System& system) override; - /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system - */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 bankCount() const override; - - /** - Get the size of a bank. - - @param bank The bank to get the size for - @return The bank's size - */ - virtual uInt16 bankSize(uInt16 bank = 0) const; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -179,33 +113,21 @@ class Cartridge3E : public Cartridge */ uInt8 peek(uInt16 address) override; - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; + private: + bool checkSwitchBank(uInt16 address, uInt8 value) override; private: - // Pointer to a dynamically allocated ROM image of the cartridge - ByteBuffer myImage; + // log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800 - // RAM contents. For now every ROM gets all 32K of potential RAM - std::array myRAM; + // The size of extra RAM in ROM address space + static constexpr uInt16 RAM_BANKS = 32; - // Size of the ROM image - size_t mySize{0}; + // RAM size + static constexpr uInt16 RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000; - // Size of the ROM image - uInt16 myRomBanks{0}; - - // Size of the ROM image - uInt16 myRamBanks{32}; - - // Indicates which bank is currently active for the first segment - uInt16 myCurrentBank{0}; + // Write port for extra RAM is at high address + static constexpr bool RAM_HIGH_WP = true; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 27eb94986..1fe28a022 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -85,7 +85,7 @@ uInt16 Cartridge3EPlus::getBank(uInt16 address) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3EPlus::bankCount() const +uInt16 Cartridge3EPlus::romBankCount() const { return uInt16(mySize >> 10); // 1K slices } diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 76919b9ae..70309d308 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -80,7 +80,7 @@ class Cartridge3EPlus: public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/Cart3F.cxx b/src/emucore/Cart3F.cxx index 7c3701c16..21b21b9c7 100644 --- a/src/emucore/Cart3F.cxx +++ b/src/emucore/Cart3F.cxx @@ -46,7 +46,7 @@ bool Cartridge3F::checkSwitchBank(uInt16 address, uInt8 value) if(address <= 0x003F) { // Make sure the bank they're asking for is reasonable - bank(value % bankCount(), 0); + bank(value % romBankCount(), 0); return true; } return false; diff --git a/src/emucore/CartAR.cxx b/src/emucore/CartAR.cxx index 5201a14df..2d8b204b6 100644 --- a/src/emucore/CartAR.cxx +++ b/src/emucore/CartAR.cxx @@ -406,7 +406,7 @@ uInt16 CartridgeAR::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeAR::bankCount() const +uInt16 CartridgeAR::romBankCount() const { return 32; } diff --git a/src/emucore/CartAR.hxx b/src/emucore/CartAR.hxx index 6fda35f38..0bc74a291 100644 --- a/src/emucore/CartAR.hxx +++ b/src/emucore/CartAR.hxx @@ -87,7 +87,7 @@ class CartridgeAR : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index 2c2cd803a..bd6d227c2 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -457,7 +457,7 @@ uInt16 CartridgeBUS::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeBUS::bankCount() const +uInt16 CartridgeBUS::romBankCount() const { return 7; } diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index d00e90133..5567f1196 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -98,7 +98,7 @@ class CartridgeBUS : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index b182634a3..2758a9825 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -430,7 +430,7 @@ uInt16 CartridgeCDF::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeCDF::bankCount() const +uInt16 CartridgeCDF::romBankCount() const { return 7; } diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 5e65bc4d4..7c5295f7a 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -104,7 +104,7 @@ class CartridgeCDF : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartCM.cxx b/src/emucore/CartCM.cxx index 5fa6dff3d..40ec603e5 100644 --- a/src/emucore/CartCM.cxx +++ b/src/emucore/CartCM.cxx @@ -163,7 +163,7 @@ uInt16 CartridgeCM::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeCM::bankCount() const +uInt16 CartridgeCM::romBankCount() const { // We report 4 banks (of ROM), even though RAM can overlap the upper 2K // of cart address space at some times diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index 2c0cf54d2..bf8b2586e 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -155,7 +155,7 @@ class CartridgeCM : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartCTY.cxx b/src/emucore/CartCTY.cxx index 1536b64e0..822473081 100644 --- a/src/emucore/CartCTY.cxx +++ b/src/emucore/CartCTY.cxx @@ -255,7 +255,7 @@ uInt16 CartridgeCTY::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeCTY::bankCount() const +uInt16 CartridgeCTY::romBankCount() const { return 8; } diff --git a/src/emucore/CartCTY.hxx b/src/emucore/CartCTY.hxx index 5626013a1..fdd6c1e19 100644 --- a/src/emucore/CartCTY.hxx +++ b/src/emucore/CartCTY.hxx @@ -153,7 +153,7 @@ class CartridgeCTY : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartDPC.cxx b/src/emucore/CartDPC.cxx index 808e658d4..c8a038c25 100644 --- a/src/emucore/CartDPC.cxx +++ b/src/emucore/CartDPC.cxx @@ -399,7 +399,7 @@ uInt16 CartridgeDPC::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDPC::bankCount() const +uInt16 CartridgeDPC::romBankCount() const { return 2; } diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index 330a0086a..6c186bfdb 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -85,7 +85,7 @@ class CartridgeDPC : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 0761eeb19..b71f5a8c0 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -619,7 +619,7 @@ uInt16 CartridgeDPCPlus::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDPCPlus::bankCount() const +uInt16 CartridgeDPCPlus::romBankCount() const { return 6; } diff --git a/src/emucore/CartDPCPlus.hxx b/src/emucore/CartDPCPlus.hxx index 46b18af99..9617d6545 100644 --- a/src/emucore/CartDPCPlus.hxx +++ b/src/emucore/CartDPCPlus.hxx @@ -100,7 +100,7 @@ class CartridgeDPCPlus : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 1a446a9a8..b8c1cde13 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -34,16 +34,19 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeEnhanced::install(System& system) { - // Copy the ROM image into my buffer - createRomAccessArrays(mySize); + // limit banked RAM size to the size of one RAM bank + uInt16 ramSize = myRamBankCount ? 1 << (myBankShift - 1) : myRamSize; // calculate bank switching and RAM sizes and masks myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 myBankMask = myBankSize - 1; // e.g. = 0x0FFF myBankSegs = 1 << (12 - myBankShift); // e.g. = 1 - myRamMask = myRamSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) - myWriteOffset = myRamWpHigh ? myRamSize : 0; - myReadOffset = myRamWpHigh ? 0 : myRamSize; + myRomOffset = myRamBankCount ? 0 : myRamSize * 2; + myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) + myWriteOffset = myRamWpHigh ? ramSize : 0; + myReadOffset = myRamWpHigh ? 0 : ramSize; + + createRomAccessArrays(mySize + (myRomOffset ? 0 : myRamSize)); // Allocate array for the current bank segments slices myCurrentSegOffset = make_unique(myBankSegs); @@ -51,41 +54,44 @@ void CartridgeEnhanced::install(System& system) // Allocate array for the RAM area myRAM = make_unique(myRamSize); - // Setup page access mySystem = &system; - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) + if(myRomOffset) { - uInt16 offset = addr & myRamMask; - access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; - access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset]; - access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize]; - mySystem->setPageAccess(addr, access); - } + // Setup page access for extended RAM; banked RAM will be setup in bank() + System::PageAccess access(this, System::PageAccessType::READ); - // Set the page accessing method for the RAM reading pages - access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE) - { - uInt16 offset = addr & myRamMask; - access.directPeekBase = &myRAM[offset]; - access.romAccessBase = &myRomAccessBase[myReadOffset + offset]; - access.romPeekCounter = &myRomAccessCounter[myReadOffset + offset]; - access.romPokeCounter = &myRomAccessCounter[myReadOffset + offset + myAccessSize]; - mySystem->setPageAccess(addr, access); + // Set the page accessing method for the RAM writing pages + // Map access to this class, since we need to inspect all accesses to + // check if RWP happens + access.type = System::PageAccessType::WRITE; + for(uInt16 addr = 0x1000 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) + { + uInt16 offset = addr & myRamMask; + access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; + access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset]; + access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } + + // Set the page accessing method for the RAM reading pages + access.type = System::PageAccessType::READ; + for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE) + { + uInt16 offset = addr & myRamMask; + access.directPeekBase = &myRAM[offset]; + access.romAccessBase = &myRomAccessBase[myReadOffset + offset]; + access.romPeekCounter = &myRomAccessCounter[myReadOffset + offset]; + access.romPokeCounter = &myRomAccessCounter[myReadOffset + offset + myAccessSize]; + mySystem->setPageAccess(addr, access); + } } // Install pages for the startup bank (TODO: currently only in first bank segment) bank(startBank(), 0); if(mySize >= 4_KB && myBankSegs > 1) // Setup the last bank segment to always point to the last ROM segment - bank(bankCount() - 1, myBankSegs - 1); + bank(romBankCount() - 1, myBankSegs - 1); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -106,63 +112,103 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) if (hotspot()) checkSwitchBank(address & 0x0FFF); - address &= myBankMask; - // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) - if(address < myReadOffset + myRamSize && address >= myReadOffset) + if(isRamBank(address)) + { + address &= myRamMask; + // This is a read access to a write port! - return peekRAM(myRAM[address], peekAddress); + // Reading from the write port triggers an unwanted write + // The RAM banks follow the ROM banks and are half the size of a ROM bank + return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address], + peekAddress); + } else - return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; + { + address &= myBankMask; + + // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) + if(address < myReadOffset + myRamSize && address >= myReadOffset) + // This is a read access to a write port! + // Reading from the write port triggers an unwanted write + return peekRAM(myRAM[address], peekAddress); + else + return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { - uInt16 pokeAddress = address; - // Switch banks if necessary + // Note: (TODO?) + // The checkSwitchBank() call makes no difference between ROM and e.g TIA space + // Writing to e.g. 0xf0xx might triger a bankswitch, is (and was!) this a bug??? if (checkSwitchBank(address & 0x0FFF, value)) return false; - address &= myBankMask; if(myRamSize) { - if(bool(address & myRamSize) == myRamWpHigh) + uInt16 pokeAddress = address; + + if(isRamBank(address)) { - pokeRAM(myRAM[address & myRamMask], pokeAddress, value); - return true; + if(bool(address & (myBankSize >> 1)) == myRamWpHigh) + { + address &= myRamMask; + // The RAM banks follow the ROM banks and are half the size of a ROM bank + pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address], + pokeAddress, value); + return true; + } + else + { + // Writing to the read port should be ignored, but trigger a break if option enabled + uInt8 dummy; + + pokeRAM(dummy, pokeAddress, value); + myRamWriteAccess = pokeAddress; + } } else { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; + //address &= myBankMask; + if(bool(address & myRamSize) == myRamWpHigh) + { + pokeRAM(myRAM[address & myRamMask], pokeAddress, value); + return true; + } + else + { + // Writing to the read port should be ignored, but trigger a break if option enabled + uInt8 dummy; - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; + pokeRAM(dummy, pokeAddress, value); + myRamWriteAccess = pokeAddress; + } } } return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM) +bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) { if(bankLocked()) return false; uInt16 segmentOffset = segment << myBankShift; - if(!isRAM) + if(!myRamBankCount || bank < romBankCount()) { // Setup ROM bank - // Remember what bank is in which segment - uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; - + uInt16 romBank = bank % romBankCount(); + // Remember what bank is in this segment + uInt32 bankOffset = myCurrentSegOffset[segment] = romBank << myBankShift; uInt16 hotspot = this->hotspot(); uInt16 hotSpotAddr; - uInt16 fromAddr = (segmentOffset + 0x1000 + myRamSize * 2) & ~System::PAGE_MASK; + uInt16 fromAddr = (0x1000 + segmentOffset + myRomOffset) & ~System::PAGE_MASK; // for ROMs < 4_KB, the whole address space will be mapped. - uInt16 toAddr = (segmentOffset + 0x1000 + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; + uInt16 toAddr = (0x1000 + segmentOffset + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; if(hotspot) hotSpotAddr = (hotspot & ~System::PAGE_MASK); @@ -185,24 +231,24 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM) mySystem->setPageAccess(addr, access); } } - /*else + else { // Setup RAM bank - // TODO: define offsets on init - uInt16 myWriteBankOffset = myBankSize >> 1; - uInt16 myReadBankOffset = 0; + uInt16 ramBank = (bank - romBankCount()) % myRamBankCount; + // The RAM banks follow the ROM banks and are half the size of a ROM bank + uInt32 bankOffset = uInt32(mySize) + (ramBank << (myBankShift - 1)); - // Remember what bank is in which segment - uInt32 bankOffset = myCurrentSegOffset[segment] = bank << myBankShift; + // Remember what bank is in this segment + myCurrentSegOffset[segment] = bank << myBankShift; // Set the page accessing method for the RAM writing pages - uInt16 fromAddr = (segmentOffset + myWriteBankOffset + 0x1000) & ~System::PAGE_MASK; - uInt16 toAddr = (segmentOffset + myWriteBankOffset + 0x1000 + myBankSize >> 1) & ~System::PAGE_MASK; + uInt16 fromAddr = (0x1000 + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; + uInt16 toAddr = (0x1000 + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; System::PageAccess access(this, System::PageAccessType::WRITE); for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) { - uInt32 offset = bankOffset + (addr & myBankMask); + uInt32 offset = bankOffset + (addr & myRamMask); access.romAccessBase = &myRomAccessBase[offset]; access.romPeekCounter = &myRomAccessCounter[offset]; @@ -211,25 +257,23 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment, bool isRAM) } // Set the page accessing method for the RAM reading pages - fromAddr = (segmentOffset + myReadBankOffset + 0x1000) & ~System::PAGE_MASK; - toAddr = (segmentOffset + myReadBankOffset + 0x1000 + myBankSize >> 1) & ~System::PAGE_MASK; - + fromAddr = (0x1000 + segmentOffset + myReadOffset) & ~System::PAGE_MASK; + toAddr = (0x1000 + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; access.type = System::PageAccessType::READ; + for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) { - uInt32 offset = bankOffset + (addr & myBankMask); + uInt32 offset = bankOffset + (addr & myRamMask); - - - uInt16 offset = addr & myRamMask; - access.directPeekBase = &myBankRAM[offset]; + access.directPeekBase = &myRAM[offset - mySize]; access.romAccessBase = &myRomAccessBase[offset]; access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; mySystem->setPageAccess(addr, access); } - }*/ + + } return myBankChanged = true; } @@ -246,23 +290,42 @@ uInt16 CartridgeEnhanced::getSegmentBank(uInt16 segment) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeEnhanced::bankCount() const +uInt16 CartridgeEnhanced::romBankCount() const { return uInt16(mySize >> myBankShift); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 CartridgeEnhanced::ramBankCount() const +{ + return myRamBankCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartridgeEnhanced::isRamBank(uInt16 address) const +{ + return myRamBankCount ? getBank(address) >= romBankCount() : false; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) { - if((address & myBankMask) < myRamSize * 2) + if(isRamBank(address)) { - // Normally, a write to the read port won't do anything - // However, the patch command is special in that ignores such - // cart restrictions - myRAM[address & myRamMask] = value; + myRAM[((myCurrentSegOffset[(address & 0xFFF) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value; } else - myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value; + { + if((address & myBankMask) < myRamSize * 2) + { + // Normally, a write to the read port won't do anything + // However, the patch command is special in that ignores such + // cart restrictions + myRAM[address & myRamMask] = value; + } + else + myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value; + } return myBankChanged = true; } diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 29046f0ea..3b68101cc 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -62,11 +62,10 @@ class CartridgeEnhanced : public Cartridge @param bank The bank that should be installed in the system @param segment The segment the bank should be using - @param isRAM True if the bank is a RAM bank @return true, if bank has changed */ - bool bank(uInt16 bank, uInt16 segment, bool isRAM = false); + bool bank(uInt16 bank, uInt16 segment); /** Install pages for the specified bank in the system. @@ -94,7 +93,21 @@ class CartridgeEnhanced : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; + + /** + Query the number of RAM 'banks' supported by the cartridge. + */ + uInt16 ramBankCount() const override; + + /** + Check if the segment at that address contains a RAM bank + + @param address The address which defines the segment + + @return true, if the segment is currently mapped to a RAM bank + */ + bool isRamBank(uInt16 address) const; /** Patch the cartridge ROM. @@ -162,9 +175,19 @@ class CartridgeEnhanced : public Cartridge // The extra RAM size uInt16 myRamSize{RAM_SIZE}; // default 0 + // The number of RAM banks + uInt16 myRamBankCount{RAM_BANKS}; // default 0 + // The mask for the extra RAM uInt16 myRamMask{0}; // RAM_SIZE - 1, but doesn't matter when RAM_SIZE is 0 + // The offset into ROM space for reading from ROM + // This is zero for types without RAM and with banked RAM + // - xxSC = 0x0100 + // - FA(2) = 0x0200 + // - CV = 0x0800 + uInt16 myRomOffset{0}; + // The offset into ROM space for writing to RAM // - xxSC = 0x0000 // - FA(2) = 0x0000 @@ -202,6 +225,9 @@ class CartridgeEnhanced : public Cartridge // The size of extra RAM in ROM address space static constexpr uInt16 RAM_SIZE = 0; // default = none + // The size of extra RAM in ROM address space + static constexpr uInt16 RAM_BANKS = 0; + // Write port for extra RAM is at low address by default static constexpr bool RAM_HIGH_WP = false; diff --git a/src/emucore/CartFC.cxx b/src/emucore/CartFC.cxx index 741935c06..925718d50 100644 --- a/src/emucore/CartFC.cxx +++ b/src/emucore/CartFC.cxx @@ -61,14 +61,14 @@ bool CartridgeFC::poke(uInt16 address, uInt8 value) case 0x0FF9: // Set the high bits of target 4k bank - if (value << 2 < bankCount()) + if (value << 2 < romBankCount()) { myTargetBank += value << 2; - myTargetBank %= bankCount(); + myTargetBank %= romBankCount(); } else // special handling when both values are identical (e.g. 4/4 or 5/5) - myTargetBank = value % bankCount(); + myTargetBank = value % romBankCount(); break; default: diff --git a/src/emucore/CartMNetwork.cxx b/src/emucore/CartMNetwork.cxx index c5ff0cfab..984769b17 100644 --- a/src/emucore/CartMNetwork.cxx +++ b/src/emucore/CartMNetwork.cxx @@ -36,7 +36,7 @@ void CartridgeMNetwork::initialize(const ByteBuffer& image, size_t size) std::copy_n(image.get(), std::min(romSize(), size), myImage.get()); createRomAccessArrays(romSize() + myRAM.size()); - myRAMSlice = bankCount() - 1; + myRAMSlice = romBankCount() - 1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -265,7 +265,7 @@ bool CartridgeMNetwork::patch(uInt16 address, uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const uInt8* CartridgeMNetwork::getImage(size_t& size) const { - size = bankCount() * BANK_SIZE; + size = romBankCount() * BANK_SIZE; return myImage.get(); } @@ -310,7 +310,7 @@ bool CartridgeMNetwork::load(Serializer& in) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeMNetwork::bankCount() const +uInt16 CartridgeMNetwork::romBankCount() const { return uInt16(mySize >> 11); } @@ -318,5 +318,5 @@ uInt16 CartridgeMNetwork::bankCount() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeMNetwork::romSize() const { - return bankCount() * BANK_SIZE; + return romBankCount() * BANK_SIZE; } diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index ef06aae57..dd9443390 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -108,7 +108,7 @@ class CartridgeMNetwork : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 58dd94522..56973392c 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -64,7 +64,7 @@ bool CartridgeSB::checkSwitchBank(uInt16 address, uInt8) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeSB::peek(uInt16 address) { - address &= (0x17FF + bankCount()); + address &= (0x17FF + romBankCount()); checkSwitchBank(address); @@ -82,7 +82,7 @@ uInt8 CartridgeSB::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeSB::poke(uInt16 address, uInt8 value) { - address &= (0x17FF + bankCount()); + address &= (0x17FF + romBankCount()); checkSwitchBank(address); diff --git a/src/emucore/CartSB.hxx b/src/emucore/CartSB.hxx index 3682dbb04..1e8a363a9 100644 --- a/src/emucore/CartSB.hxx +++ b/src/emucore/CartSB.hxx @@ -100,7 +100,7 @@ class CartridgeSB : public CartridgeEnhanced uInt16 hotspot() const override { return 0x0840; } - uInt16 getStartBank() const override { return bankCount() - 1; } + uInt16 getStartBank() const override { return romBankCount() - 1; } private: // Previous Device's page access diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index c6373fa05..9a14be24a 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -250,7 +250,7 @@ uInt16 CartridgeWD::getBank(uInt16) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeWD::bankCount() const +uInt16 CartridgeWD::romBankCount() const { return 16; } diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 0e2aad45c..88c59e469 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -101,7 +101,7 @@ class CartridgeWD : public Cartridge /** Query the number of banks supported by the cartridge. */ - uInt16 bankCount() const override; + uInt16 romBankCount() const override; /** Patch the cartridge ROM. diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 49ec158b0..bd5d87402 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -445,7 +445,7 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props) VarList::push_back(items, "Auto", "AUTO"); if(instance().hasConsole()) { - uInt16 numBanks = instance().console().cartridge().bankCount(); + uInt16 numBanks = instance().console().cartridge().romBankCount(); for(uInt16 i = 0; i < numBanks; ++i) VarList::push_back(items, i, i); From 1a6640a456d94174d621b2ccb465e6e1ed0b16bc Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 15 Apr 2020 20:59:06 +0200 Subject: [PATCH 20/52] refactored Cart3E+ --- src/debugger/gui/Cart3EPlusWidget.cxx | 196 ++++++-------- src/debugger/gui/CartDebugWidget.cxx | 2 +- src/emucore/Bankswitch.cxx | 2 +- src/emucore/Cart3E.cxx | 2 +- src/emucore/Cart3EPlus.cxx | 359 +++++--------------------- src/emucore/Cart3EPlus.hxx | 160 +++++------- src/emucore/CartEnhanced.cxx | 6 +- 7 files changed, 212 insertions(+), 515 deletions(-) diff --git a/src/debugger/gui/Cart3EPlusWidget.cxx b/src/debugger/gui/Cart3EPlusWidget.cxx index 74935f22b..a93cb8f98 100644 --- a/src/debugger/gui/Cart3EPlusWidget.cxx +++ b/src/debugger/gui/Cart3EPlusWidget.cxx @@ -30,8 +30,8 @@ Cartridge3EPlusWidget::Cartridge3EPlusWidget( size_t size = cart.mySize; ostringstream info; - info << "3EPlus cartridge - (64K ROM + RAM)\n" - << " 4-64K ROM (1K banks), 32K RAM (512b banks)\n" + info << "3EPlus cartridge - (4..64K ROM + RAM)\n" + << " 4..64K ROM (1K banks), ..32K RAM (512b banks)\n" << "Each 1K ROM selected by writing to $3F\n" "Each 512b RAM selected by writing to $3E\n" " Lower 512b of bank x (R)\n" @@ -39,83 +39,78 @@ Cartridge3EPlusWidget::Cartridge3EPlusWidget( << "Startup bank = 0/-1/-1/0 (ROM)\n"; // Eventually, we should query this from the debugger/disassembler - //uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; // Currently the cart starts at bank 0. If we change that, we have to change this too. uInt16 start = (cart.myImage[0x400-3] << 8) | cart.myImage[0x400 - 4]; - start -= start % 0x1000; - info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n"; + start &= 0xF000; + info << "Bank RORG = $" << Common::Base::HEX4 << start << "\n"; int xpos = 2, - ypos = addBaseInformation(size, "T. Jentzsch", info.str()) + - myLineHeight; + ypos = addBaseInformation(size, "Thomas Jentzsch", info.str()) + 8; VariantList bankno; - for(uInt32 i = 0; i < myCart.ROM_BANK_COUNT; ++i) + for(uInt32 i = 0; i < myCart.romBankCount(); ++i) VarList::push_back(bankno, i, i); VariantList banktype; VarList::push_back(banktype, "ROM", "ROM"); VarList::push_back(banktype, "RAM", "RAM"); - for(uInt32 i = 0; i < 4; ++i) + for(uInt32 seg = 0; seg < myCart.myBankSegs; ++seg) { - int xpos_s, ypos_s = ypos; + int xpos_s, ypos_s = ypos + 1; ostringstream label; - label << "Set segment " << i << " as "; + label << "Set segment " << seg << " as "; - new StaticTextWidget(boss, _font, xpos, ypos, _font.getStringWidth(label.str()), - myFontHeight, label.str(), TextAlign::Left); + new StaticTextWidget(boss, _font, xpos, ypos, label.str()); ypos += myLineHeight + 8; - xpos += 20; - myBankNumber[i] = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("Slot "), - myLineHeight, bankno, "Slot ", - 6*_font.getMaxCharWidth()); - addFocusWidget(myBankNumber[i]); + xpos += _font.getMaxCharWidth() * 2; + myBankNumber[seg] = + new PopUpWidget(boss, _font, xpos, ypos-2, 2 *_font.getMaxCharWidth(), + myLineHeight, bankno, "Bank "); + addFocusWidget(myBankNumber[seg]); - xpos += myBankNumber[i]->getWidth(); - myBankType[i] = - new PopUpWidget(boss, _font, xpos, ypos-2, 5*_font.getMaxCharWidth(), - myLineHeight, banktype, " of ", _font.getStringWidth(" of ")); - addFocusWidget(myBankType[i]); + xpos += myBankNumber[seg]->getWidth(); + myBankType[seg] = + new PopUpWidget(boss, _font, xpos, ypos-2, 3 *_font.getMaxCharWidth(), + myLineHeight, banktype, " of "); + addFocusWidget(myBankType[seg]); - xpos += myBankType[i]->getWidth() + 10; + xpos = myBankType[seg]->getRight() + _font.getMaxCharWidth(); - myBankCommit[i] = new ButtonWidget(boss, _font, xpos, ypos-4, + // add "Commit" button (why required?) + myBankCommit[seg] = new ButtonWidget(boss, _font, xpos, ypos-4, _font.getStringWidth(" Commit "), myButtonHeight, - "Commit", bankEnum[i]); - myBankCommit[i]->setTarget(this); - addFocusWidget(myBankCommit[i]); + "Commit", bankEnum[seg]); + myBankCommit[seg]->setTarget(this); + addFocusWidget(myBankCommit[seg]); - xpos_s = xpos + myBankCommit[i]->getWidth() + 20; + xpos_s = myBankCommit[seg]->getRight() + _font.getMaxCharWidth() * 2; StaticTextWidget* t; - int addr1 = start + (i*0x400), addr2 = addr1 + 0x1FF; + int addr1 = start + (seg * 0x400), addr2 = addr1 + 0x200; label.str(""); - label << Common::Base::HEX4 << addr1 << "-" << Common::Base::HEX4 << addr2; - t = new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, - _font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left); + label << "$" << Common::Base::HEX4 << addr1 << "-$" << Common::Base::HEX4 << (addr1 + 0x1FF); + t = new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, label.str()); - int xoffset = xpos_s+t->getWidth() + 10; - myBankState[2*i] = new EditTextWidget(boss, _font, xoffset, ypos_s, + int xoffset = t->getRight() + _font.getMaxCharWidth(); + myBankState[2*seg] = new EditTextWidget(boss, _font, xoffset, ypos_s, w - xoffset - 10, myLineHeight, ""); - myBankState[2*i]->setEditable(false, true); + myBankState[2*seg]->setEditable(false, true); ypos_s += myLineHeight + 4; label.str(""); - label << Common::Base::HEX4 << (addr2 + 1) << "-" << Common::Base::HEX4 << (addr2 + 1 + 0x1FF); - new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, - _font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left); + label << "$" << Common::Base::HEX4 << addr2 << "-$" << Common::Base::HEX4 << (addr2 + 0x1FF); + new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, label.str()); - myBankState[2*i+1] = new EditTextWidget(boss, _font, xoffset, ypos_s, + myBankState[2*seg+1] = new EditTextWidget(boss, _font, xoffset, ypos_s, w - xoffset - 10, myLineHeight, ""); - myBankState[2*i+1]->setEditable(false, true); + myBankState[2*seg+1]->setEditable(false, true); - xpos = 10; - ypos+= 2 * myLineHeight; + xpos = 2; + ypos += 2 * myLineHeight; } } @@ -163,15 +158,14 @@ void Cartridge3EPlusWidget::handleCommand(CommandSender* sender, myBankType[segment]->getSelected() < 0) return; - uInt8 bank = (segment << myCart.BANK_BITS) | - (myBankNumber[segment]->getSelected() & myCart.BIT_BANK_MASK); + uInt8 bank = myBankNumber[segment]->getSelected(); myCart.unlockBank(); if(myBankType[segment]->getSelectedTag() == "ROM") - myCart.bankROM(bank); + myCart.bank(bank, segment); else - myCart.bankRAM(bank); + myCart.bank(bank + myCart.romBankCount(), segment); myCart.lockBank(); invalidate(); @@ -183,26 +177,15 @@ string Cartridge3EPlusWidget::bankState() { ostringstream& buf = buffer(); - // In this scheme, consecutive 512b segments are either both ROM or both RAM; - // we only need to look at the lower segment to determine what the 1K bank is - for(int i = 0; i < 4; ++i) + for(int seg = 0; seg < myCart.myBankSegs; ++seg) { - uInt16 bank = myCart.bankInUse[i*2]; + int bank = myCart.getSegmentBank(seg); - if(bank == myCart.BANK_UNDEFINED) // never accessed - { - buf << " U!"; - } + if(bank >= myCart.romBankCount()) // was RAM mapped here? + buf << " RAM " << bank - myCart.romBankCount(); else - { - int bankno = bank & myCart.BIT_BANK_MASK; - - if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here? - buf << " RAM " << bankno; - else - buf << " ROM " << bankno; - } - if(i < 3) + buf << " ROM " << bank; + if(seg < myCart.myBankSegs - 1) buf << " /"; } @@ -212,68 +195,42 @@ string Cartridge3EPlusWidget::bankState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EPlusWidget::updateUIState() { - // Set description for each 512b bank state (@ each index) + // Set description for each 1K bank state (@ each index) // Set contents for actual banks number and type (@ each even index) - for(int i = 0; i < 8; ++i) + for(int seg = 0; seg < myCart.myBankSegs; ++seg) { - uInt16 bank = myCart.bankInUse[i]; + uInt16 bank = myCart.getSegmentBank(seg); + ostringstream buf; - if(bank == myCart.BANK_UNDEFINED) // never accessed + if(bank >= myCart.romBankCount()) // was RAM mapped here? { - myBankState[i]->setText("Undefined"); - if(i % 2 == 0) - { - myBankNumber[i/2]->clearSelection(); - myBankType[i/2]->clearSelection(); - } + uInt16 ramBank = bank - myCart.romBankCount(); + + buf << "RAM " << std::dec << ramBank << " @ $" << Common::Base::HEX4 + << (ramBank << myCart.myBankShift) << "(R)"; + myBankState[seg * 2]->setText(buf.str()); + + buf.str(""); + buf << "RAM " << std::dec << ramBank << " @ $" << Common::Base::HEX4 + << ((ramBank << myCart.myBankShift) + myCart.myBankSize) << "(W)"; + myBankState[seg * 2 + 1]->setText(buf.str()); + + myBankNumber[seg]->setSelected(ramBank); + myBankType[seg]->setSelected("RAM"); } else { - ostringstream buf; - int bankno = bank & myCart.BIT_BANK_MASK; + buf << "ROM " << std::dec << bank << " @ $" << Common::Base::HEX4 + << ((bank << myCart.myBankShift)); + myBankState[seg * 2]->setText(buf.str()); - if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here? - { - if(bank & myCart.BITMASK_LOWERUPPER) // upper is write port - { - buf << "RAM " << bankno << " @ $" << Common::Base::HEX4 - << (bankno << myCart.RAM_BANK_TO_POWER) << " (W)"; - myBankState[i]->setText(buf.str()); - } - else - { - buf << "RAM " << bankno << " @ $" << Common::Base::HEX4 - << (bankno << myCart.RAM_BANK_TO_POWER) << " (R)"; - myBankState[i]->setText(buf.str()); - } + buf.str(""); + buf << "ROM " << std::dec << bank << " @ $" << Common::Base::HEX4 + << ((bank << myCart.myBankShift) + myCart.myBankSize); + myBankState[seg * 2 + 1]->setText(buf.str()); - if(i % 2 == 0) - { - myBankNumber[i/2]->setSelected(bankno); - myBankType[i/2]->setSelected("RAM"); - } - } - else - { - if(bank & myCart.BITMASK_LOWERUPPER) // upper is high 512b - { - buf << "ROM " << bankno << " @ $" << Common::Base::HEX4 - << ((bankno << myCart.RAM_BANK_TO_POWER) + myCart.RAM_BANK_SIZE); - myBankState[i]->setText(buf.str()); - } - else - { - buf << "ROM " << bankno << " @ $" << Common::Base::HEX4 - << (bankno << myCart.RAM_BANK_TO_POWER); - myBankState[i]->setText(buf.str()); - } - - if(i % 2 == 0) - { - myBankNumber[i/2]->setSelected(bankno); - myBankType[i/2]->setSelected("ROM"); - } - } + myBankNumber[seg]->setSelected(bank); + myBankType[seg]->setSelected("ROM"); } } } @@ -294,9 +251,10 @@ uInt32 Cartridge3EPlusWidget::internalRamRPort(int start) string Cartridge3EPlusWidget::internalRamDescription() { ostringstream desc; + desc << "Accessible 512b at a time via:\n" << " $f000/$f400/$f800/$fc00 for Read Access\n" - << " $f200/$f600/$fa00/$fe00 for Write Access (+$200)"; + << " $f200/$f600/$fa00/$fe00 for Write Access"; return desc.str(); } diff --git a/src/debugger/gui/CartDebugWidget.cxx b/src/debugger/gui/CartDebugWidget.cxx index 9e164f4a6..208eec5a7 100644 --- a/src/debugger/gui/CartDebugWidget.cxx +++ b/src/debugger/gui/CartDebugWidget.cxx @@ -42,7 +42,7 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer const string& desc, const uInt16 maxlines) { const int lwidth = _font.getStringWidth("Manufacturer "), - fwidth = _w - lwidth - 20; + fwidth = _w - lwidth - 12; EditTextWidget* w = nullptr; ostringstream buf; diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx index 9726dc6aa..84d0dd037 100644 --- a/src/emucore/Bankswitch.cxx +++ b/src/emucore/Bankswitch.cxx @@ -105,7 +105,7 @@ Bankswitch::BSList = {{ { "128IN1" , "128IN1 Multicart (256/512K)" }, { "2K" , "2K (32-2048 bytes Atari)" }, { "3E" , "3E (32K Tigervision)" }, - { "3E+" , "3E+ (TJ modified DASH)" }, + { "3E+" , "3E+ (TJ modified 3E)" }, { "3F" , "3F (512K Tigervision)" }, { "4A50" , "4A50 (64K 4A50 + RAM)" }, { "4K" , "4K (4K Atari)" }, diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index a927ddd2d..3e7454bda 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -35,7 +35,7 @@ void Cartridge3E::install(System& system) { CartridgeEnhanced::install(system); - System::PageAccess access(this, System::PageAccessType::READWRITE); + System::PageAccess access(this, System::PageAccessType::WRITE); // The hotspots ($3E and $3F) are in TIA address space, so we claim it here for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 1fe28a022..f6ac01679 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -22,339 +22,104 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) -{ - // Allocate array for the ROM image - myImage = make_unique(mySize); + : CartridgeEnhanced(image, size, md5, settings) - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize + myRAM.size()); +{ + myBankShift = BANK_SHIFT; + myRamSize = RAM_SIZE; + myRamBankCount = RAM_BANKS; + myRamWpHigh = RAM_HIGH_WP; + + //// Allocate array for the ROM image + //myImage = make_unique(mySize); + + //// Copy the ROM image into my buffer + //std::copy_n(image.get(), mySize, myImage.get()); + //createRomAccessArrays(mySize + myRAM.size()); } +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//void Cartridge3EPlus::reset() +//{ +// initializeRAM(myRAM.data(), myRAM.size()); +// +// // Remember startup bank (0 per spec, rather than last per 3E scheme). +// // Set this to go to 3rd 1K Bank. +// initializeStartBank(0); +// +// // Initialise bank values for all ROM/RAM access +// // This is used to reverse-lookup from address to bank location +// for(auto& b: bankInUse) +// b = BANK_UNDEFINED; // bank is undefined and inaccessible! +// +// initializeBankState(); +// +// // We'll map the startup banks 0 and 3 from the image into the third 1K bank upon reset +// bankROM((0 << BANK_BITS) | 0); +// bankROM((3 << BANK_BITS) | 0); +//} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EPlus::reset() { - initializeRAM(myRAM.data(), myRAM.size()); + CartridgeEnhanced::reset(); - // Remember startup bank (0 per spec, rather than last per 3E scheme). - // Set this to go to 3rd 1K Bank. - initializeStartBank(0); - - // Initialise bank values for all ROM/RAM access - // This is used to reverse-lookup from address to bank location - for(auto& b: bankInUse) - b = BANK_UNDEFINED; // bank is undefined and inaccessible! - - initializeBankState(); - - // We'll map the startup banks 0 and 3 from the image into the third 1K bank upon reset - bankROM((0 << BANK_BITS) | 0); - bankROM((3 << BANK_BITS) | 0); + bank(mySystem->randGenerator().next() % romBankCount(), 1); + bank(mySystem->randGenerator().next() % romBankCount(), 2); + bank(startBank(), 3); // Stella reads the PC vector always from here (TODO?) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EPlus::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); - System::PageAccess access(this, System::PageAccessType::READWRITE); + System::PageAccess access(this, System::PageAccessType::WRITE); // The hotspots are in TIA address space, so we claim it here for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); - - // Initialise bank values for all ROM/RAM access - // This is used to reverse-lookup from address to bank location - for(auto& b: bankInUse) - b = BANK_UNDEFINED; // bank is undefined and inaccessible! - - initializeBankState(); - - // Setup the last segment (of 4, each 1K) to point to the first ROM slice - // Actually we DO NOT want "always". It's just on bootup, and can be out switched later - bankROM((0 << BANK_BITS) | 0); - bankROM((3 << BANK_BITS) | 0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3EPlus::getBank(uInt16 address) const +bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value) { - return bankInUse[(address & 0xFFF) >> 10]; // 1K slices -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 Cartridge3EPlus::romBankCount() const -{ - return uInt16(mySize >> 10); // 1K slices + // Switch banks if necessary + if(address == 0x003F) { + // Switch ROM bank into segment 0 + bank(value & 0b111111, value >> 6); + return true; + } + else if(address == 0x003E) + { + // Switch RAM bank into segment 0 + bank((value & 0b111111) + romBankCount(), value >> 6); + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 Cartridge3EPlus::peek(uInt16 address) { uInt16 peekAddress = address; - address &= 0x0FFF; // restrict to 4K address range + address &= 0x0FFF; - uInt8 value = 0; - uInt32 bank = (address >> (ROM_BANK_TO_POWER - 1)) & 7; // convert to 512 byte bank index (0-7) - uInt16 imageBank = bankInUse[bank]; // the ROM/RAM bank that's here + if(address < 0x0040) // TIA peek + return mySystem->tia().peek(address); - if(imageBank == BANK_UNDEFINED) // an uninitialised bank? - { - // accessing invalid bank, so return should be... random? - value = mySystem->randGenerator().next(); - - } - else if(imageBank & BITMASK_ROMRAM) // a RAM bank - { - Int32 ramBank = imageBank & BIT_BANK_MASK; // discard irrelevant bits - Int32 offset = ramBank << RAM_BANK_TO_POWER; // base bank address in RAM - offset += (address & BITMASK_RAM_BANK); // + byte offset in RAM bank - - return peekRAM(myRAM[offset], peekAddress); - } - - return value; + return CartridgeEnhanced::peek(peekAddress); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge3EPlus::poke(uInt16 address, uInt8 value) { - bool changed = false; + if(CartridgeEnhanced::poke(address, value)) + return true; - // Check for write to the bank switch address. RAM/ROM and bank # are encoded in 'value' - // There are NO mirrored hotspots. - - if(address == BANK_SWITCH_HOTSPOT_RAM) - changed = bankRAM(value); - else if(address == BANK_SWITCH_HOTSPOT_ROM) - changed = bankROM(value); - - if(!(address & 0x1000)) - { + if(address < 0x0040) // TIA poke // Handle TIA space that we claimed above - changed = changed || mySystem->tia().poke(address, value); - } - else - { - uInt32 bankNumber = (address >> RAM_BANK_TO_POWER) & 7; // now 512 byte bank # (ie: 0-7) - Int16 whichBankIsThere = bankInUse[bankNumber]; // ROM or RAM bank reference + return mySystem->tia().poke(address, value); - if(whichBankIsThere & BITMASK_ROMRAM) - { - if(address & RAM_BANK_SIZE) - { - uInt32 byteOffset = address & BITMASK_RAM_BANK; - uInt32 baseAddress = ((whichBankIsThere & BIT_BANK_MASK) << RAM_BANK_TO_POWER) + byteOffset; - pokeRAM(myRAM[baseAddress], address, value); - changed = true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - changed = false; - } - } - } - - return changed; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3EPlus::bankRAM(uInt8 bank) -{ - if(bankLocked()) // debugger can lock RAM - return false; - -//cerr << "bankRAM " << int(bank) << endl; - - // Each RAM bank uses two slots, separated by 0x200 in memory -- one read, one write. - bankRAMSlot(bank | BITMASK_ROMRAM | 0); - bankRAMSlot(bank | BITMASK_ROMRAM | BITMASK_LOWERUPPER); - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EPlus::bankRAMSlot(uInt16 bank) -{ - uInt16 bankNumber = (bank >> BANK_BITS) & 3; // which bank # we are switching TO (BITS D6,D7) to 512 byte block - uInt16 currentBank = bank & BIT_BANK_MASK; // Wrap around/restrict to valid range - bool upper = bank & BITMASK_LOWERUPPER; // is this the read or write port - - uInt32 startCurrentBank = currentBank << RAM_BANK_TO_POWER; // Effectively * 512 bytes -//cerr << "raw bank=" << std::dec << currentBank << endl -// << "startCurrentBank=$" << std::hex << startCurrentBank << endl; - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - if(upper) // We're mapping the write port - { - bankInUse[bankNumber * 2 + 1] = Int16(bank); - access.type = System::PageAccessType::WRITE; - } - else // We're mapping the read port - { - bankInUse[bankNumber * 2] = Int16(bank); - access.type = System::PageAccessType::READ; - } - - uInt16 start = 0x1000 + (bankNumber << (RAM_BANK_TO_POWER+1)) + (upper ? RAM_WRITE_OFFSET : 0); - uInt16 end = start + RAM_BANK_SIZE - 1; - -//cerr << "bank RAM: " << bankNumber << " -> " << (bankNumber * 2 + (upper ? 1 : 0)) << (upper ? " (W)" : " (R)") << endl -// << "start=" << std::hex << start << ", end=" << end << endl << endl; - for(uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE) - { - if(!upper) - access.directPeekBase = &myRAM[startCurrentBank + (addr & (RAM_BANK_SIZE - 1))]; - - access.romAccessBase = &myRomAccessBase[mySize + startCurrentBank + (addr & (RAM_BANK_SIZE - 1))]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3EPlus::bankROM(uInt8 bank) -{ - if(bankLocked()) // debugger can lock ROM - return false; - - // Map ROM bank image into the system into the correct slot - // Memory map is 1K slots at 0x1000, 0x1400, 0x1800, 0x1C00 - // Each ROM uses 2 consecutive 512 byte slots - bankROMSlot(bank | 0); - bankROMSlot(bank | BITMASK_LOWERUPPER); - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EPlus::bankROMSlot(uInt16 bank) -{ - uInt16 bankNumber = (bank >> BANK_BITS) & 3; // which bank # we are switching TO (BITS D6,D7) - uInt16 currentBank = bank & BIT_BANK_MASK; // Wrap around/restrict to valid range - bool upper = bank & BITMASK_LOWERUPPER; // is this the lower or upper 512b - - bankInUse[bankNumber * 2 + (upper ? 1 : 0)] = Int16(bank); // Record which bank switched in (as ROM) - - uInt32 startCurrentBank = currentBank << ROM_BANK_TO_POWER; // Effectively *1K - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - uInt16 start = 0x1000 + (bankNumber << ROM_BANK_TO_POWER) + (upper ? ROM_BANK_SIZE / 2 : 0); - uInt16 end = start + ROM_BANK_SIZE / 2 - 1; - - for(uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[startCurrentBank + (addr & (ROM_BANK_SIZE - 1))]; - access.romAccessBase = &myRomAccessBase[startCurrentBank + (addr & (ROM_BANK_SIZE - 1))]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EPlus::initializeBankState() -{ - // Switch in each 512b slot - for(uInt32 b = 0; b < 8; ++b) - { - if(bankInUse[b] == BANK_UNDEFINED) - { - // All accesses point to peek/poke above - System::PageAccess access(this, System::PageAccessType::READ); - uInt16 start = 0x1000 + (b << RAM_BANK_TO_POWER); - uInt16 end = start + RAM_BANK_SIZE - 1; - for(uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); - } - else if (bankInUse[b] & BITMASK_ROMRAM) - bankRAMSlot(bankInUse[b]); - else - bankROMSlot(bankInUse[b]); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3EPlus::patch(uInt16 address, uInt8 value) -{ -#if 0 - // Patch the cartridge ROM (for debugger) - - myBankChanged = true; - - uInt32 bankNumber = (address >> RAM_BANK_TO_POWER) & 7; // now 512 byte bank # (ie: 0-7) - uInt16 whichBankIsThere = bankInUse[bankNumber]; // ROM or RAM bank reference - - if (whichBankIsThere == BANK_UNDEFINED) { - - // We're trying to access undefined memory (no bank here yet). Fail! - myBankChanged = false; - - } else if (whichBankIsThere & BITMASK_ROMRAM) { // patching RAM (512 byte banks) - - uInt32 byteOffset = address & BITMASK_RAM_BANK; - uInt32 baseAddress = ((whichBankIsThere & BIT_BANK_MASK) << RAM_BANK_TO_POWER) + byteOffset; - myRAM[baseAddress] = value; // write to RAM - - // TODO: Stephen -- should we set 'myBankChanged' true when there's a RAM write? - - } else { // patching ROM (1K banks) - - uInt32 byteOffset = address & BITMASK_ROM_BANK; - uInt32 baseAddress = (whichBankIsThere << ROM_BANK_TO_POWER) + byteOffset; - myImage[baseAddress] = value; // write to the image - } - - return myBankChanged; -#else return false; -#endif -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* Cartridge3EPlus::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3EPlus::save(Serializer& out) const -{ - try - { - out.putShortArray(bankInUse.data(), bankInUse.size()); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch (...) - { - cerr << "ERROR: Cartridge3EPlus::save" << endl; - return false; - } - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool Cartridge3EPlus::load(Serializer& in) -{ - try - { - in.getShortArray(bankInUse.data(), bankInUse.size()); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch (...) - { - cerr << "ERROR: Cartridge3EPlus::load" << endl; - return false; - } - - initializeBankState(); - return true; } diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 70309d308..1a2440e40 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT class Cartridge3EPlusWidget; @@ -29,19 +29,67 @@ class Cartridge3EPlusWidget; #endif /** - Cartridge class from Thomas Jentzsch, mostly based on the 'DASH' scheme - with the following changes: + Cartridge class for new tiling engine "Boulder Dash" format games with RAM. + Kind of a combination of 3F and 3E, with better switchability. + B.Watson's Cart3E was used as a template for building this implementation. - RAM areas: - - read $x000, write $x200 - - read $x400, write $x600 - - read $x800, write $xa00 - - read $xc00, write $xe00 + The destination bank (0-3) is held in the top bits of the value written to + $3E (for RAM switching) or $3F (for ROM switching). The low 6 bits give + the actual bank number (0-63) corresponding to 512 byte blocks for RAM and + 1024 byte blocks for ROM. The maximum size is therefore 32K RAM and 64K ROM. - @author Thomas Jentzsch and Stephen Anthony + D7D6 indicate the bank number (0-3) + D5D4D3D2D1D0 indicate the actual # (0-63) from the image/ram + + ROM: + + Note: in descriptions $F000 is equivalent to $1000 -- that is, we only deal + with the low 13 bits of addressing. Stella code uses $1000, I'm used to $F000 + So, mask with top bits clear :) when reading this document. + + In this scheme, the 4K address space is broken into four 1K ROM/512b RAM segments + living at 0x1000, 0x1400, 0x1800, 0x1C00 (or, same thing, 0xF000... etc.), + + The last 1K ROM ($FC00-$FFFF) segment in the 6502 address space (ie: $1C00-$1FFF) + is initialised to point to the FIRST 1K of the ROM image, so the reset vectors + must be placed at the end of the first 1K in the ROM image. Note, this is + DIFFERENT to 3E which switches in the UPPER bank and this bank is fixed. This + allows variable sized ROM without having to detect size. First bank (0) in ROM is + the default fixed bank mapped to $FC00. + + The system requires the reset vectors to be valid on a reset, so either the + hardware first switches in the first bank, or the programmer must ensure + that the reset vector is present in ALL ROM banks which might be switched + into the last bank area. Currently the latter (programmer onus) is required, + but it would be nice for the cartridge hardware to auto-switch on reset. + + ROM switching (write of block+bank number to $3F) D7D6 upper 2 bits of bank # + indicates the destination segment (0-3, corresponding to $F000, $F400, $F800, + $FC00), and lower 6 bits indicate the 1K bank to switch in. Can handle 64 + x 1K ROM banks (64K total). + + D7 D6 D5D4D3D2D1D0 + 0 0 x x x x x x switch a 1K ROM bank xxxxxx to $F000 + 0 1 switch a 1K ROM bank xxxxxx to $F400 + 1 0 switch a 1K ROM bank xxxxxx to $F800 + 1 1 switch a 1K ROM bank xxxxxx to $FC00 + + RAM switching (write of segment+bank number to $3E) with D7D6 upper 2 bits of + bank # indicates the destination RAM segment (0-3, corresponding to $F000, + $F400, $F800, $FC00). + + Can handle 64 x 512 byte RAM banks (32K total) + + D7 D6 D5D4D3D2D1D0 + 0 0 x x x x x x switch a 512 byte RAM bank xxxxxx to $F000 with write @ $F200 + 0 1 switch a 512 byte RAM bank xxxxxx to $F400 with write @ $F600 + 1 0 switch a 512 byte RAM bank xxxxxx to $F800 with write @ $FA00 + 1 1 switch a 512 byte RAM bank xxxxxx to $FC00 with write @ $FE00 + + @author Thomas Jentzsch and Stephen Anthony */ -class Cartridge3EPlus: public Cartridge +class Cartridge3EPlus: public CartridgeEnhanced { friend class Cartridge3EPlusWidget; @@ -70,51 +118,6 @@ class Cartridge3EPlus: public Cartridge */ void install(System& system) override; - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 romBankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - /** Get a descriptor for the device name (used in error checking). @@ -152,47 +155,20 @@ class Cartridge3EPlus: public Cartridge bool poke(uInt16 address, uInt8 value) override; private: - bool bankRAM(uInt8 bank); // switch a RAM bank - bool bankROM(uInt8 bank); // switch a ROM bank + bool checkSwitchBank(uInt16 address, uInt8 value) override; - void bankRAMSlot(uInt16 bank); // switch in a 512b RAM slot (lower or upper 1/2 bank) - void bankROMSlot(uInt16 bank); // switch in a 512b RAM slot (read or write port) + private: + // log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 10; // = 1K = 0x0400 - void initializeBankState(); // set all banks according to current bankInUse state + // The size of extra RAM in ROM address space + static constexpr uInt16 RAM_BANKS = 64; - // We have an array that indicates for each of the 8 512 byte areas of the address space, which ROM/RAM - // bank is used in that area. ROM switches 1K so occupies 2 successive entries for each switch. RAM occupies - // two as well, one 512 byte for read and one for write. The RAM locations are +0x800 apart, and the ROM - // are consecutive. This allows us to determine on a read/write exactly where the data is. + // RAM size + static constexpr uInt16 RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000; - static constexpr uInt16 BANK_UNDEFINED = 0x8000; // bank is undefined and inaccessible - std::array bankInUse; // bank being used for ROM/RAM (eight 512 byte areas) - - static constexpr uInt16 BANK_SWITCH_HOTSPOT_RAM = 0x3E; // writes to this address cause bankswitching - static constexpr uInt16 BANK_SWITCH_HOTSPOT_ROM = 0x3F; // writes to this address cause bankswitching - - static constexpr uInt8 BANK_BITS = 6; // # bits for bank - static constexpr uInt8 BIT_BANK_MASK = (1 << BANK_BITS) - 1; // mask for those bits - static constexpr uInt16 BITMASK_LOWERUPPER = 0x100; // flags lower or upper section of bank (1==upper) - static constexpr uInt16 BITMASK_ROMRAM = 0x200; // flags ROM or RAM bank switching (1==RAM) - - static constexpr uInt16 MAXIMUM_BANK_COUNT = (1 << BANK_BITS); - static constexpr uInt16 RAM_BANK_TO_POWER = 9; // 2^n = 512 - static constexpr uInt16 RAM_BANK_SIZE = (1 << RAM_BANK_TO_POWER); - static constexpr uInt16 BITMASK_RAM_BANK = (RAM_BANK_SIZE - 1); - static constexpr uInt32 RAM_TOTAL_SIZE = MAXIMUM_BANK_COUNT * RAM_BANK_SIZE; - - static constexpr uInt16 ROM_BANK_TO_POWER = 10; // 2^n = 1024 - static constexpr uInt16 ROM_BANK_SIZE = (1 << ROM_BANK_TO_POWER); - static constexpr uInt16 BITMASK_ROM_BANK = (ROM_BANK_SIZE - 1); - - static constexpr uInt16 ROM_BANK_COUNT = 64; - - static constexpr uInt16 RAM_WRITE_OFFSET = 0x200; - - ByteBuffer myImage; // Pointer to a dynamically allocated ROM image of the cartridge - size_t mySize{0}; // Size of the ROM image - std::array myRAM; + // Write port for extra RAM is at high address + static constexpr bool RAM_HIGH_WP = true; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index b8c1cde13..01cf5cbcb 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -20,7 +20,7 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) + const string& md5, const Settings& settings) : Cartridge(settings, md5), mySize(size) { @@ -270,9 +270,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; mySystem->setPageAccess(addr, access); - } - - + } } return myBankChanged = true; } From 668fb487ba137cd42be5064b5fd14a3dc5a72957 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 15 Apr 2020 21:15:44 +0200 Subject: [PATCH 21/52] removed DASH type (incl. doc update) --- Changes.txt | 2 +- docs/index.html | 3 +- src/debugger/gui/CartDASHWidget.cxx | 371 ---------------------------- src/debugger/gui/CartDASHWidget.hxx | 86 ------- src/debugger/gui/module.mk | 1 - src/emucore/Bankswitch.cxx | 4 - src/emucore/Bankswitch.hxx | 10 +- src/emucore/CartDASH.cxx | 355 -------------------------- src/emucore/CartDASH.hxx | 277 --------------------- src/emucore/CartDetector.cxx | 15 +- src/emucore/CartDetector.hxx | 5 - src/emucore/module.mk | 1 - src/windows/Stella.vcxproj | 8 - src/windows/Stella.vcxproj.filters | 12 - 14 files changed, 8 insertions(+), 1142 deletions(-) delete mode 100644 src/debugger/gui/CartDASHWidget.cxx delete mode 100644 src/debugger/gui/CartDASHWidget.hxx delete mode 100644 src/emucore/CartDASH.cxx delete mode 100644 src/emucore/CartDASH.hxx diff --git a/Changes.txt b/Changes.txt index 7a6b7bc3d..e7faac008 100644 --- a/Changes.txt +++ b/Changes.txt @@ -30,7 +30,7 @@ * Restored 'cfg' directory for Distella config files. - * Removed unused CV+ bank switching type. + * Removed unused CV+ and DASH bank switching types. -Have fun! diff --git a/docs/index.html b/docs/index.html index b0065878b..18aa916dc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3781,7 +3781,7 @@ Ms Pac-Man (Stella extended codes): - + @@ -3794,7 +3794,6 @@ Ms Pac-Man (Stella extended codes): - diff --git a/src/debugger/gui/CartDASHWidget.cxx b/src/debugger/gui/CartDASHWidget.cxx deleted file mode 100644 index a3dfa1109..000000000 --- a/src/debugger/gui/CartDASHWidget.cxx +++ /dev/null @@ -1,371 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#include "CartDASH.hxx" -#include "EditTextWidget.hxx" -#include "PopUpWidget.hxx" -#include "CartDASHWidget.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartridgeDASHWidget::CartridgeDASHWidget( - GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, - int x, int y, int w, int h, CartridgeDASH& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) -{ - size_t size = cart.mySize; - - ostringstream info; - info << "DASH cartridge - (64K ROM + RAM)\n" - << " 4-64K ROM (1K banks), 32K RAM (512b banks)\n" - << "Each 1K ROM selected by writing to $3F\n" - "Each 512b RAM selected by writing to $3E\n" - " First 512B of bank x (R)\n" - " First 512B of bank x+4 (+$800) (W)\n" - << "Startup bank = 0/-1/-1/0 (ROM)\n"; - - // Eventually, we should query this from the debugger/disassembler - uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; - start -= start % 0x1000; - info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n"; - - int xpos = 2, - ypos = addBaseInformation(size, "A. Davie & T. Jentzsch", info.str()) + - myLineHeight; - - VariantList bankno; - for(uInt32 i = 0; i < myCart.ROM_BANK_COUNT; ++i) - VarList::push_back(bankno, i, i); - - VariantList banktype; - VarList::push_back(banktype, "ROM", "ROM"); - VarList::push_back(banktype, "RAM", "RAM"); - - for(uInt32 i = 0; i < 4; ++i) - { - int xpos_s, ypos_s = ypos; - - ostringstream label; - label << "Set segment " << i << " as: "; - - new StaticTextWidget(boss, _font, xpos, ypos, _font.getStringWidth(label.str()), - myFontHeight, label.str(), TextAlign::Left); - ypos += myLineHeight + 8; - - xpos += 20; - myBankNumber[i] = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("Slot "), - myLineHeight, bankno, "Slot ", - 6*_font.getMaxCharWidth()); - addFocusWidget(myBankNumber[i]); - - xpos += myBankNumber[i]->getWidth(); - myBankType[i] = - new PopUpWidget(boss, _font, xpos, ypos-2, 5*_font.getMaxCharWidth(), - myLineHeight, banktype, " of ", _font.getStringWidth(" of ")); - addFocusWidget(myBankType[i]); - - xpos += myBankType[i]->getWidth() + 10; - - myBankCommit[i] = new ButtonWidget(boss, _font, xpos, ypos-4, - _font.getStringWidth(" Commit "), myButtonHeight, - "Commit", bankEnum[i]); - myBankCommit[i]->setTarget(this); - addFocusWidget(myBankCommit[i]); - - xpos_s = xpos + myBankCommit[i]->getWidth() + 20; - - StaticTextWidget* t; - int addr1 = start + (i*0x400), addr2 = addr1 + 0x1FF; - - label.str(""); - label << Common::Base::HEX4 << addr1 << "-" << Common::Base::HEX4 << addr2; - t = new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, - _font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left); - - int xoffset = xpos_s+t->getWidth() + 10; - myBankState[2*i] = new EditTextWidget(boss, _font, xoffset, ypos_s, - w - xoffset - 10, myLineHeight, ""); - myBankState[2*i]->setEditable(false, true); - ypos_s += myLineHeight + 4; - - label.str(""); - label << Common::Base::HEX4 << (addr2 + 1) << "-" << Common::Base::HEX4 << (addr2 + 1 + 0x1FF); - new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, - _font.getStringWidth(label.str()), myFontHeight, label.str(), TextAlign::Left); - - myBankState[2*i+1] = new EditTextWidget(boss, _font, xoffset, ypos_s, - w - xoffset - 10, myLineHeight, ""); - myBankState[2*i+1]->setEditable(false, true); - - xpos = 10; - ypos+= 2 * myLineHeight; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASHWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASHWidget::loadConfig() -{ - updateUIState(); - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASHWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - uInt16 segment = 0; - switch(cmd) - { - case kBank0Changed: - segment = 0; - break; - case kBank1Changed: - segment = 1; - break; - case kBank2Changed: - segment = 2; - break; - case kBank3Changed: - segment = 3; - break; - default: - break; - } - - // Ignore bank if either number or type hasn't been selected - if(myBankNumber[segment]->getSelected() < 0 || - myBankType[segment]->getSelected() < 0) - return; - - uInt8 bank = (segment << myCart.BANK_BITS) | - (myBankNumber[segment]->getSelected() & myCart.BIT_BANK_MASK); - - myCart.unlockBank(); - - if(myBankType[segment]->getSelectedTag() == "ROM") - myCart.bankROM(bank); - else - myCart.bankRAM(bank); - - myCart.lockBank(); - invalidate(); - updateUIState(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeDASHWidget::bankState() -{ - ostringstream& buf = buffer(); - int lastROMBank = -1; - bool lastSlotRAM = false; - - for(int i = 0; i < 8; ++i) - { - uInt16 bank = myCart.bankInUse[i]; - - if(bank == myCart.BANK_UNDEFINED) // never accessed - { - buf << " U!"; - } - else - { - int bankno = bank & myCart.BIT_BANK_MASK; - - if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here? - { - // RAM will always need a '+' placed somewhere, since it always - // consists of 512B segments - bool inFirstSlot = (i % 2 == 0); - if(!(inFirstSlot || lastSlotRAM)) - { - lastSlotRAM = false; - buf << " +"; - } - - if(bank & myCart.BITMASK_LOWERUPPER) // upper is write port - buf << " RAM " << bankno << "W"; - else - buf << " RAM " << bankno << "R"; - - if(inFirstSlot) - { - buf << " +"; - lastSlotRAM = true; - } - } - else - { - // ROM can be contiguous, since 2 512B segments can form a single - // 1K bank; in this case we only show the info once - bool highBankSame = (i % 2 == 1) && (bankno == lastROMBank); - if(!highBankSame) - { - buf << " ROM " << bankno; - lastROMBank = bankno; - } - else - lastROMBank = -1; - - lastSlotRAM = false; - } - } - - if((i+1) % 2 == 0 && i < 7) - buf << " /"; - } - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASHWidget::updateUIState() -{ - // Set contents for actual banks number and type - for(int i = 0; i < 4; ++i) - { - uInt16 segment = myCart.segmentInUse[i]; - - if(segment == myCart.BANK_UNDEFINED) - { - myBankNumber[i]->clearSelection(); - myBankType[i]->clearSelection(); - } - else - { - int bankno = segment & myCart.BIT_BANK_MASK; - const string& banktype = (segment & myCart.BITMASK_ROMRAM) ? "RAM" : "ROM"; - - myBankNumber[i]->setSelected(bankno); - myBankType[i]->setSelected(banktype); - } - } - - // Set description for each 512b bank state - for(int i = 0; i < 8; ++i) - { - uInt16 bank = myCart.bankInUse[i]; - - if(bank == myCart.BANK_UNDEFINED) // never accessed - { - myBankState[i]->setText("Undefined"); - } - else - { - ostringstream buf; - int bankno = bank & myCart.BIT_BANK_MASK; - - if(bank & myCart.BITMASK_ROMRAM) // was RAM mapped here? - { - if(bank & myCart.BITMASK_LOWERUPPER) // upper is write port - { - buf << "RAM " << bankno << " @ $" << Common::Base::HEX4 - << (bankno << myCart.RAM_BANK_TO_POWER) << " (W)"; - myBankState[i]->setText(buf.str()); - } - else - { - buf << "RAM " << bankno << " @ $" << Common::Base::HEX4 - << (bankno << myCart.RAM_BANK_TO_POWER) << " (R)"; - myBankState[i]->setText(buf.str()); - } - } - else - { - if(bank & myCart.BITMASK_LOWERUPPER) // upper is high 512b - { - buf << "ROM " << bankno << " @ $" << Common::Base::HEX4 - << ((bankno << myCart.RAM_BANK_TO_POWER) + myCart.RAM_BANK_SIZE); - myBankState[i]->setText(buf.str()); - } - else - { - buf << "ROM " << bankno << " @ $" << Common::Base::HEX4 - << (bankno << myCart.RAM_BANK_TO_POWER); - myBankState[i]->setText(buf.str()); - } - } - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeDASHWidget::internalRamSize() -{ - return 32*1024; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeDASHWidget::internalRamRPort(int start) -{ - return 0x0000 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeDASHWidget::internalRamDescription() -{ - ostringstream desc; - desc << "Accessible 512b at a time via:\n" - << " $F000/$F200/$F400/etc used for Read Access\n" - << " $F800/$FA00/$FC00/etc used for Write Access (+$800)"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeDASHWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeDASHWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASHWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeDASHWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const std::array CartridgeDASHWidget::bankEnum = { - kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed -}; diff --git a/src/debugger/gui/CartDASHWidget.hxx b/src/debugger/gui/CartDASHWidget.hxx deleted file mode 100644 index e738c2292..000000000 --- a/src/debugger/gui/CartDASHWidget.hxx +++ /dev/null @@ -1,86 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#ifndef CARTRIDGEDASH_WIDGET_HXX -#define CARTRIDGEDASH_WIDGET_HXX - -class CartridgeDASH; -class ButtonWidget; -class EditTextWidget; -class PopUpWidget; - -#include "CartDebugWidget.hxx" - -class CartridgeDASHWidget : public CartDebugWidget -{ - public: - CartridgeDASHWidget(GuiObject* boss, const GUI::Font& lfont, - const GUI::Font& nfont, - int x, int y, int w, int h, - CartridgeDASH& cart); - virtual ~CartridgeDASHWidget() = default; - - private: - void updateUIState(); - - private: - CartridgeDASH& myCart; - - std::array myBankNumber{nullptr}; - std::array myBankType{nullptr}; - std::array myBankCommit{nullptr}; - std::array myBankState{nullptr}; - - struct CartState { - ByteArray internalram; - }; - CartState myOldState; - - enum BankID { - kBank0Changed = 'b0CH', - kBank1Changed = 'b1CH', - kBank2Changed = 'b2CH', - kBank3Changed = 'b3CH' - }; - static const std::array bankEnum; - - private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - // end of functions for Cartridge RAM tab - - // Following constructors and assignment operators not supported - CartridgeDASHWidget() = delete; - CartridgeDASHWidget(const CartridgeDASHWidget&) = delete; - CartridgeDASHWidget(CartridgeDASHWidget&&) = delete; - CartridgeDASHWidget& operator=(const CartridgeDASHWidget&) = delete; - CartridgeDASHWidget& operator=(CartridgeDASHWidget&&) = delete; -}; - -#endif diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index 522d31cf4..f4f94387f 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -23,7 +23,6 @@ MODULE_OBJS := \ src/debugger/gui/CartCMWidget.o \ src/debugger/gui/CartCTYWidget.o \ src/debugger/gui/CartCVWidget.o \ - src/debugger/gui/CartDASHWidget.o \ src/debugger/gui/CartDFSCWidget.o \ src/debugger/gui/CartDFWidget.o \ src/debugger/gui/CartDPCPlusWidget.o \ diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx index 84d0dd037..7ce52db58 100644 --- a/src/emucore/Bankswitch.cxx +++ b/src/emucore/Bankswitch.cxx @@ -118,7 +118,6 @@ Bankswitch::BSList = {{ { "CM" , "CM (SpectraVideo CompuMate)" }, { "CTY" , "CTY (CDW - Chetiry)" }, { "CV" , "CV (Commavid extra RAM)" }, - { "DASH" , "DASH (Experimental)" }, { "DF" , "DF (CPUWIZ 128K)" }, { "DFSC" , "DFSC (CPUWIZ 128K + RAM)" }, { "DPC" , "DPC (Pitfall II)" }, @@ -196,8 +195,6 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = { { "CM" , Bankswitch::Type::_CM }, { "CTY" , Bankswitch::Type::_CTY }, { "CV" , Bankswitch::Type::_CV }, - { "DAS" , Bankswitch::Type::_DASH }, - { "DASH" , Bankswitch::Type::_DASH }, { "DF" , Bankswitch::Type::_DF }, { "DFS" , Bankswitch::Type::_DFSC }, { "DFSC" , Bankswitch::Type::_DFSC }, @@ -260,7 +257,6 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = { { "CM" , Bankswitch::Type::_CM }, { "CTY" , Bankswitch::Type::_CTY }, { "CV" , Bankswitch::Type::_CV }, - { "DASH" , Bankswitch::Type::_DASH }, { "DF" , Bankswitch::Type::_DF }, { "DFSC" , Bankswitch::Type::_DFSC }, { "DPC" , Bankswitch::Type::_DPC }, diff --git a/src/emucore/Bankswitch.hxx b/src/emucore/Bankswitch.hxx index 4ed7cc445..9021a21ed 100644 --- a/src/emucore/Bankswitch.hxx +++ b/src/emucore/Bankswitch.hxx @@ -41,11 +41,11 @@ class Bankswitch _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, _64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50, _4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF, - _CM, _CTY, _CV, _DASH, _DF, _DFSC, _DPC, - _DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0, - _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, - _FA2, _FC, _FE, _MDM, _SB, _UA, _UASW, - _WD, _WDSW, _X07, + _CM, _CTY, _CV, _DF, _DFSC, _DPC, _DPCP, + _E0, _E7, _E78K, _EF, _EFSC, _F0, _F4, + _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, _FA2, + _FC, _FE, _MDM, _SB, _UA, _UASW, _WD, + _WDSW, _X07, #ifdef CUSTOM_ARM _CUSTOM, #endif diff --git a/src/emucore/CartDASH.cxx b/src/emucore/CartDASH.cxx deleted file mode 100644 index 6e187d76a..000000000 --- a/src/emucore/CartDASH.cxx +++ /dev/null @@ -1,355 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#include "System.hxx" -#include "TIA.hxx" -#include "CartDASH.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartridgeDASH::CartridgeDASH(const ByteBuffer& image, size_t size, - const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) -{ - // Allocate array for the ROM image - myImage = make_unique(mySize); - - // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); - createRomAccessArrays(mySize + myRAM.size()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASH::reset() -{ - initializeRAM(myRAM.data(), myRAM.size()); - - // Remember startup bank (0 per spec, rather than last per 3E scheme). - // Set this to go to 3rd 1K Bank. - initializeStartBank(0); - - // Initialise bank values for all ROM/RAM access - // This is used to reverse-lookup from address to bank location - for(uInt32 b = 0; b < 8; ++b) - { - bankInUse[b] = BANK_UNDEFINED; // bank is undefined and inaccessible! - segmentInUse[b/2] = BANK_UNDEFINED; - } - initializeBankState(); - - // We'll map the startup banks 0 and 3 from the image into the third 1K bank upon reset - bankROM((0 << BANK_BITS) | 0); - bankROM((3 << BANK_BITS) | 0); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASH::install(System& system) -{ - mySystem = &system; - - System::PageAccess access(this, System::PageAccessType::READWRITE); - - // The hotspots are in TIA address space, so we claim it here - for (uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); - - // Initialise bank values for all ROM/RAM access - // This is used to reverse-lookup from address to bank location - for (uInt32 b = 0; b < 8; ++b) - { - bankInUse[b] = BANK_UNDEFINED; // bank is undefined and inaccessible! - segmentInUse[b/2] = BANK_UNDEFINED; - } - initializeBankState(); - - // Setup the last segment (of 4, each 1K) to point to the first ROM slice - // Actually we DO NOT want "always". It's just on bootup, and can be out switched later - bankROM((0 << BANK_BITS) | 0); - bankROM((3 << BANK_BITS) | 0); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeDASH::peek(uInt16 address) -{ - uInt16 peekAddress = address; - address &= 0x0FFF; // restrict to 4K address range - - uInt8 value = 0; - uInt32 bank = (address >> (ROM_BANK_TO_POWER - 1)) & 7; // convert to 512 byte bank index (0-7) - uInt16 imageBank = bankInUse[bank]; // the ROM/RAM bank that's here - - if(imageBank == BANK_UNDEFINED) // an uninitialised bank? - { - // accessing invalid bank, so return should be... random? - value = mySystem->randGenerator().next(); - - } - else if(imageBank & BITMASK_ROMRAM) // a RAM bank - { - Int32 ramBank = imageBank & BIT_BANK_MASK; // discard irrelevant bits - Int32 offset = ramBank << RAM_BANK_TO_POWER; // base bank address in RAM - offset += (address & BITMASK_RAM_BANK); // + byte offset in RAM bank - - return peekRAM(myRAM[offset], peekAddress); - } - - return value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDASH::poke(uInt16 address, uInt8 value) -{ - bool changed = false; - - // Check for write to the bank switch address. RAM/ROM and bank # are encoded in 'value' - // There are NO mirrored hotspots. - - if (address == BANK_SWITCH_HOTSPOT_RAM) - changed = bankRAM(value); - else if (address == BANK_SWITCH_HOTSPOT_ROM) - changed = bankROM(value); - - if(!(address & 0x1000)) - { - // Handle TIA space that we claimed above - changed = changed || mySystem->tia().poke(address, value); - } - else - { - uInt32 bankNumber = (address >> RAM_BANK_TO_POWER) & 7; // now 512 byte bank # (ie: 0-7) - Int16 whichBankIsThere = bankInUse[bankNumber]; // ROM or RAM bank reference - - if(whichBankIsThere & BITMASK_ROMRAM) - { - if(address & RAM_BANK_SIZE) - { - uInt32 byteOffset = address & BITMASK_RAM_BANK; - uInt32 baseAddress = ((whichBankIsThere & BIT_BANK_MASK) << RAM_BANK_TO_POWER) + byteOffset; - pokeRAM(myRAM[baseAddress], address, value); - changed = true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - changed = false; - } - } - } - - return changed; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDASH::bankRAM(uInt8 bank) -{ - if (bankLocked()) // debugger can lock RAM - return false; - - // Each RAM bank uses two slots, separated by 0x800 in memory -- one read, one write. - bankRAMSlot(bank | BITMASK_ROMRAM | 0); - bankRAMSlot(bank | BITMASK_ROMRAM | BITMASK_LOWERUPPER); - - // Remember that this hotspot was accessed for RAM - segmentInUse[(bank >> BANK_BITS) & 3] = bank | BITMASK_ROMRAM; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASH::bankRAMSlot(uInt16 bank) -{ - uInt16 bankNumber = (bank >> BANK_BITS) & 3; // which bank # we are switching TO (BITS D6,D7) to 512 byte block - uInt16 currentBank = bank & BIT_BANK_MASK; // Wrap around/restrict to valid range - bool upper = bank & BITMASK_LOWERUPPER; // is this the read or write port - - uInt32 startCurrentBank = currentBank << RAM_BANK_TO_POWER; // Effectively * 512 bytes - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - if(upper) // We're mapping the write port - { - bankInUse[bankNumber + 4] = Int16(bank); - access.type = System::PageAccessType::WRITE; - } - else // We're mapping the read port - { - bankInUse[bankNumber] = Int16(bank); - access.type = System::PageAccessType::READ; - } - - uInt16 start = 0x1000 + (bankNumber << RAM_BANK_TO_POWER) + (upper ? RAM_WRITE_OFFSET : 0); - uInt16 end = start + RAM_BANK_SIZE - 1; - - for (uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE) - { - if(!upper) - access.directPeekBase = &myRAM[startCurrentBank + (addr & (RAM_BANK_SIZE - 1))]; - - access.romAccessBase = &myRomAccessBase[mySize + startCurrentBank + (addr & (RAM_BANK_SIZE - 1))]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDASH::bankROM(uInt8 bank) -{ - if (bankLocked()) // debugger can lock ROM - return false; - - // Map ROM bank image into the system into the correct slot - // Memory map is 1K slots at 0x1000, 0x1400, 0x1800, 0x1C00 - // Each ROM uses 2 consecutive 512 byte slots - bankROMSlot(bank | 0); - bankROMSlot(bank | BITMASK_LOWERUPPER); - - // Remember that this hotspot was accessed for ROM - segmentInUse[(bank >> BANK_BITS) & 3] = bank; - - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASH::bankROMSlot(uInt16 bank) -{ - uInt16 bankNumber = (bank >> BANK_BITS) & 3; // which bank # we are switching TO (BITS D6,D7) - uInt16 currentBank = bank & BIT_BANK_MASK; // Wrap around/restrict to valid range - bool upper = bank & BITMASK_LOWERUPPER; // is this the lower or upper 512b - - bankInUse[bankNumber * 2 + (upper ? 1 : 0)] = Int16(bank); // Record which bank switched in (as ROM) - - uInt32 startCurrentBank = currentBank << ROM_BANK_TO_POWER; // Effectively *1K - - // Setup the page access methods for the current bank - System::PageAccess access(this, System::PageAccessType::READ); - - uInt16 start = 0x1000 + (bankNumber << ROM_BANK_TO_POWER) + (upper ? ROM_BANK_SIZE / 2 : 0); - uInt16 end = start + ROM_BANK_SIZE / 2 - 1; - - for (uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE) - { - access.directPeekBase = &myImage[startCurrentBank + (addr & (ROM_BANK_SIZE - 1))]; - access.romAccessBase = &myRomAccessBase[startCurrentBank + (addr & (ROM_BANK_SIZE - 1))]; - mySystem->setPageAccess(addr, access); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDASH::initializeBankState() -{ - // Switch in each 512b slot - for(uInt32 b = 0; b < 8; ++b) - { - if(bankInUse[b] == BANK_UNDEFINED) - { - // All accesses point to peek/poke above - System::PageAccess access(this, System::PageAccessType::READ); - uInt16 start = 0x1000 + (b << RAM_BANK_TO_POWER); - uInt16 end = start + RAM_BANK_SIZE - 1; - for (uInt16 addr = start; addr <= end; addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); - } - else if (bankInUse[b] & BITMASK_ROMRAM) - bankRAMSlot(bankInUse[b]); - else - bankROMSlot(bankInUse[b]); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDASH::patch(uInt16 address, uInt8 value) -{ -#if 0 - // Patch the cartridge ROM (for debugger) - - myBankChanged = true; - - uInt32 bankNumber = (address >> RAM_BANK_TO_POWER) & 7; // now 512 byte bank # (ie: 0-7) - Int16 whichBankIsThere = bankInUse[bankNumber]; // ROM or RAM bank reference - - if (whichBankIsThere == BANK_UNDEFINED) { - - // We're trying to access undefined memory (no bank here yet). Fail! - myBankChanged = false; - - } else if (whichBankIsThere & BITMASK_ROMRAM) { // patching RAM (512 byte banks) - - uInt32 byteOffset = address & BITMASK_RAM_BANK; - uInt32 baseAddress = ((whichBankIsThere & BIT_BANK_MASK) << RAM_BANK_TO_POWER) + byteOffset; - myRAM[baseAddress] = value; // write to RAM - - // TODO: Stephen -- should we set 'myBankChanged' true when there's a RAM write? - - } else { // patching ROM (1K banks) - - uInt32 byteOffset = address & BITMASK_ROM_BANK; - uInt32 baseAddress = (whichBankIsThere << ROM_BANK_TO_POWER) + byteOffset; - myImage[baseAddress] = value; // write to the image - } - - return myBankChanged; -#else - return false; -#endif -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeDASH::getImage(size_t& size) const -{ - size = mySize; - return myImage.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDASH::save(Serializer& out) const -{ - try - { - out.putShortArray(bankInUse.data(), bankInUse.size()); - out.putShortArray(segmentInUse.data(), segmentInUse.size()); - out.putByteArray(myRAM.data(), myRAM.size()); - } - catch (...) - { - cerr << "ERROR: CartridgeDASH::save" << endl; - return false; - } - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDASH::load(Serializer& in) -{ - try - { - in.getShortArray(bankInUse.data(), bankInUse.size()); - in.getShortArray(segmentInUse.data(), segmentInUse.size()); - in.getByteArray(myRAM.data(), myRAM.size()); - } - catch (...) - { - cerr << "ERROR: CartridgeDASH::load" << endl; - return false; - } - - initializeBankState(); - return true; -} diff --git a/src/emucore/CartDASH.hxx b/src/emucore/CartDASH.hxx deleted file mode 100644 index 8bd9fa523..000000000 --- a/src/emucore/CartDASH.hxx +++ /dev/null @@ -1,277 +0,0 @@ -//============================================================================ -// -// 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 -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#ifndef CARTRIDGEDASH_HXX -#define CARTRIDGEDASH_HXX - -class System; - -#include "bspf.hxx" -#include "Cart.hxx" - -#ifdef DEBUGGER_SUPPORT -class CartridgeDASHWidget; - #include "CartDASHWidget.hxx" -#endif - -/** - Cartridge class for new tiling engine "Boulder Dash" format games with RAM. - Kind of a combination of 3F and 3E, with better switchability. - B.Watson's Cart3E was used as a template for building this implementation. - - The destination bank (0-3) is held in the top bits of the value written to - $3E (for RAM switching) or $3F (for ROM switching). The low 6 bits give - the actual bank number (0-63) corresponding to 512 byte blocks for RAM and - 1024 byte blocks for ROM. The maximum size is therefore 32K RAM and 64K ROM. - - D7D6 indicate the bank number (0-3) - D5D4D3D2D1D0 indicate the actual # (0-63) from the image/ram - - ROM: - - Note: in descriptions $F000 is equivalent to $1000 -- that is, we only deal - with the low 13 bits of addressing. Stella code uses $1000, I'm used to $F000 - So, mask with top bits clear :) when reading this document. - - In this scheme, the 4K address space is broken into four 1K ROM segments. - living at 0x1000, 0x1400, 0x1800, 0x1C00 (or, same thing, 0xF000... etc.), - and four 512 byte RAM segments, living at 0x1000, 0x1200, 0x1400, 0x1600 - with write-mirrors +0x800 of these. The last 1K ROM ($FC00-$FFFF) segment - in the 6502 address space (ie: $1C00-$1FFF) is initialised to point to the - FIRST 1K of the ROM image, so the reset vectors must be placed at the - end of the first 1K in the ROM image. Note, this is DIFFERENT to 3E which - switches in the UPPER bank and this bank is fixed. This allows variable sized - ROM without having to detect size. First bank (0) in ROM is the default fixed - bank mapped to $FC00. - - The system requires the reset vectors to be valid on a reset, so either the - hardware first switches in the first bank, or the programmer must ensure - that the reset vector is present in ALL ROM banks which might be switched - into the last bank area. Currently the latter (programmer onus) is required, - but it would be nice for the cartridge hardware to auto-switch on reset. - - ROM switching (write of block+bank number to $3F) D7D6 upper 2 bits of bank # - indicates the destination segment (0-3, corresponding to $F000, $F400, $F800, - $FC00), and lower 6 bits indicate the 1K bank to switch in. Can handle 64 - x 1K ROM banks (64K total). - - D7 D6 D5D4D3D2D1D0 - 0 0 x x x x x x switch a 1K ROM bank xxxxx to $F000 - 0 1 switch a 1K ROM bank xxxxx to $F400 - 1 0 switch a 1K ROM bank xxxxx to $F800 - 1 1 switch a 1K ROM bank xxxxx to $FC00 - - RAM switching (write of segment+bank number to $3E) with D7D6 upper 2 bits of - bank # indicates the destination RAM segment (0-3, corresponding to $F000, - $F200, $F400, $F600). Note that this allows contiguous 2K of RAM to be - configured by setting 4 consecutive RAM segments each 512 bytes with - consecutive addresses. However, as the write address of RAM is +0x800, this - invalidates ROM access as described below. - - can handle 64 x 512 byte RAM banks (32K total) - - D7 D6 D5D4D3D2D1D0 - 0 0 x x x x x x switch a 512 byte RAM bank xxxxx to $F000 with write @ $F800 - 0 1 switch a 512 byte RAM bank xxxxx to $F200 with write @ $FA00 - 1 0 switch a 512 byte RAM bank xxxxx to $F400 with write @ $FC00 - 1 1 switch a 512 byte RAM bank xxxxx to $F600 with write @ $FE00 - - It is possible to switch multiple RAM banks and ROM banks together - - For example, - F000-F1FF RAM bank A (512 byte READ) - F200-F3FF high 512 bytes of ROM bank previously loaded at F000 - F400 ROM bank 0 (1K) - F800 RAM bank A (512 byte WRITE) - FA00-FBFF high 512 bytes of ROM bank previously loaded at F400 - FC00 ROM bank 1 - - This example shows 512 bytes of RAM, and 2 1K ROM banks and two 512 byte ROM - bank halves. - - Switching RAM blocks (D7D6 of $3E) partially invalidates ROM blocks, as below... - - RAM block Invalidates ROM block - 0 0 (lower half), 2 (lower half) - 1 0 (upper half), 2 (upper half) - 2 1 (lower half), 3 (upper half) - 3 1 (upper half), 3 (lower half) - - For example, RAM block 1 uses address $F200-$F3FF and $FA00-$FBFF - ROM block 0 uses address $F000-$F3FF, and ROM block 2 uses address $F800-$FBFF - Switching in RAM block 1 makes F200-F3FF ROM inaccessible, however F000-F1FF is - still readable. So, care must be paid. - - This crazy RAM layout is useful as it allows contiguous RAM to be switched in, - up to 2K in one sequentially accessible block. This means you CAN have 2K of - consecutive RAM (don't forget to copy your reset vectors!) - - @author Andrew Davie -*/ - -class CartridgeDASH: public Cartridge -{ - friend class CartridgeDASHWidget; - - public: - /** - Create a new cartridge using the specified image and size - - @param image Pointer to the ROM image - @param size The size of the ROM image - @param md5 The md5sum of the ROM image - @param settings A reference to the various settings (read-only) - */ - CartridgeDASH(const ByteBuffer& image, size_t size, const string& md5, - const Settings& settings); - virtual ~CartridgeDASH() = default; - - public: - /** Reset device to its power-on state */ - void reset() override; - - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - - /** - Save the current state of this cart to the given Serializer. - - @param out The Serializer object to use - @return False on any errors, else true - */ - bool save(Serializer& out) const override; - - /** - Load the current state of this cart from the given Serializer. - - @param in The Serializer object to use - @return False on any errors, else true - */ - bool load(Serializer& in) override; - - /** - Get a descriptor for the device name (used in error checking). - - @return The name of the object - */ - string name() const override { return "CartridgeDASH"; } - - #ifdef DEBUGGER_SUPPORT - /** - Get debugger widget responsible for accessing the inner workings - of the cart. - */ - CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, - const GUI::Font& nfont, int x, int y, int w, int h) override - { - return new CartridgeDASHWidget(boss, lfont, nfont, x, y, w, h, *this); - } - #endif - - public: - /** - Get the byte at the specified address - - @return The byte at the specified address - */ - uInt8 peek(uInt16 address) override; - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - @return True if the poke changed the device address space, else false - */ - bool poke(uInt16 address, uInt8 value) override; - - private: - bool bankRAM(uInt8 bank); // switch a RAM bank - bool bankROM(uInt8 bank); // switch a ROM bank - - void bankRAMSlot(uInt16 bank); // switch in a 512b RAM slot (lower or upper 1/2 bank) - void bankROMSlot(uInt16 bank); // switch in a 512b RAM slot (read or write port) - - void initializeBankState(); // set all banks according to current bankInUse state - - // We have an array that indicates for each of the 8 512 byte areas of the address space, which ROM/RAM - // bank is used in that area. ROM switches 1K so occupies 2 successive entries for each switch. RAM occupies - // two as well, one 512 byte for read and one for write. The RAM locations are +0x800 apart, and the ROM - // are consecutive. This allows us to determine on a read/write exactly where the data is. - - static constexpr uInt16 BANK_UNDEFINED = 0x8000; // bank is undefined and inaccessible - std::array bankInUse; // bank being used for ROM/RAM (eight 512 byte areas) - std::array segmentInUse; // set by bank methods, to know which hotspot was accessed - - static constexpr uInt16 BANK_SWITCH_HOTSPOT_RAM = 0x3E; // writes to this address cause bankswitching - static constexpr uInt16 BANK_SWITCH_HOTSPOT_ROM = 0x3F; // writes to this address cause bankswitching - - static constexpr uInt8 BANK_BITS = 6; // # bits for bank - static constexpr uInt8 BIT_BANK_MASK = (1 << BANK_BITS) - 1; // mask for those bits - static constexpr uInt16 BITMASK_LOWERUPPER = 0x100; // flags lower or upper section of bank (1==upper) - static constexpr uInt16 BITMASK_ROMRAM = 0x200; // flags ROM or RAM bank switching (1==RAM) - - static constexpr uInt16 MAXIMUM_BANK_COUNT = (1 << BANK_BITS); - static constexpr uInt16 RAM_BANK_TO_POWER = 9; // 2^n = 512 - static constexpr uInt16 RAM_BANK_SIZE = (1 << RAM_BANK_TO_POWER); - static constexpr uInt16 BITMASK_RAM_BANK = (RAM_BANK_SIZE - 1); - static constexpr uInt32 RAM_TOTAL_SIZE = MAXIMUM_BANK_COUNT * RAM_BANK_SIZE; - - static constexpr uInt16 ROM_BANK_TO_POWER = 10; // 2^n = 1024 - static constexpr uInt16 ROM_BANK_SIZE = (1 << ROM_BANK_TO_POWER); - static constexpr uInt16 BITMASK_ROM_BANK = (ROM_BANK_SIZE - 1); - - static constexpr uInt16 ROM_BANK_COUNT = 64; - - static constexpr uInt16 RAM_WRITE_OFFSET = 0x800; - - ByteBuffer myImage; // Pointer to a dynamically allocated ROM image of the cartridge - size_t mySize{0}; // Size of the ROM image - std::array myRAM; - - private: - // Following constructors and assignment operators not supported - CartridgeDASH() = delete; - CartridgeDASH(const CartridgeDASH&) = delete; - CartridgeDASH(CartridgeDASH&&) = delete; - CartridgeDASH& operator=(const CartridgeDASH&) = delete; - CartridgeDASH& operator=(CartridgeDASH&&) = delete; -}; - -#endif diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 09e0def71..4d7a583eb 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -33,7 +33,6 @@ #include "CartCM.hxx" #include "CartCTY.hxx" #include "CartCV.hxx" -#include "CartDASH.hxx" #include "CartDF.hxx" #include "CartDFSC.hxx" #include "CartDPC.hxx" @@ -277,8 +276,6 @@ CartDetector::createFromImage(const ByteBuffer& image, size_t size, Bankswitch:: return make_unique(image, size, md5, settings); case Bankswitch::Type::_CV: return make_unique(image, size, md5, settings); - case Bankswitch::Type::_DASH: - return make_unique(image, size, md5, settings); case Bankswitch::Type::_DF: return make_unique(image, size, md5, settings); case Bankswitch::Type::_DFSC: @@ -522,9 +519,7 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } // Variable sized ROM formats are independent of image size and come last - if(isProbablyDASH(image, size)) - type = Bankswitch::Type::_DASH; - else if(isProbably3EPlus(image, size)) + if(isProbably3EPlus(image, size)) type = Bankswitch::Type::_3EP; else if(isProbablyMDM(image, size)) type = Bankswitch::Type::_MDM; @@ -750,14 +745,6 @@ bool CartDetector::isProbablyCV(const ByteBuffer& image, size_t size) return searchForBytes(image.get(), size, signature[1], 3, 1); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartDetector::isProbablyDASH(const ByteBuffer& image, size_t size) -{ - // DASH cart is identified key 'TJAD' in the ROM - uInt8 tjad[] = { 'T', 'J', 'A', 'D' }; - return searchForBytes(image.get(), size, tjad, 4, 1); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbablyDF(const ByteBuffer& image, size_t size, Bankswitch::Type& type) diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 8f9d04ac9..63a98b053 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -175,11 +175,6 @@ class CartDetector */ static bool isProbablyCV(const ByteBuffer& image, size_t size); - /** - Returns true if the image is probably a DASH bankswitching cartridge - */ - static bool isProbablyDASH(const ByteBuffer& image, size_t size); - /** Returns true if the image is probably a DF/DFSC bankswitching cartridge */ diff --git a/src/emucore/module.mk b/src/emucore/module.mk index 4b72d3b22..9c81e28ec 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -21,7 +21,6 @@ MODULE_OBJS := \ src/emucore/CartCM.o \ src/emucore/CartCTY.o \ src/emucore/CartCV.o \ - src/emucore/CartDASH.o \ src/emucore/CartDPC.o \ src/emucore/CartDPCPlus.o \ src/emucore/CartE0.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 46fd9a877..b081dde0d 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -588,9 +588,6 @@ true - - true - true @@ -721,7 +718,6 @@ - @@ -1595,9 +1591,6 @@ true - - true - true @@ -1740,7 +1733,6 @@ - diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 8f9d893f8..f0c9b601d 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -723,9 +723,6 @@ Source Files\emucore - - Source Files\emucore - Source Files\debugger @@ -735,9 +732,6 @@ Source Files\debugger - - Source Files\debugger - Source Files\emucore @@ -1703,9 +1697,6 @@ Header Files\emucore - - Header Files\emucore - Header Files\debugger @@ -1715,9 +1706,6 @@ Header Files\debugger - - Header Files\debugger - Header Files\emucore From 13dfed21828b4f407492eddaa90b46e0733a4b13 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 16 Apr 2020 09:40:15 +0200 Subject: [PATCH 22/52] fix some Clang-Tidy warnings small bugfix for CartFA2 --- src/emucore/Cart3E.cxx | 2 +- src/emucore/Cart3EPlus.cxx | 2 +- src/emucore/CartBF.cxx | 2 +- src/emucore/CartDF.cxx | 2 +- src/emucore/CartEF.cxx | 2 +- src/emucore/CartEnhanced.cxx | 68 ++++++++++++++++++------------------ src/emucore/CartEnhanced.hxx | 10 ++++++ src/emucore/CartFA2.cxx | 6 ++-- src/emucore/CartFE.cxx | 2 +- src/emucore/CartSB.cxx | 3 +- 10 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/emucore/Cart3E.cxx b/src/emucore/Cart3E.cxx index 3e7454bda..642ac6ce1 100644 --- a/src/emucore/Cart3E.cxx +++ b/src/emucore/Cart3E.cxx @@ -64,7 +64,7 @@ bool Cartridge3E::checkSwitchBank(uInt16 address, uInt8 value) uInt8 Cartridge3E::peek(uInt16 address) { uInt16 peekAddress = address; - address &= 0x0FFF; + address &= ROM_MASK; if(address < 0x0040) // TIA access return mySystem->tia().peek(address); diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index f6ac01679..274e1f9db 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -103,7 +103,7 @@ bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value) uInt8 Cartridge3EPlus::peek(uInt16 address) { uInt16 peekAddress = address; - address &= 0x0FFF; + address &= ROM_MASK; if(address < 0x0040) // TIA peek return mySystem->tia().peek(address); diff --git a/src/emucore/CartBF.cxx b/src/emucore/CartBF.cxx index 0d1921c17..ce3c53198 100644 --- a/src/emucore/CartBF.cxx +++ b/src/emucore/CartBF.cxx @@ -30,7 +30,7 @@ bool CartridgeBF::checkSwitchBank(uInt16 address, uInt8) { // Due to the way addressing is set up, we will only get here if the // address is in the hotspot range ($1F80 - $1FFF) - address &= 0x0FFF; + address &= ROM_MASK; // Switch banks if necessary if((address >= 0x0F80) && (address <= 0x0FBF)) diff --git a/src/emucore/CartDF.cxx b/src/emucore/CartDF.cxx index db9ab62d2..0f4d9a1ca 100644 --- a/src/emucore/CartDF.cxx +++ b/src/emucore/CartDF.cxx @@ -28,7 +28,7 @@ CartridgeDF::CartridgeDF(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDF::checkSwitchBank(uInt16 address, uInt8) { - address &= 0x0FFF; + address &= ROM_MASK; // Switch banks if necessary if((address >= 0x0FC0) && (address <= 0x0FDF)) diff --git a/src/emucore/CartEF.cxx b/src/emucore/CartEF.cxx index 70cd8236b..039f4aa5c 100644 --- a/src/emucore/CartEF.cxx +++ b/src/emucore/CartEF.cxx @@ -28,7 +28,7 @@ CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEF::checkSwitchBank(uInt16 address, uInt8) { - address &= 0x0FFF; + address &= ROM_MASK; // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FEF)) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 01cf5cbcb..5816181f2 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -35,18 +35,18 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, void CartridgeEnhanced::install(System& system) { // limit banked RAM size to the size of one RAM bank - uInt16 ramSize = myRamBankCount ? 1 << (myBankShift - 1) : myRamSize; + uInt16 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : myRamSize; // calculate bank switching and RAM sizes and masks - myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 - myBankMask = myBankSize - 1; // e.g. = 0x0FFF - myBankSegs = 1 << (12 - myBankShift); // e.g. = 1 - myRomOffset = myRamBankCount ? 0 : myRamSize * 2; - myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) - myWriteOffset = myRamWpHigh ? ramSize : 0; - myReadOffset = myRamWpHigh ? 0 : ramSize; + myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 + myBankMask = myBankSize - 1; // e.g. = 0x0FFF + myBankSegs = 1 << (MAX_BANK_SHIFT - myBankShift); // e.g. = 1 + myRomOffset = myRamBankCount > 0 ? 0 : myRamSize * 2; + myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) + myWriteOffset = myRamWpHigh ? ramSize : 0; // e.g. = 0x0000 + myReadOffset = myRamWpHigh ? 0 : ramSize; // e.g. = 0x0080 - createRomAccessArrays(mySize + (myRomOffset ? 0 : myRamSize)); + createRomAccessArrays(mySize + (myRomOffset > 0 ? 0 : myRamSize)); // Allocate array for the current bank segments slices myCurrentSegOffset = make_unique(myBankSegs); @@ -56,7 +56,7 @@ void CartridgeEnhanced::install(System& system) mySystem = &system; - if(myRomOffset) + if(myRomOffset > 0) { // Setup page access for extended RAM; banked RAM will be setup in bank() System::PageAccess access(this, System::PageAccessType::READ); @@ -65,7 +65,7 @@ void CartridgeEnhanced::install(System& system) // Map access to this class, since we need to inspect all accesses to // check if RWP happens access.type = System::PageAccessType::WRITE; - for(uInt16 addr = 0x1000 + myWriteOffset; addr < 0x1000 + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; @@ -76,7 +76,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; - for(uInt16 addr = 0x1000 + myReadOffset; addr < 0x1000 + myReadOffset + myRamSize; addr += System::PAGE_SIZE) + for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; access.directPeekBase = &myRAM[offset]; @@ -110,8 +110,8 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - if (hotspot()) - checkSwitchBank(address & 0x0FFF); + if (hotspot() != 0) + checkSwitchBank(address & ROM_MASK); if(isRamBank(address)) { @@ -120,7 +120,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // This is a read access to a write port! // Reading from the write port triggers an unwanted write // The RAM banks follow the ROM banks and are half the size of a ROM bank - return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address], + return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], peekAddress); } else @@ -133,7 +133,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // Reading from the write port triggers an unwanted write return peekRAM(myRAM[address], peekAddress); else - return myImage[myCurrentSegOffset[(peekAddress & 0xFFF) >> myBankShift] + address]; + return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] + address]; } } @@ -144,10 +144,10 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) // Note: (TODO?) // The checkSwitchBank() call makes no difference between ROM and e.g TIA space // Writing to e.g. 0xf0xx might triger a bankswitch, is (and was!) this a bug??? - if (checkSwitchBank(address & 0x0FFF, value)) + if (checkSwitchBank(address & ROM_MASK, value)) return false; - if(myRamSize) + if(myRamSize > 0) { uInt16 pokeAddress = address; @@ -157,7 +157,7 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { address &= myRamMask; // The RAM banks follow the ROM banks and are half the size of a ROM bank - pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & 0xFFF) >> myBankShift] - mySize) >> 1) + address], + pokeRAM(myRAM[((myCurrentSegOffset[(pokeAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], pokeAddress, value); return true; } @@ -198,7 +198,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt16 segmentOffset = segment << myBankShift; - if(!myRamBankCount || bank < romBankCount()) + if(myRamBankCount == 0 || bank < romBankCount()) { // Setup ROM bank uInt16 romBank = bank % romBankCount(); @@ -206,11 +206,11 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt32 bankOffset = myCurrentSegOffset[segment] = romBank << myBankShift; uInt16 hotspot = this->hotspot(); uInt16 hotSpotAddr; - uInt16 fromAddr = (0x1000 + segmentOffset + myRomOffset) & ~System::PAGE_MASK; + uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myRomOffset) & ~System::PAGE_MASK; // for ROMs < 4_KB, the whole address space will be mapped. - uInt16 toAddr = (0x1000 + segmentOffset + (mySize < 4_KB ? 0x1000 : myBankSize)) & ~System::PAGE_MASK; + uInt16 toAddr = (ROM_OFFSET + segmentOffset + (mySize < 4_KB ? 4_KB : myBankSize)) & ~System::PAGE_MASK; - if(hotspot) + if(hotspot != 0) hotSpotAddr = (hotspot & ~System::PAGE_MASK); else hotSpotAddr = 0xFFFF; // none @@ -242,8 +242,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) myCurrentSegOffset[segment] = bank << myBankShift; // Set the page accessing method for the RAM writing pages - uInt16 fromAddr = (0x1000 + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; - uInt16 toAddr = (0x1000 + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; + uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myWriteOffset) & ~System::PAGE_MASK; + uInt16 toAddr = (ROM_OFFSET + segmentOffset + myWriteOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; System::PageAccess access(this, System::PageAccessType::WRITE); for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) @@ -257,8 +257,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) } // Set the page accessing method for the RAM reading pages - fromAddr = (0x1000 + segmentOffset + myReadOffset) & ~System::PAGE_MASK; - toAddr = (0x1000 + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; + fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK; + toAddr = (ROM_OFFSET + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; access.type = System::PageAccessType::READ; for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) @@ -270,7 +270,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; mySystem->setPageAccess(addr, access); - } + } } return myBankChanged = true; } @@ -278,7 +278,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeEnhanced::getBank(uInt16 address) const { - return myCurrentSegOffset[(address & 0xFFF) >> myBankShift] >> myBankShift; + return myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] >> myBankShift; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -302,7 +302,7 @@ uInt16 CartridgeEnhanced::ramBankCount() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeEnhanced::isRamBank(uInt16 address) const { - return myRamBankCount ? getBank(address) >= romBankCount() : false; + return myRamBankCount > 0 ? getBank(address) >= romBankCount() : false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -310,7 +310,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) { if(isRamBank(address)) { - myRAM[((myCurrentSegOffset[(address & 0xFFF) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value; + myRAM[((myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] - mySize) >> 1) + (address & myRamMask)] = value; } else { @@ -322,7 +322,7 @@ bool CartridgeEnhanced::patch(uInt16 address, uInt8 value) myRAM[address & myRamMask] = value; } else - myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)] = value; + myImage[myCurrentSegOffset[(address & ROM_MASK) >> myBankShift] + (address & myBankMask)] = value; } return myBankChanged = true; @@ -341,7 +341,7 @@ bool CartridgeEnhanced::save(Serializer& out) const try { out.putIntArray(myCurrentSegOffset.get(), myBankSegs); - if(myRamSize) + if(myRamSize > 0) out.putByteArray(myRAM.get(), myRamSize); } catch(...) @@ -359,7 +359,7 @@ bool CartridgeEnhanced::load(Serializer& in) try { in.getIntArray(myCurrentSegOffset.get(), myBankSegs); - if(myRamSize) + if(myRamSize > 0) in.getByteArray(myRAM.get(), myRamSize); } catch(...) diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 3b68101cc..e66aeb9f5 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -218,6 +218,13 @@ class CartridgeEnhanced : public Cartridge // The size of the ROM image size_t mySize{0}; + protected: + // The offset into address space for accessing ROM + static constexpr uInt16 ROM_OFFSET = 0x1000; + + // The mask for ROM address space + static constexpr uInt16 ROM_MASK = 0x0FFF; + private: // Calculated as: log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 12; // default = 4K @@ -231,6 +238,9 @@ class CartridgeEnhanced : public Cartridge // Write port for extra RAM is at low address by default static constexpr bool RAM_HIGH_WP = false; + // The maximum shift (for a 4K bank size) + static constexpr uInt16 MAX_BANK_SHIFT = 12; ; // -> 4K + protected: /** Check hotspots and switch bank if triggered. diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 1e4251988..6662e8171 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -35,7 +35,7 @@ CartridgeFA2::CartridgeFA2(const ByteBuffer& image, size_t size, myImage = make_unique(mySize); // Copy the ROM image into my buffer - std::copy_n(image.get(), mySize, myImage.get()); + std::copy_n(img_ptr, mySize, myImage.get()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -53,7 +53,7 @@ bool CartridgeFA2::checkSwitchBank(uInt16 address, uInt8) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeFA2::peek(uInt16 address) { - if((address & 0x0FFF) == 0x0FF4) + if((address & ROM_MASK) == 0x0FF4) { // Load/save RAM to/from Harmony cart flash if(mySize == 28_KB && !bankLocked()) @@ -66,7 +66,7 @@ uInt8 CartridgeFA2::peek(uInt16 address) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeFA2::poke(uInt16 address, uInt8 value) { - if((address & 0x0FFF) == 0x0FF4) + if((address & ROM_MASK) == 0x0FF4) { // Load/save RAM to/from Harmony cart flash if(mySize == 28_KB && !bankLocked()) diff --git a/src/emucore/CartFE.cxx b/src/emucore/CartFE.cxx index 3a07730e0..7c3debda3 100644 --- a/src/emucore/CartFE.cxx +++ b/src/emucore/CartFE.cxx @@ -63,7 +63,7 @@ bool CartridgeFE::checkSwitchBank(uInt16 address, uInt8 value) uInt8 CartridgeFE::peek(uInt16 address) { uInt8 value = (address < 0x200) ? mySystem->m6532().peek(address) : - myImage[myCurrentSegOffset[(address & 0xFFF) >> myBankShift] + (address & myBankMask)]; + myImage[myCurrentSegOffset[(address & myBankMask) >> myBankShift] + (address & myBankMask)]; // Check if we hit hotspot checkSwitchBank(address, value); diff --git a/src/emucore/CartSB.cxx b/src/emucore/CartSB.cxx index 56973392c..5caa01be7 100644 --- a/src/emucore/CartSB.cxx +++ b/src/emucore/CartSB.cxx @@ -54,13 +54,12 @@ bool CartridgeSB::checkSwitchBank(uInt16 address, uInt8) // Switch banks if necessary if((address & 0x1800) == 0x0800) { - bank(address & startBank()); + bank(address & (romBankCount() - 1)); return true; } return false; } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeSB::peek(uInt16 address) { From ace948e6edeb10c7266972be57f1fd0978ad6171 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Thu, 16 Apr 2020 10:33:37 -0230 Subject: [PATCH 23/52] Fix compile error for UNIX builds. --- src/debugger/gui/module.mk | 2 +- src/emucore/CartEnhanced.hxx | 2 +- src/emucore/module.mk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index f4f94387f..d1ffc81c0 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -21,7 +21,7 @@ MODULE_OBJS := \ src/debugger/gui/CartCDFWidget.o \ src/debugger/gui/CartCDFInfoWidget.o \ src/debugger/gui/CartCMWidget.o \ - src/debugger/gui/CartCTYWidget.o \ + src/debugger/gui/CartCTYWidget.o \ src/debugger/gui/CartCVWidget.o \ src/debugger/gui/CartDFSCWidget.o \ src/debugger/gui/CartDFWidget.o \ diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index e66aeb9f5..a45e4796e 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -239,7 +239,7 @@ class CartridgeEnhanced : public Cartridge static constexpr bool RAM_HIGH_WP = false; // The maximum shift (for a 4K bank size) - static constexpr uInt16 MAX_BANK_SHIFT = 12; ; // -> 4K + static constexpr uInt16 MAX_BANK_SHIFT = 12; // -> 4K protected: /** diff --git a/src/emucore/module.mk b/src/emucore/module.mk index 9c81e28ec..dc953b86e 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -20,7 +20,7 @@ MODULE_OBJS := \ src/emucore/CartCDF.o \ src/emucore/CartCM.o \ src/emucore/CartCTY.o \ - src/emucore/CartCV.o \ + src/emucore/CartCV.o \ src/emucore/CartDPC.o \ src/emucore/CartDPCPlus.o \ src/emucore/CartE0.o \ From bb05a04c3cfe55518ae9f9bce903317a812c083a Mon Sep 17 00:00:00 2001 From: Thomas Jentzsch Date: Thu, 16 Apr 2020 18:54:29 +0200 Subject: [PATCH 24/52] small naming alignment between CartBUS and CartCDF --- src/debugger/gui/CartBUSWidget.cxx | 8 ++-- src/debugger/gui/CartCDFWidget.cxx | 8 ++-- src/emucore/CartBUS.cxx | 72 +++++++++++++++--------------- src/emucore/CartBUS.hxx | 4 +- src/emucore/CartCDF.cxx | 56 +++++++++++------------ src/emucore/CartCDF.hxx | 4 +- 6 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/debugger/gui/CartBUSWidget.cxx b/src/debugger/gui/CartBUSWidget.cxx index b9c25a77d..8f6a9b22b 100644 --- a/src/debugger/gui/CartBUSWidget.cxx +++ b/src/debugger/gui/CartBUSWidget.cxx @@ -238,7 +238,7 @@ void CartridgeBUSWidget::saveOldState() } for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myBUSRAM[i]); + myOldState.internalram.push_back(myCart.myRAM[i]); myOldState.samplepointer.push_back(myCart.getSample()); } @@ -438,18 +438,18 @@ const ByteArray& CartridgeBUSWidget::internalRamCurrent(int start, int count) { myRamCurrent.clear(); for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myBUSRAM[start + i]); + myRamCurrent.push_back(myCart.myRAM[start + i]); return myRamCurrent; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeBUSWidget::internalRamSetValue(int addr, uInt8 value) { - myCart.myBUSRAM[addr] = value; + myCart.myRAM[addr] = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeBUSWidget::internalRamGetValue(int addr) { - return myCart.myBUSRAM[addr]; + return myCart.myRAM[addr]; } diff --git a/src/debugger/gui/CartCDFWidget.cxx b/src/debugger/gui/CartCDFWidget.cxx index 60b68d5c4..8c4fdf2fc 100644 --- a/src/debugger/gui/CartCDFWidget.cxx +++ b/src/debugger/gui/CartCDFWidget.cxx @@ -232,7 +232,7 @@ void CartridgeCDFWidget::saveOldState() } for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myCDFRAM[i]); + myOldState.internalram.push_back(myCart.myRAM[i]); myOldState.samplepointer.push_back(myCart.getSample()); } @@ -437,20 +437,20 @@ const ByteArray& CartridgeCDFWidget::internalRamCurrent(int start, int count) { myRamCurrent.clear(); for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myCDFRAM[start + i]); + myRamCurrent.push_back(myCart.myRAM[start + i]); return myRamCurrent; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCDFWidget::internalRamSetValue(int addr, uInt8 value) { - myCart.myCDFRAM[addr] = value; + myCart.myRAM[addr] = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeCDFWidget::internalRamGetValue(int addr) { - return myCart.myCDFRAM[addr]; + return myCart.myRAM[addr]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartBUS.cxx b/src/emucore/CartBUS.cxx index bd6d227c2..e2eb9b74a 100644 --- a/src/emucore/CartBUS.cxx +++ b/src/emucore/CartBUS.cxx @@ -56,16 +56,16 @@ CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size, myProgramImage = myImage.data() + 4_KB; // Pointer to BUS driver in RAM - myBusDriverImage = myBUSRAM.data(); + myDriverImage = myRAM.data(); // Pointer to the display RAM - myDisplayImage = myBUSRAM.data() + DSRAM; + myDisplayImage = myRAM.data() + DSRAM; // Create Thumbulator ARM emulator bool devSettings = settings.getBool("dev.settings"); myThumbEmulator = make_unique( reinterpret_cast(myImage.data()), - reinterpret_cast(myBUSRAM.data()), + reinterpret_cast(myRAM.data()), static_cast(myImage.size()), devSettings ? settings.getBool("dev.thumb.trapfatal") : false, Thumbulator::ConfigureFor::BUS, this ); @@ -76,7 +76,7 @@ CartridgeBUS::CartridgeBUS(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeBUS::reset() { - initializeRAM(myBUSRAM.data() + 2_KB, 6_KB); + initializeRAM(myRAM.data() + 2_KB, 6_KB); // BUS always starts in bank 6 initializeStartBank(6); @@ -95,7 +95,7 @@ void CartridgeBUS::reset() void CartridgeBUS::setInitialState() { // Copy initial BUS driver to Harmony RAM - std::copy_n(myImage.begin(), 2_KB, myBusDriverImage); + std::copy_n(myImage.begin(), 2_KB, myDriverImage); myMusicWaveformSize.fill(27); @@ -254,7 +254,7 @@ uInt8 CartridgeBUS::peek(uInt16 address) if (sampleaddress < 0x8000) peekvalue = myImage[sampleaddress]; else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40002000) // check for RAM - peekvalue = myBUSRAM[sampleaddress - 0x40000000]; + peekvalue = myRAM[sampleaddress - 0x40000000]; else peekvalue = 0; @@ -552,7 +552,7 @@ bool CartridgeBUS::save(Serializer& out) const out.putShort(myBankOffset); // Harmony RAM - out.putByteArray(myBUSRAM.data(), myBUSRAM.size()); + out.putByteArray(myRAM.data(), myRAM.size()); // Addresses for bus override logic out.putShort(myBusOverdriveAddress); @@ -593,7 +593,7 @@ bool CartridgeBUS::load(Serializer& in) myBankOffset = in.getShort(); // Harmony RAM - in.getByteArray(myBUSRAM.data(), myBUSRAM.size()); + in.getByteArray(myRAM.data(), myRAM.size()); // Addresses for bus override logic myBusOverdriveAddress = in.getShort(); @@ -633,40 +633,40 @@ uInt32 CartridgeBUS::getDatastreamPointer(uInt8 index) const { // index &= 0x0f; - return myBUSRAM[DSxPTR + index*4 + 0] + // low byte - (myBUSRAM[DSxPTR + index*4 + 1] << 8) + - (myBUSRAM[DSxPTR + index*4 + 2] << 16) + - (myBUSRAM[DSxPTR + index*4 + 3] << 24) ; // high byte + return myRAM[DSxPTR + index*4 + 0] + // low byte + (myRAM[DSxPTR + index*4 + 1] << 8) + + (myRAM[DSxPTR + index*4 + 2] << 16) + + (myRAM[DSxPTR + index*4 + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeBUS::setDatastreamPointer(uInt8 index, uInt32 value) { // index &= 0x0f; - myBUSRAM[DSxPTR + index*4 + 0] = value & 0xff; // low byte - myBUSRAM[DSxPTR + index*4 + 1] = (value >> 8) & 0xff; - myBUSRAM[DSxPTR + index*4 + 2] = (value >> 16) & 0xff; - myBUSRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte + myRAM[DSxPTR + index*4 + 0] = value & 0xff; // low byte + myRAM[DSxPTR + index*4 + 1] = (value >> 8) & 0xff; + myRAM[DSxPTR + index*4 + 2] = (value >> 16) & 0xff; + myRAM[DSxPTR + index*4 + 3] = (value >> 24) & 0xff; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeBUS::getDatastreamIncrement(uInt8 index) const { // index &= 0x0f; - return myBUSRAM[DSxINC + index*4 + 0] + // low byte - (myBUSRAM[DSxINC + index*4 + 1] << 8) + - (myBUSRAM[DSxINC + index*4 + 2] << 16) + - (myBUSRAM[DSxINC + index*4 + 3] << 24) ; // high byte + return myRAM[DSxINC + index*4 + 0] + // low byte + (myRAM[DSxINC + index*4 + 1] << 8) + + (myRAM[DSxINC + index*4 + 2] << 16) + + (myRAM[DSxINC + index*4 + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeBUS::getAddressMap(uInt8 index) const { // index &= 0x0f; - return myBUSRAM[DSMAPS + index*4 + 0] + // low byte - (myBUSRAM[DSMAPS + index*4 + 1] << 8) + - (myBUSRAM[DSMAPS + index*4 + 2] << 16) + - (myBUSRAM[DSMAPS + index*4 + 3] << 24) ; // high byte + return myRAM[DSMAPS + index*4 + 0] + // low byte + (myRAM[DSMAPS + index*4 + 1] << 8) + + (myRAM[DSMAPS + index*4 + 2] << 16) + + (myRAM[DSMAPS + index*4 + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -686,10 +686,10 @@ uInt32 CartridgeBUS::getWaveform(uInt8 index) const uInt32 result; - result = myBUSRAM[WAVEFORM + index*4 + 0] + // low byte - (myBUSRAM[WAVEFORM + index*4 + 1] << 8) + - (myBUSRAM[WAVEFORM + index*4 + 2] << 16) + - (myBUSRAM[WAVEFORM + index*4 + 3] << 24); // high byte + result = myRAM[WAVEFORM + index*4 + 0] + // low byte + (myRAM[WAVEFORM + index*4 + 1] << 8) + + (myRAM[WAVEFORM + index*4 + 2] << 16) + + (myRAM[WAVEFORM + index*4 + 3] << 24); // high byte result -= 0x40000800; @@ -704,10 +704,10 @@ uInt32 CartridgeBUS::getSample() { uInt32 result; - result = myBUSRAM[WAVEFORM + 0] + // low byte - (myBUSRAM[WAVEFORM + 1] << 8) + - (myBUSRAM[WAVEFORM + 2] << 16) + - (myBUSRAM[WAVEFORM + 3] << 24); // high byte + result = myRAM[WAVEFORM + 0] + // low byte + (myRAM[WAVEFORM + 1] << 8) + + (myRAM[WAVEFORM + 2] << 16) + + (myRAM[WAVEFORM + 3] << 24); // high byte return result; } @@ -722,10 +722,10 @@ uInt32 CartridgeBUS::getWaveformSize(uInt8 index) const void CartridgeBUS::setAddressMap(uInt8 index, uInt32 value) { // index &= 0x0f; - myBUSRAM[DSMAPS + index*4 + 0] = value & 0xff; // low byte - myBUSRAM[DSMAPS + index*4 + 1] = (value >> 8) & 0xff; - myBUSRAM[DSMAPS + index*4 + 2] = (value >> 16) & 0xff; - myBUSRAM[DSMAPS + index*4 + 3] = (value >> 24) & 0xff; // high byte + myRAM[DSMAPS + index*4 + 0] = value & 0xff; // low byte + myRAM[DSMAPS + index*4 + 1] = (value >> 8) & 0xff; + myRAM[DSMAPS + index*4 + 2] = (value >> 16) & 0xff; + myRAM[DSMAPS + index*4 + 3] = (value >> 24) & 0xff; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartBUS.hxx b/src/emucore/CartBUS.hxx index 5567f1196..3ab40f7ec 100644 --- a/src/emucore/CartBUS.hxx +++ b/src/emucore/CartBUS.hxx @@ -220,13 +220,13 @@ class CartridgeBUS : public Cartridge uInt8* myDisplayImage{nullptr}; // Pointer to the 2K BUS driver image in RAM - uInt8* myBusDriverImage{nullptr}; + uInt8* myDriverImage{nullptr}; // The BUS 8k RAM image, used as: // $0000 - 2K BUS driver // $0800 - 4K Display Data // $1800 - 2K C Variable & Stack - std::array myBUSRAM; + std::array myRAM; // Pointer to the Thumb ARM emulator object unique_ptr myThumbEmulator; diff --git a/src/emucore/CartCDF.cxx b/src/emucore/CartCDF.cxx index 2758a9825..6f9a5f4f7 100644 --- a/src/emucore/CartCDF.cxx +++ b/src/emucore/CartCDF.cxx @@ -72,10 +72,10 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, myProgramImage = myImage.data() + 4_KB; // Pointer to CDF driver in RAM - myBusDriverImage = myCDFRAM.data(); + myDriverImage = myRAM.data(); // Pointer to the display RAM - myDisplayImage = myCDFRAM.data() + DSRAM; + myDisplayImage = myRAM.data() + DSRAM; setupVersion(); @@ -83,7 +83,7 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, bool devSettings = settings.getBool("dev.settings"); myThumbEmulator = make_unique( reinterpret_cast(myImage.data()), - reinterpret_cast(myCDFRAM.data()), + reinterpret_cast(myRAM.data()), static_cast(myImage.size()), devSettings ? settings.getBool("dev.thumb.trapfatal") : false, thumulatorConfiguration(myCDFSubtype), this); @@ -93,7 +93,7 @@ CartridgeCDF::CartridgeCDF(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeCDF::reset() { - initializeRAM(myCDFRAM.data()+2_KB, myCDFRAM.size()-2_KB); + initializeRAM(myRAM.data()+2_KB, myRAM.size()-2_KB); // CDF always starts in bank 6 initializeStartBank(6); @@ -111,7 +111,7 @@ void CartridgeCDF::reset() void CartridgeCDF::setInitialState() { // Copy initial CDF driver to Harmony RAM - std::copy_n(myImage.begin(), 2_KB, myBusDriverImage); + std::copy_n(myImage.begin(), 2_KB, myDriverImage); myMusicWaveformSize.fill(27); @@ -255,7 +255,7 @@ uInt8 CartridgeCDF::peek(uInt16 address) if (sampleaddress < 0x8000) peekvalue = myImage[sampleaddress]; else if (sampleaddress >= 0x40000000 && sampleaddress < 0x40002000) // check for RAM - peekvalue = myCDFRAM[sampleaddress - 0x40000000]; + peekvalue = myRAM[sampleaddress - 0x40000000]; else peekvalue = 0; @@ -508,7 +508,7 @@ bool CartridgeCDF::save(Serializer& out) const out.putShort(myJMPoperandAddress); // Harmony RAM - out.putByteArray(myCDFRAM.data(), myCDFRAM.size()); + out.putByteArray(myRAM.data(), myRAM.size()); // Audio info out.putIntArray(myMusicCounters.data(), myMusicCounters.size()); @@ -548,7 +548,7 @@ bool CartridgeCDF::load(Serializer& in) myJMPoperandAddress = in.getShort(); // Harmony RAM - in.getByteArray(myCDFRAM.data(), myCDFRAM.size()); + in.getByteArray(myRAM.data(), myRAM.size()); // Audio info in.getIntArray(myMusicCounters.data(), myMusicCounters.size()); @@ -577,10 +577,10 @@ uInt32 CartridgeCDF::getDatastreamPointer(uInt8 index) const { uInt16 address = myDatastreamBase + index * 4; - return myCDFRAM[address + 0] + // low byte - (myCDFRAM[address + 1] << 8) + - (myCDFRAM[address + 2] << 16) + - (myCDFRAM[address + 3] << 24) ; // high byte + return myRAM[address + 0] + // low byte + (myRAM[address + 1] << 8) + + (myRAM[address + 2] << 16) + + (myRAM[address + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -588,10 +588,10 @@ void CartridgeCDF::setDatastreamPointer(uInt8 index, uInt32 value) { uInt16 address = myDatastreamBase + 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 + myRAM[address + 0] = value & 0xff; // low byte + myRAM[address + 1] = (value >> 8) & 0xff; + myRAM[address + 2] = (value >> 16) & 0xff; + myRAM[address + 3] = (value >> 24) & 0xff; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -599,10 +599,10 @@ uInt32 CartridgeCDF::getDatastreamIncrement(uInt8 index) const { uInt16 address = myDatastreamIncrementBase + index * 4; - return myCDFRAM[address + 0] + // low byte - (myCDFRAM[address + 1] << 8) + - (myCDFRAM[address + 2] << 16) + - (myCDFRAM[address + 3] << 24) ; // high byte + return myRAM[address + 0] + // low byte + (myRAM[address + 1] << 8) + + (myRAM[address + 2] << 16) + + (myRAM[address + 3] << 24) ; // high byte } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -610,10 +610,10 @@ uInt32 CartridgeCDF::getWaveform(uInt8 index) const { uInt16 address = myWaveformBase + index * 4; - uInt32 result = myCDFRAM[address + 0] + // low byte - (myCDFRAM[address + 1] << 8) + - (myCDFRAM[address + 2] << 16) + - (myCDFRAM[address + 3] << 24); // high byte + uInt32 result = myRAM[address + 0] + // low byte + (myRAM[address + 1] << 8) + + (myRAM[address + 2] << 16) + + (myRAM[address + 3] << 24); // high byte result -= (0x40000000 + DSRAM); @@ -628,10 +628,10 @@ uInt32 CartridgeCDF::getSample() { uInt16 address = myWaveformBase; - uInt32 result = myCDFRAM[address + 0] + // low byte - (myCDFRAM[address + 1] << 8) + - (myCDFRAM[address + 2] << 16) + - (myCDFRAM[address + 3] << 24); // high byte + uInt32 result = myRAM[address + 0] + // low byte + (myRAM[address + 1] << 8) + + (myRAM[address + 2] << 16) + + (myRAM[address + 3] << 24); // high byte return result; } diff --git a/src/emucore/CartCDF.hxx b/src/emucore/CartCDF.hxx index 7c5295f7a..14b1eda26 100644 --- a/src/emucore/CartCDF.hxx +++ b/src/emucore/CartCDF.hxx @@ -220,13 +220,13 @@ class CartridgeCDF : public Cartridge uInt8* myDisplayImage{nullptr}; // Pointer to the 2K CDF driver image in RAM - uInt8* myBusDriverImage{nullptr}; + uInt8* myDriverImage{nullptr}; // The CDF 8k RAM image, used as: // $0000 - 2K CDF driver // $0800 - 4K Display Data // $1800 - 2K C Variable & Stack - std::array myCDFRAM; + std::array myRAM; // Pointer to the Thumb ARM emulator object unique_ptr myThumbEmulator; From b264e7634487545e0b359a1468ad985d4a9a9c19 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 17 Apr 2020 13:43:49 +0200 Subject: [PATCH 25/52] refactored CartWD fixed CartEnhanced for multi-segment ROMs with extra RAM improved CartEnhanced by enabling directPoke for extra RAM --- src/emucore/Cart3EPlus.cxx | 31 +---- src/emucore/CartEnhanced.cxx | 11 +- src/emucore/CartEnhanced.hxx | 2 +- src/emucore/CartWD.cxx | 221 ++++++----------------------------- src/emucore/CartWD.hxx | 86 +++----------- 5 files changed, 60 insertions(+), 291 deletions(-) diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 274e1f9db..5803f2136 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -29,44 +29,17 @@ Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size, myRamSize = RAM_SIZE; myRamBankCount = RAM_BANKS; myRamWpHigh = RAM_HIGH_WP; - - //// Allocate array for the ROM image - //myImage = make_unique(mySize); - - //// Copy the ROM image into my buffer - //std::copy_n(image.get(), mySize, myImage.get()); - //createRomAccessArrays(mySize + myRAM.size()); } -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//void Cartridge3EPlus::reset() -//{ -// initializeRAM(myRAM.data(), myRAM.size()); -// -// // Remember startup bank (0 per spec, rather than last per 3E scheme). -// // Set this to go to 3rd 1K Bank. -// initializeStartBank(0); -// -// // Initialise bank values for all ROM/RAM access -// // This is used to reverse-lookup from address to bank location -// for(auto& b: bankInUse) -// b = BANK_UNDEFINED; // bank is undefined and inaccessible! -// -// initializeBankState(); -// -// // We'll map the startup banks 0 and 3 from the image into the third 1K bank upon reset -// bankROM((0 << BANK_BITS) | 0); -// bankROM((3 << BANK_BITS) | 0); -//} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EPlus::reset() { CartridgeEnhanced::reset(); + // 1st segment in mapped to start bank in CartridgeEnhanced bank(mySystem->randGenerator().next() % romBankCount(), 1); bank(mySystem->randGenerator().next() % romBankCount(), 2); - bank(startBank(), 3); // Stella reads the PC vector always from here (TODO?) + bank(startBank(), 3); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 5816181f2..d75c77ac8 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -68,6 +68,8 @@ void CartridgeEnhanced::install(System& system) for(uInt16 addr = ROM_OFFSET + myWriteOffset; addr < ROM_OFFSET + myWriteOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; + + access.directPokeBase = &myRAM[offset]; access.romAccessBase = &myRomAccessBase[myWriteOffset + offset]; access.romPeekCounter = &myRomAccessCounter[myWriteOffset + offset]; access.romPokeCounter = &myRomAccessCounter[myWriteOffset + offset + myAccessSize]; @@ -76,6 +78,7 @@ void CartridgeEnhanced::install(System& system) // Set the page accessing method for the RAM reading pages access.type = System::PageAccessType::READ; + access.directPokeBase = nullptr; for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; @@ -125,7 +128,7 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) } else { - address &= myBankMask; + address &= ROM_MASK; // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) if(address < myReadOffset + myRamSize && address >= myReadOffset) @@ -133,7 +136,8 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) // Reading from the write port triggers an unwanted write return peekRAM(myRAM[address], peekAddress); else - return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] + address]; + return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] + + (peekAddress & myBankMask)]; } } @@ -206,7 +210,8 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) uInt32 bankOffset = myCurrentSegOffset[segment] = romBank << myBankShift; uInt16 hotspot = this->hotspot(); uInt16 hotSpotAddr; - uInt16 fromAddr = (ROM_OFFSET + segmentOffset + myRomOffset) & ~System::PAGE_MASK; + // Skip extra RAM; if existing it is only mapped into first segment + uInt16 fromAddr = (ROM_OFFSET + segmentOffset + (segment == 0 ? myRomOffset : 0)) & ~System::PAGE_MASK; // for ROMs < 4_KB, the whole address space will be mapped. uInt16 toAddr = (ROM_OFFSET + segmentOffset + (mySize < 4_KB ? 4_KB : myBankSize)) & ~System::PAGE_MASK; diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index a45e4796e..10dbfb0d6 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -65,7 +65,7 @@ class CartridgeEnhanced : public Cartridge @return true, if bank has changed */ - bool bank(uInt16 bank, uInt16 segment); + virtual bool bank(uInt16 bank, uInt16 segment); /** Install pages for the specified bank in the system. diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index 9a14be24a..ff72a2b38 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -23,70 +23,46 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeWD::CartridgeWD(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(std::min(8_KB + 3, size)) + : CartridgeEnhanced(image, size, md5, settings) { // Copy the ROM image into my buffer if (mySize == 8_KB + 3) { - // swap slices 2 & 3 - std::copy_n(image.get(), 1_KB * 2, myImage.begin()); - std::copy_n(image.get() + 1_KB * 3, 1_KB * 1, myImage.begin() + 1_KB * 2); - std::copy_n(image.get() + 1_KB * 2, 1_KB * 1, myImage.begin() + 1_KB * 3); - std::copy_n(image.get() + 1_KB * 4, 1_KB * 4, myImage.begin() + 1_KB * 4); + // swap slices 2 & 3 of bad dump and correct size + std::copy_n(image.get() + 1_KB * 3, 1_KB * 1, myImage.get() + 1_KB * 2); + std::copy_n(image.get() + 1_KB * 2, 1_KB * 1, myImage.get() + 1_KB * 3); + mySize = 8_KB; } - else - std::copy_n(image.get(), mySize, myImage.begin()); - createRomAccessArrays(8_KB); + myDirectPeek = false; + + myBankShift = BANK_SHIFT; + myRamSize = RAM_SIZE; + myRamWpHigh = RAM_HIGH_WP; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeWD::reset() { - initializeRAM(myRAM.data(), myRAM.size()); - initializeStartBank(0); + CartridgeEnhanced::reset(); myCyclesAtBankswitchInit = 0; myPendingBank = 0xF0; // one more than the allowable bank # - - // Setup segments to some default slices - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeWD::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); - // Set the page accessing method for the RAM reading pages - System::PageAccess read(this, System::PageAccessType::READ); - for(uInt16 addr = 0x1000; addr < 0x1040; addr += System::PAGE_SIZE) - { - read.directPeekBase = &myRAM[addr & 0x003F]; - read.romAccessBase = &myRomAccessBase[addr & 0x003F]; - read.romPeekCounter = &myRomAccessCounter[addr & 0x003F]; - read.romPokeCounter = &myRomAccessCounter[(addr & 0x003F) + 8_KB]; - mySystem->setPageAccess(addr, read); - } + System::PageAccess access(this, System::PageAccessType::READ); - // Set the page accessing method for the RAM writing pages - // Map access to this class, since we need to inspect all accesses to - // check if RWP happens - System::PageAccess write(this, System::PageAccessType::WRITE); - for(uInt16 addr = 0x1040; addr < 0x1080; addr += System::PAGE_SIZE) - { - write.romAccessBase = &myRomAccessBase[addr & 0x003F]; - write.romPeekCounter = &myRomAccessCounter[addr & 0x003F]; - write.romPokeCounter = &myRomAccessCounter[(addr & 0x003F) + 8_KB]; - mySystem->setPageAccess(addr, write); - } + // The hotspots are in TIA address space, so we claim it here + for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) + mySystem->setPageAccess(addr, access); // Mirror all access in TIA; by doing so we're taking responsibility // for that address space in peek and poke below. - mySystem->tia().installDelegate(system, *this); - - // Setup segments to some default slices - bank(startBank()); + //mySystem->tia().installDelegate(system, *this); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -113,134 +89,31 @@ uInt8 CartridgeWD::peek(uInt16 address) return mySystem->tia().peek(address); } else - { - uInt16 peekAddress = address; - address &= 0x0FFF; - - if(address < 0x0040) // RAM read port - return myRAM[address]; - else if(address < 0x0080) // RAM write port - // Reading from the write port @ $1040 - $107F triggers an unwanted write - return peekRAM(myRAM[address & 0x003F], peekAddress); - else if(address < 0x0400) - return myImage[myOffset[0] + (address & 0x03FF)]; - else if(address < 0x0800) - return myImage[myOffset[1] + (address & 0x03FF)]; - else if(address < 0x0C00) - return myImage[myOffset[2] + (address & 0x03FF)]; - else - return mySegment3[address & 0x03FF]; - } + return CartridgeEnhanced::peek(address); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeWD::poke(uInt16 address, uInt8 value) { - if(!(address & 0x1000)) // TIA addresses + if(address < 0x40) return mySystem->tia().poke(address, value); - else - { - if(address & 0x040) - { - pokeRAM(myRAM[address & 0x003F], address, value); - return true; - } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - pokeRAM(dummy, address, value); - myRamWriteAccess = address; - return false; - } - } + return CartridgeEnhanced::poke(address, value); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeWD::bank(uInt16 bank) +bool CartridgeWD::bank(uInt16 bank, uInt16) { - if(bankLocked() || bank > 15) return false; + if(bankLocked()) return false; - myCurrentBank = bank; + myCurrentBank = bank % romBankCount(); - segmentZero(ourBankOrg[bank & 0x7].zero); - segmentOne(ourBankOrg[bank & 0x7].one); - segmentTwo(ourBankOrg[bank & 0x7].two); - segmentThree(ourBankOrg[bank & 0x7].three); + CartridgeEnhanced::bank(ourBankOrg[myCurrentBank].zero, 0); + CartridgeEnhanced::bank(ourBankOrg[myCurrentBank].one, 1); + CartridgeEnhanced::bank(ourBankOrg[myCurrentBank].two, 2); + CartridgeEnhanced::bank(ourBankOrg[myCurrentBank].three, 3); - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWD::segmentZero(uInt8 slice) -{ - uInt16 offset = slice << 10; - System::PageAccess access(this, System::PageAccessType::READ); - - // Skip first 128 bytes; it is always RAM - for(uInt16 addr = 0x1080; addr < 0x1400; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + 8_KB]; - mySystem->setPageAccess(addr, access); - } - myOffset[0] = offset; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWD::segmentOne(uInt8 slice) -{ - uInt16 offset = slice << 10; - System::PageAccess access(this, System::PageAccessType::READ); - - for(uInt16 addr = 0x1400; addr < 0x1800; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + 8_KB]; - mySystem->setPageAccess(addr, access); - } - myOffset[1] = offset; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWD::segmentTwo(uInt8 slice) -{ - uInt16 offset = slice << 10; - System::PageAccess access(this, System::PageAccessType::READ); - - for(uInt16 addr = 0x1800; addr < 0x1C00; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + 8_KB]; - mySystem->setPageAccess(addr, access); - } - myOffset[2] = offset; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWD::segmentThree(uInt8 slice) -{ - uInt16 offset = slice << 10; - - // Make a copy of the address space pointed to by the slice - // Then overwrite one byte with 0 - std::copy_n(myImage.begin()+offset, mySegment3.size(), mySegment3.begin()); - mySegment3[0x3FC] = 0; - - System::PageAccess access(this, System::PageAccessType::READ); - - for(uInt16 addr = 0x1C00; addr < 0x2000; addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[offset + (addr & 0x03FF)]; - access.romPeekCounter = &myRomAccessCounter[offset + (addr & 0x03FF)]; - access.romPokeCounter = &myRomAccessCounter[offset + (addr & 0x03FF) + 8_KB]; - mySystem->setPageAccess(addr, access); - } - myOffset[3] = offset; + return true; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -249,41 +122,13 @@ uInt16 CartridgeWD::getBank(uInt16) const return myCurrentBank; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeWD::romBankCount() const -{ - return 16; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeWD::patch(uInt16 address, uInt8 value) -{ - address &= 0x0FFF; - - uInt16 idx = address >> 10; - myImage[myOffset[idx] + (address & 0x03FF)] = value; - - // The upper segment is mirrored, so we need to patch its buffer too - if(idx == 3) - mySegment3[(address & 0x03FF)] = value; - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeWD::getImage(size_t& size) const -{ - size = mySize; - return myImage.data(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeWD::save(Serializer& out) const { + CartridgeEnhanced::save(out); try { out.putShort(myCurrentBank); - out.putByteArray(myRAM.data(), myRAM.size()); out.putLong(myCyclesAtBankswitchInit); out.putShort(myPendingBank); } @@ -299,10 +144,10 @@ bool CartridgeWD::save(Serializer& out) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeWD::load(Serializer& in) { + CartridgeEnhanced::load(in); try { myCurrentBank = in.getShort(); - in.getByteArray(myRAM.data(), myRAM.size()); myCyclesAtBankswitchInit = in.getLong(); myPendingBank = in.getShort(); @@ -319,9 +164,9 @@ bool CartridgeWD::load(Serializer& in) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const std::array CartridgeWD::ourBankOrg = {{ - // 0 1 2 3 4 5 6 7 - { 0, 0, 1, 3 }, // Bank 0, 8 2 1 - 1 - - - - - { 0, 1, 2, 3 }, // Bank 1, 9 1 1 1 1 - - - - + // 0 1 2 3 4 5 6 7 + { 0, 0, 1, 3 }, // Bank 0, 8 2 1 - 1 - - - - + { 0, 1, 2, 3 }, // Bank 1, 9 1 1 1 1 - - - - { 4, 5, 6, 7 }, // Bank 2, 10 - - - - 1 1 1 1 { 7, 4, 2, 3 }, // Bank 3, 11 - - 1 1 1 - - 1 { 0, 0, 6, 7 }, // Bank 4, 12 2 - - - - - 1 1 diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 88c59e469..9623cfa96 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "Cart.hxx" +#include "CartEnhanced.hxx" #ifdef DEBUGGER_SUPPORT #include "CartWDWidget.hxx" #endif @@ -45,15 +45,15 @@ class System; $0037, $003F: 6,0,5,1 - In the uppermost (third) segment, the byte at $3FC is overwritten by 0. + (Removed: In the uppermost (third) segment, the byte at $3FC is overwritten by 0.) The 64 bytes of RAM are accessible at $1000 - $103F (read port) and $1040 - $107F (write port). Because the RAM takes 128 bytes of address space, the range $1000 - $107F of segment 0 ROM will never be available. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ -class CartridgeWD : public Cartridge +class CartridgeWD : public CartridgeEnhanced { friend class CartridgeWDWidget; @@ -89,7 +89,7 @@ class CartridgeWD : public Cartridge @param bank The bank that should be installed in the system */ - bool bank(uInt16 bank) override; + bool bank(uInt16 bank, uInt16 = 0) override; /** Get the current bank. @@ -98,28 +98,6 @@ class CartridgeWD : public Cartridge */ uInt16 getBank(uInt16 address = 0) const override; - /** - Query the number of banks supported by the cartridge. - */ - uInt16 romBankCount() const override; - - /** - Patch the cartridge ROM. - - @param address The ROM address to patch - @param value The value to place into the address - @return Success or failure of the patch operation - */ - bool patch(uInt16 address, uInt8 value) override; - - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - /** Save the current state of this cart to the given Serializer. @@ -173,51 +151,9 @@ class CartridgeWD : public Cartridge bool poke(uInt16 address, uInt8 value) override; private: - /** - Install the specified slice for segment zero. - - @param slice The slice to map into the segment - */ - void segmentZero(uInt8 slice); - - /** - Install the specified slice for segment one. - - @param slice The slice to map into the segment - */ - void segmentOne(uInt8 slice); - - /** - Install the specified slice for segment two. - - @param slice The slice to map into the segment - */ - void segmentTwo(uInt8 slice); - - /** - Install the specified slice for segment three. - Note that this method also takes care of setting one byte to 0. - - @param slice The slice to map into the segment - */ - void segmentThree(uInt8 slice); + bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; }; private: - // The 8K ROM image of the cartridge - std::array myImage; - - // Indicates the actual size of the ROM image (either 8K or 8K + 3) - size_t mySize{0}; - - // The 64 bytes RAM of the cartridge - std::array myRAM; - - // The 1K ROM mirror of segment 3 (sometimes contains extra 3 bytes) - std::array mySegment3; - - // Indicates the offset for each of the four segments - std::array myOffset; - // Indicates the cycle at which a bankswitch was initiated uInt64 myCyclesAtBankswitchInit{0}; @@ -233,6 +169,16 @@ class CartridgeWD : public Cartridge }; static const std::array ourBankOrg; + private: + // log(ROM bank segment size) / log(2) + static constexpr uInt16 BANK_SHIFT = 10; // = 1K = 0x0400 + + // RAM size + static constexpr uInt16 RAM_SIZE = 0x40; + + // Write port for extra RAM is at low address by default + static constexpr bool RAM_HIGH_WP = true; + private: // Following constructors and assignment operators not supported CartridgeWD() = delete; From 5587306fb91e58438d45c524f7f0861f14dbfc5c Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Fri, 17 Apr 2020 11:42:11 -0230 Subject: [PATCH 26/52] Fix clang compile warning. --- src/emucore/CartWD.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 9623cfa96..20596868e 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -151,7 +151,7 @@ class CartridgeWD : public CartridgeEnhanced bool poke(uInt16 address, uInt8 value) override; private: - bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; }; + bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; } private: // Indicates the cycle at which a bankswitch was initiated From 5568dd3007f7b4ba5ce00806b0ad3b2f0d7503e3 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 17 Apr 2020 20:47:29 +0200 Subject: [PATCH 27/52] enable directPokeBase for RAM banks in CartridgeEnhanced --- src/emucore/CartEnhanced.cxx | 46 +++++++++++++++--------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index d75c77ac8..11eb0ca75 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -82,6 +82,7 @@ void CartridgeEnhanced::install(System& system) for(uInt16 addr = ROM_OFFSET + myReadOffset; addr < ROM_OFFSET + myReadOffset + myRamSize; addr += System::PAGE_SIZE) { uInt16 offset = addr & myRamMask; + access.directPeekBase = &myRAM[offset]; access.romAccessBase = &myRomAccessBase[myReadOffset + offset]; access.romPeekCounter = &myRomAccessCounter[myReadOffset + offset]; @@ -126,19 +127,18 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) return peekRAM(myRAM[((myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] - mySize) >> 1) + address], peekAddress); } - else - { - address &= ROM_MASK; + address &= ROM_MASK; - // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) - if(address < myReadOffset + myRamSize && address >= myReadOffset) - // This is a read access to a write port! - // Reading from the write port triggers an unwanted write - return peekRAM(myRAM[address], peekAddress); - else - return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] - + (peekAddress & myBankMask)]; + // Write port is e.g. at 0xF000 - 0xF07F (128 bytes) + if(address < myReadOffset + myRamSize && address >= myReadOffset) + { + // This is a read access to a write port! + // Reading from the write port triggers an unwanted write + return peekRAM(myRAM[address], peekAddress); } + + return myImage[myCurrentSegOffset[(peekAddress & ROM_MASK) >> myBankShift] + + (peekAddress & myBankMask)]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -153,6 +153,7 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) if(myRamSize > 0) { + // Code should never get here (System::PageAccess::directPoke() handles this) uInt16 pokeAddress = address; if(isRamBank(address)) @@ -165,14 +166,6 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) pokeAddress, value); return true; } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - } } else { @@ -182,15 +175,12 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) pokeRAM(myRAM[address & myRamMask], pokeAddress, value); return true; } - else - { - // Writing to the read port should be ignored, but trigger a break if option enabled - uInt8 dummy; - - pokeRAM(dummy, pokeAddress, value); - myRamWriteAccess = pokeAddress; - } } + // Writing to the read port should be ignored, but trigger a break if option enabled + uInt8 dummy; + + pokeRAM(dummy, pokeAddress, value); + myRamWriteAccess = pokeAddress; } return false; } @@ -255,6 +245,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) { uInt32 offset = bankOffset + (addr & myRamMask); + access.directPokeBase = &myRAM[offset - mySize]; access.romAccessBase = &myRomAccessBase[offset]; access.romPeekCounter = &myRomAccessCounter[offset]; access.romPokeCounter = &myRomAccessCounter[offset + myAccessSize]; @@ -265,6 +256,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) fromAddr = (ROM_OFFSET + segmentOffset + myReadOffset) & ~System::PAGE_MASK; toAddr = (ROM_OFFSET + segmentOffset + myReadOffset + (myBankSize >> 1)) & ~System::PAGE_MASK; access.type = System::PageAccessType::READ; + access.directPokeBase = nullptr; for(uInt16 addr = fromAddr; addr < toAddr; addr += System::PAGE_SIZE) { From 51432f713ee3869512b6c31d1943ab47d2981e42 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 18 Apr 2020 17:51:21 +0200 Subject: [PATCH 28/52] fix display of changed PopUpWidget in debugger allow using IDs with PopUpWidget's ContextMenu --- src/gui/ContextMenu.cxx | 10 +++++----- src/gui/ContextMenu.hxx | 4 ++++ src/gui/PopUpWidget.cxx | 10 +++++++++- src/gui/PopUpWidget.hxx | 2 ++ 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index 11e09e475..cf142255f 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -181,7 +181,7 @@ bool ContextMenu::sendSelectionUp() return false; _selectedItem--; - sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, -1); + sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, _id); return true; } @@ -192,7 +192,7 @@ bool ContextMenu::sendSelectionDown() return false; _selectedItem++; - sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, -1); + sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, _id); return true; } @@ -203,7 +203,7 @@ bool ContextMenu::sendSelectionFirst() return false; _selectedItem = 0; - sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, -1); + sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, _id); return true; } @@ -214,7 +214,7 @@ bool ContextMenu::sendSelectionLast() return false; _selectedItem = int(_entries.size()) - 1; - sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, -1); + sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, _id); return true; } @@ -375,7 +375,7 @@ void ContextMenu::sendSelection() // Send any command associated with the selection _selectedItem = item; - sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, -1); + sendCommand(_cmd ? _cmd : ContextMenu::kItemSelectedCmd, _selectedItem, _id); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index 28d485f1a..40858f8b9 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -45,6 +45,9 @@ class ContextMenu : public Dialog, public CommandSender const VariantList& items, int cmd = 0, int width = 0); virtual ~ContextMenu() = default; + /** Set the parent widget's ID */ + void setID(uInt32 id) { _id = id; } + /** Add the given items to the widget. */ void addItems(const VariantList& items); @@ -121,6 +124,7 @@ class ContextMenu : public Dialog, public CommandSender ColorId _scrollUpColor{kColor}, _scrollDnColor{kColor}; int _cmd{0}; + int _id{-1}; uInt32 _xorig{0}, _yorig{0}; uInt32 _maxWidth{0}; diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 6b530f6d1..9cc233060 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -50,6 +50,14 @@ PopUpWidget::PopUpWidget(GuiObject* boss, const GUI::Font& font, myMenu = make_unique(this, font, list, cmd, w); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PopUpWidget::setID(uInt32 id) +{ + myMenu->setID(id); + + Widget::setID(id); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PopUpWidget::addItems(const VariantList& items) { @@ -219,5 +227,5 @@ void PopUpWidget::drawWidget(bool hilite) TextAlign align = (_font.getStringWidth(name) > w-6) ? TextAlign::Right : TextAlign::Left; s.drawString(_font, name, x+2, _y+myTextY, w-6, - !(isEnabled() && onTop) ? kColor : kTextColor, align); + !(isEnabled() && onTop) ? kColor : _changed ? kDbgChangedTextColor : kTextColor, align); } diff --git a/src/gui/PopUpWidget.hxx b/src/gui/PopUpWidget.hxx index f79e575f8..955263f5f 100644 --- a/src/gui/PopUpWidget.hxx +++ b/src/gui/PopUpWidget.hxx @@ -41,6 +41,8 @@ class PopUpWidget : public Widget, public CommandSender const string& label, int labelWidth = 0, int cmd = 0); virtual ~PopUpWidget() = default; + void setID(uInt32 id); + int getTop() const override { return _y + 1; } int getBottom() const override { return _y + 1 + getHeight(); } From a14a20c9a047797e1467ad7dafb541b4af8047c5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 18 Apr 2020 19:22:08 +0200 Subject: [PATCH 29/52] fixed description background color in CartRamWidget --- src/debugger/gui/CartRamWidget.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debugger/gui/CartRamWidget.cxx b/src/debugger/gui/CartRamWidget.cxx index 1dfcfdaac..cfed3d3e5 100644 --- a/src/debugger/gui/CartRamWidget.cxx +++ b/src/debugger/gui/CartRamWidget.cxx @@ -65,13 +65,14 @@ CartRamWidget::CartRamWidget( StringParser bs(desc, (fwidth - kScrollBarWidth) / myFontWidth); const StringList& sl = bs.stringList(); uInt32 lines = uInt32(sl.size()); - if(lines < 3) lines = 3; + if(lines < 2) lines = 2; if(lines > maxlines) lines = maxlines; new StaticTextWidget(_boss, _font, xpos, ypos + 1, "Description "); myDesc = new StringListWidget(boss, nfont, xpos+lwidth, ypos - 1, fwidth, lines * myLineHeight, false); myDesc->setEditable(false); + myDesc->setEnabled(false); myDesc->setList(sl); addFocusWidget(myDesc); From e5b919a8e0d9b84017c4c7590fb94f19fd123a9e Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 19 Apr 2020 10:23:27 +0200 Subject: [PATCH 30/52] refactored multiple CartXXWidget classes --- src/debugger/gui/Cart0840Widget.cxx | 75 +----- src/debugger/gui/Cart0840Widget.hxx | 15 +- src/debugger/gui/Cart2KWidget.cxx | 26 +- src/debugger/gui/Cart2KWidget.hxx | 11 +- src/debugger/gui/Cart3EWidget.cxx | 2 +- src/debugger/gui/Cart4KSCWidget.cxx | 91 +------ src/debugger/gui/Cart4KSCWidget.hxx | 29 +- src/debugger/gui/Cart4KWidget.cxx | 32 ++- src/debugger/gui/Cart4KWidget.hxx | 11 +- src/debugger/gui/CartCVWidget.cxx | 169 ++++++------ src/debugger/gui/CartCVWidget.hxx | 47 ++-- src/debugger/gui/CartDebugWidget.cxx | 2 +- src/debugger/gui/CartE0Widget.cxx | 145 +++------- src/debugger/gui/CartE0Widget.hxx | 24 +- src/debugger/gui/CartEnhancedWidget.cxx | 344 ++++++++++++++++++++++++ src/debugger/gui/CartEnhancedWidget.hxx | 108 ++++++++ src/debugger/gui/CartF0Widget.cxx | 82 +----- src/debugger/gui/CartF0Widget.hxx | 15 +- src/debugger/gui/CartF4SCWidget.cxx | 150 +---------- src/debugger/gui/CartF4SCWidget.hxx | 34 +-- src/debugger/gui/CartF4Widget.cxx | 81 +----- src/debugger/gui/CartF4Widget.hxx | 15 +- src/debugger/gui/CartF6SCWidget.cxx | 144 +--------- src/debugger/gui/CartF6SCWidget.hxx | 32 +-- src/debugger/gui/CartF6Widget.cxx | 75 +----- src/debugger/gui/CartF6Widget.hxx | 15 +- src/debugger/gui/CartF8SCWidget.cxx | 142 +--------- src/debugger/gui/CartF8SCWidget.hxx | 33 +-- src/debugger/gui/CartF8Widget.cxx | 73 +---- src/debugger/gui/CartF8Widget.hxx | 14 +- src/debugger/gui/CartUAWidget.cxx | 82 ++---- src/debugger/gui/CartUAWidget.hxx | 18 +- src/debugger/gui/module.mk | 1 + src/emucore/Cart4K.cxx | 1 - src/emucore/CartEnhanced.cxx | 2 +- src/emucore/CartEnhanced.hxx | 33 ++- src/emucore/CartUA.hxx | 2 + src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 + 39 files changed, 844 insertions(+), 1339 deletions(-) create mode 100644 src/debugger/gui/CartEnhancedWidget.cxx create mode 100644 src/debugger/gui/CartEnhancedWidget.hxx diff --git a/src/debugger/gui/Cart0840Widget.cxx b/src/debugger/gui/Cart0840Widget.cxx index 6582701bc..c49c86d09 100644 --- a/src/debugger/gui/Cart0840Widget.cxx +++ b/src/debugger/gui/Cart0840Widget.cxx @@ -16,80 +16,25 @@ //============================================================================ #include "Cart0840.hxx" -#include "PopUpWidget.hxx" #include "Cart0840Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge0840Widget::Cartridge0840Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge0840& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 2 * 4096; + myHotspotDelta = 0x40; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Cartridge0840Widget::description() +{ ostringstream info; - info << "0840 ECONObanking, two 4K banks\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < 2; - ++i, offset += 0x1000, spot += 0x40) - { - uInt16 start = uInt16((cart.myImage[offset+1] << 8) | cart.myImage[offset]); - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $" << spot << ")\n"; - } + info << "0840 ECONObanking, two 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Fred X. Quimby", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($800)"); - VarList::push_back(items, "1 ($840)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($800)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge0840Widget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge0840Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Cartridge0840Widget::bankState() -{ - ostringstream& buf = buffer(); - - static const std::array spot = { "$800", "$840" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/Cart0840Widget.hxx b/src/debugger/gui/Cart0840Widget.hxx index 239f28bf8..89e8706c6 100644 --- a/src/debugger/gui/Cart0840Widget.hxx +++ b/src/debugger/gui/Cart0840Widget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGE0840_WIDGET_HXX class Cartridge0840; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class Cartridge0840Widget : public CartDebugWidget +class Cartridge0840Widget : public CartEnhancedWidget { public: Cartridge0840Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class Cartridge0840Widget : public CartDebugWidget virtual ~Cartridge0840Widget() = default; private: - Cartridge0840& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Fred X. Quimby"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported Cartridge0840Widget() = delete; Cartridge0840Widget(const Cartridge0840Widget&) = delete; diff --git a/src/debugger/gui/Cart2KWidget.cxx b/src/debugger/gui/Cart2KWidget.cxx index 745c52316..c97bc440f 100644 --- a/src/debugger/gui/Cart2KWidget.cxx +++ b/src/debugger/gui/Cart2KWidget.cxx @@ -22,18 +22,18 @@ Cartridge2KWidget::Cartridge2KWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge2K& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - // Eventually, we should query this from the debugger/disassembler - size_t size; - - cart.getImage(size); - - uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; - start -= start % size; - - ostringstream info; - info << "Standard 2K cartridge, non-bankswitched\n" - << "Accessible @ $" << Common::Base::HEX4 << start << " - " << "$" << (start + size - 1); - addBaseInformation(size, "Atari", info.str()); + initialize(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Cartridge2KWidget::description() +{ + ostringstream info; + + info << "Standard 2K cartridge, non-bankswitched\n"; + info << CartEnhancedWidget::description(); + + return info.str(); } diff --git a/src/debugger/gui/Cart2KWidget.hxx b/src/debugger/gui/Cart2KWidget.hxx index 0580078f7..e6e0fe9d2 100644 --- a/src/debugger/gui/Cart2KWidget.hxx +++ b/src/debugger/gui/Cart2KWidget.hxx @@ -20,9 +20,9 @@ class Cartridge2K; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class Cartridge2KWidget : public CartDebugWidget +class Cartridge2KWidget : public CartEnhancedWidget { public: Cartridge2KWidget(GuiObject* boss, const GUI::Font& lfont, @@ -32,10 +32,11 @@ class Cartridge2KWidget : public CartDebugWidget virtual ~Cartridge2KWidget() = default; private: - // No implementation for non-bankswitched ROMs - void loadConfig() override { } - void handleCommand(CommandSender* sender, int cmd, int data, int id) override { } + string manufacturer() override { return "Atari"; } + string description() override; + + private: // Following constructors and assignment operators not supported Cartridge2KWidget() = delete; Cartridge2KWidget(const Cartridge2KWidget&) = delete; diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx index e91b268ab..287bdd112 100644 --- a/src/debugger/gui/Cart3EWidget.cxx +++ b/src/debugger/gui/Cart3EWidget.cxx @@ -161,7 +161,7 @@ string Cartridge3EWidget::bankState() if(bank < myCart.romBankCount()) buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive"; else - buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRomBanks; + buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRamBanks; return buf.str(); } diff --git a/src/debugger/gui/Cart4KSCWidget.cxx b/src/debugger/gui/Cart4KSCWidget.cxx index 8729c077f..105136dd5 100644 --- a/src/debugger/gui/Cart4KSCWidget.cxx +++ b/src/debugger/gui/Cart4KSCWidget.cxx @@ -15,8 +15,6 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "Cart4KSC.hxx" #include "Cart4KSCWidget.hxx" @@ -24,87 +22,18 @@ Cartridge4KSCWidget::Cartridge4KSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4KSC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - // Eventually, we should query this from the debugger/disassembler - uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC]; - start -= start % 0x1000; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Cartridge4KSCWidget::description() +{ ostringstream info; - info << "4KSC cartridge, non-bankswitched\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Accessible @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF); - addBaseInformation(4096, "homebrew intermediate format", info.str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge4KSCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 Cartridge4KSCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 Cartridge4KSCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Cartridge4KSCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& Cartridge4KSCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& Cartridge4KSCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge4KSCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge4KSCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Cartridge4KSCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + info << "4KSC cartridge, non-bankswitched\n"; + info << CartEnhancedWidget::description(); + + return info.str(); } diff --git a/src/debugger/gui/Cart4KSCWidget.hxx b/src/debugger/gui/Cart4KSCWidget.hxx index 6a6ee2d8c..832c2c127 100644 --- a/src/debugger/gui/Cart4KSCWidget.hxx +++ b/src/debugger/gui/Cart4KSCWidget.hxx @@ -20,9 +20,9 @@ class Cartridge4KSC; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class Cartridge4KSCWidget : public CartDebugWidget +class Cartridge4KSCWidget : public CartEnhancedWidget { public: Cartridge4KSCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -32,30 +32,11 @@ class Cartridge4KSCWidget : public CartDebugWidget virtual ~Cartridge4KSCWidget() = default; private: - Cartridge4KSC& myCart; - struct CartState { - ByteArray internalram; - }; - CartState myOldState; + string manufacturer() override { return "homebrew intermediate format"; } + + string description() override; private: - // No implementation for non-bankswitched ROMs - void loadConfig() override { } - void handleCommand(CommandSender* sender, int cmd, int data, int id) override { } - - void saveOldState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported Cartridge4KSCWidget() = delete; Cartridge4KSCWidget(const Cartridge4KSCWidget&) = delete; diff --git a/src/debugger/gui/Cart4KWidget.cxx b/src/debugger/gui/Cart4KWidget.cxx index ed4ef7218..14091bd15 100644 --- a/src/debugger/gui/Cart4KWidget.cxx +++ b/src/debugger/gui/Cart4KWidget.cxx @@ -22,15 +22,29 @@ Cartridge4KWidget::Cartridge4KWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4K& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - // Eventually, we should query this from the debugger/disassembler - uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC]; - start -= start % 0x1000; + initialize(); - ostringstream info; - info << "Standard 4K cartridge, non-bankswitched\n" - << "Accessible @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF); - addBaseInformation(4096, "Atari", info.str()); + //// Eventually, we should query this from the debugger/disassembler + //uInt16 start = (cart.myImage[0xFFD] << 8) | cart.myImage[0xFFC]; + //start -= start % 0x1000; + + //ostringstream info; + //info << "Standard 4K cartridge, non-bankswitched\n" + // << "Accessible @ $" << Common::Base::HEX4 << start << " - " + // << "$" << (start + 0xFFF); + //addBaseInformation(4096, "Atari", info.str()); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Cartridge4KWidget::description() +{ + ostringstream info; + + info << "Standard 4K cartridge, non-bankswitched\n"; + info << CartEnhancedWidget::description(); + + return info.str(); +} + diff --git a/src/debugger/gui/Cart4KWidget.hxx b/src/debugger/gui/Cart4KWidget.hxx index 3ba39a3d9..886e2a060 100644 --- a/src/debugger/gui/Cart4KWidget.hxx +++ b/src/debugger/gui/Cart4KWidget.hxx @@ -20,9 +20,9 @@ class Cartridge4K; -#include "CartDebugWidget.hxx" +#include "CartEnhanced.hxx" -class Cartridge4KWidget : public CartDebugWidget +class Cartridge4KWidget : public CartEnhancedWidget { public: Cartridge4KWidget(GuiObject* boss, const GUI::Font& lfont, @@ -32,10 +32,11 @@ class Cartridge4KWidget : public CartDebugWidget virtual ~Cartridge4KWidget() = default; private: - // No implementation for non-bankswitched ROMs - void loadConfig() override { } - void handleCommand(CommandSender* sender, int cmd, int data, int id) override { } + string manufacturer() override { return "Atari"; } + string description() override; + + private: // Following constructors and assignment operators not supported Cartridge4KWidget() = delete; Cartridge4KWidget(const Cartridge4KWidget&) = delete; diff --git a/src/debugger/gui/CartCVWidget.cxx b/src/debugger/gui/CartCVWidget.cxx index bae69cfba..167ff7122 100644 --- a/src/debugger/gui/CartCVWidget.cxx +++ b/src/debugger/gui/CartCVWidget.cxx @@ -24,88 +24,101 @@ CartridgeCVWidget::CartridgeCVWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCV& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - // Eventually, we should query this from the debugger/disassembler - uInt16 size = 2048; - uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; - start -= start % size; + initialize(); + //// Eventually, we should query this from the debugger/disassembler + //uInt16 size = 2048; + //uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; + //start -= start % size; + + //ostringstream info; + //info << "CV 2K ROM + 1K RAM , non-bankswitched\n" + // << "1024 bytes RAM @ $F000 - $F7FF\n" + // << " $F000 - $F3FF (R), $F400 - $F7FF (W)\n" + // << "ROM accessible @ $" << Common::Base::HEX4 << start << " - " + // << "$" << (start + size - 1); + + //addBaseInformation(cart.mySize, "CommaVid", info.str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeCVWidget::description() +{ ostringstream info; - info << "CV 2K ROM + 1K RAM , non-bankswitched\n" - << "1024 bytes RAM @ $F000 - $F7FF\n" - << " $F000 - $F3FF (R), $F400 - $F7FF (W)\n" - << "ROM accessible @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + size - 1); - addBaseInformation(cart.mySize, "CommaVid", info.str()); + info << "CV 2K ROM + 1K RAM , non-bankswitched\n"; + info << CartEnhancedWidget::description(); + + return info.str(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVWidget::saveOldState() -{ - myOldState.internalram.clear(); - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeCVWidget::internalRamSize() -{ - return 1024; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeCVWidget::internalRamRPort(int start) -{ - return 0xF000 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeCVWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F3FF used for Read Access\n" - << "$F400 - $F7FF used for Write Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeCVWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeCVWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeCVWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeCVWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeCVWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF000, false); -} +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//void CartridgeCVWidget::saveOldState() +//{ +// myOldState.internalram.clear(); +// +// for(uInt32 i = 0; i < internalRamSize(); ++i) +// myOldState.internalram.push_back(myCart.myRAM[i]); +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//uInt32 CartridgeCVWidget::internalRamSize() +//{ +// return 1024; +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//uInt32 CartridgeCVWidget::internalRamRPort(int start) +//{ +// return 0xF000 + start; +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//string CartridgeCVWidget::internalRamDescription() +//{ +// ostringstream desc; +// desc << "$F000 - $F3FF used for Read Access\n" +// << "$F400 - $F7FF used for Write Access"; +// +// return desc.str(); +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//const ByteArray& CartridgeCVWidget::internalRamOld(int start, int count) +//{ +// myRamOld.clear(); +// for(int i = 0; i < count; i++) +// myRamOld.push_back(myOldState.internalram[start + i]); +// return myRamOld; +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//const ByteArray& CartridgeCVWidget::internalRamCurrent(int start, int count) +//{ +// myRamCurrent.clear(); +// for(int i = 0; i < count; i++) +// myRamCurrent.push_back(myCart.myRAM[start + i]); +// return myRamCurrent; +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//void CartridgeCVWidget::internalRamSetValue(int addr, uInt8 value) +//{ +// myCart.myRAM[addr] = value; +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//uInt8 CartridgeCVWidget::internalRamGetValue(int addr) +//{ +// return myCart.myRAM[addr]; +//} +// +//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//string CartridgeCVWidget::internalRamLabel(int addr) +//{ +// CartDebug& dbg = instance().debugger().cartDebug(); +// return dbg.getLabel(addr + 0xF000, false); +//} diff --git a/src/debugger/gui/CartCVWidget.hxx b/src/debugger/gui/CartCVWidget.hxx index f9d59812b..73452204c 100644 --- a/src/debugger/gui/CartCVWidget.hxx +++ b/src/debugger/gui/CartCVWidget.hxx @@ -20,9 +20,9 @@ class CartridgeCV; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeCVWidget : public CartDebugWidget +class CartridgeCVWidget : public CartEnhancedWidget { public: CartridgeCVWidget(GuiObject* boss, const GUI::Font& lfont, @@ -32,30 +32,35 @@ class CartridgeCVWidget : public CartDebugWidget virtual ~CartridgeCVWidget() = default; private: - CartridgeCV& myCart; - struct CartState { - ByteArray internalram; - }; - CartState myOldState; + //CartridgeCV& myCart; + //struct CartState { + // ByteArray internalram; + //}; + //CartState myOldState; private: - // No implementation for non-bankswitched ROMs - void loadConfig() override { } - void handleCommand(CommandSender* sender, int cmd, int data, int id) override { } + string manufacturer() override { return "CommaVid"; } - void saveOldState() override; + string description() override; - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab + //// No implementation for non-bankswitched ROMs + //void loadConfig() override { } + //void handleCommand(CommandSender* sender, int cmd, int data, int id) override { } + //void saveOldState() override; + + //// start of functions for Cartridge RAM tab + //uInt32 internalRamSize() override; + //uInt32 internalRamRPort(int start) override; + //string internalRamDescription() override; + //const ByteArray& internalRamOld(int start, int count) override; + //const ByteArray& internalRamCurrent(int start, int count) override; + //void internalRamSetValue(int addr, uInt8 value) override; + //uInt8 internalRamGetValue(int addr) override; + //string internalRamLabel(int addr) override; + //// end of functions for Cartridge RAM tab + + private: // Following constructors and assignment operators not supported CartridgeCVWidget() = delete; CartridgeCVWidget(const CartridgeCVWidget&) = delete; diff --git a/src/debugger/gui/CartDebugWidget.cxx b/src/debugger/gui/CartDebugWidget.cxx index 208eec5a7..25423ebd7 100644 --- a/src/debugger/gui/CartDebugWidget.cxx +++ b/src/debugger/gui/CartDebugWidget.cxx @@ -65,7 +65,7 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer w->setEditable(false); y += myLineHeight + 4; - StringParser bs(desc, (fwidth - kScrollBarWidth) / myFontWidth - 4); + StringParser bs(desc, (fwidth - kScrollBarWidth - 4) / myFontWidth); const StringList& sl = bs.stringList(); uInt32 lines = uInt32(sl.size()); if(lines < 3) lines = 3; diff --git a/src/debugger/gui/CartE0Widget.cxx b/src/debugger/gui/CartE0Widget.cxx index 861c99228..4588abcdc 100644 --- a/src/debugger/gui/CartE0Widget.cxx +++ b/src/debugger/gui/CartE0Widget.cxx @@ -16,129 +16,60 @@ //============================================================================ #include "CartE0.hxx" -#include "PopUpWidget.hxx" #include "CartE0Widget.hxx" -static constexpr std::array seg0 = { - "0 ($FFE0)", "1 ($FFE1)", "2 ($FFE2)", "3 ($FFE3)", - "4 ($FFE4)", "5 ($FFE5)", "6 ($FFE6)", "7 ($FFE7)" -}; -static constexpr std::array seg1 = { - "0 ($FFE8)", "1 ($FFE9)", "2 ($FFEA)", "3 ($FFEB)", - "4 ($FFEC)", "5 ($FFED)", "6 ($FFEE)", "7 ($FFEF)" -}; -static constexpr std::array seg2 = { - "0 ($FFF0)", "1 ($FFF1)", "2 ($FFF2)", "3 ($FFF3)", - "4 ($FFF4)", "5 ($FFF5)", "6 ($FFF6)", "7 ($FFF7)" -}; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeE0Widget::CartridgeE0Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeE0& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 8 * 1024; + initialize(); +} - string info = - "E0 cartridge, eight 1K slices\n" - "Segment 0 accessible @ $F000 - $F3FF\n" - " Hotspots $FE0 to $FE7\n" - "Segment 1 accessible @ $F400 - $F7FF\n" - " Hotspots $FE8 to $FEF\n" - "Segment 2 accessible @ $F800 - $FBFF\n" - " Hotspots $FF0 to $FF7\n" - "Segment 3 accessible @ $FC00 - $FFFF\n" - " Always points to last 1K of ROM\n" - "Startup slices = 4 / 5 / 6 or undetermined\n"; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeE0Widget::description() +{ + ostringstream info; -#if 0 - // Eventually, we should query this from the debugger/disassembler - uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; - start -= start % 0x1000; - info << "Bank RORG" << " = $" << HEX4 << start << "\n"; -#endif - int xpos = 2, - ypos = addBaseInformation(size, "Parker Brothers", info) + myLineHeight; + info << "E0 cartridge,\n eight 1K banks mapped into four segments\n"; + info << CartEnhancedWidget::description(); - VariantList items0, items1, items2; - for(int i = 0; i < 8; ++i) + return info.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeE0Widget::romDescription() +{ + ostringstream info; + + for(int seg = 0; seg < 4; ++seg) { - VarList::push_back(items0, seg0[i]); - VarList::push_back(items1, seg1[i]); - VarList::push_back(items2, seg2[i]); + uInt16 segmentOffset = seg << 10; // myCart.myBankShift; + + info << "Segment #" << seg << " accessible @ $" + << Common::Base::HEX4 << (ADDR_BASE | segmentOffset) + << " - $" << (ADDR_BASE | segmentOffset + /*myCart.myBankSize - 1*/ 0x3FF) << ",\n"; + if (seg < 3) + info << " Hotspots " << hotspotStr(0, seg) << " - " << hotspotStr(7, seg) << "\n"; + else + info << " Always points to last 1K bank of ROM\n"; } + info << "Startup banks = 4 / 5 / 6 or undetermined"; - const int lwidth = _font.getStringWidth("Set slice for segment X "); - mySlice0 = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("7 ($FFF7)"), - myLineHeight, items0, "Set slice for segment 0 ", - lwidth, kSlice0Changed); - mySlice0->setTarget(this); - addFocusWidget(mySlice0); - ypos += mySlice0->getHeight() + 4; - - mySlice1 = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("7 ($FFF7)"), - myLineHeight, items1, "Set slice for segment 1 ", - lwidth, kSlice1Changed); - mySlice1->setTarget(this); - addFocusWidget(mySlice1); - ypos += mySlice1->getHeight() + 4; - - mySlice2 = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("7 ($FFF7)"), - myLineHeight, items2, "Set slice for segment 2 ", - lwidth, kSlice2Changed); - mySlice2->setTarget(this); - addFocusWidget(mySlice2); + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0Widget::loadConfig() +string CartridgeE0Widget::hotspotStr(int bank, int segment) { - mySlice0->setSelectedIndex(myCart.getSegmentBank(0)); - mySlice1->setSelectedIndex(myCart.getSegmentBank(1)); - mySlice2->setSelectedIndex(myCart.getSegmentBank(2)); + ostringstream info; + uInt16 hotspot = myCart.hotspot(); - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeE0Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - myCart.unlockBank(); - - switch(cmd) - { - case kSlice0Changed: - myCart.bank(mySlice0->getSelected(), 0); - break; - case kSlice1Changed: - myCart.bank(mySlice1->getSelected(), 1); - break; - case kSlice2Changed: - myCart.bank(mySlice2->getSelected(), 2); - break; - default: - break; - } - - myCart.lockBank(); - invalidate(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeE0Widget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Slices: " << std::dec - << seg0[myCart.getSegmentBank(0)] << " / " - << seg1[myCart.getSegmentBank(1)] << " / " - << seg2[myCart.getSegmentBank(2)]; - - return buf.str(); + if(hotspot & 0x1000) + hotspot |= ADDR_BASE; + + info << "$" << Common::Base::HEX1 << (hotspot + bank + segment * 8); + + return info.str(); } diff --git a/src/debugger/gui/CartE0Widget.hxx b/src/debugger/gui/CartE0Widget.hxx index bdbe73182..fe3e9d374 100644 --- a/src/debugger/gui/CartE0Widget.hxx +++ b/src/debugger/gui/CartE0Widget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEE0_WIDGET_HXX class CartridgeE0; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeE0Widget : public CartDebugWidget +class CartridgeE0Widget : public CartEnhancedWidget { public: CartridgeE0Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,21 +32,16 @@ class CartridgeE0Widget : public CartDebugWidget virtual ~CartridgeE0Widget() = default; private: - CartridgeE0& myCart; - PopUpWidget *mySlice0{nullptr}, *mySlice1{nullptr}, *mySlice2{nullptr}; + string manufacturer() override { return "Parker Brothers"; } - enum { - kSlice0Changed = 's0CH', - kSlice1Changed = 's1CH', - kSlice2Changed = 's2CH' - }; + string description() override; + string romDescription() override; + + string hotspotStr(int bank, int segment) override; + + int bankSegs() override { return 3; } private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeE0Widget() = delete; CartridgeE0Widget(const CartridgeE0Widget&) = delete; diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx new file mode 100644 index 000000000..39732fc80 --- /dev/null +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -0,0 +1,344 @@ +//============================================================================ +// +// 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 +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + + +#include "PopUpWidget.hxx" +#include "CartEnhanced.hxx" +#include "CartEnhancedWidget.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CartEnhancedWidget::CartEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, + const GUI::Font& nfont, + int x, int y, int w, int h, + CartridgeEnhanced& cart) + : CartDebugWidget(boss, lfont, nfont, x, y, w, h), + myCart(cart) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartEnhancedWidget::initialize() +{ + int ypos = addBaseInformation(size(), manufacturer(), description(), descriptionLines()) + + myLineHeight; + + bankSelect(ypos); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +size_t CartEnhancedWidget::size() +{ + size_t size; + + myCart.getImage(size); + + return size; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::description() +{ + ostringstream info; + + if (myCart.myRamSize > 0) + info << ramDescription(); + info << romDescription(); + + return info.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int CartEnhancedWidget::descriptionLines() +{ + return 20; // should be enough for almost all types +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::ramDescription() +{ + ostringstream info; + + info << myCart.myRamSize << " bytes RAM @ " + << "$" << Common::Base::HEX4 << ADDR_BASE << " - " + << "$" << (ADDR_BASE | (myCart.myRamSize * 2 - 1)) << "\n" + << " $" << (ADDR_BASE | myCart.myReadOffset) + << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamSize - 1)) << " (R)" + << ", $" << (ADDR_BASE | myCart.myWriteOffset) + << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamSize - 1)) << " (W)\n"; + + return info.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::romDescription() +{ + ostringstream info; + size_t size; + const uInt8* image = myCart.getImage(size); + + if(myCart.romBankCount() > 1) + { + info << "Startup bank = #" << myCart.startBank() << " or undetermined\n"; + for(int bank = 0, offset = 0xFFC; bank < myCart.romBankCount(); ++bank, offset += 0x1000) + { + uInt16 start = (image[offset + 1] << 8) | image[offset]; + start -= start % 0x1000; + + info << "Bank #" << bank << " @ $" + << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - $" << (start + 0xFFF) + << " (hotspot " << hotspotStr(bank) << ")\n"; + } + } + else + { + uInt16 start = (image[myCart.mySize - 3] << 8) | image[myCart.mySize - 4]; + start -= start % std::min(int(size), 0x1000); + + info << "ROM accessible @ $" + << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - " + << "$" << Common::Base::HEX4 << (start + myCart.mySize - 1); + } + + return info.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartEnhancedWidget::bankSelect(int& ypos) +{ + if(myCart.romBankCount() > 1) + { + int xpos = 2; + + myBankWidgets = make_unique(bankSegs()); + + for(int seg = 0; seg < bankSegs(); ++seg) + { + // fill bank and hotspot list + uInt16 hotspot = myCart.hotspot(); + VariantList items; + int pw = 0; + + for(int bank = 0; bank < myCart.romBankCount(); ++bank) + { + ostringstream buf; + + buf << std::setw(bank < 10 ? 2 : 1) << "#" << std::dec << bank; + if(hotspot >= 0x100 && myHotspotDelta > 0) + buf << " (" << hotspotStr(bank, seg) << ")"; + VarList::push_back(items, buf.str()); + pw = std::max(pw, _font.getStringWidth(buf.str())); + } + + // create widgets + ostringstream buf; + + buf << "Set bank"; + if(bankSegs() > 1) + buf << " for segment #" << seg << " "; + else + buf << " "; // align with info + + myBankWidgets[seg] = new PopUpWidget(_boss, _font, xpos, ypos - 2, + pw, myLineHeight, items, buf.str(), + 0, kBankChanged); + myBankWidgets[seg]->setTarget(this); + myBankWidgets[seg]->setID(seg); + addFocusWidget(myBankWidgets[seg]); + + ypos += myBankWidgets[seg]->getHeight() + 4; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::bankState() +{ + if(myCart.romBankCount() > 1) + { + ostringstream& buf = buffer(); + uInt16 hotspot = myCart.hotspot(); + bool hasRamBanks = myCart.myRamBankCount > 0; + + if(bankSegs() > 1) + { + buf << "Segments: "; + + for(int seg = 0; seg < bankSegs(); ++seg) + { + int bank = myCart.getSegmentBank(seg); + bool isRamBank = (bank >= myCart.romBankCount()); + + + if(seg > 0) + buf << " / "; + + buf << "#" << std::dec << (bank - (isRamBank ? myCart.romBankCount() : 0)); + + if(isRamBank) // was RAM mapped here? + buf << " RAM"; + else if (hasRamBanks) + buf << " ROM"; + + if(hotspot >= 0x100) + buf << " (" << (bankSegs() < 3 ? "hotspot " : "") << hotspotStr(bank) << ")"; + } + } + else + { + buf << "Bank #" << std::dec << myCart.getBank(); + + if(hotspot >= 0x100) + buf << " (hotspot " << hotspotStr(myCart.getSegmentBank()) << ")"; + } + return buf.str(); + } + return "0 (non-bankswitched)"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::hotspotStr(int bank, int segment) +{ + ostringstream info; + uInt16 hotspot = myCart.hotspot(); + + if(hotspot & 0x1000) + hotspot |= ADDR_BASE; + + info << "$" << Common::Base::HEX1 << (hotspot + bank * myHotspotDelta); + + return info.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int CartEnhancedWidget::bankSegs() +{ + return myCart.myBankSegs; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartEnhancedWidget::saveOldState() +{ + myOldState.internalRam.clear(); + for(uInt32 i = 0; i < myCart.myRamSize; ++i) + myOldState.internalRam.push_back(myCart.myRAM[i]); + + myOldState.banks.clear(); + for(int seg = 0; seg < bankSegs(); ++seg) + myOldState.banks.push_back(myCart.getSegmentBank(seg)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartEnhancedWidget::loadConfig() +{ + if(myBankWidgets != nullptr) + { + for(int seg = 0; seg < bankSegs(); ++seg) + myBankWidgets[seg]->setSelectedIndex(myCart.getSegmentBank(seg), + myCart.getSegmentBank(seg) != myOldState.banks[seg]); + } + CartDebugWidget::loadConfig(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartEnhancedWidget::handleCommand(CommandSender* sender, + int cmd, int data, int id) +{ + if(cmd == kBankChanged) + { + myCart.unlockBank(); + myCart.bank(myBankWidgets[id]->getSelected(), id); + myCart.lockBank(); + invalidate(); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 CartEnhancedWidget::internalRamSize() +{ + return myCart.myRamSize; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 CartEnhancedWidget::internalRamRPort(int start) +{ + return ADDR_BASE + myCart.myReadOffset + start; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::internalRamDescription() +{ + ostringstream desc; + + // order RW by addresses + if(myCart.myReadOffset <= myCart.myWriteOffset) + { + desc << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) + << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamSize - 1)) + << " used for Read Access\n"; + } + + desc + << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myWriteOffset) + << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamSize - 1)) + << " used for Write Access"; + + if(myCart.myReadOffset > myCart.myWriteOffset) + { + desc << "\n$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) + << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamSize - 1)) + << " used for Read Access"; + } + + return desc.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const ByteArray& CartEnhancedWidget::internalRamOld(int start, int count) +{ + myRamOld.clear(); + for(int i = 0; i < count; i++) + myRamOld.push_back(myOldState.internalRam[start + i]); + return myRamOld; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +const ByteArray& CartEnhancedWidget::internalRamCurrent(int start, int count) +{ + myRamCurrent.clear(); + for(int i = 0; i < count; i++) + myRamCurrent.push_back(myCart.myRAM[start + i]); + return myRamCurrent; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartEnhancedWidget::internalRamSetValue(int addr, uInt8 value) +{ + myCart.myRAM[addr] = value; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt8 CartEnhancedWidget::internalRamGetValue(int addr) +{ + return myCart.myRAM[addr]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartEnhancedWidget::internalRamLabel(int addr) +{ + CartDebug& dbg = instance().debugger().cartDebug(); + return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false); +} diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx new file mode 100644 index 000000000..3bff6350a --- /dev/null +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -0,0 +1,108 @@ +//============================================================================ +// +// 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 +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CART_ENHANCED_WIDGET_HXX +#define CART_ENHANCED_WIDGET_HXX + +class CartridgeEnhanced; +class PopUpWidget; + +namespace GUI { + class Font; +} + +#include "CartDebugWidget.hxx" + +class CartEnhancedWidget : public CartDebugWidget +{ + public: + CartEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, + const GUI::Font& nfont, + int x, int y, int w, int h, + CartridgeEnhanced& cart); + virtual ~CartEnhancedWidget() = default; + + protected: + void initialize(); + + virtual size_t size(); + + virtual string manufacturer() = 0; + + virtual string description(); + + virtual int descriptionLines(); + + virtual string ramDescription(); + + virtual string romDescription(); + + virtual void bankSelect(int& ypos); + + virtual string hotspotStr(int bank, int segment = 0); + + virtual int bankSegs(); // { return myCart.myBankSegs; } + + void saveOldState() override; + void loadConfig() override; + + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + + string bankState() override; + + // start of functions for Cartridge RAM tab + uInt32 internalRamSize() override; + uInt32 internalRamRPort(int start) override; + string internalRamDescription() override; + const ByteArray& internalRamOld(int start, int count) override; + const ByteArray& internalRamCurrent(int start, int count) override; + void internalRamSetValue(int addr, uInt8 value) override; + uInt8 internalRamGetValue(int addr) override; + string internalRamLabel(int addr) override; + // end of functions for Cartridge RAM tab + + protected: + enum { kBankChanged = 'bkCH' }; + + struct CartState { + ByteArray internalRam; + ByteArray banks; + }; + CartState myOldState; + + CartridgeEnhanced& myCart; + + // Distance between two hotspots + int myHotspotDelta{1}; + + std::unique_ptr myBankWidgets{nullptr}; + + + // Display all addresses based on this + static constexpr uInt16 ADDR_BASE = 0xF000; + + private: + // Following constructors and assignment operators not supported + CartEnhancedWidget() = delete; + CartEnhancedWidget(const CartEnhancedWidget&) = delete; + CartEnhancedWidget(CartEnhancedWidget&&) = delete; + CartEnhancedWidget& operator=(const CartEnhancedWidget&) = delete; + CartEnhancedWidget& operator=(CartEnhancedWidget&&) = delete; +}; + +#endif + diff --git a/src/debugger/gui/CartF0Widget.cxx b/src/debugger/gui/CartF0Widget.cxx index c7564cefa..c4826249e 100644 --- a/src/debugger/gui/CartF0Widget.cxx +++ b/src/debugger/gui/CartF0Widget.cxx @@ -16,85 +16,28 @@ //============================================================================ #include "CartF0.hxx" -#include "PopUpWidget.hxx" #include "CartF0Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF0Widget::CartridgeF0Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF0& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 16 * 4096; + myHotspotDelta = 0; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF0Widget::description() +{ ostringstream info; - info << "64K Megaboy F0 cartridge, 16 4K banks\n" - << "Startup bank = #" << cart.startBank() << " or undetermined\n" - << "Bankswitch triggered by accessing $1FF0\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC; i < 16; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start - << " - " << "$" << (start + 0xFFF) << "\n"; - } + info << "Megaboy F0 cartridge, 16 4K banks\n" + << "Startup bank = #" << myCart.startBank() << " or undetermined\n" + << "Bankswitch triggered by accessing $" << Common::Base::HEX4 << 0xFFF0 << "\n"; - int xpos = 2, - ypos = addBaseInformation(size, "Dynacom Megaboy", - info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0"); - VarList::push_back(items, " 1"); - VarList::push_back(items, " 2"); - VarList::push_back(items, " 3"); - VarList::push_back(items, " 4"); - VarList::push_back(items, " 5"); - VarList::push_back(items, " 6"); - VarList::push_back(items, " 7"); - VarList::push_back(items, " 8"); - VarList::push_back(items, " 9"); - VarList::push_back(items, " 10"); - VarList::push_back(items, " 11"); - VarList::push_back(items, " 12"); - VarList::push_back(items, " 13"); - VarList::push_back(items, " 14"); - VarList::push_back(items, " 15"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth(" 15"), - myLineHeight, items, "Set bank #", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF0Widget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF0Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -102,7 +45,8 @@ string CartridgeF0Widget::bankState() { ostringstream& buf = buffer(); - buf << "Bank = #" << std::dec << myCart.getBank() << ", hotspot = $FFF0"; + buf << "Bank #" << std::dec << myCart.getBank() + << " (hotspot $" << Common::Base::HEX4 << 0xFFF0 << ")"; return buf.str(); } diff --git a/src/debugger/gui/CartF0Widget.hxx b/src/debugger/gui/CartF0Widget.hxx index 6225fff71..b7aa701bc 100644 --- a/src/debugger/gui/CartF0Widget.hxx +++ b/src/debugger/gui/CartF0Widget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEF0_WIDGET_HXX class CartridgeF0; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF0Widget : public CartDebugWidget +class CartridgeF0Widget : public CartEnhancedWidget { public: CartridgeF0Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,13 @@ class CartridgeF0Widget : public CartDebugWidget virtual ~CartridgeF0Widget() = default; private: - CartridgeF0& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Dynacom Megaboy"; } - enum { kBankChanged = 'bkCH' }; - - private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + string description() override; string bankState() override; +private: // Following constructors and assignment operators not supported CartridgeF0Widget() = delete; CartridgeF0Widget(const CartridgeF0Widget&) = delete; diff --git a/src/debugger/gui/CartF4SCWidget.cxx b/src/debugger/gui/CartF4SCWidget.cxx index 512edba55..b85251cbe 100644 --- a/src/debugger/gui/CartF4SCWidget.cxx +++ b/src/debugger/gui/CartF4SCWidget.cxx @@ -15,157 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartF4SC.hxx" -#include "PopUpWidget.hxx" #include "CartF4SCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4SCWidget::CartridgeF4SCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF4SC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 8 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF4SCWidget::description() +{ ostringstream info; - info << "Standard F4SC cartridge, eight 4K banks\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF4; i < 8; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x100) << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "Standard F4SC cartridge, eight 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Atari", info.str(), 15) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF4)"); - VarList::push_back(items, "1 ($FFF5)"); - VarList::push_back(items, "2 ($FFF6)"); - VarList::push_back(items, "3 ($FFF7)"); - VarList::push_back(items, "4 ($FFF8)"); - VarList::push_back(items, "5 ($FFF9)"); - VarList::push_back(items, "6 ($FFFA)"); - VarList::push_back(items, "7 ($FFFB)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4SCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4SCWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4SCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF4SCWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeF4SCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeF4SCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF4SCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeF4SCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeF4SCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4SCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF4SCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF4SCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + return info.str(); } diff --git a/src/debugger/gui/CartF4SCWidget.hxx b/src/debugger/gui/CartF4SCWidget.hxx index e2ec21f06..8c22c6d74 100644 --- a/src/debugger/gui/CartF4SCWidget.hxx +++ b/src/debugger/gui/CartF4SCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEF4SC_WIDGET_HXX class CartridgeF4SC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF4SCWidget : public CartDebugWidget +class CartridgeF4SCWidget : public CartEnhancedWidget { public: CartridgeF4SCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,36 +32,11 @@ class CartridgeF4SCWidget : public CartDebugWidget virtual ~CartridgeF4SCWidget() = default; private: - CartridgeF4SC& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Atari"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeF4SCWidget() = delete; CartridgeF4SCWidget(const CartridgeF4SCWidget&) = delete; diff --git a/src/debugger/gui/CartF4Widget.cxx b/src/debugger/gui/CartF4Widget.cxx index 3d5848cd0..ae884cfa9 100644 --- a/src/debugger/gui/CartF4Widget.cxx +++ b/src/debugger/gui/CartF4Widget.cxx @@ -16,87 +16,24 @@ //============================================================================ #include "CartF4.hxx" -#include "PopUpWidget.hxx" #include "CartF4Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF4Widget::CartridgeF4Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF4& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 8 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF4Widget::description() +{ ostringstream info; - info << "Standard F4 cartridge, eight 4K banks\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF4; i < 8; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "Standard F4 cartridge, eight 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Atari", info.str(), 15) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF4)"); - VarList::push_back(items, "1 ($FFF5)"); - VarList::push_back(items, "2 ($FFF6)"); - VarList::push_back(items, "3 ($FFF7)"); - VarList::push_back(items, "4 ($FFF8)"); - VarList::push_back(items, "5 ($FFF9)"); - VarList::push_back(items, "6 ($FFFA)"); - VarList::push_back(items, "7 ($FFFB)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4Widget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF4Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF4Widget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFF4", "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartF4Widget.hxx b/src/debugger/gui/CartF4Widget.hxx index 7487a1b4b..2201b246b 100644 --- a/src/debugger/gui/CartF4Widget.hxx +++ b/src/debugger/gui/CartF4Widget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEF4_WIDGET_HXX class CartridgeF4; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF4Widget : public CartDebugWidget +class CartridgeF4Widget : public CartEnhancedWidget { public: CartridgeF4Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeF4Widget : public CartDebugWidget virtual ~CartridgeF4Widget() = default; private: - CartridgeF4& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Atari"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeF4Widget() = delete; CartridgeF4Widget(const CartridgeF4Widget&) = delete; diff --git a/src/debugger/gui/CartF6SCWidget.cxx b/src/debugger/gui/CartF6SCWidget.cxx index 863ff2948..bfa99b5c5 100644 --- a/src/debugger/gui/CartF6SCWidget.cxx +++ b/src/debugger/gui/CartF6SCWidget.cxx @@ -15,151 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartF6SC.hxx" -#include "PopUpWidget.hxx" #include "CartF6SCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6SCWidget::CartridgeF6SCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF6SC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 4 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF6SCWidget::description() +{ ostringstream info; - info << "Standard F6SC cartridge, four 4K banks\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 4; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x100) << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "Standard F6SC cartridge, four 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF6)"); - VarList::push_back(items, "1 ($FFF7)"); - VarList::push_back(items, "2 ($FFF8)"); - VarList::push_back(items, "3 ($FFF9)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6SCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6SCWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6SCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF6SCWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeF6SCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeF6SCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF6SCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeF6SCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeF6SCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6SCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF6SCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF6SCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + return info.str(); } diff --git a/src/debugger/gui/CartF6SCWidget.hxx b/src/debugger/gui/CartF6SCWidget.hxx index deee0e836..6b0aab9f8 100644 --- a/src/debugger/gui/CartF6SCWidget.hxx +++ b/src/debugger/gui/CartF6SCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEF6SC_WIDGET_HXX class CartridgeF6SC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF6SCWidget : public CartDebugWidget +class CartridgeF6SCWidget : public CartEnhancedWidget { public: CartridgeF6SCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,34 +32,11 @@ class CartridgeF6SCWidget : public CartDebugWidget virtual ~CartridgeF6SCWidget() = default; private: - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartridgeF6SC& myCart; - PopUpWidget* myBank{nullptr}; - CartState myOldState; + string manufacturer() override { return "Atari"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeF6SCWidget() = delete; CartridgeF6SCWidget(const CartridgeF6SCWidget&) = delete; diff --git a/src/debugger/gui/CartF6Widget.cxx b/src/debugger/gui/CartF6Widget.cxx index 114d20e18..692c40258 100644 --- a/src/debugger/gui/CartF6Widget.cxx +++ b/src/debugger/gui/CartF6Widget.cxx @@ -16,81 +16,24 @@ //============================================================================ #include "CartF6.hxx" -#include "PopUpWidget.hxx" #include "CartF6Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF6Widget::CartridgeF6Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF6& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 4 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF6Widget::description() +{ ostringstream info; - info << "Standard F6 cartridge, four 4K banks\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF6; i < 4; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "Standard F6 cartridge, four 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF6)"); - VarList::push_back(items, "1 ($FFF7)"); - VarList::push_back(items, "2 ($FFF8)"); - VarList::push_back(items, "3 ($FFF9)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx) "), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6Widget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF6Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF6Widget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { "$FFF6", "$FFF7", "$FFF8", "$FFF9" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartF6Widget.hxx b/src/debugger/gui/CartF6Widget.hxx index 392eb6a0c..e36933ac7 100644 --- a/src/debugger/gui/CartF6Widget.hxx +++ b/src/debugger/gui/CartF6Widget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEF6_WIDGET_HXX class CartridgeF6; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF6Widget : public CartDebugWidget +class CartridgeF6Widget : public CartEnhancedWidget { public: CartridgeF6Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeF6Widget : public CartDebugWidget virtual ~CartridgeF6Widget() = default; private: - CartridgeF6& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Atari"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeF6Widget() = delete; CartridgeF6Widget(const CartridgeF6Widget&) = delete; diff --git a/src/debugger/gui/CartF8SCWidget.cxx b/src/debugger/gui/CartF8SCWidget.cxx index 1f432e224..78e1c70a9 100644 --- a/src/debugger/gui/CartF8SCWidget.cxx +++ b/src/debugger/gui/CartF8SCWidget.cxx @@ -15,149 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartF8SC.hxx" -#include "PopUpWidget.hxx" #include "CartF8SCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8SCWidget::CartridgeF8SCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF8SC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 8192; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF8SCWidget::description() +{ ostringstream info; - info << "Standard F8SC cartridge, two 4K banks\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 2; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x100) << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "Standard F8SC cartridge, two 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF8)"); - VarList::push_back(items, "1 ($FFF9)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8SCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8SCWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8SCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF8SCWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { "$FFF8", "$FFF9" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeF8SCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeF8SCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF8SCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeF8SCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeF8SCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8SCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeF8SCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF8SCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + return info.str(); } diff --git a/src/debugger/gui/CartF8SCWidget.hxx b/src/debugger/gui/CartF8SCWidget.hxx index 7bebef602..3332f9a4b 100644 --- a/src/debugger/gui/CartF8SCWidget.hxx +++ b/src/debugger/gui/CartF8SCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEF8SC_WIDGET_HXX class CartridgeF8SC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF8SCWidget : public CartDebugWidget +class CartridgeF8SCWidget : public CartEnhancedWidget { public: CartridgeF8SCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,35 +32,11 @@ class CartridgeF8SCWidget : public CartDebugWidget virtual ~CartridgeF8SCWidget() = default; private: - CartridgeF8SC& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Atari"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeF8SCWidget() = delete; CartridgeF8SCWidget(const CartridgeF8SCWidget&) = delete; diff --git a/src/debugger/gui/CartF8Widget.cxx b/src/debugger/gui/CartF8Widget.cxx index ca648b5f1..ed1481b2a 100644 --- a/src/debugger/gui/CartF8Widget.cxx +++ b/src/debugger/gui/CartF8Widget.cxx @@ -16,79 +16,24 @@ //============================================================================ #include "CartF8.hxx" -#include "PopUpWidget.hxx" #include "CartF8Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeF8Widget::CartridgeF8Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF8& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 2 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeF8Widget::description() +{ ostringstream info; - info << "Standard F8 cartridge, two 4K banks\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 2; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "Standard F8 cartridge, two 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Atari", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF8)"); - VarList::push_back(items, "1 ($FFF9)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8Widget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeF8Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeF8Widget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { "$FFF8", "$FFF9" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartF8Widget.hxx b/src/debugger/gui/CartF8Widget.hxx index 507ad464b..34856f2ee 100644 --- a/src/debugger/gui/CartF8Widget.hxx +++ b/src/debugger/gui/CartF8Widget.hxx @@ -21,9 +21,9 @@ class CartridgeF8; class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeF8Widget : public CartDebugWidget +class CartridgeF8Widget : public CartEnhancedWidget { public: CartridgeF8Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +33,11 @@ class CartridgeF8Widget : public CartDebugWidget virtual ~CartridgeF8Widget() = default; private: - CartridgeF8& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Atari"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeF8Widget() = delete; CartridgeF8Widget(const CartridgeF8Widget&) = delete; diff --git a/src/debugger/gui/CartUAWidget.cxx b/src/debugger/gui/CartUAWidget.cxx index 7417d8b44..f3865b998 100644 --- a/src/debugger/gui/CartUAWidget.cxx +++ b/src/debugger/gui/CartUAWidget.cxx @@ -16,89 +16,37 @@ //============================================================================ #include "CartUA.hxx" -#include "PopUpWidget.hxx" #include "CartUAWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeUAWidget::CartridgeUAWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart), + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), mySwappedHotspots(swapHotspots) { - uInt16 size = 2 * 4096; + myHotspotDelta = 0x20; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeUAWidget::description() +{ ostringstream info; - info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = mySwappedHotspots ? 0x240 : 0x220; i < 2; - ++i, offset += 0x1000, spot += mySwappedHotspots ? -0x20 : 0x20) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspots = $" << spot << ", $" << (spot | 0x80) << ")\n"; - } + info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "UA Limited", info.str()) + myLineHeight; - - VariantList items; - if (swapHotspots) - { - VarList::push_back(items, "0 ($240, $2C0)"); - VarList::push_back(items, "1 ($220, $2A0)"); - } - else - { - VarList::push_back(items, "0 ($220, $2A0)"); - VarList::push_back(items, "1 ($240, $2C0)"); - } - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFx, $FFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeUAWidget::loadConfig() +string CartridgeUAWidget::hotspotStr(int bank, int) { - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); + ostringstream info; + uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta; - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); + info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80); - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeUAWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeUAWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { "$220, $2A0", "$240, $2C0" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspots = " << spot[myCart.getBank() ^ (mySwappedHotspots ? 1U : 0U)]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartUAWidget.hxx b/src/debugger/gui/CartUAWidget.hxx index 346b1c1d2..bb61d25c9 100644 --- a/src/debugger/gui/CartUAWidget.hxx +++ b/src/debugger/gui/CartUAWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEUA_WIDGET_HXX class CartridgeUA; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeUAWidget : public CartDebugWidget +class CartridgeUAWidget : public CartEnhancedWidget { public: CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,19 +32,16 @@ class CartridgeUAWidget : public CartDebugWidget virtual ~CartridgeUAWidget() = default; private: - CartridgeUA& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "UA Limited"; } - bool mySwappedHotspots; + string description() override; - enum { kBankChanged = 'bkCH' }; + string hotspotStr(int bank, int) override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; + const bool mySwappedHotspots; + private: // Following constructors and assignment operators not supported CartridgeUAWidget() = delete; CartridgeUAWidget(const CartridgeUAWidget&) = delete; diff --git a/src/debugger/gui/module.mk b/src/debugger/gui/module.mk index d1ffc81c0..8f19ce5fa 100644 --- a/src/debugger/gui/module.mk +++ b/src/debugger/gui/module.mk @@ -28,6 +28,7 @@ MODULE_OBJS := \ src/debugger/gui/CartDPCPlusWidget.o \ src/debugger/gui/CartDPCWidget.o \ src/debugger/gui/CartE0Widget.o \ + src/debugger/gui/CartEnhancedWidget.o \ src/debugger/gui/CartMNetworkWidget.o \ src/debugger/gui/CartE7Widget.o \ src/debugger/gui/CartE78KWidget.o \ diff --git a/src/emucore/Cart4K.cxx b/src/emucore/Cart4K.cxx index d26ccfec0..9e684afad 100644 --- a/src/emucore/Cart4K.cxx +++ b/src/emucore/Cart4K.cxx @@ -23,5 +23,4 @@ Cartridge4K::Cartridge4K(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) : CartridgeEnhanced(image, size, md5, settings) { - cerr << "Cartridge4K" << endl; } diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 11eb0ca75..05f954e3e 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -205,7 +205,7 @@ bool CartridgeEnhanced::bank(uInt16 bank, uInt16 segment) // for ROMs < 4_KB, the whole address space will be mapped. uInt16 toAddr = (ROM_OFFSET + segmentOffset + (mySize < 4_KB ? 4_KB : myBankSize)) & ~System::PAGE_MASK; - if(hotspot != 0) + if(hotspot & 0x1000) hotSpotAddr = (hotspot & ~System::PAGE_MASK); else hotSpotAddr = 0xFFFF; // none diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 10dbfb0d6..ecf8a0a58 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -22,6 +22,9 @@ class System; #include "bspf.hxx" #include "Cart.hxx" +#ifdef DEBUGGER_SUPPORT + #include "CartEnhancedWidget.hxx" +#endif /** Enhanced cartridge base class used for multiple cart types. @@ -30,6 +33,8 @@ class System; */ class CartridgeEnhanced : public Cartridge { + friend class CartEnhancedWidget; + public: /** Create a new cartridge using the specified image @@ -142,7 +147,6 @@ class CartridgeEnhanced : public Cartridge */ bool load(Serializer& in) override; - public: /** Get the byte at the specified address. @@ -159,19 +163,25 @@ class CartridgeEnhanced : public Cartridge */ bool poke(uInt16 address, uInt8 value) override; + /** + Get the hotspot in ROM address space. + + @return The first hotspot address (ususally in ROM) space or 0 + */ + virtual uInt16 hotspot() const { return 0; } + // TODO: handle cases where there the hotspots cover multiple pages + protected: // The '2 ^ N = bank segment size' exponent uInt16 myBankShift{BANK_SHIFT}; // default 12 (-> one 4K segment) // The size of a bank's segment - uInt16 myBankSize{0}; + uInt16 myBankSize{uInt16(4_KB)}; // The mask for a bank segment - uInt16 myBankMask{0}; - - // The number of segments a bank is split into - uInt16 myBankSegs{0}; + uInt16 myBankMask{ROM_MASK}; + protected: // The extra RAM size uInt16 myRamSize{RAM_SIZE}; // default 0 @@ -181,6 +191,9 @@ class CartridgeEnhanced : public Cartridge // The mask for the extra RAM uInt16 myRamMask{0}; // RAM_SIZE - 1, but doesn't matter when RAM_SIZE is 0 + // The number of segments a bank is split into (default 1) + uInt16 myBankSegs{1}; + // The offset into ROM space for reading from ROM // This is zero for types without RAM and with banked RAM // - xxSC = 0x0100 @@ -259,14 +272,6 @@ class CartridgeEnhanced : public Cartridge */ virtual uInt16 getStartBank() const { return 0; } - /** - Get the hotspot in ROM address space. - - @return The first hotspot address (ususally in ROM) space or 0 - */ - virtual uInt16 hotspot() const { return 0; } - // TODO: handle cases where there the hotspots cover multiple pages - private: // Following constructors and assignment operators not supported CartridgeEnhanced() = delete; diff --git a/src/emucore/CartUA.hxx b/src/emucore/CartUA.hxx index 97569dd76..77b83d10b 100644 --- a/src/emucore/CartUA.hxx +++ b/src/emucore/CartUA.hxx @@ -100,6 +100,8 @@ class CartridgeUA : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; + uInt16 hotspot() const override { return 0x0220; } + private: // Previous Device's page access std::array myHotSpotPageAccess; diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index b081dde0d..28b0efe29 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -618,6 +618,7 @@ true + true @@ -1621,6 +1622,7 @@ true + true diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index f0c9b601d..536cf54eb 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -996,6 +996,9 @@ Source Files\emucore + + Source Files\debugger + @@ -2045,6 +2048,9 @@ Header Files\emucore + + Header Files\debugger + From 4e314a5fe23adc0bdaa1abe3a1b3f04b11aeb6fa Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 19 Apr 2020 12:19:44 +0200 Subject: [PATCH 31/52] improve bankswitching masking in CartEnhanced --- src/emucore/Cart3F.hxx | 2 ++ src/emucore/CartE0.cxx | 2 ++ src/emucore/CartEnhanced.cxx | 7 ++++--- src/emucore/CartEnhanced.hxx | 3 +++ src/emucore/CartF0.cxx | 2 +- src/emucore/CartF4.cxx | 4 ++-- src/emucore/CartF6.cxx | 4 ++-- src/emucore/CartF8.cxx | 4 ++-- src/emucore/CartFA.cxx | 4 ++-- src/emucore/CartFA2.cxx | 4 ++-- src/emucore/CartFC.cxx | 2 +- 11 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/emucore/Cart3F.hxx b/src/emucore/Cart3F.hxx index d9f3e9fa6..7bdcbd99c 100644 --- a/src/emucore/Cart3F.hxx +++ b/src/emucore/Cart3F.hxx @@ -87,6 +87,8 @@ class Cartridge3F : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value) override; + uInt16 hotspot() const override { return 0x003F; } + private: // log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800 diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index 97752e447..d9c37d7e4 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -48,6 +48,8 @@ void CartridgeE0::reset() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeE0::checkSwitchBank(uInt16 address, uInt8) { + address &= ROM_MASK; + // Switch banks if necessary if((address >= 0x0FE0) && (address <= 0x0FE7)) { diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 05f954e3e..ea167b1d5 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -114,8 +114,9 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) { uInt16 peekAddress = address; - if (hotspot() != 0) - checkSwitchBank(address & ROM_MASK); + // hotspots in TIA range are reacting to pokes only + if (hotspot() >= 0x80) + checkSwitchBank(address & ADDR_MASK); if(isRamBank(address)) { @@ -148,7 +149,7 @@ bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) // Note: (TODO?) // The checkSwitchBank() call makes no difference between ROM and e.g TIA space // Writing to e.g. 0xf0xx might triger a bankswitch, is (and was!) this a bug??? - if (checkSwitchBank(address & ROM_MASK, value)) + if (checkSwitchBank(address & ADDR_MASK, value)) return false; if(myRamSize > 0) diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index ecf8a0a58..c3702d118 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -232,6 +232,9 @@ class CartridgeEnhanced : public Cartridge size_t mySize{0}; protected: + // The mask for 6507 address space + static constexpr uInt16 ADDR_MASK = 0x1FFF; + // The offset into address space for accessing ROM static constexpr uInt16 ROM_OFFSET = 0x1000; diff --git a/src/emucore/CartF0.cxx b/src/emucore/CartF0.cxx index 9f021a685..8747c57f3 100644 --- a/src/emucore/CartF0.cxx +++ b/src/emucore/CartF0.cxx @@ -28,7 +28,7 @@ CartridgeF0::CartridgeF0(const ByteBuffer& image, size_t size, bool CartridgeF0::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary - if(address == 0x0FF0) + if(address == 0x1FF0) { // Switch to next bank uInt8 nextBank = ((getBank()) + 1) & 0x0F; diff --git a/src/emucore/CartF4.cxx b/src/emucore/CartF4.cxx index 0cb689228..6a8cd6e00 100644 --- a/src/emucore/CartF4.cxx +++ b/src/emucore/CartF4.cxx @@ -29,9 +29,9 @@ bool CartridgeF4::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary // Note: addresses could be calculated from hotspot and bank count - if((address >= 0x0FF4) && (address <= 0x0FFB)) + if((address >= 0x1FF4) && (address <= 0x1FFB)) { - bank(address - 0x0FF4); + bank(address - 0x1FF4); return true; } return false; diff --git a/src/emucore/CartF6.cxx b/src/emucore/CartF6.cxx index 567424d7a..50e993e26 100644 --- a/src/emucore/CartF6.cxx +++ b/src/emucore/CartF6.cxx @@ -29,9 +29,9 @@ bool CartridgeF6::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary // Note: addresses could be calculated from hotspot and bank count - if((address >= 0x0FF6) && (address <= 0x0FF9)) + if((address >= 0x1FF6) && (address <= 0x1FF9)) { - bank(address - 0x0FF6); + bank(address - 0x1FF6); return true; } return false; diff --git a/src/emucore/CartF8.cxx b/src/emucore/CartF8.cxx index 79b4708c4..5d898091c 100644 --- a/src/emucore/CartF8.cxx +++ b/src/emucore/CartF8.cxx @@ -30,12 +30,12 @@ bool CartridgeF8::checkSwitchBank(uInt16 address, uInt8) // Switch banks if necessary switch(address) { - case 0x0FF8: + case 0x1FF8: // Set the current bank to the lower 4k bank bank(0); return true; - case 0x0FF9: + case 0x1FF9: // Set the current bank to the upper 4k bank bank(1); return true; diff --git a/src/emucore/CartFA.cxx b/src/emucore/CartFA.cxx index 3f1062f41..082e403f7 100644 --- a/src/emucore/CartFA.cxx +++ b/src/emucore/CartFA.cxx @@ -30,9 +30,9 @@ CartridgeFA::CartridgeFA(const ByteBuffer& image, size_t size, bool CartridgeFA::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary - if((address >= 0x0FF8) && (address <= 0x0FFA)) + if((address >= 0x1FF8) && (address <= 0x1FFA)) { - bank(address - 0x0FF8); + bank(address - 0x1FF8); return true; } return false; diff --git a/src/emucore/CartFA2.cxx b/src/emucore/CartFA2.cxx index 6662e8171..14c8f2156 100644 --- a/src/emucore/CartFA2.cxx +++ b/src/emucore/CartFA2.cxx @@ -42,9 +42,9 @@ CartridgeFA2::CartridgeFA2(const ByteBuffer& image, size_t size, bool CartridgeFA2::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary - if((address >= 0x0FF5) && (address <= 0x0FFB)) + if((address >= 0x1FF5) && (address <= 0x1FFB)) { - bank(address - 0x0FF5); + bank(address - 0x1FF5); return true; } return false; diff --git a/src/emucore/CartFC.cxx b/src/emucore/CartFC.cxx index 925718d50..c415ba1af 100644 --- a/src/emucore/CartFC.cxx +++ b/src/emucore/CartFC.cxx @@ -37,7 +37,7 @@ void CartridgeFC::reset() bool CartridgeFC::checkSwitchBank(uInt16 address, uInt8) { // Switch banks if necessary - if(address == 0x0FFC) + if(address == 0x1FFC) { // Trigger the bank switch bank(myTargetBank); From 453cb84060d119b09e23f9c4e1013575b3b6f2a2 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 19 Apr 2020 18:59:07 +0200 Subject: [PATCH 32/52] refactored Cart3F, CartCV and CartBF(SC) widgets --- src/debugger/gui/Cart3FWidget.cxx | 79 ++------- src/debugger/gui/Cart3FWidget.hxx | 17 +- src/debugger/gui/CartBFSCWidget.cxx | 218 ++---------------------- src/debugger/gui/CartBFSCWidget.hxx | 33 +--- src/debugger/gui/CartBFWidget.cxx | 145 +--------------- src/debugger/gui/CartBFWidget.hxx | 15 +- src/debugger/gui/CartCVWidget.cxx | 85 +-------- src/debugger/gui/CartE0Widget.hxx | 1 + src/debugger/gui/CartEnhancedWidget.cxx | 17 +- src/debugger/gui/CartEnhancedWidget.hxx | 2 +- src/debugger/gui/CartF0Widget.hxx | 2 +- src/emucore/CartEnhanced.cxx | 3 - 12 files changed, 65 insertions(+), 552 deletions(-) diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index 13cd851bd..76f331502 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -16,80 +16,33 @@ //============================================================================ #include "Cart3F.hxx" -#include "PopUpWidget.hxx" #include "Cart3FWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3FWidget::Cartridge3FWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3F& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) +{ + myHotspotDelta = 0; + initialize(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Cartridge3FWidget::description() { ostringstream info; size_t size; + const uInt8* image = myCart.getImage(size); - cart.getImage(size); - info << "Tigervision 3F cartridge, 2-256 2K banks\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n" - << "First 2K bank selected by writing to $3F\n" - << "Last 2K always points to last 2K of ROM\n"; - + info << "Tigervision 3F cartridge, 2 - 256 2K banks\n" + << "First 2K bank selected by writing to " << hotspotStr() << "\n" + << "Last 2K always points to last 2K of ROM\n" + << "Startup bank = " << myCart.startBank() << " or undetermined\n"; // Eventually, we should query this from the debugger/disassembler - uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; + uInt16 start = (image[size-3] << 8) | image[size-4]; start -= start % 0x1000; - info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n"; + info << "Bank RORG $" << Common::Base::HEX4 << start << "\n"; - int xpos = 2, - ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight; - - VariantList items; - for(uInt16 i = 0; i < cart.romBankCount(); ++i) - VarList::push_back(items, Variant(i).toString() + " ($3F)"); - - ostringstream label; - label << "Set bank ($" << Common::Base::HEX4 << start << " - $" << - (start+0x7FF) << ") "; - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3F) "), - myLineHeight, items, label.str(), - _font.getStringWidth(label.str()), kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3FWidget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(0), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3FWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Cartridge3FWidget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Bank = #" << std::dec << myCart.getSegmentBank() << ", hotspot = $3F"; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/Cart3FWidget.hxx b/src/debugger/gui/Cart3FWidget.hxx index 859184057..7e3ee65e9 100644 --- a/src/debugger/gui/Cart3FWidget.hxx +++ b/src/debugger/gui/Cart3FWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGE3F_WIDGET_HXX class Cartridge3F; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class Cartridge3FWidget : public CartDebugWidget +class Cartridge3FWidget : public CartEnhancedWidget { public: Cartridge3FWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,13 @@ class Cartridge3FWidget : public CartDebugWidget virtual ~Cartridge3FWidget() = default; private: - Cartridge3F& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "TigerVision"; } - enum { kBankChanged = 'bkCH' }; + string description() override; + + int bankSegs() override { return 1; } private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported Cartridge3FWidget() = delete; Cartridge3FWidget(const Cartridge3FWidget&) = delete; diff --git a/src/debugger/gui/CartBFSCWidget.cxx b/src/debugger/gui/CartBFSCWidget.cxx index 819e72b39..00109d9e9 100644 --- a/src/debugger/gui/CartBFSCWidget.cxx +++ b/src/debugger/gui/CartBFSCWidget.cxx @@ -15,221 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartBFSC.hxx" -#include "PopUpWidget.hxx" #include "CartBFSCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBFSCWidget::CartridgeBFSCWidget( - GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, - int x, int y, int w, int h, CartridgeBFSC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, + int x, int y, int w, int h, CartridgeBFSC& cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 64 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeBFSCWidget::description() +{ ostringstream info; - info << "256K BFSC + RAM, 64 4K banks\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100) - << " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "256K BFSC + RAM, 64 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0 ($FF80)"); - VarList::push_back(items, " 1 ($FF81)"); - VarList::push_back(items, " 2 ($FF82)"); - VarList::push_back(items, " 3 ($FF83)"); - VarList::push_back(items, " 4 ($FF84)"); - VarList::push_back(items, " 5 ($FF85)"); - VarList::push_back(items, " 6 ($FF86)"); - VarList::push_back(items, " 7 ($FF87)"); - VarList::push_back(items, " 8 ($FF88)"); - VarList::push_back(items, " 9 ($FF89)"); - VarList::push_back(items, "10 ($FF8A)"); - VarList::push_back(items, "11 ($FF8B)"); - VarList::push_back(items, "12 ($FF8C)"); - VarList::push_back(items, "13 ($FF8D)"); - VarList::push_back(items, "14 ($FF8E)"); - VarList::push_back(items, "15 ($FF8F)"); - VarList::push_back(items, "16 ($FF90)"); - VarList::push_back(items, "17 ($FF91)"); - VarList::push_back(items, "18 ($FF92)"); - VarList::push_back(items, "19 ($FF93)"); - VarList::push_back(items, "20 ($FF94)"); - VarList::push_back(items, "21 ($FF95)"); - VarList::push_back(items, "22 ($FF96)"); - VarList::push_back(items, "23 ($FF97)"); - VarList::push_back(items, "24 ($FF98)"); - VarList::push_back(items, "25 ($FF99)"); - VarList::push_back(items, "26 ($FF9A)"); - VarList::push_back(items, "27 ($FF9B)"); - VarList::push_back(items, "28 ($FF9C)"); - VarList::push_back(items, "29 ($FF9D)"); - VarList::push_back(items, "30 ($FF9E)"); - VarList::push_back(items, "31 ($FF9F)"); - VarList::push_back(items, "32 ($FFA0)"); - VarList::push_back(items, "33 ($FFA1)"); - VarList::push_back(items, "34 ($FFA2)"); - VarList::push_back(items, "35 ($FFA3)"); - VarList::push_back(items, "36 ($FFA4)"); - VarList::push_back(items, "37 ($FFA5)"); - VarList::push_back(items, "38 ($FFA6)"); - VarList::push_back(items, "39 ($FFA7)"); - VarList::push_back(items, "40 ($FFA8)"); - VarList::push_back(items, "41 ($FFA9)"); - VarList::push_back(items, "42 ($FFAA)"); - VarList::push_back(items, "43 ($FFAB)"); - VarList::push_back(items, "44 ($FFAC)"); - VarList::push_back(items, "45 ($FFAD)"); - VarList::push_back(items, "46 ($FFAE)"); - VarList::push_back(items, "47 ($FFAF)"); - VarList::push_back(items, "48 ($FFB0)"); - VarList::push_back(items, "49 ($FFB1)"); - VarList::push_back(items, "50 ($FFB2)"); - VarList::push_back(items, "51 ($FFB3)"); - VarList::push_back(items, "52 ($FFB4)"); - VarList::push_back(items, "53 ($FFB5)"); - VarList::push_back(items, "54 ($FFB6)"); - VarList::push_back(items, "55 ($FFB7)"); - VarList::push_back(items, "56 ($FFB8)"); - VarList::push_back(items, "57 ($FFB9)"); - VarList::push_back(items, "58 ($FFBA)"); - VarList::push_back(items, "59 ($FFBB)"); - VarList::push_back(items, "60 ($FFBC)"); - VarList::push_back(items, "61 ($FFBD)"); - VarList::push_back(items, "62 ($FFBE)"); - VarList::push_back(items, "63 ($FFBF)"); - - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("63 ($FFBF)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFSCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFSCWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFSCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeBFSCWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FF80", "$FF81", "$FF82", "$FF83", "$FF84", "$FF85", "$FF86", "$FF87", - "$FF88", "$FF89", "$FF8A", "$FF8B", "$FF8C", "$FF8D", "$FF8E", "$FF8F", - "$FF90", "$FF91", "$FF92", "$FF93", "$FF94", "$FF95", "$FF96", "$FF97", - "$FF98", "$FF99", "$FF9A", "$FF9B", "$FF9C", "$FF9D", "$FF9E", "$FF9F", - "$FFA0", "$FFA1", "$FFA2", "$FFA3", "$FFA4", "$FFA5", "$FFA6", "$FFA7", - "$FFA8", "$FFA9", "$FFAA", "$FFAB", "$FFAC", "$FFAD", "$FFAE", "$FFAF", - "$FFB0", "$FFB1", "$FFB2", "$FFB3", "$FFB4", "$FFB5", "$FFB6", "$FFB7", - "$FFB8", "$FFB9", "$FFBA", "$FFBB", "$FFBC", "$FFBD", "$FFBE", "$FFBF" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeBFSCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeBFSCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeBFSCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeBFSCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeBFSCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFSCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeBFSCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeBFSCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + return info.str(); } diff --git a/src/debugger/gui/CartBFSCWidget.hxx b/src/debugger/gui/CartBFSCWidget.hxx index 3068672f0..5e394eae5 100644 --- a/src/debugger/gui/CartBFSCWidget.hxx +++ b/src/debugger/gui/CartBFSCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEBFSC_WIDGET_HXX class CartridgeBFSC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeBFSCWidget : public CartDebugWidget +class CartridgeBFSCWidget : public CartEnhancedWidget { public: CartridgeBFSCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,35 +32,11 @@ class CartridgeBFSCWidget : public CartDebugWidget virtual ~CartridgeBFSCWidget() = default; private: - CartridgeBFSC& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "CPUWIZ"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeBFSCWidget() = delete; CartridgeBFSCWidget(const CartridgeBFSCWidget&) = delete; diff --git a/src/debugger/gui/CartBFWidget.cxx b/src/debugger/gui/CartBFWidget.cxx index 96ddc5662..001f50658 100644 --- a/src/debugger/gui/CartBFWidget.cxx +++ b/src/debugger/gui/CartBFWidget.cxx @@ -16,151 +16,24 @@ //============================================================================ #include "CartBF.hxx" -#include "PopUpWidget.hxx" #include "CartBFWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeBFWidget::CartridgeBFWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeBF& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 64 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeBFWidget::description() +{ ostringstream info; - info << "BF cartridge, 64 4K banks\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xF80; i < 64; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "256K BF cartridge, 64 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0 ($FF80)"); - VarList::push_back(items, " 1 ($FF81)"); - VarList::push_back(items, " 2 ($FF82)"); - VarList::push_back(items, " 3 ($FF83)"); - VarList::push_back(items, " 4 ($FF84)"); - VarList::push_back(items, " 5 ($FF85)"); - VarList::push_back(items, " 6 ($FF86)"); - VarList::push_back(items, " 7 ($FF87)"); - VarList::push_back(items, " 8 ($FF88)"); - VarList::push_back(items, " 9 ($FF89)"); - VarList::push_back(items, "10 ($FF8A)"); - VarList::push_back(items, "11 ($FF8B)"); - VarList::push_back(items, "12 ($FF8C)"); - VarList::push_back(items, "13 ($FF8D)"); - VarList::push_back(items, "14 ($FF8E)"); - VarList::push_back(items, "15 ($FF8F)"); - VarList::push_back(items, "16 ($FF90)"); - VarList::push_back(items, "17 ($FF91)"); - VarList::push_back(items, "18 ($FF92)"); - VarList::push_back(items, "19 ($FF93)"); - VarList::push_back(items, "20 ($FF94)"); - VarList::push_back(items, "21 ($FF95)"); - VarList::push_back(items, "22 ($FF96)"); - VarList::push_back(items, "23 ($FF97)"); - VarList::push_back(items, "24 ($FF98)"); - VarList::push_back(items, "25 ($FF99)"); - VarList::push_back(items, "26 ($FF9A)"); - VarList::push_back(items, "27 ($FF9B)"); - VarList::push_back(items, "28 ($FF9C)"); - VarList::push_back(items, "29 ($FF9D)"); - VarList::push_back(items, "30 ($FF9E)"); - VarList::push_back(items, "31 ($FF9F)"); - VarList::push_back(items, "32 ($FFA0)"); - VarList::push_back(items, "33 ($FFA1)"); - VarList::push_back(items, "34 ($FFA2)"); - VarList::push_back(items, "35 ($FFA3)"); - VarList::push_back(items, "36 ($FFA4)"); - VarList::push_back(items, "37 ($FFA5)"); - VarList::push_back(items, "38 ($FFA6)"); - VarList::push_back(items, "39 ($FFA7)"); - VarList::push_back(items, "40 ($FFA8)"); - VarList::push_back(items, "41 ($FFA9)"); - VarList::push_back(items, "42 ($FFAA)"); - VarList::push_back(items, "43 ($FFAB)"); - VarList::push_back(items, "44 ($FFAC)"); - VarList::push_back(items, "45 ($FFAD)"); - VarList::push_back(items, "46 ($FFAE)"); - VarList::push_back(items, "47 ($FFAF)"); - VarList::push_back(items, "48 ($FFB0)"); - VarList::push_back(items, "49 ($FFB1)"); - VarList::push_back(items, "50 ($FFB2)"); - VarList::push_back(items, "51 ($FFB3)"); - VarList::push_back(items, "52 ($FFB4)"); - VarList::push_back(items, "53 ($FFB5)"); - VarList::push_back(items, "54 ($FFB6)"); - VarList::push_back(items, "55 ($FFB7)"); - VarList::push_back(items, "56 ($FFB8)"); - VarList::push_back(items, "57 ($FFB9)"); - VarList::push_back(items, "58 ($FFBA)"); - VarList::push_back(items, "59 ($FFBB)"); - VarList::push_back(items, "60 ($FFBC)"); - VarList::push_back(items, "61 ($FFBD)"); - VarList::push_back(items, "62 ($FFBE)"); - VarList::push_back(items, "63 ($FFBF)"); - - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("64 ($FFBF)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFWidget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeBFWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeBFWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FF80", "$FF81", "$FF82", "$FF83", "$FF84", "$FF85", "$FF86", "$FF87", - "$FF88", "$FF89", "$FF8A", "$FF8B", "$FF8C", "$FF8D", "$FF8E", "$FF8F", - "$FF90", "$FF91", "$FF92", "$FF93", "$FF94", "$FF95", "$FF96", "$FF97", - "$FF98", "$FF99", "$FF9A", "$FF9B", "$FF9C", "$FF9D", "$FF9E", "$FF9F", - "$FFA0", "$FFA1", "$FFA2", "$FFA3", "$FFA4", "$FFA5", "$FFA6", "$FFA7", - "$FFA8", "$FFA9", "$FFAA", "$FFAB", "$FFAC", "$FFAD", "$FFAE", "$FFAF", - "$FFB0", "$FFB1", "$FFB2", "$FFB3", "$FFB4", "$FFB5", "$FFB6", "$FFB7", - "$FFB8", "$FFB9", "$FFBA", "$FFBB", "$FFBC", "$FFBD", "$FFBE", "$FFBF" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartBFWidget.hxx b/src/debugger/gui/CartBFWidget.hxx index d084dbbc3..6c8d37257 100644 --- a/src/debugger/gui/CartBFWidget.hxx +++ b/src/debugger/gui/CartBFWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEBF_WIDGET_HXX class CartridgeBF; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeBFWidget : public CartDebugWidget +class CartridgeBFWidget : public CartEnhancedWidget { public: CartridgeBFWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeBFWidget : public CartDebugWidget virtual ~CartridgeBFWidget() = default; private: - CartridgeBF& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "CPUWIZ"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeBFWidget() = delete; CartridgeBFWidget(const CartridgeBFWidget&) = delete; diff --git a/src/debugger/gui/CartCVWidget.cxx b/src/debugger/gui/CartCVWidget.cxx index 167ff7122..1517cc843 100644 --- a/src/debugger/gui/CartCVWidget.cxx +++ b/src/debugger/gui/CartCVWidget.cxx @@ -27,20 +27,6 @@ CartridgeCVWidget::CartridgeCVWidget( : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); - - //// Eventually, we should query this from the debugger/disassembler - //uInt16 size = 2048; - //uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; - //start -= start % size; - - //ostringstream info; - //info << "CV 2K ROM + 1K RAM , non-bankswitched\n" - // << "1024 bytes RAM @ $F000 - $F7FF\n" - // << " $F000 - $F3FF (R), $F400 - $F7FF (W)\n" - // << "ROM accessible @ $" << Common::Base::HEX4 << start << " - " - // << "$" << (start + size - 1); - - //addBaseInformation(cart.mySize, "CommaVid", info.str()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -48,77 +34,8 @@ string CartridgeCVWidget::description() { ostringstream info; - info << "CV 2K ROM + 1K RAM , non-bankswitched\n"; + info << "CV 2K ROM + 1K RAM, non-bankswitched\n"; info << CartEnhancedWidget::description(); return info.str(); } - - -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//void CartridgeCVWidget::saveOldState() -//{ -// myOldState.internalram.clear(); -// -// for(uInt32 i = 0; i < internalRamSize(); ++i) -// myOldState.internalram.push_back(myCart.myRAM[i]); -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//uInt32 CartridgeCVWidget::internalRamSize() -//{ -// return 1024; -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//uInt32 CartridgeCVWidget::internalRamRPort(int start) -//{ -// return 0xF000 + start; -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//string CartridgeCVWidget::internalRamDescription() -//{ -// ostringstream desc; -// desc << "$F000 - $F3FF used for Read Access\n" -// << "$F400 - $F7FF used for Write Access"; -// -// return desc.str(); -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//const ByteArray& CartridgeCVWidget::internalRamOld(int start, int count) -//{ -// myRamOld.clear(); -// for(int i = 0; i < count; i++) -// myRamOld.push_back(myOldState.internalram[start + i]); -// return myRamOld; -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//const ByteArray& CartridgeCVWidget::internalRamCurrent(int start, int count) -//{ -// myRamCurrent.clear(); -// for(int i = 0; i < count; i++) -// myRamCurrent.push_back(myCart.myRAM[start + i]); -// return myRamCurrent; -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//void CartridgeCVWidget::internalRamSetValue(int addr, uInt8 value) -//{ -// myCart.myRAM[addr] = value; -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//uInt8 CartridgeCVWidget::internalRamGetValue(int addr) -//{ -// return myCart.myRAM[addr]; -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//string CartridgeCVWidget::internalRamLabel(int addr) -//{ -// CartDebug& dbg = instance().debugger().cartDebug(); -// return dbg.getLabel(addr + 0xF000, false); -//} diff --git a/src/debugger/gui/CartE0Widget.hxx b/src/debugger/gui/CartE0Widget.hxx index fe3e9d374..0bc5694ea 100644 --- a/src/debugger/gui/CartE0Widget.hxx +++ b/src/debugger/gui/CartE0Widget.hxx @@ -41,6 +41,7 @@ class CartridgeE0Widget : public CartEnhancedWidget string hotspotStr(int bank, int segment) override; int bankSegs() override { return 3; } + private: // Following constructors and assignment operators not supported CartridgeE0Widget() = delete; diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index 39732fc80..d38c5534c 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -92,25 +92,30 @@ string CartEnhancedWidget::romDescription() if(myCart.romBankCount() > 1) { - info << "Startup bank = #" << myCart.startBank() << " or undetermined\n"; for(int bank = 0, offset = 0xFFC; bank < myCart.romBankCount(); ++bank, offset += 0x1000) { uInt16 start = (image[offset + 1] << 8) | image[offset]; start -= start % 0x1000; - info << "Bank #" << bank << " @ $" + info << "Bank #" << std::dec << bank << " @ $" << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - $" << (start + 0xFFF) << " (hotspot " << hotspotStr(bank) << ")\n"; } + info << "Startup bank = #" << std::dec << myCart.startBank() << " or undetermined\n"; } else { uInt16 start = (image[myCart.mySize - 3] << 8) | image[myCart.mySize - 4]; - start -= start % std::min(int(size), 0x1000); + start -= start % std::min(int(size), 0x1000); + // special check for ROMs where the extra RAM is not included in the image (e.g. CV). + if((start & 0xFFF) < size) + { + start += myCart.myRomOffset; + } info << "ROM accessible @ $" - << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - " - << "$" << Common::Base::HEX4 << (start + myCart.mySize - 1); + << Common::Base::HEX4 << start << " - $" + << Common::Base::HEX4 << (start + myCart.mySize - 1); } return info.str(); @@ -201,7 +206,7 @@ string CartEnhancedWidget::bankState() { buf << "Bank #" << std::dec << myCart.getBank(); - if(hotspot >= 0x100) + //if(hotspot >= 0x100) buf << " (hotspot " << hotspotStr(myCart.getSegmentBank()) << ")"; } return buf.str(); diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index 3bff6350a..dccc9fde0 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -53,7 +53,7 @@ class CartEnhancedWidget : public CartDebugWidget virtual void bankSelect(int& ypos); - virtual string hotspotStr(int bank, int segment = 0); + virtual string hotspotStr(int bank = 0, int segment = 0); virtual int bankSegs(); // { return myCart.myBankSegs; } diff --git a/src/debugger/gui/CartF0Widget.hxx b/src/debugger/gui/CartF0Widget.hxx index b7aa701bc..9ba5aa3ab 100644 --- a/src/debugger/gui/CartF0Widget.hxx +++ b/src/debugger/gui/CartF0Widget.hxx @@ -38,7 +38,7 @@ class CartridgeF0Widget : public CartEnhancedWidget string bankState() override; -private: + private: // Following constructors and assignment operators not supported CartridgeF0Widget() = delete; CartridgeF0Widget(const CartridgeF0Widget&) = delete; diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index ea167b1d5..3e69a06f8 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -146,9 +146,6 @@ uInt8 CartridgeEnhanced::peek(uInt16 address) bool CartridgeEnhanced::poke(uInt16 address, uInt8 value) { // Switch banks if necessary - // Note: (TODO?) - // The checkSwitchBank() call makes no difference between ROM and e.g TIA space - // Writing to e.g. 0xf0xx might triger a bankswitch, is (and was!) this a bug??? if (checkSwitchBank(address & ADDR_MASK, value)) return false; From 62c15ec5897491e6499ad7d046641d0ff3589179 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 19 Apr 2020 23:08:25 +0200 Subject: [PATCH 33/52] added 'Turbo" mode --- Changes.txt | 2 ++ docs/index.html | 51 ++++++++++++++++++++------------- src/common/FrameBufferSDL2.cxx | 3 +- src/common/PKeyboardHandler.cxx | 1 + src/emucore/Console.cxx | 22 +++++++++++++- src/emucore/Console.hxx | 5 ++++ src/emucore/Event.hxx | 1 + src/emucore/EventHandler.cxx | 6 ++++ src/emucore/EventHandler.hxx | 2 +- src/emucore/FrameBuffer.cxx | 5 +++- src/emucore/Settings.cxx | 2 ++ 11 files changed, 76 insertions(+), 24 deletions(-) diff --git a/Changes.txt b/Changes.txt index e7faac008..61989ecd9 100644 --- a/Changes.txt +++ b/Changes.txt @@ -22,6 +22,8 @@ a game. This allows the user to save high scores for these games. For each game and variation, the top 10 scores can be saved. (TODO: Doc) + * Added 'Turbo' mode, runs the game as fast as the computer allows. + * Added option which lets default ROM path follow launcher navigation (TODO: Doc) * Added displaying last write address in the debugger. diff --git a/docs/index.html b/docs/index.html index 18aa916dc..c7185ebe1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1626,6 +1626,12 @@ + + + + + + @@ -2004,6 +2010,11 @@ + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index d7b9ecb17..bce5c2e7c 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -320,7 +320,8 @@ bool FrameBufferSDL2::setVideoMode(const string& title, const VideoMode& mode) } uInt32 renderFlags = SDL_RENDERER_ACCELERATED; - if(myOSystem.settings().getBool("vsync")) // V'synced blits option + if(myOSystem.settings().getBool("vsync") + && !myOSystem.settings().getBool("turbo")) // V'synced blits option renderFlags |= SDL_RENDERER_PRESENTVSYNC; const string& video = myOSystem.settings().getString("video"); // Render hint if(video != "") diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 76d48dd1a..bc2c545ca 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -468,6 +468,7 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo {Event::ToggleColorLoss, KBDK_L, KBDM_CTRL}, {Event::TogglePalette, KBDK_P, KBDM_CTRL}, {Event::ToggleInter, KBDK_I, KBDM_CTRL}, + {Event::ToggleTurbo, KBDK_T, KBDM_CTRL}, {Event::ToggleJitter, KBDK_J, MOD3}, {Event::ToggleFrameStats, KBDK_L, MOD3}, {Event::ToggleTimeMachine, KBDK_T, MOD3}, diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 518030966..fc5c1e9be 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -563,6 +563,24 @@ void Console::toggleInter() myOSystem.frameBuffer().showMessage(ss.str()); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Console::toggleTurbo() +{ + bool enabled = myOSystem.settings().getBool("turbo"); + + myOSystem.settings().setValue("turbo", !enabled); + + // update speed + initializeAudio(); + + // update VSync + myOSystem.createFrameBuffer(); + + ostringstream ss; + ss << "Turbo mode " << (!enabled ? "enabled" : "disabled"); + myOSystem.frameBuffer().showMessage(ss.str()); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Console::togglePhosphor() { @@ -657,7 +675,9 @@ void Console::initializeAudio() .updatePlaybackPeriod(myAudioSettings.fragmentSize()) .updateAudioQueueExtraFragments(myAudioSettings.bufferSize()) .updateAudioQueueHeadroom(myAudioSettings.headroom()) - .updateSpeedFactor(myOSystem.settings().getFloat("speed")); + .updateSpeedFactor(myOSystem.settings().getBool("turbo") + ? 20.0F + : myOSystem.settings().getFloat("speed")); createAudioQueue(); myTIA->setAudioQueue(myAudioQueue); diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index eb85025a6..33c3b117c 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -221,6 +221,11 @@ class Console : public Serializable, public ConsoleIO */ void toggleInter(); + /** + Toggle turbo mode on/off + */ + void toggleTurbo(); + /** Toggles phosphor effect. diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index b82bb7f50..c45fc1e0a 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -120,6 +120,7 @@ class Event ToggleFrameStats, ToggleSAPortOrder, ExitGame, // add new events from here to avoid that user remapped events get overwritten + ToggleTurbo, LastType }; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 4433ed244..1a11c604b 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -539,6 +539,10 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated) if (pressed && !repeated) myOSystem.console().toggleInter(); return; + case Event::ToggleTurbo: + if (pressed && !repeated) myOSystem.console().toggleTurbo(); + return; + case Event::ToggleJitter: if (pressed && !repeated) myOSystem.console().toggleJitter(); return; @@ -1815,6 +1819,7 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { { { Event::TogglePauseMode, "Toggle Pause mode", "" }, { Event::StartPauseMode, "Start Pause mode", "" }, { Event::Fry, "Fry cartridge", "" }, + { Event::ToggleTurbo, "Toggle Turbo mode", "" }, { Event::DebuggerMode, "Toggle Debugger mode", "" }, { Event::ConsoleSelect, "Select", "" }, @@ -2023,6 +2028,7 @@ EventHandler::MenuActionList EventHandler::ourMenuActionList = { { const Event::EventSet EventHandler::MiscEvents = { Event::Quit, Event::ReloadConsole, Event::Fry, Event::StartPauseMode, Event::TogglePauseMode, Event::OptionsMenuMode, Event::CmdMenuMode, Event::ExitMode, + Event::ToggleTurbo, Event::TakeSnapshot, Event::ToggleContSnapshots, Event::ToggleContSnapshotsFrame, // Event::MouseAxisXMove, Event::MouseAxisYMove, // Event::MouseButtonLeftValue, Event::MouseButtonRightValue, diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 7fa56d17d..8148fa085 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -468,7 +468,7 @@ class EventHandler #else PNG_SIZE = 0, #endif - EMUL_ACTIONLIST_SIZE = 144 + PNG_SIZE + COMBO_SIZE, + EMUL_ACTIONLIST_SIZE = 145 + PNG_SIZE + COMBO_SIZE, MENU_ACTIONLIST_SIZE = 18 ; diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 68b6e8caa..3c64c5d8f 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -502,7 +502,10 @@ void FrameBuffer::drawFrameStats(float framesPerSecond) ss << std::fixed << std::setprecision(1) << framesPerSecond << "fps @ " - << std::fixed << std::setprecision(0) << 100 * myOSystem.settings().getFloat("speed") + << std::fixed << std::setprecision(0) << 100 * + (myOSystem.settings().getBool("turbo") + ? 20.0F + : myOSystem.settings().getFloat("speed")) << "% speed"; myStatsMsg.surface->drawString(f, ss.str(), xPos, yPos, diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index c3feece37..50e45cd06 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -157,6 +157,7 @@ Settings::Settings() setPermanent("threads", "false"); setTemporary("romloadcount", "0"); setTemporary("maxres", ""); + setTemporary("turbo", "0"); #ifdef DEBUGGER_SUPPORT // Debugger/disassembly options @@ -400,6 +401,7 @@ void Settings::usage() const << " z26|\n" << " user>\n" << " -speed Run emulation at the given speed\n" + << " -turbo <1|0> Enable 'Turbo' mode for maximum emulation speed\n" << " -uimessages <1|0> Show onscreen UI messages for different events\n" << endl #ifdef SOUND_SUPPORT From 77fb0ef009c81c672dd1e9101021f5024c53e6c3 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sun, 19 Apr 2020 23:21:08 +0200 Subject: [PATCH 34/52] some cleanup in CartCVWidget --- src/debugger/gui/CartCVWidget.hxx | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/debugger/gui/CartCVWidget.hxx b/src/debugger/gui/CartCVWidget.hxx index 73452204c..dd8e971ab 100644 --- a/src/debugger/gui/CartCVWidget.hxx +++ b/src/debugger/gui/CartCVWidget.hxx @@ -31,35 +31,11 @@ class CartridgeCVWidget : public CartEnhancedWidget CartridgeCV& cart); virtual ~CartridgeCVWidget() = default; - private: - //CartridgeCV& myCart; - //struct CartState { - // ByteArray internalram; - //}; - //CartState myOldState; - private: string manufacturer() override { return "CommaVid"; } string description() override; - //// No implementation for non-bankswitched ROMs - //void loadConfig() override { } - //void handleCommand(CommandSender* sender, int cmd, int data, int id) override { } - - //void saveOldState() override; - - //// start of functions for Cartridge RAM tab - //uInt32 internalRamSize() override; - //uInt32 internalRamRPort(int start) override; - //string internalRamDescription() override; - //const ByteArray& internalRamOld(int start, int count) override; - //const ByteArray& internalRamCurrent(int start, int count) override; - //void internalRamSetValue(int addr, uInt8 value) override; - //uInt8 internalRamGetValue(int addr) override; - //string internalRamLabel(int addr) override; - //// end of functions for Cartridge RAM tab - private: // Following constructors and assignment operators not supported CartridgeCVWidget() = delete; From c198372c2996c88556581199a7c683fcb3cfa73a Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 20 Apr 2020 12:45:05 +0200 Subject: [PATCH 35/52] sort single file ZIP files correctly (fixes #612) --- src/emucore/FSNode.cxx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 6965839ef..64af7212e 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -58,6 +58,20 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, if (!_realNode->getChildren(tmp, mode)) return false; + #if defined(ZIP_SUPPORT) + // before sorting, replace single file ZIP archive names with contained file names + // because they are displayed using their contained file names + for (auto& i : tmp) + { + if (BSPF::endsWithIgnoreCase(i->getPath(), ".zip")) + { + FilesystemNodeZIP node(i->getPath()); + + i->setName(node.getName()); + } + } + #endif + std::sort(tmp.begin(), tmp.end(), [](const AbstractFSNodePtr& node1, const AbstractFSNodePtr& node2) { From e8f7bbce6547ea895b3d98555459ac2120009726 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 20 Apr 2020 20:46:28 +0200 Subject: [PATCH 36/52] Improved 3E auto detection --- src/emucore/CartDetector.cxx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index 4d7a583eb..b40e75c49 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -620,11 +620,16 @@ bool CartDetector::isProbably0840(const ByteBuffer& image, size_t size) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbably3E(const ByteBuffer& image, size_t size) { - // 3E cart bankswitching is triggered by storing the bank number - // in address 3E using 'STA $3E', commonly followed by an - // immediate mode LDA - uInt8 signature[] = { 0x85, 0x3E, 0xA9, 0x00 }; // STA $3E; LDA #$00 - return searchForBytes(image.get(), size, signature, 4, 1); + // 3E cart RAM bankswitching is triggered by storing the bank number + // in address 3E using 'STA $3E', ROM bankswitching is triggered by + // storing the bank number in address 3F using 'STA $3F'. + // We expect the latter will be present at least 2 times, since there + // are at least two banks + + uInt8 signature1[] = { 0x85, 0x3E }; // STA $3E + uInt8 signature2[] = { 0x85, 0x3F }; // STA $3F + return searchForBytes(image.get(), size, signature1, 2, 1) + && searchForBytes(image.get(), size, signature2, 2, 2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From cc78be70d5be07b23ed4c2eac7d2d75ede71b117 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Mon, 20 Apr 2020 21:06:16 +0200 Subject: [PATCH 37/52] refactored CartDF(SC)Widget and CartEF(SC)Widget classes --- src/debugger/gui/CartDFSCWidget.cxx | 178 ++-------------------------- src/debugger/gui/CartDFSCWidget.hxx | 33 +----- src/debugger/gui/CartDFWidget.cxx | 109 ++--------------- src/debugger/gui/CartDFWidget.hxx | 15 +-- src/debugger/gui/CartEFSCWidget.cxx | 160 ++----------------------- src/debugger/gui/CartEFSCWidget.hxx | 33 +----- src/debugger/gui/CartEFWidget.cxx | 91 ++------------ src/debugger/gui/CartEFWidget.hxx | 15 +-- 8 files changed, 52 insertions(+), 582 deletions(-) diff --git a/src/debugger/gui/CartDFSCWidget.cxx b/src/debugger/gui/CartDFSCWidget.cxx index e03fbf1c6..0744ca182 100644 --- a/src/debugger/gui/CartDFSCWidget.cxx +++ b/src/debugger/gui/CartDFSCWidget.cxx @@ -15,185 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartDFSC.hxx" -#include "PopUpWidget.hxx" #include "CartDFSCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDFSCWidget::CartridgeDFSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDFSC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 32 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeDFSCWidget::description() +{ ostringstream info; - info << "128K DFSC + RAM, 32 4K banks\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFC0; i < 32; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100) - << " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "128K DFSC + RAM, 32 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0 ($FFC0)"); - VarList::push_back(items, " 1 ($FFC1)"); - VarList::push_back(items, " 2 ($FFC2)"); - VarList::push_back(items, " 3 ($FFC3)"); - VarList::push_back(items, " 4 ($FFC4)"); - VarList::push_back(items, " 5 ($FFC5)"); - VarList::push_back(items, " 6 ($FFC6)"); - VarList::push_back(items, " 7 ($FFC7)"); - VarList::push_back(items, " 8 ($FFC8)"); - VarList::push_back(items, " 9 ($FFC9)"); - VarList::push_back(items, "10 ($FFCA)"); - VarList::push_back(items, "11 ($FFCB)"); - VarList::push_back(items, "12 ($FFCC)"); - VarList::push_back(items, "13 ($FFCD)"); - VarList::push_back(items, "14 ($FFCE)"); - VarList::push_back(items, "15 ($FFCF)"); - VarList::push_back(items, "16 ($FFD0)"); - VarList::push_back(items, "17 ($FFD1)"); - VarList::push_back(items, "18 ($FFD2)"); - VarList::push_back(items, "19 ($FFD3)"); - VarList::push_back(items, "20 ($FFD4)"); - VarList::push_back(items, "21 ($FFD5)"); - VarList::push_back(items, "22 ($FFD6)"); - VarList::push_back(items, "23 ($FFD7)"); - VarList::push_back(items, "24 ($FFD8)"); - VarList::push_back(items, "25 ($FFD9)"); - VarList::push_back(items, "26 ($FFDA)"); - VarList::push_back(items, "27 ($FFDB)"); - VarList::push_back(items, "28 ($FFDC)"); - VarList::push_back(items, "29 ($FFDD)"); - VarList::push_back(items, "30 ($FFDE)"); - VarList::push_back(items, "31 ($FFDF)"); - - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("31 ($FFE0)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFSCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFSCWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFSCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeDFSCWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFC0", "$FFC1", "$FFC2", "$FFC3", "$FFC4", "$FFC5", "$FFC6", "$FFC7", - "$FFC8", "$FFC9", "$FFCA", "$FFCB", "$FFCC", "$FFCD", "$FFCE", "$FFCF", - "$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFE7", - "$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeDFSCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeDFSCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeDFSCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeDFSCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeDFSCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFSCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeDFSCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeDFSCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + return info.str(); } diff --git a/src/debugger/gui/CartDFSCWidget.hxx b/src/debugger/gui/CartDFSCWidget.hxx index 4d4a07feb..7aff641ee 100644 --- a/src/debugger/gui/CartDFSCWidget.hxx +++ b/src/debugger/gui/CartDFSCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEDFSC_WIDGET_HXX class CartridgeDFSC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeDFSCWidget : public CartDebugWidget +class CartridgeDFSCWidget : public CartEnhancedWidget { public: CartridgeDFSCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,35 +32,11 @@ class CartridgeDFSCWidget : public CartDebugWidget virtual ~CartridgeDFSCWidget() = default; private: - CartridgeDFSC& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "CPUWIZ"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeDFSCWidget() = delete; CartridgeDFSCWidget(const CartridgeDFSCWidget&) = delete; diff --git a/src/debugger/gui/CartDFWidget.cxx b/src/debugger/gui/CartDFWidget.cxx index c8fde5fff..cdb6d4f1b 100644 --- a/src/debugger/gui/CartDFWidget.cxx +++ b/src/debugger/gui/CartDFWidget.cxx @@ -16,115 +16,24 @@ //============================================================================ #include "CartDF.hxx" -#include "PopUpWidget.hxx" #include "CartDFWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDFWidget::CartridgeDFWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDF& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 32 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeDFWidget::description() +{ ostringstream info; - info << "EF 2 cartridge, 32 4K banks\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFD0; i < 32; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "128K DF, 32 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "CPUWIZ", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0 ($FFC0)"); - VarList::push_back(items, " 1 ($FFC1)"); - VarList::push_back(items, " 2 ($FFC2)"); - VarList::push_back(items, " 3 ($FFC3)"); - VarList::push_back(items, " 4 ($FFC4)"); - VarList::push_back(items, " 5 ($FFC5)"); - VarList::push_back(items, " 6 ($FFC6)"); - VarList::push_back(items, " 7 ($FFC7)"); - VarList::push_back(items, " 8 ($FFC8)"); - VarList::push_back(items, " 9 ($FFC9)"); - VarList::push_back(items, "10 ($FFCA)"); - VarList::push_back(items, "11 ($FFCB)"); - VarList::push_back(items, "12 ($FFCC)"); - VarList::push_back(items, "13 ($FFCD)"); - VarList::push_back(items, "14 ($FFCE)"); - VarList::push_back(items, "15 ($FFCF)"); - VarList::push_back(items, "16 ($FFD0)"); - VarList::push_back(items, "17 ($FFD1)"); - VarList::push_back(items, "18 ($FFD2)"); - VarList::push_back(items, "19 ($FFD3)"); - VarList::push_back(items, "20 ($FFD4)"); - VarList::push_back(items, "21 ($FFD5)"); - VarList::push_back(items, "22 ($FFD6)"); - VarList::push_back(items, "23 ($FFD7)"); - VarList::push_back(items, "24 ($FFD8)"); - VarList::push_back(items, "25 ($FFD9)"); - VarList::push_back(items, "26 ($FFDA)"); - VarList::push_back(items, "27 ($FFDB)"); - VarList::push_back(items, "28 ($FFDC)"); - VarList::push_back(items, "29 ($FFDD)"); - VarList::push_back(items, "30 ($FFDE)"); - VarList::push_back(items, "31 ($FFDF)"); - - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("31 ($FFDF)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFWidget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeDFWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeDFWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFC0", "$FFC1", "$FFC2", "$FFC3", "$FFC4", "$FFC5", "$FFC6", "$FFC7", - "$FFC8", "$FFC9", "$FFCA", "$FFCB", "$FFCC", "$FFCD", "$FFCE", "$FFCF", - "$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFD7", - "$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartDFWidget.hxx b/src/debugger/gui/CartDFWidget.hxx index 146763b75..d37176627 100644 --- a/src/debugger/gui/CartDFWidget.hxx +++ b/src/debugger/gui/CartDFWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEDF_WIDGET_HXX class CartridgeDF; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeDFWidget : public CartDebugWidget +class CartridgeDFWidget : public CartEnhancedWidget { public: CartridgeDFWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeDFWidget : public CartDebugWidget virtual ~CartridgeDFWidget() = default; private: - CartridgeDF& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "CPUWIZ"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeDFWidget() = delete; CartridgeDFWidget(const CartridgeDFWidget&) = delete; diff --git a/src/debugger/gui/CartEFSCWidget.cxx b/src/debugger/gui/CartEFSCWidget.cxx index a7bae36c7..8783ca09f 100644 --- a/src/debugger/gui/CartEFSCWidget.cxx +++ b/src/debugger/gui/CartEFSCWidget.cxx @@ -15,167 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartEFSC.hxx" -#include "PopUpWidget.hxx" #include "CartEFSCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEFSCWidget::CartridgeEFSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEFSC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 16 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeEFSCWidget::description() +{ ostringstream info; - info << "64K H. Runner EFSC + RAM, 16 4K banks\n" - << "128 bytes RAM @ $F000 - $F0FF\n" - << " $F080 - $F0FF (R), $F000 - $F07F (W)\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFE0; i < 16; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << (start + 0x100) - << " - " << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "64K H. Runner EFSC + RAM, 16 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Paul Slocum / Homestar Runner", - info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0 ($FFE0)"); - VarList::push_back(items, " 1 ($FFE1)"); - VarList::push_back(items, " 2 ($FFE2)"); - VarList::push_back(items, " 3 ($FFE3)"); - VarList::push_back(items, " 4 ($FFE4)"); - VarList::push_back(items, " 5 ($FFE5)"); - VarList::push_back(items, " 6 ($FFE6)"); - VarList::push_back(items, " 7 ($FFE7)"); - VarList::push_back(items, " 8 ($FFE8)"); - VarList::push_back(items, " 9 ($FFE9)"); - VarList::push_back(items, "10 ($FFEA)"); - VarList::push_back(items, "11 ($FFEB)"); - VarList::push_back(items, "12 ($FFEC)"); - VarList::push_back(items, "13 ($FFED)"); - VarList::push_back(items, "14 ($FFEE)"); - VarList::push_back(items, "15 ($FFEF)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("15 ($FFE0)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFSCWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFSCWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFSCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeEFSCWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7", - "$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeEFSCWidget::internalRamSize() -{ - return 128; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeEFSCWidget::internalRamRPort(int start) -{ - return 0xF080 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeEFSCWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F07F used for Write Access\n" - << "$F080 - $F0FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeEFSCWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeEFSCWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFSCWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeEFSCWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeEFSCWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF080, false); + return info.str(); } diff --git a/src/debugger/gui/CartEFSCWidget.hxx b/src/debugger/gui/CartEFSCWidget.hxx index b9e902f69..c5d6c4eeb 100644 --- a/src/debugger/gui/CartEFSCWidget.hxx +++ b/src/debugger/gui/CartEFSCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEEFSC_WIDGET_HXX class CartridgeEFSC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeEFSCWidget : public CartDebugWidget +class CartridgeEFSCWidget : public CartEnhancedWidget { public: CartridgeEFSCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,35 +32,11 @@ class CartridgeEFSCWidget : public CartDebugWidget virtual ~CartridgeEFSCWidget() = default; private: - CartridgeEFSC& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Paul Slocum / Homestar Runner"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeEFSCWidget() = delete; CartridgeEFSCWidget(const CartridgeEFSCWidget&) = delete; diff --git a/src/debugger/gui/CartEFWidget.cxx b/src/debugger/gui/CartEFWidget.cxx index 165c205bf..4fbc9a030 100644 --- a/src/debugger/gui/CartEFWidget.cxx +++ b/src/debugger/gui/CartEFWidget.cxx @@ -16,97 +16,24 @@ //============================================================================ #include "CartEF.hxx" -#include "PopUpWidget.hxx" #include "CartEFWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeEFWidget::CartridgeEFWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEF& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 16 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeEFWidget::description() +{ ostringstream info; - info << "64K H. Runner EF cartridge, 16 4K banks\n" - << "Startup bank = " << cart.startBank() << "\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFE0; i < 16; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "64K H. Runner EF cartridge, 16 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Paul Slocum / Homestar Runner", - info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0 ($FFE0)"); - VarList::push_back(items, " 1 ($FFE1)"); - VarList::push_back(items, " 2 ($FFE2)"); - VarList::push_back(items, " 3 ($FFE3)"); - VarList::push_back(items, " 4 ($FFE4)"); - VarList::push_back(items, " 5 ($FFE5)"); - VarList::push_back(items, " 6 ($FFE6)"); - VarList::push_back(items, " 7 ($FFE7)"); - VarList::push_back(items, " 8 ($FFE8)"); - VarList::push_back(items, " 9 ($FFE9)"); - VarList::push_back(items, "10 ($FFEA)"); - VarList::push_back(items, "11 ($FFEB)"); - VarList::push_back(items, "12 ($FFEC)"); - VarList::push_back(items, "13 ($FFED)"); - VarList::push_back(items, "14 ($FFEE)"); - VarList::push_back(items, "15 ($FFEF)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("15 ($FFE0)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFWidget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeEFWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeEFWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7", - "$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartEFWidget.hxx b/src/debugger/gui/CartEFWidget.hxx index 3f34fa6cb..7299b22d3 100644 --- a/src/debugger/gui/CartEFWidget.hxx +++ b/src/debugger/gui/CartEFWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEEF_WIDGET_HXX class CartridgeEF; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeEFWidget : public CartDebugWidget +class CartridgeEFWidget : public CartEnhancedWidget { public: CartridgeEFWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeEFWidget : public CartDebugWidget virtual ~CartridgeEFWidget() = default; private: - CartridgeEF& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Paul Slocum / Homestar Runner"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeEFWidget() = delete; CartridgeEFWidget(const CartridgeEFWidget&) = delete; From 1abfcd648c52c3b2c5a3bccc7931788174852b87 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 21 Apr 2020 09:42:51 +0200 Subject: [PATCH 38/52] refactored CartWDWidget and CartX07Widget improved cart info formatting --- src/debugger/gui/CartE0Widget.cxx | 9 +- src/debugger/gui/CartE0Widget.hxx | 2 +- src/debugger/gui/CartEnhancedWidget.cxx | 49 +++++--- src/debugger/gui/CartEnhancedWidget.hxx | 2 +- src/debugger/gui/CartUAWidget.cxx | 4 +- src/debugger/gui/CartUAWidget.hxx | 2 +- src/debugger/gui/CartWDWidget.cxx | 156 ++++-------------------- src/debugger/gui/CartWDWidget.hxx | 35 ++---- src/debugger/gui/CartX07Widget.cxx | 86 ++----------- src/debugger/gui/CartX07Widget.hxx | 15 +-- src/emucore/CartWD.hxx | 2 + 11 files changed, 86 insertions(+), 276 deletions(-) diff --git a/src/debugger/gui/CartE0Widget.cxx b/src/debugger/gui/CartE0Widget.cxx index 4588abcdc..b2b6368dc 100644 --- a/src/debugger/gui/CartE0Widget.cxx +++ b/src/debugger/gui/CartE0Widget.cxx @@ -51,7 +51,7 @@ string CartridgeE0Widget::romDescription() << Common::Base::HEX4 << (ADDR_BASE | segmentOffset) << " - $" << (ADDR_BASE | segmentOffset + /*myCart.myBankSize - 1*/ 0x3FF) << ",\n"; if (seg < 3) - info << " Hotspots " << hotspotStr(0, seg) << " - " << hotspotStr(7, seg) << "\n"; + info << " Hotspots " << hotspotStr(0, seg, true) << " - " << hotspotStr(7, seg, true) << "\n"; else info << " Always points to last 1K bank of ROM\n"; } @@ -61,15 +61,14 @@ string CartridgeE0Widget::romDescription() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeE0Widget::hotspotStr(int bank, int segment) +string CartridgeE0Widget::hotspotStr(int bank, int segment, bool noBrackets) { ostringstream info; uInt16 hotspot = myCart.hotspot(); - if(hotspot & 0x1000) - hotspot |= ADDR_BASE; - + info << (noBrackets ? "" : "("); info << "$" << Common::Base::HEX1 << (hotspot + bank + segment * 8); + info << (noBrackets ? "" : ")"); return info.str(); } diff --git a/src/debugger/gui/CartE0Widget.hxx b/src/debugger/gui/CartE0Widget.hxx index 0bc5694ea..8d0dbb386 100644 --- a/src/debugger/gui/CartE0Widget.hxx +++ b/src/debugger/gui/CartE0Widget.hxx @@ -38,7 +38,7 @@ class CartridgeE0Widget : public CartEnhancedWidget string romDescription() override; - string hotspotStr(int bank, int segment) override; + string hotspotStr(int bank, int segment, bool noBrackets = false) override; int bankSegs() override { return 3; } diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index d38c5534c..f9e1e7772 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -96,18 +96,23 @@ string CartEnhancedWidget::romDescription() { uInt16 start = (image[offset + 1] << 8) | image[offset]; start -= start % 0x1000; + string hash = myCart.romBankCount() > 10 && bank < 10 ? " #" : "#"; - info << "Bank #" << std::dec << bank << " @ $" - << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - $" << (start + 0xFFF) - << " (hotspot " << hotspotStr(bank) << ")\n"; + info << "Bank " << hash << std::dec << bank << " @ $" + << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - $" << (start + 0xFFF); + if(myCart.hotspot() != 0) + info << " " << hotspotStr(bank, 0, true); + info << "\n"; } info << "Startup bank = #" << std::dec << myCart.startBank() << " or undetermined\n"; } else { uInt16 start = (image[myCart.mySize - 3] << 8) | image[myCart.mySize - 4]; + uInt16 end; start -= start % std::min(int(size), 0x1000); + end = start + uInt16(myCart.mySize) - 1; // special check for ROMs where the extra RAM is not included in the image (e.g. CV). if((start & 0xFFF) < size) { @@ -115,7 +120,7 @@ string CartEnhancedWidget::romDescription() } info << "ROM accessible @ $" << Common::Base::HEX4 << start << " - $" - << Common::Base::HEX4 << (start + myCart.mySize - 1); + << Common::Base::HEX4 << end; } return info.str(); @@ -133,7 +138,6 @@ void CartEnhancedWidget::bankSelect(int& ypos) for(int seg = 0; seg < bankSegs(); ++seg) { // fill bank and hotspot list - uInt16 hotspot = myCart.hotspot(); VariantList items; int pw = 0; @@ -142,8 +146,9 @@ void CartEnhancedWidget::bankSelect(int& ypos) ostringstream buf; buf << std::setw(bank < 10 ? 2 : 1) << "#" << std::dec << bank; - if(hotspot >= 0x100 && myHotspotDelta > 0) - buf << " (" << hotspotStr(bank, seg) << ")"; + //if(myCart.hotspot() >= 0x100 && myHotspotDelta > 0) + if(myCart.hotspot() != 0 && myHotspotDelta > 0) + buf << " " << hotspotStr(bank, seg); VarList::push_back(items, buf.str()); pw = std::max(pw, _font.getStringWidth(buf.str())); } @@ -198,16 +203,17 @@ string CartEnhancedWidget::bankState() else if (hasRamBanks) buf << " ROM"; - if(hotspot >= 0x100) - buf << " (" << (bankSegs() < 3 ? "hotspot " : "") << hotspotStr(bank) << ")"; + //if(hotspot >= 0x100) + if(hotspot != 0 && myHotspotDelta > 0) + buf << " " << hotspotStr(bank, 0, bankSegs() < 3); } } else { buf << "Bank #" << std::dec << myCart.getBank(); - //if(hotspot >= 0x100) - buf << " (hotspot " << hotspotStr(myCart.getSegmentBank()) << ")"; + if(hotspot != 0 && myHotspotDelta > 0) + buf << " " << hotspotStr(myCart.getBank(), 0, true); } return buf.str(); } @@ -215,7 +221,7 @@ string CartEnhancedWidget::bankState() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::hotspotStr(int bank, int segment) +string CartEnhancedWidget::hotspotStr(int bank, int segment, bool prefix) { ostringstream info; uInt16 hotspot = myCart.hotspot(); @@ -223,7 +229,9 @@ string CartEnhancedWidget::hotspotStr(int bank, int segment) if(hotspot & 0x1000) hotspot |= ADDR_BASE; + info << "(" << (prefix ? "hotspot " : ""); info << "$" << Common::Base::HEX1 << (hotspot + bank * myHotspotDelta); + info << ")"; return info.str(); } @@ -242,8 +250,11 @@ void CartEnhancedWidget::saveOldState() myOldState.internalRam.push_back(myCart.myRAM[i]); myOldState.banks.clear(); - for(int seg = 0; seg < bankSegs(); ++seg) - myOldState.banks.push_back(myCart.getSegmentBank(seg)); + if (bankSegs() > 1) + for(int seg = 0; seg < bankSegs(); ++seg) + myOldState.banks.push_back(myCart.getSegmentBank(seg)); + else + myOldState.banks.push_back(myCart.getBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -251,9 +262,13 @@ void CartEnhancedWidget::loadConfig() { if(myBankWidgets != nullptr) { - for(int seg = 0; seg < bankSegs(); ++seg) - myBankWidgets[seg]->setSelectedIndex(myCart.getSegmentBank(seg), - myCart.getSegmentBank(seg) != myOldState.banks[seg]); + if (bankSegs() > 1) + for(int seg = 0; seg < bankSegs(); ++seg) + myBankWidgets[seg]->setSelectedIndex(myCart.getSegmentBank(seg), + myCart.getSegmentBank(seg) != myOldState.banks[seg]); + else + myBankWidgets[0]->setSelectedIndex(myCart.getBank(), + myCart.getBank() != myOldState.banks[0]); } CartDebugWidget::loadConfig(); } diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index dccc9fde0..a3b0e54cf 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -53,7 +53,7 @@ class CartEnhancedWidget : public CartDebugWidget virtual void bankSelect(int& ypos); - virtual string hotspotStr(int bank = 0, int segment = 0); + virtual string hotspotStr(int bank = 0, int segment = 0, bool prefix = false); virtual int bankSegs(); // { return myCart.myBankSegs; } diff --git a/src/debugger/gui/CartUAWidget.cxx b/src/debugger/gui/CartUAWidget.cxx index f3865b998..ffaef806b 100644 --- a/src/debugger/gui/CartUAWidget.cxx +++ b/src/debugger/gui/CartUAWidget.cxx @@ -41,12 +41,14 @@ string CartridgeUAWidget::description() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeUAWidget::hotspotStr(int bank, int) +string CartridgeUAWidget::hotspotStr(int bank, int, bool prefix) { ostringstream info; uInt16 hotspot = myCart.hotspot() + (bank ^ (mySwappedHotspots ? 1 : 0)) * myHotspotDelta; + info << "(" << (prefix ? "hotspot " : ""); info << "$" << Common::Base::HEX1 << hotspot << ", $" << (hotspot | 0x80); + info << ")"; return info.str(); } diff --git a/src/debugger/gui/CartUAWidget.hxx b/src/debugger/gui/CartUAWidget.hxx index bb61d25c9..8a49136a2 100644 --- a/src/debugger/gui/CartUAWidget.hxx +++ b/src/debugger/gui/CartUAWidget.hxx @@ -36,7 +36,7 @@ class CartridgeUAWidget : public CartEnhancedWidget string description() override; - string hotspotStr(int bank, int) override; + string hotspotStr(int bank, int seg, bool prefix = false) override; private: const bool mySwappedHotspots; diff --git a/src/debugger/gui/CartWDWidget.cxx b/src/debugger/gui/CartWDWidget.cxx index c89c3c8c8..16fe416ec 100644 --- a/src/debugger/gui/CartWDWidget.cxx +++ b/src/debugger/gui/CartWDWidget.cxx @@ -15,157 +15,45 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartWD.hxx" -#include "PopUpWidget.hxx" #include "CartWDWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeWDWidget::CartridgeWDWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeWD& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - string info = - "This scheme has eight 1K slices, which can be mapped into four 1K " - "segments in various combinations. Each 'bank' selects a predefined " - "segment arrangement (indicated in square brackets)\n" - "In the third (uppermost) segment the byte at $3FC is overwritten with 0.\n\n" - "64 bytes RAM @ $F000 - $F080\n" - " $F000 - $F03F (R), $F040 - $F07F (W)\n"; - - int xpos = 2, - ypos = addBaseInformation(myCart.mySize, "Wickstead Design", info, 12) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($30) [0,0,1,3]", 0); - VarList::push_back(items, "1 ($31) [0,1,2,3]", 1); - VarList::push_back(items, "2 ($32) [4,5,6,7]", 2); - VarList::push_back(items, "3 ($33) [7,4,2,3]", 3); - VarList::push_back(items, "4 ($34) [0,0,6,7]", 4); - VarList::push_back(items, "5 ($35) [0,1,7,6]", 5); - VarList::push_back(items, "6 ($36) [2,3,4,5]", 6); - VarList::push_back(items, "7 ($37) [6,0,5,1]", 7); - VarList::push_back(items, "8 ($38) [0,0,1,3]", 8); - VarList::push_back(items, "9 ($39) [0,1,2,3]", 9); - VarList::push_back(items, "10 ($3A) [4,5,6,7]", 10); - VarList::push_back(items, "11 ($3B) [7,4,2,3]", 11); - VarList::push_back(items, "12 ($3C) [0,0,6,7]", 12); - VarList::push_back(items, "13 ($3D) [0,1,7,6]", 13); - VarList::push_back(items, "14 ($3E) [2,3,4,5]", 14); - VarList::push_back(items, "15 ($3F) [6,0,5,1]", 15); - myBank = new PopUpWidget(boss, _font, xpos, ypos-2, - _font.getStringWidth("15 ($3F) [6,0,5,1]"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); + initialize(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWDWidget::saveOldState() +string CartridgeWDWidget::description() { - myOldState.internalram.clear(); + ostringstream info; - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); + info << "8K + RAM Wickstead Design cartridge, \n" + << " eight 1K banks, mapped into four segments\n" + << "Hotspots $" << Common::Base::HEX1 << myCart.hotspot() << " - $" << (myCart.hotspot() + 7) << ", " + << "each hotspot selects a [predefined bank mapping]\n"; + info << ramDescription(); - myOldState.bank = myCart.getBank(); + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWDWidget::loadConfig() +string CartridgeWDWidget::hotspotStr(int bank, int segment, bool prefix) { - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); + ostringstream info; + CartridgeWD& cart = dynamic_cast(myCart); + CartridgeWD::BankOrg banks = cart.ourBankOrg[bank]; - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWDWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeWDWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array segments = { - "[0,0,1,3]", "[0,1,2,3]", "[4,5,6,7]", "[7,4,2,3]", - "[0,0,6,7]", "[0,1,7,6]", "[2,3,4,5]", "[6,0,5,1]" - }; - uInt16 bank = myCart.getBank(); - buf << "Bank = " << std::dec << bank << ", segments = " << segments[bank & 0x7]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeWDWidget::internalRamSize() -{ - return 64; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeWDWidget::internalRamRPort(int start) -{ - return 0xF000 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeWDWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F03F used for Read Access\n" - << "$F040 - $F07F used for Write Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeWDWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; ++i) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeWDWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; ++i) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeWDWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeWDWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeWDWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF000, false); + info << "(" << (prefix ? "hotspot " : "") + << "$" << Common::Base::HEX1 << (myCart.hotspot() + bank) << ") [" + << uInt16(banks.zero) << ", " + << uInt16(banks.one) << ", " + << uInt16(banks.two) << ", " + << uInt16(banks.three) << "]"; + + return info.str(); } diff --git a/src/debugger/gui/CartWDWidget.hxx b/src/debugger/gui/CartWDWidget.hxx index f52f4a2a9..9bab7af30 100644 --- a/src/debugger/gui/CartWDWidget.hxx +++ b/src/debugger/gui/CartWDWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEWD_WIDGET_HXX class CartridgeWD; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeWDWidget : public CartDebugWidget +class CartridgeWDWidget : public CartEnhancedWidget { public: CartridgeWDWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,35 +32,15 @@ class CartridgeWDWidget : public CartDebugWidget virtual ~CartridgeWDWidget() = default; private: - CartridgeWD& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Wickstead Design"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; // Current banking layout - }; - CartState myOldState; + string description() override; - enum { kBankChanged = 'bkCH' }; + string hotspotStr(int bank, int seg = 0, bool prefix = false) override; + + int bankSegs() override { return 1; } private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeWDWidget() = delete; CartridgeWDWidget(const CartridgeWDWidget&) = delete; diff --git a/src/debugger/gui/CartX07Widget.cxx b/src/debugger/gui/CartX07Widget.cxx index 0c6bc5b95..4fb31a9ca 100644 --- a/src/debugger/gui/CartX07Widget.cxx +++ b/src/debugger/gui/CartX07Widget.cxx @@ -16,94 +16,26 @@ //============================================================================ #include "CartX07.hxx" -#include "PopUpWidget.hxx" #include "CartX07Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeX07Widget::CartridgeX07Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeX07& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt32 size = 16 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeX07Widget::description() +{ ostringstream info; + info << "64K X07 cartridge, 16 4K banks\n" - << "Startup bank = " << cart.startBank() << "\n" << "Multiple hotspots, all below $1000\n" << "See documentation for further details\n"; + info << CartEnhancedWidget::description(); - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC; i < 16; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start - << " - " << "$" << (start + 0xFFF) << "\n"; - } - - int xpos = 2, - ypos = addBaseInformation(size, "AtariAge / John Payson / Fred Quimby", - info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, " 0"); - VarList::push_back(items, " 1"); - VarList::push_back(items, " 2"); - VarList::push_back(items, " 3"); - VarList::push_back(items, " 4"); - VarList::push_back(items, " 5"); - VarList::push_back(items, " 6"); - VarList::push_back(items, " 7"); - VarList::push_back(items, " 8"); - VarList::push_back(items, " 9"); - VarList::push_back(items, " 10"); - VarList::push_back(items, " 11"); - VarList::push_back(items, " 12"); - VarList::push_back(items, " 13"); - VarList::push_back(items, " 14"); - VarList::push_back(items, " 15"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth(" 15"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeX07Widget::loadConfig() -{ - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); - - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeX07Widget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeX07Widget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Bank = " << std::dec << myCart.getBank(); - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartX07Widget.hxx b/src/debugger/gui/CartX07Widget.hxx index 00782dca8..a096c5d0d 100644 --- a/src/debugger/gui/CartX07Widget.hxx +++ b/src/debugger/gui/CartX07Widget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEX07_WIDGET_HXX class CartridgeX07; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeX07Widget : public CartDebugWidget +class CartridgeX07Widget : public CartEnhancedWidget { public: CartridgeX07Widget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeX07Widget : public CartDebugWidget virtual ~CartridgeX07Widget() = default; private: - CartridgeX07& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "AtariAge / John Payson / Fred Quimby"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeX07Widget() = delete; CartridgeX07Widget(const CartridgeX07Widget&) = delete; diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 20596868e..1fd42ac71 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -153,6 +153,8 @@ class CartridgeWD : public CartridgeEnhanced private: bool checkSwitchBank(uInt16, uInt8 = 0) override { return false; } + uInt16 hotspot() const override { return 0x0030; } + private: // Indicates the cycle at which a bankswitch was initiated uInt64 myCyclesAtBankswitchInit{0}; From 1ea0fab16ac0da3e973223fb904357af8a55e89b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 21 Apr 2020 12:15:28 +0200 Subject: [PATCH 39/52] refactored CartFA(2), CartFC and CartFE widget classes --- src/debugger/gui/CartEnhancedWidget.cxx | 13 +- src/debugger/gui/CartEnhancedWidget.hxx | 2 +- src/debugger/gui/CartFA2Widget.cxx | 160 +++--------------------- src/debugger/gui/CartFA2Widget.hxx | 34 ++--- src/debugger/gui/CartFAWidget.cxx | 143 ++------------------- src/debugger/gui/CartFAWidget.hxx | 33 +---- src/debugger/gui/CartFCWidget.cxx | 78 ++++-------- src/debugger/gui/CartFCWidget.hxx | 17 +-- src/debugger/gui/CartFEWidget.cxx | 66 +++------- src/debugger/gui/CartFEWidget.hxx | 18 +-- src/emucore/CartFA2.hxx | 2 +- src/emucore/CartFE.hxx | 2 + 12 files changed, 100 insertions(+), 468 deletions(-) diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index f9e1e7772..a2e22c094 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -31,12 +31,14 @@ CartEnhancedWidget::CartEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartEnhancedWidget::initialize() +int CartEnhancedWidget::initialize() { int ypos = addBaseInformation(size(), manufacturer(), description(), descriptionLines()) + myLineHeight; bankSelect(ypos); + + return ypos; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -64,7 +66,7 @@ string CartEnhancedWidget::description() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int CartEnhancedWidget::descriptionLines() { - return 20; // should be enough for almost all types + return 18; // should be enough for almost all types } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -101,7 +103,12 @@ string CartEnhancedWidget::romDescription() info << "Bank " << hash << std::dec << bank << " @ $" << Common::Base::HEX4 << (start + myCart.myRomOffset) << " - $" << (start + 0xFFF); if(myCart.hotspot() != 0) - info << " " << hotspotStr(bank, 0, true); + { + string hs = hotspotStr(bank, 0, true); + if(hs.length() > 22) + info << "\n "; + info << " " << hs; + } info << "\n"; } info << "Startup bank = #" << std::dec << myCart.startBank() << " or undetermined\n"; diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index a3b0e54cf..2cbd22ced 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -37,7 +37,7 @@ class CartEnhancedWidget : public CartDebugWidget virtual ~CartEnhancedWidget() = default; protected: - void initialize(); + int initialize(); virtual size_t size(); diff --git a/src/debugger/gui/CartFA2Widget.cxx b/src/debugger/gui/CartFA2Widget.cxx index 9a24eb5a7..40fab9d4d 100644 --- a/src/debugger/gui/CartFA2Widget.cxx +++ b/src/debugger/gui/CartFA2Widget.cxx @@ -15,65 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartFA2.hxx" -#include "PopUpWidget.hxx" #include "CartFA2Widget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFA2Widget::CartridgeFA2Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA2& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - size_t size = cart.mySize; - - ostringstream info; - info << "Modified FA RAM+, six or seven 4K banks\n" - << "256 bytes RAM @ $F000 - $F1FF\n" - << " $F100 - $F1FF (R), $F000 - $F0FF (W)\n" - << "RAM can be loaded/saved to Harmony flash by accessing $FFF4\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF5; i < cart.romBankCount(); - ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x200) << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } - int xpos = 2, - ypos = addBaseInformation(size, "Chris D. Walton (Star Castle 2600)", - info.str(), 15) + myLineHeight; + ypos = initialize(); - VariantList items; - VarList::push_back(items, "0 ($FFF5)"); - VarList::push_back(items, "1 ($FFF6)"); - VarList::push_back(items, "2 ($FFF7)"); - VarList::push_back(items, "3 ($FFF8)"); - VarList::push_back(items, "4 ($FFF9)"); - VarList::push_back(items, "5 ($FFFA)"); - if(cart.romBankCount() == 7) - VarList::push_back(items, "6 ($FFFB)"); - - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); - ypos += myLineHeight + 20; + ypos += 12; const int bwidth = _font.getStringWidth("Erase") + 20; StaticTextWidget* t = new StaticTextWidget(boss, _font, xpos, ypos, - _font.getStringWidth("Harmony Flash "), - myFontHeight, "Harmony Flash ", TextAlign::Left); + _font.getStringWidth("Harmony flash memory "), + myFontHeight, "Harmony flash memory ", TextAlign::Left); xpos += t->getWidth() + 4; myFlashErase = @@ -98,123 +58,39 @@ CartridgeFA2Widget::CartridgeFA2Widget( } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2Widget::saveOldState() +string CartridgeFA2Widget::description() { - myOldState.internalram.clear(); + ostringstream info; - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); + info << "Modified FA RAM+, six or seven 4K banks\n"; + info << "RAM+ can be loaded/saved to Harmony flash memory by accessing $" + << Common::Base::HEX4 << 0xFFF4 << "\n"; + info << CartEnhancedWidget::description(); - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2Widget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeFA2Widget::handleCommand(CommandSender* sender, int cmd, int data, int id) { + CartridgeFA2& cart = dynamic_cast(myCart); + switch(cmd) { - case kBankChanged: - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - break; - case kFlashErase: - myCart.flash(0); + cart.flash(0); break; case kFlashLoad: - myCart.flash(1); + cart.flash(1); break; case kFlashSave: - myCart.flash(2); + cart.flash(2); break; default: - break; + CartEnhancedWidget::handleCommand(sender, cmd, data, id); } } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFA2Widget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { - "$FFF5", "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB" - }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeFA2Widget::internalRamSize() -{ - return 256; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeFA2Widget::internalRamRPort(int start) -{ - return 0xF100 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFA2Widget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F0FF used for Write Access\n" - << "$F100 - $F1FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeFA2Widget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeFA2Widget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFA2Widget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeFA2Widget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFA2Widget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF100, false); -} diff --git a/src/debugger/gui/CartFA2Widget.hxx b/src/debugger/gui/CartFA2Widget.hxx index 0b5fe3fb4..30b1ec81f 100644 --- a/src/debugger/gui/CartFA2Widget.hxx +++ b/src/debugger/gui/CartFA2Widget.hxx @@ -20,11 +20,10 @@ class CartridgeFA2; class ButtonWidget; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeFA2Widget : public CartDebugWidget +class CartridgeFA2Widget : public CartEnhancedWidget { public: CartridgeFA2Widget(GuiObject* boss, const GUI::Font& lfont, @@ -34,41 +33,22 @@ class CartridgeFA2Widget : public CartDebugWidget virtual ~CartridgeFA2Widget() = default; private: - CartridgeFA2& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Chris D. Walton (Star Castle 2600 Arcade)"; } + + string description() override; + ButtonWidget *myFlashErase{nullptr}, *myFlashLoad{nullptr}, *myFlashSave{nullptr}; - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - enum { - kBankChanged = 'bkCH', kFlashErase = 'flER', kFlashLoad = 'flLD', kFlashSave = 'flSV' }; private: - void saveOldState() override; - void loadConfig() override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - + private: // Following constructors and assignment operators not supported CartridgeFA2Widget() = delete; CartridgeFA2Widget(const CartridgeFA2Widget&) = delete; diff --git a/src/debugger/gui/CartFAWidget.cxx b/src/debugger/gui/CartFAWidget.cxx index e32a3eec0..b3fefff6d 100644 --- a/src/debugger/gui/CartFAWidget.cxx +++ b/src/debugger/gui/CartFAWidget.cxx @@ -15,150 +15,25 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "Debugger.hxx" -#include "CartDebug.hxx" #include "CartFA.hxx" -#include "PopUpWidget.hxx" #include "CartFAWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFAWidget::CartridgeFAWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = 3 * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeFAWidget::description() +{ ostringstream info; - info << "CBS RAM+ FA cartridge, three 4K banks\n" - << "256 bytes RAM @ $F000 - $F1FF\n" - << " $F100 - $F1FF (R), $F000 - $F0FF (W)\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0xFF8; i < 3; ++i, offset += 0x1000) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x200) << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; - } + info << "CBS RAM+ FA cartridge, three 4K banks\n"; + info << CartEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "CBS", info.str()) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($FFF8)"); - VarList::push_back(items, "1 ($FFF9)"); - VarList::push_back(items, "2 ($FFFA)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFAWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - - myOldState.bank = myCart.getBank(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFAWidget::loadConfig() -{ - myBank->setSelectedIndex(myCart.getBank(), myCart.getBank() != myOldState.bank); - - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFAWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFAWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array spot = { "$FFF8", "$FFF9", "$FFFA" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; - - return buf.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeFAWidget::internalRamSize() -{ - return 256; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartridgeFAWidget::internalRamRPort(int start) -{ - return 0xF100 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFAWidget::internalRamDescription() -{ - ostringstream desc; - desc << "$F000 - $F0FF used for Write Access\n" - << "$F100 - $F1FF used for Read Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeFAWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartridgeFAWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFAWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartridgeFAWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFAWidget::internalRamLabel(int addr) -{ - CartDebug& dbg = instance().debugger().cartDebug(); - return dbg.getLabel(addr + 0xF100, false); + return info.str(); } diff --git a/src/debugger/gui/CartFAWidget.hxx b/src/debugger/gui/CartFAWidget.hxx index e4e1da416..b7fbb3308 100644 --- a/src/debugger/gui/CartFAWidget.hxx +++ b/src/debugger/gui/CartFAWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEFA_WIDGET_HXX class CartridgeFA; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeFAWidget : public CartDebugWidget +class CartridgeFAWidget : public CartEnhancedWidget { public: CartridgeFAWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,35 +32,11 @@ class CartridgeFAWidget : public CartDebugWidget virtual ~CartridgeFAWidget() = default; private: - CartridgeFA& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "CBS"; } - struct CartState { - ByteArray internalram; - uInt16 bank{0}; - }; - CartState myOldState; - - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - string internalRamLabel(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported CartridgeFAWidget() = delete; CartridgeFAWidget(const CartridgeFAWidget&) = delete; diff --git a/src/debugger/gui/CartFCWidget.cxx b/src/debugger/gui/CartFCWidget.cxx index a034b56e3..8210eed2e 100644 --- a/src/debugger/gui/CartFCWidget.cxx +++ b/src/debugger/gui/CartFCWidget.cxx @@ -16,80 +16,44 @@ //============================================================================ #include "CartFC.hxx" -#include "PopUpWidget.hxx" #include "CartFCWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFCWidget::CartridgeFCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFC& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - uInt16 size = cart.romBankCount() * 4096; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeFCWidget::description() +{ ostringstream info; - info << "FC cartridge, up to eight 4K banks\n" - << "Startup bank = " << cart.startBank() << " or undetermined\n"; + uInt16 hotspot = myCart.hotspot() | ADDR_BASE; - // Eventually, we should query this from the debugger/disassembler + info << "FC cartridge, up to eight 4K banks\n"; info << "Bank selected by hotspots\n" - << " $FFF8 (defines low 2 bits)\n" - << " $FFF9 (defines high bits)\n" - << " $FFFC (triggers bank switch)"; + << " $" << Common::Base::HEX4 << hotspot << " (defines low 2 bits)\n" + << " $" << Common::Base::HEX4 << (hotspot + 1) << " (defines high bits)\n" + << " $" << Common::Base::HEX4 << (hotspot + 4) << " (triggers bank switch)\n"; - int xpos = 2, - ypos = addBaseInformation(size, "Amiga Corp.", info.str()) + myLineHeight; + info << CartEnhancedWidget::description(); - VariantList items; - for (uInt16 i = 0; i < cart.romBankCount(); ++i) - VarList::push_back(items, Variant(i).toString() + - " ($FFF8 = " + Variant(i & 0b11).toString() + - "/$FFF9 = " + Variant(i >> 2).toString() +")"); - - myBank = new PopUpWidget(boss, _font, xpos, ypos - 2, - _font.getStringWidth("7 ($FFF8 = 3/$FFF9 = 1)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFCWidget::loadConfig() +string CartridgeFCWidget::hotspotStr(int bank, int, bool prefix) { - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); + ostringstream info; + uInt16 hotspot = myCart.hotspot() | ADDR_BASE; - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); + info << "(" << (prefix ? "hotspots " : ""); + info << "$" << Common::Base::HEX4 << hotspot << " = " << (bank & 0b11); + info << ", $" << Common::Base::HEX4 << (hotspot + 1) << " = " << (bank >> 2); + info << ")"; - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFCWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if (cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFCWidget::bankState() -{ - ostringstream& buf = buffer(); - uInt16 bank = myCart.getBank(); - - buf << "Bank = #" << std::dec << bank - << ", hotspots $FFF8 = " << (bank & 0b11) - << "/$FF99 = " << (bank >> 2); - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartFCWidget.hxx b/src/debugger/gui/CartFCWidget.hxx index 0e74246ed..f1bb4a50f 100644 --- a/src/debugger/gui/CartFCWidget.hxx +++ b/src/debugger/gui/CartFCWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEFC_WIDGET_HXX class CartridgeFC; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeFCWidget : public CartDebugWidget +class CartridgeFCWidget : public CartEnhancedWidget { public: CartridgeFCWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,13 @@ class CartridgeFCWidget : public CartDebugWidget virtual ~CartridgeFCWidget() = default; private: - CartridgeFC& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Amiga Corp."; } - enum { kBankChanged = 'bkCH' }; + string description() override; + + string hotspotStr(int bank, int seg = 0, bool prefix = false) override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeFCWidget() = delete; CartridgeFCWidget(const CartridgeFCWidget&) = delete; diff --git a/src/debugger/gui/CartFEWidget.cxx b/src/debugger/gui/CartFEWidget.cxx index afccb359f..dbe992a4f 100644 --- a/src/debugger/gui/CartFEWidget.cxx +++ b/src/debugger/gui/CartFEWidget.cxx @@ -16,72 +16,36 @@ //============================================================================ #include "CartFE.hxx" -#include "PopUpWidget.hxx" #include "CartFEWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeFEWidget::CartridgeFEWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFE& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - string info = - "FE cartridge, two 4K banks\n" - "Monitors access to hotspot $01FE, and uses " - "upper 3 bits of databus for bank number:\n" - "Bank 0 @ $F000 - $FFFF (DATA = 111, D5 = 1)\n" - "Bank 1 @ $D000 - $DFFF (DATA = 110, D5 = 0)\n"; - - int xpos = 2, - ypos = addBaseInformation(2 * 4096, "Activision", info) + myLineHeight; - - VariantList items; - VarList::push_back(items, "0 ($01FE, D5=1)"); - VarList::push_back(items, "1 ($01FE, D5=0)"); - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, - _font.getStringWidth("0 ($01FE, D5=1)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); + initialize(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFEWidget::loadConfig() +string CartridgeFEWidget::description() { - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); + ostringstream info; - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); + info << "FE cartridge, two 4K banks\n" + << "Monitors access to hotspot $01FE, and uses " + << "upper 3 bits of databus for bank number:\n"; + info << CartEnhancedWidget::description(); - CartDebugWidget::loadConfig(); + return info.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeFEWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) +string CartridgeFEWidget::hotspotStr(int bank, int, bool) { - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeFEWidget::bankState() -{ - ostringstream& buf = buffer(); - - static constexpr std::array range = { "$F000", "$D000" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", address range = " << range[myCart.getBank()]; - - return buf.str(); + ostringstream info; + + info << "(DATA = 11" << !bank << ", D5 = " << !bank << ")"; + + return info.str(); } diff --git a/src/debugger/gui/CartFEWidget.hxx b/src/debugger/gui/CartFEWidget.hxx index a9f37190c..05a320a71 100644 --- a/src/debugger/gui/CartFEWidget.hxx +++ b/src/debugger/gui/CartFEWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGEFE_WIDGET_HXX class CartridgeFE; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeFEWidget : public CartDebugWidget +class CartridgeFEWidget : public CartEnhancedWidget { public: CartridgeFEWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,18 +32,13 @@ class CartridgeFEWidget : public CartDebugWidget virtual ~CartridgeFEWidget() = default; private: - CartridgeFE& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Activision"; } - enum { kBankChanged = 'bkCH' }; + string description() override; + + string hotspotStr(int bank, int, bool) override; private: - // No implementation for non-bankswitched ROMs - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeFEWidget() = delete; CartridgeFEWidget(const CartridgeFEWidget&) = delete; diff --git a/src/emucore/CartFA2.hxx b/src/emucore/CartFA2.hxx index 8175f4cdc..16d33bf2b 100644 --- a/src/emucore/CartFA2.hxx +++ b/src/emucore/CartFA2.hxx @@ -110,7 +110,7 @@ class CartridgeFA2 : public CartridgeFA private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 hotspot() const override { return 0x1FF4; } + uInt16 hotspot() const override { return 0x1FF5; } uInt16 getStartBank() const override { return 0; } diff --git a/src/emucore/CartFE.hxx b/src/emucore/CartFE.hxx index 3132704cd..6c453d284 100644 --- a/src/emucore/CartFE.hxx +++ b/src/emucore/CartFE.hxx @@ -165,6 +165,8 @@ class CartridgeFE : public CartridgeEnhanced */ bool checkSwitchBank(uInt16 address, uInt8 value) override; + uInt16 hotspot() const override { return 0x01FE; } + private: // Whether previous address by peek/poke equals $01FE (hotspot) bool myLastAccessWasFE{false}; From eaf1d5bba668c19bbadf489986788aa2b22fdbb5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 21 Apr 2020 12:40:19 +0200 Subject: [PATCH 40/52] renamed CartridgeEnhancedWidget class --- src/debugger/gui/Cart0840Widget.cxx | 4 +-- src/debugger/gui/Cart0840Widget.hxx | 2 +- src/debugger/gui/Cart2KWidget.cxx | 4 +-- src/debugger/gui/Cart2KWidget.hxx | 2 +- src/debugger/gui/Cart3FWidget.cxx | 2 +- src/debugger/gui/Cart3FWidget.hxx | 2 +- src/debugger/gui/Cart4KSCWidget.cxx | 4 +-- src/debugger/gui/Cart4KSCWidget.hxx | 2 +- src/debugger/gui/Cart4KWidget.cxx | 4 +-- src/debugger/gui/Cart4KWidget.hxx | 2 +- src/debugger/gui/CartBFSCWidget.cxx | 4 +-- src/debugger/gui/CartBFSCWidget.hxx | 2 +- src/debugger/gui/CartBFWidget.cxx | 4 +-- src/debugger/gui/CartBFWidget.hxx | 2 +- src/debugger/gui/CartCVWidget.cxx | 4 +-- src/debugger/gui/CartCVWidget.hxx | 2 +- src/debugger/gui/CartDFSCWidget.cxx | 4 +-- src/debugger/gui/CartDFSCWidget.hxx | 2 +- src/debugger/gui/CartDFWidget.cxx | 4 +-- src/debugger/gui/CartDFWidget.hxx | 2 +- src/debugger/gui/CartE0Widget.cxx | 4 +-- src/debugger/gui/CartE0Widget.hxx | 2 +- src/debugger/gui/CartEFSCWidget.cxx | 4 +-- src/debugger/gui/CartEFSCWidget.hxx | 2 +- src/debugger/gui/CartEFWidget.cxx | 4 +-- src/debugger/gui/CartEFWidget.hxx | 2 +- src/debugger/gui/CartEnhancedWidget.cxx | 44 ++++++++++++------------- src/debugger/gui/CartEnhancedWidget.hxx | 22 ++++++------- src/debugger/gui/CartF0Widget.cxx | 2 +- src/debugger/gui/CartF0Widget.hxx | 2 +- src/debugger/gui/CartF4SCWidget.cxx | 4 +-- src/debugger/gui/CartF4SCWidget.hxx | 2 +- src/debugger/gui/CartF4Widget.cxx | 4 +-- src/debugger/gui/CartF4Widget.hxx | 2 +- src/debugger/gui/CartF6SCWidget.cxx | 4 +-- src/debugger/gui/CartF6SCWidget.hxx | 2 +- src/debugger/gui/CartF6Widget.cxx | 4 +-- src/debugger/gui/CartF6Widget.hxx | 2 +- src/debugger/gui/CartF8SCWidget.cxx | 4 +-- src/debugger/gui/CartF8SCWidget.hxx | 2 +- src/debugger/gui/CartF8Widget.cxx | 4 +-- src/debugger/gui/CartF8Widget.hxx | 2 +- src/debugger/gui/CartFA2Widget.cxx | 6 ++-- src/debugger/gui/CartFA2Widget.hxx | 2 +- src/debugger/gui/CartFAWidget.cxx | 4 +-- src/debugger/gui/CartFAWidget.hxx | 2 +- src/debugger/gui/CartFCWidget.cxx | 4 +-- src/debugger/gui/CartFCWidget.hxx | 2 +- src/debugger/gui/CartFEWidget.cxx | 4 +-- src/debugger/gui/CartFEWidget.hxx | 2 +- src/debugger/gui/CartUAWidget.cxx | 4 +-- src/debugger/gui/CartUAWidget.hxx | 2 +- src/debugger/gui/CartWDWidget.cxx | 2 +- src/debugger/gui/CartWDWidget.hxx | 2 +- src/debugger/gui/CartX07Widget.cxx | 4 +-- src/debugger/gui/CartX07Widget.hxx | 2 +- src/emucore/CartEnhanced.hxx | 2 +- 57 files changed, 113 insertions(+), 113 deletions(-) diff --git a/src/debugger/gui/Cart0840Widget.cxx b/src/debugger/gui/Cart0840Widget.cxx index c49c86d09..eb9275035 100644 --- a/src/debugger/gui/Cart0840Widget.cxx +++ b/src/debugger/gui/Cart0840Widget.cxx @@ -22,7 +22,7 @@ Cartridge0840Widget::Cartridge0840Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge0840& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { myHotspotDelta = 0x40; initialize(); @@ -34,7 +34,7 @@ string Cartridge0840Widget::description() ostringstream info; info << "0840 ECONObanking, two 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/Cart0840Widget.hxx b/src/debugger/gui/Cart0840Widget.hxx index 89e8706c6..00605b262 100644 --- a/src/debugger/gui/Cart0840Widget.hxx +++ b/src/debugger/gui/Cart0840Widget.hxx @@ -22,7 +22,7 @@ class Cartridge0840; #include "CartEnhancedWidget.hxx" -class Cartridge0840Widget : public CartEnhancedWidget +class Cartridge0840Widget : public CartridgeEnhancedWidget { public: Cartridge0840Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/Cart2KWidget.cxx b/src/debugger/gui/Cart2KWidget.cxx index c97bc440f..d87445ed3 100644 --- a/src/debugger/gui/Cart2KWidget.cxx +++ b/src/debugger/gui/Cart2KWidget.cxx @@ -22,7 +22,7 @@ Cartridge2KWidget::Cartridge2KWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge2K& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string Cartridge2KWidget::description() ostringstream info; info << "Standard 2K cartridge, non-bankswitched\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/Cart2KWidget.hxx b/src/debugger/gui/Cart2KWidget.hxx index e6e0fe9d2..123e3ddf5 100644 --- a/src/debugger/gui/Cart2KWidget.hxx +++ b/src/debugger/gui/Cart2KWidget.hxx @@ -22,7 +22,7 @@ class Cartridge2K; #include "CartEnhancedWidget.hxx" -class Cartridge2KWidget : public CartEnhancedWidget +class Cartridge2KWidget : public CartridgeEnhancedWidget { public: Cartridge2KWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/Cart3FWidget.cxx b/src/debugger/gui/Cart3FWidget.cxx index 76f331502..ff5b0d219 100644 --- a/src/debugger/gui/Cart3FWidget.cxx +++ b/src/debugger/gui/Cart3FWidget.cxx @@ -22,7 +22,7 @@ Cartridge3FWidget::Cartridge3FWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3F& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { myHotspotDelta = 0; initialize(); diff --git a/src/debugger/gui/Cart3FWidget.hxx b/src/debugger/gui/Cart3FWidget.hxx index 7e3ee65e9..e5f97a392 100644 --- a/src/debugger/gui/Cart3FWidget.hxx +++ b/src/debugger/gui/Cart3FWidget.hxx @@ -22,7 +22,7 @@ class Cartridge3F; #include "CartEnhancedWidget.hxx" -class Cartridge3FWidget : public CartEnhancedWidget +class Cartridge3FWidget : public CartridgeEnhancedWidget { public: Cartridge3FWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/Cart4KSCWidget.cxx b/src/debugger/gui/Cart4KSCWidget.cxx index 105136dd5..b6bc05d51 100644 --- a/src/debugger/gui/Cart4KSCWidget.cxx +++ b/src/debugger/gui/Cart4KSCWidget.cxx @@ -22,7 +22,7 @@ Cartridge4KSCWidget::Cartridge4KSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4KSC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string Cartridge4KSCWidget::description() ostringstream info; info << "4KSC cartridge, non-bankswitched\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/Cart4KSCWidget.hxx b/src/debugger/gui/Cart4KSCWidget.hxx index 832c2c127..624a5623a 100644 --- a/src/debugger/gui/Cart4KSCWidget.hxx +++ b/src/debugger/gui/Cart4KSCWidget.hxx @@ -22,7 +22,7 @@ class Cartridge4KSC; #include "CartEnhancedWidget.hxx" -class Cartridge4KSCWidget : public CartEnhancedWidget +class Cartridge4KSCWidget : public CartridgeEnhancedWidget { public: Cartridge4KSCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/Cart4KWidget.cxx b/src/debugger/gui/Cart4KWidget.cxx index 14091bd15..deca594fb 100644 --- a/src/debugger/gui/Cart4KWidget.cxx +++ b/src/debugger/gui/Cart4KWidget.cxx @@ -22,7 +22,7 @@ Cartridge4KWidget::Cartridge4KWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge4K& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); @@ -43,7 +43,7 @@ string Cartridge4KWidget::description() ostringstream info; info << "Standard 4K cartridge, non-bankswitched\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/Cart4KWidget.hxx b/src/debugger/gui/Cart4KWidget.hxx index 886e2a060..3fd18eb66 100644 --- a/src/debugger/gui/Cart4KWidget.hxx +++ b/src/debugger/gui/Cart4KWidget.hxx @@ -22,7 +22,7 @@ class Cartridge4K; #include "CartEnhanced.hxx" -class Cartridge4KWidget : public CartEnhancedWidget +class Cartridge4KWidget : public CartridgeEnhancedWidget { public: Cartridge4KWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartBFSCWidget.cxx b/src/debugger/gui/CartBFSCWidget.cxx index 00109d9e9..15f10ff62 100644 --- a/src/debugger/gui/CartBFSCWidget.cxx +++ b/src/debugger/gui/CartBFSCWidget.cxx @@ -22,7 +22,7 @@ CartridgeBFSCWidget::CartridgeBFSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeBFSC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeBFSCWidget::description() ostringstream info; info << "256K BFSC + RAM, 64 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartBFSCWidget.hxx b/src/debugger/gui/CartBFSCWidget.hxx index 5e394eae5..739f41388 100644 --- a/src/debugger/gui/CartBFSCWidget.hxx +++ b/src/debugger/gui/CartBFSCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeBFSC; #include "CartEnhancedWidget.hxx" -class CartridgeBFSCWidget : public CartEnhancedWidget +class CartridgeBFSCWidget : public CartridgeEnhancedWidget { public: CartridgeBFSCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartBFWidget.cxx b/src/debugger/gui/CartBFWidget.cxx index 001f50658..cbaabf076 100644 --- a/src/debugger/gui/CartBFWidget.cxx +++ b/src/debugger/gui/CartBFWidget.cxx @@ -22,7 +22,7 @@ CartridgeBFWidget::CartridgeBFWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeBF& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeBFWidget::description() ostringstream info; info << "256K BF cartridge, 64 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartBFWidget.hxx b/src/debugger/gui/CartBFWidget.hxx index 6c8d37257..b67391c63 100644 --- a/src/debugger/gui/CartBFWidget.hxx +++ b/src/debugger/gui/CartBFWidget.hxx @@ -22,7 +22,7 @@ class CartridgeBF; #include "CartEnhancedWidget.hxx" -class CartridgeBFWidget : public CartEnhancedWidget +class CartridgeBFWidget : public CartridgeEnhancedWidget { public: CartridgeBFWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartCVWidget.cxx b/src/debugger/gui/CartCVWidget.cxx index 1517cc843..f76718375 100644 --- a/src/debugger/gui/CartCVWidget.cxx +++ b/src/debugger/gui/CartCVWidget.cxx @@ -24,7 +24,7 @@ CartridgeCVWidget::CartridgeCVWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeCV& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -35,7 +35,7 @@ string CartridgeCVWidget::description() ostringstream info; info << "CV 2K ROM + 1K RAM, non-bankswitched\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartCVWidget.hxx b/src/debugger/gui/CartCVWidget.hxx index dd8e971ab..63fc6f237 100644 --- a/src/debugger/gui/CartCVWidget.hxx +++ b/src/debugger/gui/CartCVWidget.hxx @@ -22,7 +22,7 @@ class CartridgeCV; #include "CartEnhancedWidget.hxx" -class CartridgeCVWidget : public CartEnhancedWidget +class CartridgeCVWidget : public CartridgeEnhancedWidget { public: CartridgeCVWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartDFSCWidget.cxx b/src/debugger/gui/CartDFSCWidget.cxx index 0744ca182..ed792acb4 100644 --- a/src/debugger/gui/CartDFSCWidget.cxx +++ b/src/debugger/gui/CartDFSCWidget.cxx @@ -22,7 +22,7 @@ CartridgeDFSCWidget::CartridgeDFSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDFSC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeDFSCWidget::description() ostringstream info; info << "128K DFSC + RAM, 32 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartDFSCWidget.hxx b/src/debugger/gui/CartDFSCWidget.hxx index 7aff641ee..9e4481fa8 100644 --- a/src/debugger/gui/CartDFSCWidget.hxx +++ b/src/debugger/gui/CartDFSCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeDFSC; #include "CartEnhancedWidget.hxx" -class CartridgeDFSCWidget : public CartEnhancedWidget +class CartridgeDFSCWidget : public CartridgeEnhancedWidget { public: CartridgeDFSCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartDFWidget.cxx b/src/debugger/gui/CartDFWidget.cxx index cdb6d4f1b..653588e56 100644 --- a/src/debugger/gui/CartDFWidget.cxx +++ b/src/debugger/gui/CartDFWidget.cxx @@ -22,7 +22,7 @@ CartridgeDFWidget::CartridgeDFWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeDF& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeDFWidget::description() ostringstream info; info << "128K DF, 32 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartDFWidget.hxx b/src/debugger/gui/CartDFWidget.hxx index d37176627..9b45552b9 100644 --- a/src/debugger/gui/CartDFWidget.hxx +++ b/src/debugger/gui/CartDFWidget.hxx @@ -22,7 +22,7 @@ class CartridgeDF; #include "CartEnhancedWidget.hxx" -class CartridgeDFWidget : public CartEnhancedWidget +class CartridgeDFWidget : public CartridgeEnhancedWidget { public: CartridgeDFWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartE0Widget.cxx b/src/debugger/gui/CartE0Widget.cxx index b2b6368dc..12205c463 100644 --- a/src/debugger/gui/CartE0Widget.cxx +++ b/src/debugger/gui/CartE0Widget.cxx @@ -22,7 +22,7 @@ CartridgeE0Widget::CartridgeE0Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeE0& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeE0Widget::description() ostringstream info; info << "E0 cartridge,\n eight 1K banks mapped into four segments\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartE0Widget.hxx b/src/debugger/gui/CartE0Widget.hxx index 8d0dbb386..a9d84b461 100644 --- a/src/debugger/gui/CartE0Widget.hxx +++ b/src/debugger/gui/CartE0Widget.hxx @@ -22,7 +22,7 @@ class CartridgeE0; #include "CartEnhancedWidget.hxx" -class CartridgeE0Widget : public CartEnhancedWidget +class CartridgeE0Widget : public CartridgeEnhancedWidget { public: CartridgeE0Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartEFSCWidget.cxx b/src/debugger/gui/CartEFSCWidget.cxx index 8783ca09f..d6f60ddba 100644 --- a/src/debugger/gui/CartEFSCWidget.cxx +++ b/src/debugger/gui/CartEFSCWidget.cxx @@ -22,7 +22,7 @@ CartridgeEFSCWidget::CartridgeEFSCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEFSC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeEFSCWidget::description() ostringstream info; info << "64K H. Runner EFSC + RAM, 16 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartEFSCWidget.hxx b/src/debugger/gui/CartEFSCWidget.hxx index c5d6c4eeb..975f17f8a 100644 --- a/src/debugger/gui/CartEFSCWidget.hxx +++ b/src/debugger/gui/CartEFSCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeEFSC; #include "CartEnhancedWidget.hxx" -class CartridgeEFSCWidget : public CartEnhancedWidget +class CartridgeEFSCWidget : public CartridgeEnhancedWidget { public: CartridgeEFSCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartEFWidget.cxx b/src/debugger/gui/CartEFWidget.cxx index 4fbc9a030..c00d2c3f6 100644 --- a/src/debugger/gui/CartEFWidget.cxx +++ b/src/debugger/gui/CartEFWidget.cxx @@ -22,7 +22,7 @@ CartridgeEFWidget::CartridgeEFWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEF& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeEFWidget::description() ostringstream info; info << "64K H. Runner EF cartridge, 16 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartEFWidget.hxx b/src/debugger/gui/CartEFWidget.hxx index 7299b22d3..7d173836a 100644 --- a/src/debugger/gui/CartEFWidget.hxx +++ b/src/debugger/gui/CartEFWidget.hxx @@ -22,7 +22,7 @@ class CartridgeEF; #include "CartEnhancedWidget.hxx" -class CartridgeEFWidget : public CartEnhancedWidget +class CartridgeEFWidget : public CartridgeEnhancedWidget { public: CartridgeEFWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index a2e22c094..d4c6b4cf0 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -21,7 +21,7 @@ #include "CartEnhancedWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartEnhancedWidget::CartEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, +CartridgeEnhancedWidget::CartridgeEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeEnhanced& cart) @@ -31,7 +31,7 @@ CartEnhancedWidget::CartEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int CartEnhancedWidget::initialize() +int CartridgeEnhancedWidget::initialize() { int ypos = addBaseInformation(size(), manufacturer(), description(), descriptionLines()) + myLineHeight; @@ -42,7 +42,7 @@ int CartEnhancedWidget::initialize() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -size_t CartEnhancedWidget::size() +size_t CartridgeEnhancedWidget::size() { size_t size; @@ -52,7 +52,7 @@ size_t CartEnhancedWidget::size() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::description() +string CartridgeEnhancedWidget::description() { ostringstream info; @@ -64,13 +64,13 @@ string CartEnhancedWidget::description() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int CartEnhancedWidget::descriptionLines() +int CartridgeEnhancedWidget::descriptionLines() { return 18; // should be enough for almost all types } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::ramDescription() +string CartridgeEnhancedWidget::ramDescription() { ostringstream info; @@ -86,7 +86,7 @@ string CartEnhancedWidget::ramDescription() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::romDescription() +string CartridgeEnhancedWidget::romDescription() { ostringstream info; size_t size; @@ -134,7 +134,7 @@ string CartEnhancedWidget::romDescription() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartEnhancedWidget::bankSelect(int& ypos) +void CartridgeEnhancedWidget::bankSelect(int& ypos) { if(myCart.romBankCount() > 1) { @@ -182,7 +182,7 @@ void CartEnhancedWidget::bankSelect(int& ypos) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::bankState() +string CartridgeEnhancedWidget::bankState() { if(myCart.romBankCount() > 1) { @@ -228,7 +228,7 @@ string CartEnhancedWidget::bankState() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::hotspotStr(int bank, int segment, bool prefix) +string CartridgeEnhancedWidget::hotspotStr(int bank, int segment, bool prefix) { ostringstream info; uInt16 hotspot = myCart.hotspot(); @@ -244,13 +244,13 @@ string CartEnhancedWidget::hotspotStr(int bank, int segment, bool prefix) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int CartEnhancedWidget::bankSegs() +int CartridgeEnhancedWidget::bankSegs() { return myCart.myBankSegs; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartEnhancedWidget::saveOldState() +void CartridgeEnhancedWidget::saveOldState() { myOldState.internalRam.clear(); for(uInt32 i = 0; i < myCart.myRamSize; ++i) @@ -265,7 +265,7 @@ void CartEnhancedWidget::saveOldState() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartEnhancedWidget::loadConfig() +void CartridgeEnhancedWidget::loadConfig() { if(myBankWidgets != nullptr) { @@ -281,7 +281,7 @@ void CartEnhancedWidget::loadConfig() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartEnhancedWidget::handleCommand(CommandSender* sender, +void CartridgeEnhancedWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { if(cmd == kBankChanged) @@ -294,19 +294,19 @@ void CartEnhancedWidget::handleCommand(CommandSender* sender, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartEnhancedWidget::internalRamSize() +uInt32 CartridgeEnhancedWidget::internalRamSize() { return myCart.myRamSize; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 CartEnhancedWidget::internalRamRPort(int start) +uInt32 CartridgeEnhancedWidget::internalRamRPort(int start) { return ADDR_BASE + myCart.myReadOffset + start; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::internalRamDescription() +string CartridgeEnhancedWidget::internalRamDescription() { ostringstream desc; @@ -334,7 +334,7 @@ string CartEnhancedWidget::internalRamDescription() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartEnhancedWidget::internalRamOld(int start, int count) +const ByteArray& CartridgeEnhancedWidget::internalRamOld(int start, int count) { myRamOld.clear(); for(int i = 0; i < count; i++) @@ -343,7 +343,7 @@ const ByteArray& CartEnhancedWidget::internalRamOld(int start, int count) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& CartEnhancedWidget::internalRamCurrent(int start, int count) +const ByteArray& CartridgeEnhancedWidget::internalRamCurrent(int start, int count) { myRamCurrent.clear(); for(int i = 0; i < count; i++) @@ -352,19 +352,19 @@ const ByteArray& CartEnhancedWidget::internalRamCurrent(int start, int count) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartEnhancedWidget::internalRamSetValue(int addr, uInt8 value) +void CartridgeEnhancedWidget::internalRamSetValue(int addr, uInt8 value) { myCart.myRAM[addr] = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 CartEnhancedWidget::internalRamGetValue(int addr) +uInt8 CartridgeEnhancedWidget::internalRamGetValue(int addr) { return myCart.myRAM[addr]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartEnhancedWidget::internalRamLabel(int addr) +string CartridgeEnhancedWidget::internalRamLabel(int addr) { CartDebug& dbg = instance().debugger().cartDebug(); return dbg.getLabel(addr + ADDR_BASE + myCart.myReadOffset, false); diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index 2cbd22ced..42ffce1c9 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -27,14 +27,14 @@ namespace GUI { #include "CartDebugWidget.hxx" -class CartEnhancedWidget : public CartDebugWidget +class CartridgeEnhancedWidget : public CartDebugWidget { public: - CartEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, - const GUI::Font& nfont, - int x, int y, int w, int h, - CartridgeEnhanced& cart); - virtual ~CartEnhancedWidget() = default; + CartridgeEnhancedWidget(GuiObject* boss, const GUI::Font& lfont, + const GUI::Font& nfont, + int x, int y, int w, int h, + CartridgeEnhanced& cart); + virtual ~CartridgeEnhancedWidget() = default; protected: int initialize(); @@ -97,11 +97,11 @@ class CartEnhancedWidget : public CartDebugWidget private: // Following constructors and assignment operators not supported - CartEnhancedWidget() = delete; - CartEnhancedWidget(const CartEnhancedWidget&) = delete; - CartEnhancedWidget(CartEnhancedWidget&&) = delete; - CartEnhancedWidget& operator=(const CartEnhancedWidget&) = delete; - CartEnhancedWidget& operator=(CartEnhancedWidget&&) = delete; + CartridgeEnhancedWidget() = delete; + CartridgeEnhancedWidget(const CartridgeEnhancedWidget&) = delete; + CartridgeEnhancedWidget(CartridgeEnhancedWidget&&) = delete; + CartridgeEnhancedWidget& operator=(const CartridgeEnhancedWidget&) = delete; + CartridgeEnhancedWidget& operator=(CartridgeEnhancedWidget&&) = delete; }; #endif diff --git a/src/debugger/gui/CartF0Widget.cxx b/src/debugger/gui/CartF0Widget.cxx index c4826249e..78b13f2d9 100644 --- a/src/debugger/gui/CartF0Widget.cxx +++ b/src/debugger/gui/CartF0Widget.cxx @@ -22,7 +22,7 @@ CartridgeF0Widget::CartridgeF0Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF0& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { myHotspotDelta = 0; initialize(); diff --git a/src/debugger/gui/CartF0Widget.hxx b/src/debugger/gui/CartF0Widget.hxx index 9ba5aa3ab..017d88e78 100644 --- a/src/debugger/gui/CartF0Widget.hxx +++ b/src/debugger/gui/CartF0Widget.hxx @@ -22,7 +22,7 @@ class CartridgeF0; #include "CartEnhancedWidget.hxx" -class CartridgeF0Widget : public CartEnhancedWidget +class CartridgeF0Widget : public CartridgeEnhancedWidget { public: CartridgeF0Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartF4SCWidget.cxx b/src/debugger/gui/CartF4SCWidget.cxx index b85251cbe..8f75b6fce 100644 --- a/src/debugger/gui/CartF4SCWidget.cxx +++ b/src/debugger/gui/CartF4SCWidget.cxx @@ -22,7 +22,7 @@ CartridgeF4SCWidget::CartridgeF4SCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF4SC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeF4SCWidget::description() ostringstream info; info << "Standard F4SC cartridge, eight 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartF4SCWidget.hxx b/src/debugger/gui/CartF4SCWidget.hxx index 8c22c6d74..c6570a9fa 100644 --- a/src/debugger/gui/CartF4SCWidget.hxx +++ b/src/debugger/gui/CartF4SCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeF4SC; #include "CartEnhancedWidget.hxx" -class CartridgeF4SCWidget : public CartEnhancedWidget +class CartridgeF4SCWidget : public CartridgeEnhancedWidget { public: CartridgeF4SCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartF4Widget.cxx b/src/debugger/gui/CartF4Widget.cxx index ae884cfa9..5069f029d 100644 --- a/src/debugger/gui/CartF4Widget.cxx +++ b/src/debugger/gui/CartF4Widget.cxx @@ -22,7 +22,7 @@ CartridgeF4Widget::CartridgeF4Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF4& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeF4Widget::description() ostringstream info; info << "Standard F4 cartridge, eight 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartF4Widget.hxx b/src/debugger/gui/CartF4Widget.hxx index 2201b246b..d444a5956 100644 --- a/src/debugger/gui/CartF4Widget.hxx +++ b/src/debugger/gui/CartF4Widget.hxx @@ -22,7 +22,7 @@ class CartridgeF4; #include "CartEnhancedWidget.hxx" -class CartridgeF4Widget : public CartEnhancedWidget +class CartridgeF4Widget : public CartridgeEnhancedWidget { public: CartridgeF4Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartF6SCWidget.cxx b/src/debugger/gui/CartF6SCWidget.cxx index bfa99b5c5..d2556799c 100644 --- a/src/debugger/gui/CartF6SCWidget.cxx +++ b/src/debugger/gui/CartF6SCWidget.cxx @@ -22,7 +22,7 @@ CartridgeF6SCWidget::CartridgeF6SCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF6SC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeF6SCWidget::description() ostringstream info; info << "Standard F6SC cartridge, four 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartF6SCWidget.hxx b/src/debugger/gui/CartF6SCWidget.hxx index 6b0aab9f8..1ed6378a7 100644 --- a/src/debugger/gui/CartF6SCWidget.hxx +++ b/src/debugger/gui/CartF6SCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeF6SC; #include "CartEnhancedWidget.hxx" -class CartridgeF6SCWidget : public CartEnhancedWidget +class CartridgeF6SCWidget : public CartridgeEnhancedWidget { public: CartridgeF6SCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartF6Widget.cxx b/src/debugger/gui/CartF6Widget.cxx index 692c40258..66bcbc6a7 100644 --- a/src/debugger/gui/CartF6Widget.cxx +++ b/src/debugger/gui/CartF6Widget.cxx @@ -22,7 +22,7 @@ CartridgeF6Widget::CartridgeF6Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF6& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeF6Widget::description() ostringstream info; info << "Standard F6 cartridge, four 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartF6Widget.hxx b/src/debugger/gui/CartF6Widget.hxx index e36933ac7..2d0eb3734 100644 --- a/src/debugger/gui/CartF6Widget.hxx +++ b/src/debugger/gui/CartF6Widget.hxx @@ -22,7 +22,7 @@ class CartridgeF6; #include "CartEnhancedWidget.hxx" -class CartridgeF6Widget : public CartEnhancedWidget +class CartridgeF6Widget : public CartridgeEnhancedWidget { public: CartridgeF6Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartF8SCWidget.cxx b/src/debugger/gui/CartF8SCWidget.cxx index 78e1c70a9..baae2360a 100644 --- a/src/debugger/gui/CartF8SCWidget.cxx +++ b/src/debugger/gui/CartF8SCWidget.cxx @@ -22,7 +22,7 @@ CartridgeF8SCWidget::CartridgeF8SCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF8SC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeF8SCWidget::description() ostringstream info; info << "Standard F8SC cartridge, two 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartF8SCWidget.hxx b/src/debugger/gui/CartF8SCWidget.hxx index 3332f9a4b..3f6199783 100644 --- a/src/debugger/gui/CartF8SCWidget.hxx +++ b/src/debugger/gui/CartF8SCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeF8SC; #include "CartEnhancedWidget.hxx" -class CartridgeF8SCWidget : public CartEnhancedWidget +class CartridgeF8SCWidget : public CartridgeEnhancedWidget { public: CartridgeF8SCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartF8Widget.cxx b/src/debugger/gui/CartF8Widget.cxx index ed1481b2a..d3dd88c23 100644 --- a/src/debugger/gui/CartF8Widget.cxx +++ b/src/debugger/gui/CartF8Widget.cxx @@ -22,7 +22,7 @@ CartridgeF8Widget::CartridgeF8Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeF8& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeF8Widget::description() ostringstream info; info << "Standard F8 cartridge, two 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartF8Widget.hxx b/src/debugger/gui/CartF8Widget.hxx index 34856f2ee..a0577f250 100644 --- a/src/debugger/gui/CartF8Widget.hxx +++ b/src/debugger/gui/CartF8Widget.hxx @@ -23,7 +23,7 @@ class PopUpWidget; #include "CartEnhancedWidget.hxx" -class CartridgeF8Widget : public CartEnhancedWidget +class CartridgeF8Widget : public CartridgeEnhancedWidget { public: CartridgeF8Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartFA2Widget.cxx b/src/debugger/gui/CartFA2Widget.cxx index 40fab9d4d..1c2562628 100644 --- a/src/debugger/gui/CartFA2Widget.cxx +++ b/src/debugger/gui/CartFA2Widget.cxx @@ -22,7 +22,7 @@ CartridgeFA2Widget::CartridgeFA2Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA2& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { int xpos = 2, ypos = initialize(); @@ -65,7 +65,7 @@ string CartridgeFA2Widget::description() info << "Modified FA RAM+, six or seven 4K banks\n"; info << "RAM+ can be loaded/saved to Harmony flash memory by accessing $" << Common::Base::HEX4 << 0xFFF4 << "\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } @@ -91,6 +91,6 @@ void CartridgeFA2Widget::handleCommand(CommandSender* sender, break; default: - CartEnhancedWidget::handleCommand(sender, cmd, data, id); + CartridgeEnhancedWidget::handleCommand(sender, cmd, data, id); } } diff --git a/src/debugger/gui/CartFA2Widget.hxx b/src/debugger/gui/CartFA2Widget.hxx index 30b1ec81f..98508644c 100644 --- a/src/debugger/gui/CartFA2Widget.hxx +++ b/src/debugger/gui/CartFA2Widget.hxx @@ -23,7 +23,7 @@ class ButtonWidget; #include "CartEnhancedWidget.hxx" -class CartridgeFA2Widget : public CartEnhancedWidget +class CartridgeFA2Widget : public CartridgeEnhancedWidget { public: CartridgeFA2Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartFAWidget.cxx b/src/debugger/gui/CartFAWidget.cxx index b3fefff6d..aea8a2061 100644 --- a/src/debugger/gui/CartFAWidget.cxx +++ b/src/debugger/gui/CartFAWidget.cxx @@ -22,7 +22,7 @@ CartridgeFAWidget::CartridgeFAWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -33,7 +33,7 @@ string CartridgeFAWidget::description() ostringstream info; info << "CBS RAM+ FA cartridge, three 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartFAWidget.hxx b/src/debugger/gui/CartFAWidget.hxx index b7fbb3308..2d7311a71 100644 --- a/src/debugger/gui/CartFAWidget.hxx +++ b/src/debugger/gui/CartFAWidget.hxx @@ -22,7 +22,7 @@ class CartridgeFA; #include "CartEnhancedWidget.hxx" -class CartridgeFAWidget : public CartEnhancedWidget +class CartridgeFAWidget : public CartridgeEnhancedWidget { public: CartridgeFAWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartFCWidget.cxx b/src/debugger/gui/CartFCWidget.cxx index 8210eed2e..d206ec694 100644 --- a/src/debugger/gui/CartFCWidget.cxx +++ b/src/debugger/gui/CartFCWidget.cxx @@ -22,7 +22,7 @@ CartridgeFCWidget::CartridgeFCWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFC& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -39,7 +39,7 @@ string CartridgeFCWidget::description() << " $" << Common::Base::HEX4 << (hotspot + 1) << " (defines high bits)\n" << " $" << Common::Base::HEX4 << (hotspot + 4) << " (triggers bank switch)\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartFCWidget.hxx b/src/debugger/gui/CartFCWidget.hxx index f1bb4a50f..f6d56af71 100644 --- a/src/debugger/gui/CartFCWidget.hxx +++ b/src/debugger/gui/CartFCWidget.hxx @@ -22,7 +22,7 @@ class CartridgeFC; #include "CartEnhancedWidget.hxx" -class CartridgeFCWidget : public CartEnhancedWidget +class CartridgeFCWidget : public CartridgeEnhancedWidget { public: CartridgeFCWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartFEWidget.cxx b/src/debugger/gui/CartFEWidget.cxx index dbe992a4f..ce7267e6e 100644 --- a/src/debugger/gui/CartFEWidget.cxx +++ b/src/debugger/gui/CartFEWidget.cxx @@ -22,7 +22,7 @@ CartridgeFEWidget::CartridgeFEWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFE& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -35,7 +35,7 @@ string CartridgeFEWidget::description() info << "FE cartridge, two 4K banks\n" << "Monitors access to hotspot $01FE, and uses " << "upper 3 bits of databus for bank number:\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartFEWidget.hxx b/src/debugger/gui/CartFEWidget.hxx index 05a320a71..468fcc144 100644 --- a/src/debugger/gui/CartFEWidget.hxx +++ b/src/debugger/gui/CartFEWidget.hxx @@ -22,7 +22,7 @@ class CartridgeFE; #include "CartEnhancedWidget.hxx" -class CartridgeFEWidget : public CartEnhancedWidget +class CartridgeFEWidget : public CartridgeEnhancedWidget { public: CartridgeFEWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartUAWidget.cxx b/src/debugger/gui/CartUAWidget.cxx index ffaef806b..f6ae16bc7 100644 --- a/src/debugger/gui/CartUAWidget.cxx +++ b/src/debugger/gui/CartUAWidget.cxx @@ -22,7 +22,7 @@ CartridgeUAWidget::CartridgeUAWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeUA& cart, bool swapHotspots) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), mySwappedHotspots(swapHotspots) { myHotspotDelta = 0x20; @@ -35,7 +35,7 @@ string CartridgeUAWidget::description() ostringstream info; info << "8K UA cartridge" << (mySwappedHotspots ? " (swapped banks)" : "") << ", two 4K banks\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartUAWidget.hxx b/src/debugger/gui/CartUAWidget.hxx index 8a49136a2..a610a1316 100644 --- a/src/debugger/gui/CartUAWidget.hxx +++ b/src/debugger/gui/CartUAWidget.hxx @@ -22,7 +22,7 @@ class CartridgeUA; #include "CartEnhancedWidget.hxx" -class CartridgeUAWidget : public CartEnhancedWidget +class CartridgeUAWidget : public CartridgeEnhancedWidget { public: CartridgeUAWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartWDWidget.cxx b/src/debugger/gui/CartWDWidget.cxx index 16fe416ec..94d7e8060 100644 --- a/src/debugger/gui/CartWDWidget.cxx +++ b/src/debugger/gui/CartWDWidget.cxx @@ -22,7 +22,7 @@ CartridgeWDWidget::CartridgeWDWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeWD& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } diff --git a/src/debugger/gui/CartWDWidget.hxx b/src/debugger/gui/CartWDWidget.hxx index 9bab7af30..746d62e63 100644 --- a/src/debugger/gui/CartWDWidget.hxx +++ b/src/debugger/gui/CartWDWidget.hxx @@ -22,7 +22,7 @@ class CartridgeWD; #include "CartEnhancedWidget.hxx" -class CartridgeWDWidget : public CartEnhancedWidget +class CartridgeWDWidget : public CartridgeEnhancedWidget { public: CartridgeWDWidget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/debugger/gui/CartX07Widget.cxx b/src/debugger/gui/CartX07Widget.cxx index 4fb31a9ca..2c4a167d4 100644 --- a/src/debugger/gui/CartX07Widget.cxx +++ b/src/debugger/gui/CartX07Widget.cxx @@ -22,7 +22,7 @@ CartridgeX07Widget::CartridgeX07Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeX07& cart) - : CartEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { initialize(); } @@ -35,7 +35,7 @@ string CartridgeX07Widget::description() info << "64K X07 cartridge, 16 4K banks\n" << "Multiple hotspots, all below $1000\n" << "See documentation for further details\n"; - info << CartEnhancedWidget::description(); + info << CartridgeEnhancedWidget::description(); return info.str(); } diff --git a/src/debugger/gui/CartX07Widget.hxx b/src/debugger/gui/CartX07Widget.hxx index a096c5d0d..58492e7e6 100644 --- a/src/debugger/gui/CartX07Widget.hxx +++ b/src/debugger/gui/CartX07Widget.hxx @@ -22,7 +22,7 @@ class CartridgeX07; #include "CartEnhancedWidget.hxx" -class CartridgeX07Widget : public CartEnhancedWidget +class CartridgeX07Widget : public CartridgeEnhancedWidget { public: CartridgeX07Widget(GuiObject* boss, const GUI::Font& lfont, diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index c3702d118..ad97409a9 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -33,7 +33,7 @@ class System; */ class CartridgeEnhanced : public Cartridge { - friend class CartEnhancedWidget; + friend class CartridgeEnhancedWidget; public: /** From 069703f4897622aa02ec7fb1d5bcfe7889d37263 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 21 Apr 2020 15:14:52 +0200 Subject: [PATCH 41/52] remove dynamic casting --- src/debugger/gui/CartFA2Widget.cxx | 11 +++++------ src/debugger/gui/CartFA2Widget.hxx | 9 ++++++--- src/debugger/gui/CartWDWidget.cxx | 6 +++--- src/debugger/gui/CartWDWidget.hxx | 3 +++ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/debugger/gui/CartFA2Widget.cxx b/src/debugger/gui/CartFA2Widget.cxx index 1c2562628..e7dcba933 100644 --- a/src/debugger/gui/CartFA2Widget.cxx +++ b/src/debugger/gui/CartFA2Widget.cxx @@ -22,7 +22,8 @@ CartridgeFA2Widget::CartridgeFA2Widget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeFA2& cart) - : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), + myCartFA2(cart) { int xpos = 2, ypos = initialize(); @@ -74,20 +75,18 @@ string CartridgeFA2Widget::description() void CartridgeFA2Widget::handleCommand(CommandSender* sender, int cmd, int data, int id) { - CartridgeFA2& cart = dynamic_cast(myCart); - switch(cmd) { case kFlashErase: - cart.flash(0); + myCartFA2.flash(0); break; case kFlashLoad: - cart.flash(1); + myCartFA2.flash(1); break; case kFlashSave: - cart.flash(2); + myCartFA2.flash(2); break; default: diff --git a/src/debugger/gui/CartFA2Widget.hxx b/src/debugger/gui/CartFA2Widget.hxx index 98508644c..06865c495 100644 --- a/src/debugger/gui/CartFA2Widget.hxx +++ b/src/debugger/gui/CartFA2Widget.hxx @@ -33,9 +33,7 @@ class CartridgeFA2Widget : public CartridgeEnhancedWidget virtual ~CartridgeFA2Widget() = default; private: - string manufacturer() override { return "Chris D. Walton (Star Castle 2600 Arcade)"; } - - string description() override; + CartridgeFA2& myCartFA2; ButtonWidget *myFlashErase{nullptr}, *myFlashLoad{nullptr}, *myFlashSave{nullptr}; @@ -45,6 +43,11 @@ class CartridgeFA2Widget : public CartridgeEnhancedWidget kFlashSave = 'flSV' }; + private: + string manufacturer() override { return "Chris D. Walton (Star Castle 2600 Arcade)"; } + + string description() override; + private: void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/debugger/gui/CartWDWidget.cxx b/src/debugger/gui/CartWDWidget.cxx index 94d7e8060..268e81bf1 100644 --- a/src/debugger/gui/CartWDWidget.cxx +++ b/src/debugger/gui/CartWDWidget.cxx @@ -22,7 +22,8 @@ CartridgeWDWidget::CartridgeWDWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeWD& cart) - : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), + myCartWD(cart) { initialize(); } @@ -45,8 +46,7 @@ string CartridgeWDWidget::description() string CartridgeWDWidget::hotspotStr(int bank, int segment, bool prefix) { ostringstream info; - CartridgeWD& cart = dynamic_cast(myCart); - CartridgeWD::BankOrg banks = cart.ourBankOrg[bank]; + CartridgeWD::BankOrg banks = myCartWD.ourBankOrg[bank]; info << "(" << (prefix ? "hotspot " : "") << "$" << Common::Base::HEX1 << (myCart.hotspot() + bank) << ") [" diff --git a/src/debugger/gui/CartWDWidget.hxx b/src/debugger/gui/CartWDWidget.hxx index 746d62e63..0201cffa5 100644 --- a/src/debugger/gui/CartWDWidget.hxx +++ b/src/debugger/gui/CartWDWidget.hxx @@ -31,6 +31,9 @@ class CartridgeWDWidget : public CartridgeEnhancedWidget CartridgeWD& cart); virtual ~CartridgeWDWidget() = default; +private: + CartridgeWD& myCartWD; + private: string manufacturer() override { return "Wickstead Design"; } From 1064a1153fd05f9fc6e506684bcba89246de7a53 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 21 Apr 2020 16:20:37 +0200 Subject: [PATCH 42/52] order KeyMap and JoyMap when saving --- src/common/JoyMap.cxx | 28 +++++++++++++++++++++++++++- src/common/KeyMap.cxx | 24 +++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/common/JoyMap.cxx b/src/common/JoyMap.cxx index 2a20b4a8b..266dd5e74 100644 --- a/src/common/JoyMap.cxx +++ b/src/common/JoyMap.cxx @@ -185,9 +185,35 @@ JoyMap::JoyMappingArray JoyMap::getEventMapping(const Event::Type event, const E // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string JoyMap::saveMapping(const EventMode mode) const { + using MapType = std::pair; + std::vector sortedMap(myMap.begin(), myMap.end()); + + std::sort(sortedMap.begin(), sortedMap.end(), + [](const MapType& a, const MapType& b) + { + // Event::Type first + if(a.second != b.second) + return a.second < b.second; + + if(a.first.button != b.first.button) + return a.first.button < b.first.button; + + if(a.first.axis != b.first.axis) + return a.first.axis < b.first.axis; + + if(a.first.adir != b.first.adir) + return a.first.adir < b.first.adir; + + if(a.first.hat != b.first.hat) + return a.first.hat < b.first.hat; + + return a.first.hdir < b.first.hdir; + } + ); + ostringstream buf; - for (auto item : myMap) + for (auto item : sortedMap) { if (item.first.mode == mode) { diff --git a/src/common/KeyMap.cxx b/src/common/KeyMap.cxx index eca0369ec..47b34dc9c 100644 --- a/src/common/KeyMap.cxx +++ b/src/common/KeyMap.cxx @@ -16,11 +16,12 @@ //============================================================================ #include "KeyMap.hxx" +#include // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void KeyMap::add(const Event::Type event, const Mapping& mapping) { - myMap[convertMod(mapping)] = event; + myMap[convertMod(mapping)] = event; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -32,7 +33,7 @@ void KeyMap::add(const Event::Type event, const EventMode mode, const int key, c // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void KeyMap::erase(const Mapping& mapping) { - myMap.erase(convertMod(mapping)); + myMap.erase(convertMod(mapping)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -170,9 +171,26 @@ KeyMap::MappingArray KeyMap::getEventMapping(const Event::Type event, const Even // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string KeyMap::saveMapping(const EventMode mode) const { + using MapType = std::pair; + std::vector sortedMap(myMap.begin(), myMap.end()); + + std::sort(sortedMap.begin(), sortedMap.end(), + [](const MapType& a, const MapType& b) + { + // Event::Type first + if(a.second != b.second) + return a.second < b.second; + + if(a.first.key != b.first.key) + return a.first.key < b.first.key; + + return a.first.mod < b.first.mod; + } + ); + ostringstream buf; - for (auto item : myMap) + for (auto item : sortedMap) { if (item.first.mode == mode) { From 7ad10aa5d3a24b34f2926fcf65aaff731bd8b29f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 21 Apr 2020 17:21:08 +0200 Subject: [PATCH 43/52] fix checking for existing mapping when applying default mappings (fixes #620) --- src/common/PJoystickHandler.cxx | 4 ++-- src/common/PKeyboardHandler.cxx | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index e67793078..3b2452798 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -250,9 +250,9 @@ void PhysicalJoystickHandler::setDefaultAction(int stick, if(updateDefaults) { - // if there is no existing mapping for the event or + // if there is no existing mapping for the event and // the default mapping for the event is unused, set default key for event - if(j->joyMap.getEventMapping(map.event, mode).size() == 0 || + if(j->joyMap.getEventMapping(map.event, mode).size() == 0 && !j->joyMap.check(mode, map.button, map.axis, map.adir, map.hat, map.hdir)) { if (map.hat == JOY_CTRL_NONE) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index bc2c545ca..b1a16eeef 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -80,11 +80,16 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event, if (updateDefaults) { - // if there is no existing mapping for the event or + if (map.event == Event::ToggleSAPortOrder) + int i = 0; + + // if there is no existing mapping for the event and // the default mapping for the event is unused, set default key for event - if (myKeyMap.getEventMapping(map.event, mode).size() == 0 || + if (myKeyMap.getEventMapping(map.event, mode).size() == 0 && !myKeyMap.check(mode, map.key, map.mod)) { + if (map.event == Event::ConsoleReset) + int i = 0; addMapping(map.event, mode, map.key, StellaMod(map.mod)); } } From 50ae9f7a621899ebbc7cc7bfc47f7439ac552052 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 22 Apr 2020 10:08:36 +0200 Subject: [PATCH 44/52] add 3EX bankswitching type (addresses #619) (TODO: debugger details) --- src/debugger/gui/Cart3EWidget.cxx | 2 +- src/debugger/gui/CartEnhancedWidget.cxx | 2 +- src/emucore/Bankswitch.cxx | 5 +- src/emucore/Bankswitch.hxx | 16 ++--- src/emucore/Cart3E.hxx | 6 +- src/emucore/Cart3EPlus.hxx | 2 +- src/emucore/Cart3EX.cxx | 27 ++++++++ src/emucore/Cart3EX.hxx | 87 +++++++++++++++++++++++++ src/emucore/Cart4KSC.hxx | 2 +- src/emucore/CartBFSC.hxx | 2 +- src/emucore/CartCV.hxx | 2 +- src/emucore/CartDFSC.hxx | 2 +- src/emucore/CartDetector.cxx | 33 ++++++++-- src/emucore/CartDetector.hxx | 5 ++ src/emucore/CartEFSC.hxx | 2 +- src/emucore/CartEnhanced.cxx | 4 +- src/emucore/CartEnhanced.hxx | 6 +- src/emucore/CartF4SC.hxx | 2 +- src/emucore/CartF6SC.hxx | 2 +- src/emucore/CartF8SC.hxx | 2 +- src/emucore/CartFA.hxx | 2 +- src/emucore/CartWD.hxx | 2 +- src/emucore/module.mk | 1 + src/windows/Stella.vcxproj | 2 + src/windows/Stella.vcxproj.filters | 6 ++ 25 files changed, 190 insertions(+), 34 deletions(-) create mode 100644 src/emucore/Cart3EX.cxx create mode 100644 src/emucore/Cart3EX.hxx diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx index 287bdd112..b2ab3584c 100644 --- a/src/debugger/gui/Cart3EWidget.cxx +++ b/src/debugger/gui/Cart3EWidget.cxx @@ -169,7 +169,7 @@ string Cartridge3EWidget::bankState() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 Cartridge3EWidget::internalRamSize() { - return 32*1024; + return uInt32(myCart.myRamSize); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index d4c6b4cf0..35c5f9e25 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -296,7 +296,7 @@ void CartridgeEnhancedWidget::handleCommand(CommandSender* sender, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeEnhancedWidget::internalRamSize() { - return myCart.myRamSize; + return uInt32(myCart.myRamSize); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/Bankswitch.cxx b/src/emucore/Bankswitch.cxx index 7ce52db58..1b907eea7 100644 --- a/src/emucore/Bankswitch.cxx +++ b/src/emucore/Bankswitch.cxx @@ -104,7 +104,8 @@ Bankswitch::BSList = {{ { "64IN1" , "64IN1 Multicart (128/256K)" }, { "128IN1" , "128IN1 Multicart (256/512K)" }, { "2K" , "2K (32-2048 bytes Atari)" }, - { "3E" , "3E (32K Tigervision)" }, + { "3E" , "3E (Tigervision, 32K RAM)" }, + { "3EX" , "3EX (Tigervision, 256K RAM)" }, { "3E+" , "3E+ (TJ modified 3E)" }, { "3F" , "3F (512K Tigervision)" }, { "4A50" , "4A50 (64K 4A50 + RAM)" }, @@ -178,6 +179,7 @@ Bankswitch::ExtensionMap Bankswitch::ourExtensions = { { "128N1" , Bankswitch::Type::_128IN1 }, { "2K" , Bankswitch::Type::_2K }, { "3E" , Bankswitch::Type::_3E }, + { "3EX" , Bankswitch::Type::_3EX }, { "3EP" , Bankswitch::Type::_3EP }, { "3E+" , Bankswitch::Type::_3EP }, { "3F" , Bankswitch::Type::_3F }, @@ -245,6 +247,7 @@ Bankswitch::NameToTypeMap Bankswitch::ourNameToTypes = { { "2K" , Bankswitch::Type::_2K }, { "3E" , Bankswitch::Type::_3E }, { "3E+" , Bankswitch::Type::_3EP }, + { "3EX" , Bankswitch::Type::_3EX }, { "3F" , Bankswitch::Type::_3F }, { "4A50" , Bankswitch::Type::_4A50 }, { "4K" , Bankswitch::Type::_4K }, diff --git a/src/emucore/Bankswitch.hxx b/src/emucore/Bankswitch.hxx index 9021a21ed..0dd3871c7 100644 --- a/src/emucore/Bankswitch.hxx +++ b/src/emucore/Bankswitch.hxx @@ -38,14 +38,14 @@ class Bankswitch public: // Currently supported bankswitch schemes enum class Type { - _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, - _64IN1, _128IN1, _2K, _3E, _3EP, _3F, _4A50, - _4K, _4KSC, _AR, _BF, _BFSC, _BUS, _CDF, - _CM, _CTY, _CV, _DF, _DFSC, _DPC, _DPCP, - _E0, _E7, _E78K, _EF, _EFSC, _F0, _F4, - _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, _FA2, - _FC, _FE, _MDM, _SB, _UA, _UASW, _WD, - _WDSW, _X07, + _AUTO, _0840, _2IN1, _4IN1, _8IN1, _16IN1, _32IN1, + _64IN1, _128IN1, _2K, _3E, _3EX, _3EP, _3F, + _4A50, _4K, _4KSC, _AR, _BF, _BFSC, _BUS, + _CDF, _CM, _CTY, _CV, _DF, _DFSC, _DPC, + _DPCP, _E0, _E7, _E78K, _EF, _EFSC, _F0, + _F4, _F4SC, _F6, _F6SC, _F8, _F8SC, _FA, + _FA2, _FC, _FE, _MDM, _SB, _UA, _UASW, + _WD, _WDSW, _X07, #ifdef CUSTOM_ARM _CUSTOM, #endif diff --git a/src/emucore/Cart3E.hxx b/src/emucore/Cart3E.hxx index 4871c67a6..613fa610c 100644 --- a/src/emucore/Cart3E.hxx +++ b/src/emucore/Cart3E.hxx @@ -116,15 +116,15 @@ class Cartridge3E : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value) override; - private: + protected: // log(ROM bank segment size) / log(2) static constexpr uInt16 BANK_SHIFT = 11; // = 2K = 0x0800 - // The size of extra RAM in ROM address space + // The number of RAM banks static constexpr uInt16 RAM_BANKS = 32; // RAM size - static constexpr uInt16 RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000; + static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x8000; // Write port for extra RAM is at high address static constexpr bool RAM_HIGH_WP = true; diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 1a2440e40..209ab89dc 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -165,7 +165,7 @@ class Cartridge3EPlus: public CartridgeEnhanced static constexpr uInt16 RAM_BANKS = 64; // RAM size - static constexpr uInt16 RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000; + static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000; // Write port for extra RAM is at high address static constexpr bool RAM_HIGH_WP = true; diff --git a/src/emucore/Cart3EX.cxx b/src/emucore/Cart3EX.cxx new file mode 100644 index 000000000..4f9c7ac45 --- /dev/null +++ b/src/emucore/Cart3EX.cxx @@ -0,0 +1,27 @@ +//============================================================================ +// +// 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 +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "Cart3EX.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Cartridge3EX::Cartridge3EX(const ByteBuffer& image, size_t size, + const string& md5, const Settings& settings) + : Cartridge3E(image, size, md5, settings) +{ + myRamSize = RAM_SIZE; + myRamBankCount = RAM_BANKS; +} diff --git a/src/emucore/Cart3EX.hxx b/src/emucore/Cart3EX.hxx new file mode 100644 index 000000000..99181cffd --- /dev/null +++ b/src/emucore/Cart3EX.hxx @@ -0,0 +1,87 @@ +//============================================================================ +// +// 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 +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CARTRIDGE3EX_HXX +#define CARTRIDGE3EX_HXX + +class System; + +#include "Cart3E.hxx" +#ifdef DEBUGGER_SUPPORT +//#include "Cart3EXWidget.hxx" +#endif + +/** + This is an enhanced version of 3E which supports up to 256KB RAM. + + @author Thomas Jentzsch +*/ + +class Cartridge3EX : public Cartridge3E +{ + //friend class Cartridge3EXWidget; + +public: + /** + Create a new cartridge using the specified image and size + + @param image Pointer to the ROM image + @param size The size of the ROM image + @param md5 The md5sum of the ROM image + @param settings A reference to the various settings (read-only) + */ + Cartridge3EX(const ByteBuffer& image, size_t size, const string& md5, + const Settings& settings); + virtual ~Cartridge3EX() = default; + +public: + /** + Get a descriptor for the device name (used in error checking). + + @return The name of the object + */ + string name() const override { return "Cartridge3EX"; } + +#ifdef DEBUGGER_SUPPORT + ///** + // Get debugger widget responsible for accessing the inner workings + // of the cart. + //*/ + //CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, + // const GUI::Font& nfont, int x, int y, int w, int h) override + //{ + // return new Cartridge3EXWidget(boss, lfont, nfont, x, y, w, h, *this); + //} +#endif + +private: + // The number of RAM banks + static constexpr uInt16 RAM_BANKS = 256; + + // RAM size + static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 256K = 0x40000; + +private: + // Following constructors and assignment operators not supported + Cartridge3EX() = delete; + Cartridge3EX(const Cartridge3EX&) = delete; + Cartridge3EX(Cartridge3EX&&) = delete; + Cartridge3EX& operator=(const Cartridge3EX&) = delete; + Cartridge3EX& operator=(Cartridge3EX&&) = delete; +}; + +#endif diff --git a/src/emucore/Cart4KSC.hxx b/src/emucore/Cart4KSC.hxx index 64dde3c39..3f28de9ce 100644 --- a/src/emucore/Cart4KSC.hxx +++ b/src/emucore/Cart4KSC.hxx @@ -72,7 +72,7 @@ class Cartridge4KSC : public Cartridge4K private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr size_t RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartBFSC.hxx b/src/emucore/CartBFSC.hxx index 35c4b84ca..9bb22aa0a 100644 --- a/src/emucore/CartBFSC.hxx +++ b/src/emucore/CartBFSC.hxx @@ -74,7 +74,7 @@ class CartridgeBFSC : public CartridgeBF private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr uInt32 RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartCV.hxx b/src/emucore/CartCV.hxx index 1b4773e5e..a5403b19f 100644 --- a/src/emucore/CartCV.hxx +++ b/src/emucore/CartCV.hxx @@ -89,7 +89,7 @@ class CartridgeCV : public CartridgeEnhanced static constexpr uInt16 BANK_SHIFT = 11; // 2K // RAM size - static constexpr uInt16 RAM_SIZE = 0x400; // 1K + static constexpr uInt32 RAM_SIZE = 0x400; // 1K // Write port for extra RAM is at high address static constexpr bool RAM_HIGH_WP = true; diff --git a/src/emucore/CartDFSC.hxx b/src/emucore/CartDFSC.hxx index cf3661039..637dde3da 100644 --- a/src/emucore/CartDFSC.hxx +++ b/src/emucore/CartDFSC.hxx @@ -72,7 +72,7 @@ class CartridgeDFSC : public CartridgeDF private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr size_t RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartDetector.cxx b/src/emucore/CartDetector.cxx index b40e75c49..8544a72f0 100644 --- a/src/emucore/CartDetector.cxx +++ b/src/emucore/CartDetector.cxx @@ -20,6 +20,7 @@ #include "Cart0840.hxx" #include "Cart2K.hxx" #include "Cart3E.hxx" +#include "Cart3EX.hxx" #include "Cart3EPlus.hxx" #include "Cart3F.hxx" #include "Cart4A50.hxx" @@ -250,6 +251,8 @@ CartDetector::createFromImage(const ByteBuffer& image, size_t size, Bankswitch:: return make_unique(image, size, md5, settings); case Bankswitch::Type::_3E: return make_unique(image, size, md5, settings); + case Bankswitch::Type::_3EX: + return make_unique(image, size, md5, settings); case Bankswitch::Type::_3EP: return make_unique(image, size, md5, settings); case Bankswitch::Type::_3F: @@ -380,6 +383,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si type = Bankswitch::Type::_4K; else if(isProbablyE0(image, size)) type = Bankswitch::Type::_E0; + else if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) @@ -419,6 +424,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si type = Bankswitch::Type::_E7; else if (isProbablyFC(image, size)) type = Bankswitch::Type::_FC; + else if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; /* no known 16K 3F ROMS @@ -445,6 +452,8 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si type = Bankswitch::Type::_CTY; else if(isProbablySC(image, size)) type = Bankswitch::Type::_F4SC; + else if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) @@ -471,7 +480,9 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } else if(size == 64_KB) { - if(isProbably3E(image, size)) + if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; + else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; @@ -486,7 +497,9 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } else if(size == 128_KB) { - if(isProbably3E(image, size)) + if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; + else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbablyDF(image, size, type)) ; // type has been set directly in the function @@ -499,7 +512,9 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } else if(size == 256_KB) { - if(isProbably3E(image, size)) + if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; + else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbablyBF(image, size, type)) ; // type has been set directly in the function @@ -510,7 +525,9 @@ Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t si } else // what else can we do? { - if(isProbably3E(image, size)) + if(isProbably3EX(image, size)) + type = Bankswitch::Type::_3EX; + else if(isProbably3E(image, size)) type = Bankswitch::Type::_3E; else if(isProbably3F(image, size)) type = Bankswitch::Type::_3F; @@ -632,6 +649,14 @@ bool CartDetector::isProbably3E(const ByteBuffer& image, size_t size) && searchForBytes(image.get(), size, signature2, 2, 2); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool CartDetector::isProbably3EX(const ByteBuffer& image, size_t size) +{ + // 3EX cart have at least 2 occurrences of the string "3EX" + uInt8 _3EX[] = { '3', 'E', 'X'}; + return searchForBytes(image.get(), size, _3EX, 3, 2); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartDetector::isProbably3EPlus(const ByteBuffer& image, size_t size) { diff --git a/src/emucore/CartDetector.hxx b/src/emucore/CartDetector.hxx index 63a98b053..8dc734b42 100644 --- a/src/emucore/CartDetector.hxx +++ b/src/emucore/CartDetector.hxx @@ -130,6 +130,11 @@ class CartDetector */ static bool isProbably3E(const ByteBuffer& image, size_t size); + /** + Returns true if the image is probably a 3EX bankswitching cartridge + */ + static bool isProbably3EX(const ByteBuffer& image, size_t size); + /** Returns true if the image is probably a 3E+ bankswitching cartridge */ diff --git a/src/emucore/CartEFSC.hxx b/src/emucore/CartEFSC.hxx index d204d1ef5..f6c7e40ea 100644 --- a/src/emucore/CartEFSC.hxx +++ b/src/emucore/CartEFSC.hxx @@ -76,7 +76,7 @@ class CartridgeEFSC : public CartridgeEF private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr size_t RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 3e69a06f8..0bb6f54fb 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -35,13 +35,13 @@ CartridgeEnhanced::CartridgeEnhanced(const ByteBuffer& image, size_t size, void CartridgeEnhanced::install(System& system) { // limit banked RAM size to the size of one RAM bank - uInt16 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : myRamSize; + uInt32 ramSize = myRamBankCount > 0 ? 1 << (myBankShift - 1) : uInt32(myRamSize); // calculate bank switching and RAM sizes and masks myBankSize = 1 << myBankShift; // e.g. = 2 ^ 12 = 4K = 0x1000 myBankMask = myBankSize - 1; // e.g. = 0x0FFF myBankSegs = 1 << (MAX_BANK_SHIFT - myBankShift); // e.g. = 1 - myRomOffset = myRamBankCount > 0 ? 0 : myRamSize * 2; + myRomOffset = myRamBankCount > 0 ? 0 : uInt32(myRamSize) * 2; myRamMask = ramSize - 1; // e.g. = 0xFFFF (doesn't matter for RAM size 0) myWriteOffset = myRamWpHigh ? ramSize : 0; // e.g. = 0x0000 myReadOffset = myRamWpHigh ? 0 : ramSize; // e.g. = 0x0080 diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index ad97409a9..743a4b50e 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -183,7 +183,7 @@ class CartridgeEnhanced : public Cartridge protected: // The extra RAM size - uInt16 myRamSize{RAM_SIZE}; // default 0 + size_t myRamSize{RAM_SIZE}; // default 0 // The number of RAM banks uInt16 myRamBankCount{RAM_BANKS}; // default 0 @@ -246,9 +246,9 @@ class CartridgeEnhanced : public Cartridge static constexpr uInt16 BANK_SHIFT = 12; // default = 4K // The size of extra RAM in ROM address space - static constexpr uInt16 RAM_SIZE = 0; // default = none + static constexpr size_t RAM_SIZE = 0; // default = none - // The size of extra RAM in ROM address space + // The number of RAM banks static constexpr uInt16 RAM_BANKS = 0; // Write port for extra RAM is at low address by default diff --git a/src/emucore/CartF4SC.hxx b/src/emucore/CartF4SC.hxx index 5f49a33a6..58b255e42 100644 --- a/src/emucore/CartF4SC.hxx +++ b/src/emucore/CartF4SC.hxx @@ -69,7 +69,7 @@ class CartridgeF4SC : public CartridgeF4 private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr size_t RAM_SIZE = 0x80; // RAM mask static constexpr uInt16 RAM_MASK = RAM_SIZE - 1; diff --git a/src/emucore/CartF6SC.hxx b/src/emucore/CartF6SC.hxx index a791a538d..c61c9715f 100644 --- a/src/emucore/CartF6SC.hxx +++ b/src/emucore/CartF6SC.hxx @@ -69,7 +69,7 @@ class CartridgeF6SC : public CartridgeF6 private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr size_t RAM_SIZE = 0x80; // RAM mask static constexpr uInt16 RAM_MASK = RAM_SIZE - 1; diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index 25fe0dfe3..c5a005543 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -69,7 +69,7 @@ class CartridgeF8SC : public CartridgeF8 private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x80; + static constexpr size_t RAM_SIZE = 0x80; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartFA.hxx b/src/emucore/CartFA.hxx index 920f2bdec..a2f197b75 100644 --- a/src/emucore/CartFA.hxx +++ b/src/emucore/CartFA.hxx @@ -79,7 +79,7 @@ class CartridgeFA : public CartridgeEnhanced private: // RAM size - static constexpr uInt16 RAM_SIZE = 0x100; + static constexpr size_t RAM_SIZE = 0x100; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 1fd42ac71..6feb6be63 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -176,7 +176,7 @@ class CartridgeWD : public CartridgeEnhanced static constexpr uInt16 BANK_SHIFT = 10; // = 1K = 0x0400 // RAM size - static constexpr uInt16 RAM_SIZE = 0x40; + static constexpr size_t RAM_SIZE = 0x40; // Write port for extra RAM is at low address by default static constexpr bool RAM_HIGH_WP = true; diff --git a/src/emucore/module.mk b/src/emucore/module.mk index dc953b86e..e0dd4f96f 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -11,6 +11,7 @@ MODULE_OBJS := \ src/emucore/Cart2K.o \ src/emucore/Cart3E.o \ src/emucore/Cart3EPlus.o \ + src/emucore/Cart3EX.o \ src/emucore/Cart3F.o \ src/emucore/Cart4A50.o \ src/emucore/Cart4K.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 28b0efe29..1095f2c09 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -711,6 +711,7 @@ + @@ -1727,6 +1728,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 536cf54eb..fb763da4c 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -999,6 +999,9 @@ Source Files\debugger + + Source Files\emucore + @@ -2051,6 +2054,9 @@ Header Files\debugger + + Header Files\emucore + From 619d12018c74a9ee3ecbeee6dd2386e520c46ca1 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 22 Apr 2020 12:50:26 +0200 Subject: [PATCH 45/52] 3EX now reads number of RAM banks - 1 from 0xfffa --- Changes.txt | 2 ++ docs/index.html | 7 ++++--- src/emucore/Cart3EX.cxx | 3 ++- src/emucore/Cart3EX.hxx | 3 --- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Changes.txt b/Changes.txt index 61989ecd9..20ed3e411 100644 --- a/Changes.txt +++ b/Changes.txt @@ -32,6 +32,8 @@ * Restored 'cfg' directory for Distella config files. + * Added 3EX bank switching type. + * Removed unused CV+ and DASH bank switching types. -Have fun! diff --git a/docs/index.html b/docs/index.html index c7185ebe1..6f9fb85a9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3790,8 +3790,9 @@ Ms Pac-Man (Stella extended codes): - - + + + @@ -3826,7 +3827,7 @@ Ms Pac-Man (Stella extended codes): - + diff --git a/src/emucore/Cart3EX.cxx b/src/emucore/Cart3EX.cxx index 4f9c7ac45..889935a07 100644 --- a/src/emucore/Cart3EX.cxx +++ b/src/emucore/Cart3EX.cxx @@ -23,5 +23,6 @@ Cartridge3EX::Cartridge3EX(const ByteBuffer& image, size_t size, : Cartridge3E(image, size, md5, settings) { myRamSize = RAM_SIZE; - myRamBankCount = RAM_BANKS; + // 0xFFFA contains RAM bank count - 1; + myRamBankCount = image[size - 6] + 1; } diff --git a/src/emucore/Cart3EX.hxx b/src/emucore/Cart3EX.hxx index 99181cffd..e7ba2ecfd 100644 --- a/src/emucore/Cart3EX.hxx +++ b/src/emucore/Cart3EX.hxx @@ -69,9 +69,6 @@ public: #endif private: - // The number of RAM banks - static constexpr uInt16 RAM_BANKS = 256; - // RAM size static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 256K = 0x40000; From c8eacc854c50b632c3b27e36e9951183590bb330 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 22 Apr 2020 19:58:40 +0200 Subject: [PATCH 46/52] refactored Cart3EWidget (also supports 3EX) added RAM bank support to CartEnhancedWidget --- src/common/PKeyboardHandler.cxx | 5 - src/debugger/gui/Cart3EWidget.cxx | 225 ++++++++++-------------- src/debugger/gui/Cart3EWidget.hxx | 42 ++--- src/debugger/gui/CartEnhancedWidget.cxx | 75 +++++--- src/debugger/gui/CartEnhancedWidget.hxx | 2 + src/emucore/Cart3EX.cxx | 2 +- src/emucore/Cart3EX.hxx | 16 -- 7 files changed, 157 insertions(+), 210 deletions(-) diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index b1a16eeef..57a3bfd4b 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -80,16 +80,11 @@ void PhysicalKeyboardHandler::setDefaultKey(EventMapping map, Event::Type event, if (updateDefaults) { - if (map.event == Event::ToggleSAPortOrder) - int i = 0; - // if there is no existing mapping for the event and // the default mapping for the event is unused, set default key for event if (myKeyMap.getEventMapping(map.event, mode).size() == 0 && !myKeyMap.check(mode, map.key, map.mod)) { - if (map.event == Event::ConsoleReset) - int i = 0; addMapping(map.event, mode, map.key, StellaMod(map.mod)); } } diff --git a/src/debugger/gui/Cart3EWidget.cxx b/src/debugger/gui/Cart3EWidget.cxx index b2ab3584c..4683ea7d4 100644 --- a/src/debugger/gui/Cart3EWidget.cxx +++ b/src/debugger/gui/Cart3EWidget.cxx @@ -23,129 +23,134 @@ Cartridge3EWidget::Cartridge3EWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3E& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart), - myNumRomBanks(myCart.romBankCount()), - myNumRamBanks(myCart.ramBankCount()) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - size_t size = cart.mySize; - - ostringstream info; - info << "3E cartridge - (3F + RAM)\n" - << " 2-256 2K ROM (currently " << myNumRomBanks << "), 32 1K RAM\n" - << "First 2K (ROM) selected by writing to $3F\n" - "First 2K (RAM) selected by writing to $3E\n" - " $F000 - $F3FF (R), $F400 - $F7FF (W)\n" - "Last 2K always points to last 2K of ROM\n"; - if(cart.startBank() < myNumRomBanks) - info << "Startup bank = " << cart.startBank() << " (ROM)\n"; - else - info << "Startup bank = " << (cart.startBank()-myNumRomBanks) << " (RAM)\n"; - - // Eventually, we should query this from the debugger/disassembler - uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4]; - start -= start % 0x1000; - info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n"; - - int xpos = 2, - ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight; - - VariantList romitems; - for(uInt32 i = 0; i < myNumRomBanks; ++i) - VarList::push_back(romitems, i); - VarList::push_back(romitems, "Inactive", ""); - - VariantList ramitems; - for(uInt32 i = 0; i < myNumRamBanks; ++i) - VarList::push_back(ramitems, i); - VarList::push_back(ramitems, "Inactive", ""); - - ostringstream label; - label << "Set bank ($" << Common::Base::HEX4 << start << " - $" - << (start+0x7FF) << "): "; - - new StaticTextWidget(_boss, _font, xpos, ypos, _font.getStringWidth(label.str()), - myFontHeight, label.str(), TextAlign::Left); - ypos += myLineHeight + 8; - - xpos += 40; - myROMBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3E) "), - myLineHeight, romitems, "ROM ($3F) ", - _font.getStringWidth("ROM ($3F) "), kROMBankChanged); - myROMBank->setTarget(this); - addFocusWidget(myROMBank); - - xpos += myROMBank->getWidth() + 20; - myRAMBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3E) "), - myLineHeight, ramitems, "RAM ($3E) ", - _font.getStringWidth("RAM ($3E) "), kRAMBankChanged); - myRAMBank->setTarget(this); - addFocusWidget(myRAMBank); + initialize(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EWidget::saveOldState() +string Cartridge3EWidget::description() { - myOldState.internalram.clear(); + ostringstream info; + size_t size; + const uInt8* image = myCart.getImage(size); + uInt16 numRomBanks = myCart.romBankCount(); + uInt16 numRamBanks = myCart.ramBankCount(); - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); - myOldState.bank = myCart.getBank(); + info << "3E cartridge (3F + RAM),\n" + << " " << numRomBanks << " 2K ROM banks, " << numRamBanks << " 1K RAM banks\n" + << "First 2K (ROM) selected by writing to $3F\n" + "First 2K (RAM) selected by writing to $3E\n"; + info << CartridgeEnhancedWidget::ramDescription(); + info << "Last 2K always points to last 2K of ROM\n"; + + if(myCart.startBank() < numRomBanks) + info << "Startup bank = " << myCart.startBank() << " (ROM)\n"; + else + info << "Startup bank = " << (myCart.startBank() - numRomBanks) << " (RAM)\n"; + + // Eventually, we should query this from the debugger/disassembler + uInt16 start = (image[size-3] << 8) | image[size-4]; + start -= start % 0x1000; + info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n"; + + return info.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Cartridge3EWidget::bankList(uInt16 bankCount, int seg, VariantList& items, int& width) +{ + CartridgeEnhancedWidget::bankList(bankCount, seg, items, width); + + VarList::push_back(items, "Inactive", ""); + width = _font.getStringWidth("Inactive"); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Cartridge3EWidget::bankSelect(int& ypos) +{ + int xpos = 2; + VariantList items; + int pw; + + myBankWidgets = make_unique(2); + + bankList(myCart.romBankCount(), 0, items, pw); + myBankWidgets[0] = + new PopUpWidget(_boss, _font, xpos, ypos - 2, pw, + myLineHeight, items, "Set bank ", + _font.getStringWidth("Set bank "), kBankChanged); + myBankWidgets[0]->setTarget(this); + myBankWidgets[0]->setID(0); + addFocusWidget(myBankWidgets[0]); + + StaticTextWidget* t = new StaticTextWidget(_boss, _font, myBankWidgets[0]->getRight(), ypos - 1, " (ROM)"); + + xpos = t->getRight() + 20; + items.clear(); + bankList(myCart.ramBankCount(), 0, items, pw); + myBankWidgets[1] = + new PopUpWidget(_boss, _font, xpos, ypos - 2, pw, + myLineHeight, items, "", 0, kRAMBankChanged); + myBankWidgets[1]->setTarget(this); + myBankWidgets[1]->setID(1); + addFocusWidget(myBankWidgets[1]); + + new StaticTextWidget(_boss, _font, myBankWidgets[1]->getRight(), ypos - 1, " (RAM)"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EWidget::loadConfig() { + uInt16 oldBank = myOldState.banks[0]; + uInt16 bank = myCart.getBank(); + if(myCart.getBank() < myCart.romBankCount()) { - myROMBank->setSelectedIndex(myCart.getBank() % myNumRomBanks, myOldState.bank != myCart.getBank()); - myRAMBank->setSelectedMax(myOldState.bank >= myCart.romBankCount()); + myBankWidgets[0]->setSelectedIndex(bank, oldBank != bank); + myBankWidgets[1]->setSelectedMax(oldBank >= myCart.romBankCount()); } else { - myROMBank->setSelectedMax(myOldState.bank < myCart.romBankCount()); - myRAMBank->setSelectedIndex(myCart.getBank() - myCart.romBankCount(), myOldState.bank != myCart.getBank()); + myBankWidgets[0]->setSelectedMax(oldBank < myCart.romBankCount()); + myBankWidgets[1]->setSelectedIndex(bank - myCart.romBankCount(), oldBank != bank); } CartDebugWidget::loadConfig(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) +void Cartridge3EWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { uInt16 bank = 0; - if(cmd == kROMBankChanged) + if(cmd == kBankChanged) { - if(myROMBank->getSelected() < int(myNumRomBanks)) + if(myBankWidgets[0]->getSelected() < myCart.romBankCount()) { - bank = myROMBank->getSelected(); - myRAMBank->setSelectedMax(); + bank = myBankWidgets[0]->getSelected(); + myBankWidgets[1]->setSelectedMax(); } else { bank = myCart.romBankCount(); // default to first RAM bank - myRAMBank->setSelectedIndex(0); + myBankWidgets[1]->setSelectedIndex(0); } } else if(cmd == kRAMBankChanged) { - if(myRAMBank->getSelected() < int(myNumRamBanks)) + if(myBankWidgets[1]->getSelected() < myCart.ramBankCount()) { - myROMBank->setSelectedMax(); - bank = myRAMBank->getSelected() + myCart.romBankCount(); + myBankWidgets[0]->setSelectedMax(); + bank = myBankWidgets[1]->getSelected() + myCart.romBankCount(); } else { bank = 0; // default to first ROM bank - myROMBank->setSelectedIndex(0); + myBankWidgets[0]->setSelectedIndex(0); } } - myCart.unlockBank(); myCart.bank(bank); myCart.lockBank(); @@ -156,65 +161,13 @@ void Cartridge3EWidget::handleCommand(CommandSender* sender, string Cartridge3EWidget::bankState() { ostringstream& buf = buffer(); - uInt16 bank = myCart.getBank(); + if(bank < myCart.romBankCount()) - buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive"; + buf << "ROM bank #" << std::dec << bank % myCart.romBankCount() << ", RAM inactive"; else - buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRamBanks; + buf << "ROM inactive, RAM bank #" + << std::dec << (bank - myCart.romBankCount()) % myCart.ramBankCount(); return buf.str(); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 Cartridge3EWidget::internalRamSize() -{ - return uInt32(myCart.myRamSize); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 Cartridge3EWidget::internalRamRPort(int start) -{ - return 0x0000 + start; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Cartridge3EWidget::internalRamDescription() -{ - ostringstream desc; - desc << "Accessible 1K at a time via:\n" - << " $F000 - $F3FF used for Read Access\n" - << " $F400 - $F7FF used for Write Access"; - - return desc.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& Cartridge3EWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& Cartridge3EWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge3EWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} diff --git a/src/debugger/gui/Cart3EWidget.hxx b/src/debugger/gui/Cart3EWidget.hxx index 623a8877e..e1d4f266b 100644 --- a/src/debugger/gui/Cart3EWidget.hxx +++ b/src/debugger/gui/Cart3EWidget.hxx @@ -19,11 +19,12 @@ #define CARTRIDGE3E_WIDGET_HXX class Cartridge3E; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class Cartridge3EWidget : public CartDebugWidget +// Note: This class supports 3EX too + +class Cartridge3EWidget : public CartridgeEnhancedWidget { public: Cartridge3EWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,39 +34,28 @@ class Cartridge3EWidget : public CartDebugWidget virtual ~Cartridge3EWidget() = default; private: - Cartridge3E& myCart; - const uInt32 myNumRomBanks{0}; - const uInt32 myNumRamBanks{0}; - PopUpWidget *myROMBank{nullptr}, *myRAMBank{nullptr}; - - struct CartState { - ByteArray internalram; - uInt16 bank; - }; - CartState myOldState; - enum { - kROMBankChanged = 'rmCH', kRAMBankChanged = 'raCH' }; private: - void saveOldState() override; + string manufacturer() override { return "Andrew Davie & Thomas Jentzsch"; } + + string description() override; + + void bankList(uInt16 bankCount, int seg, VariantList& items, int& width) override; + + void bankSelect(int& ypos) override; + + int bankSegs() override { return 1; } + void loadConfig() override; + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; string bankState() override; - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - // end of functions for Cartridge RAM tab - + private: // Following constructors and assignment operators not supported Cartridge3EWidget() = delete; Cartridge3EWidget(const Cartridge3EWidget&) = delete; diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index 35c5f9e25..a59e4f985 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -74,13 +74,15 @@ string CartridgeEnhancedWidget::ramDescription() { ostringstream info; - info << myCart.myRamSize << " bytes RAM @ " - << "$" << Common::Base::HEX4 << ADDR_BASE << " - " - << "$" << (ADDR_BASE | (myCart.myRamSize * 2 - 1)) << "\n" - << " $" << (ADDR_BASE | myCart.myReadOffset) - << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamSize - 1)) << " (R)" + if(myCart.ramBankCount() == 0) + info << myCart.myRamSize << " bytes RAM @ " + << "$" << Common::Base::HEX4 << ADDR_BASE << " - " + << "$" << (ADDR_BASE | (myCart.myRamSize * 2 - 1)) << "\n"; + + info << " $" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) + << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) << " (R)" << ", $" << (ADDR_BASE | myCart.myWriteOffset) - << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamSize - 1)) << " (W)\n"; + << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamMask)) << " (W)\n"; return info.str(); } @@ -133,6 +135,23 @@ string CartridgeEnhancedWidget::romDescription() return info.str(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeEnhancedWidget::bankList(uInt16 bankCount, int seg, VariantList& items, int& width) +{ + width = 0; + + for(int bank = 0; bank < bankCount; ++bank) + { + ostringstream buf; + + buf << std::setw(bank < 10 ? 2 : 1) << "#" << std::dec << bank; + if(myCart.hotspot() != 0 && myHotspotDelta > 0) + buf << " " << hotspotStr(bank, seg); + VarList::push_back(items, buf.str()); + width = std::max(width, _font.getStringWidth(buf.str())); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeEnhancedWidget::bankSelect(int& ypos) { @@ -148,17 +167,7 @@ void CartridgeEnhancedWidget::bankSelect(int& ypos) VariantList items; int pw = 0; - for(int bank = 0; bank < myCart.romBankCount(); ++bank) - { - ostringstream buf; - - buf << std::setw(bank < 10 ? 2 : 1) << "#" << std::dec << bank; - //if(myCart.hotspot() >= 0x100 && myHotspotDelta > 0) - if(myCart.hotspot() != 0 && myHotspotDelta > 0) - buf << " " << hotspotStr(bank, seg); - VarList::push_back(items, buf.str()); - pw = std::max(pw, _font.getStringWidth(buf.str())); - } + bankList(myCart.romBankCount(), seg, items, pw); // create widgets ostringstream buf; @@ -282,7 +291,7 @@ void CartridgeEnhancedWidget::loadConfig() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeEnhancedWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) + int cmd, int data, int id) { if(cmd == kBankChanged) { @@ -302,31 +311,45 @@ uInt32 CartridgeEnhancedWidget::internalRamSize() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 CartridgeEnhancedWidget::internalRamRPort(int start) { - return ADDR_BASE + myCart.myReadOffset + start; + if(myCart.ramBankCount() == 0) + return ADDR_BASE + myCart.myReadOffset + start; + else + return start; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartridgeEnhancedWidget::internalRamDescription() { ostringstream desc; + string indent = ""; + + if(myCart.ramBankCount()) + { + desc << "Accessible "; + if (myCart.bankSize() >> 1 >= 1024) + desc << ((myCart.bankSize() >> 1) / 1024) << "K"; + else + desc << (myCart.bankSize() >> 1) << " bytes"; + desc << " at a time via:\n"; + indent = " "; + } // order RW by addresses if(myCart.myReadOffset <= myCart.myWriteOffset) { - desc << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) - << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamSize - 1)) + desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) + << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) << " used for Read Access\n"; } - desc - << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myWriteOffset) - << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamSize - 1)) + desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myWriteOffset) + << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamMask)) << " used for Write Access"; if(myCart.myReadOffset > myCart.myWriteOffset) { - desc << "\n$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) - << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamSize - 1)) + desc << indent << "\n$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) + << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) << " used for Read Access"; } diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index 42ffce1c9..1f4ae6f30 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -51,6 +51,8 @@ class CartridgeEnhancedWidget : public CartDebugWidget virtual string romDescription(); + virtual void bankList(uInt16 bankCount, int seg, VariantList& items, int& width); + virtual void bankSelect(int& ypos); virtual string hotspotStr(int bank = 0, int segment = 0, bool prefix = false); diff --git a/src/emucore/Cart3EX.cxx b/src/emucore/Cart3EX.cxx index 889935a07..c71fdd242 100644 --- a/src/emucore/Cart3EX.cxx +++ b/src/emucore/Cart3EX.cxx @@ -22,7 +22,7 @@ Cartridge3EX::Cartridge3EX(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) : Cartridge3E(image, size, md5, settings) { - myRamSize = RAM_SIZE; // 0xFFFA contains RAM bank count - 1; myRamBankCount = image[size - 6] + 1; + myRamSize = (myBankSize >> 1) * myRamBankCount; } diff --git a/src/emucore/Cart3EX.hxx b/src/emucore/Cart3EX.hxx index e7ba2ecfd..7df53593e 100644 --- a/src/emucore/Cart3EX.hxx +++ b/src/emucore/Cart3EX.hxx @@ -21,9 +21,6 @@ class System; #include "Cart3E.hxx" -#ifdef DEBUGGER_SUPPORT -//#include "Cart3EXWidget.hxx" -#endif /** This is an enhanced version of 3E which supports up to 256KB RAM. @@ -33,7 +30,6 @@ class System; class Cartridge3EX : public Cartridge3E { - //friend class Cartridge3EXWidget; public: /** @@ -56,18 +52,6 @@ public: */ string name() const override { return "Cartridge3EX"; } -#ifdef DEBUGGER_SUPPORT - ///** - // Get debugger widget responsible for accessing the inner workings - // of the cart. - //*/ - //CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, - // const GUI::Font& nfont, int x, int y, int w, int h) override - //{ - // return new Cartridge3EXWidget(boss, lfont, nfont, x, y, w, h, *this); - //} -#endif - private: // RAM size static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 256K = 0x40000; From a27b6a7f3d61f79786d992b690ec9a6d85a0570b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 23 Apr 2020 10:46:09 +0200 Subject: [PATCH 47/52] refactored CartMDM and CartSB widget classes --- src/debugger/gui/CartMDMWidget.cxx | 82 +++++++++++------------------- src/debugger/gui/CartMDMWidget.hxx | 21 +++++--- src/debugger/gui/CartSBWidget.cxx | 79 ++++------------------------ src/debugger/gui/CartSBWidget.hxx | 15 ++---- src/emucore/CartMDM.hxx | 2 + src/emucore/CartSB.hxx | 2 +- 6 files changed, 59 insertions(+), 142 deletions(-) diff --git a/src/debugger/gui/CartMDMWidget.cxx b/src/debugger/gui/CartMDMWidget.cxx index 48afbaf77..a3509cb34 100644 --- a/src/debugger/gui/CartMDMWidget.cxx +++ b/src/debugger/gui/CartMDMWidget.cxx @@ -17,45 +17,39 @@ #include "CartMDM.hxx" #include "PopUpWidget.hxx" -#include "Widget.hxx" #include "CartMDMWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeMDMWidget::CartridgeMDMWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeMDM& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), + myCartMDM(cart) +{ + initialize(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartridgeMDMWidget::description() { ostringstream info; - size_t size; - myCart.getImage(size); - info << "Menu Driven Megacart, containing up to 128 4K banks\n" - << "Startup bank = " << cart.startBank() << "\n" - << "\nBanks are selected by reading from $800 - $BFF, where the lower " - "byte determines the 4K bank to use."; + info << "Menu Driven Megacart, " << myCart.romBankCount() << " 4K banks\n" + << "Banks are selected by reading from $800 - $" << Common::Base::HEX1 << 0xBFF + << ", where the lower byte determines the 4K bank to use.\n"; + info << CartridgeEnhancedWidget::description(); - int xpos = 2, - ypos = addBaseInformation(size, "Edwin Blink", info.str(), 15) + myLineHeight; + return info.str(); +} - VariantList items; - for(uInt32 i = 0x800; i < (0x800U + myCart.romBankCount()); ++i) - { - info.str(""); - info << std::dec << (i & 0xFF) << " ($" << Common::Base::HEX4 << i << ")"; - VarList::push_back(items, info.str()); - } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void CartridgeMDMWidget::bankSelect(int& ypos) +{ + CartridgeEnhancedWidget::bankSelect(ypos); + int xpos = myBankWidgets[0]->getRight() + 20; + ypos = myBankWidgets[0]->getTop(); - myBank = - new PopUpWidget(boss, _font, xpos, ypos, _font.getStringWidth("xxx ($0FFF)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); - - xpos += myBank->getWidth() + 30; - myBankDisabled = new CheckboxWidget(boss, _font, xpos, ypos + 1, + myBankDisabled = new CheckboxWidget(_boss, _font, xpos, ypos + 1, "Bankswitching is locked/disabled", kBankDisabled); myBankDisabled->setTarget(this); @@ -65,39 +59,21 @@ CartridgeMDMWidget::CartridgeMDMWidget( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeMDMWidget::loadConfig() { - myBank->setSelectedIndex(myCart.getBank()); - myBank->setEnabled(!myCart.myBankingDisabled); - myBankDisabled->setState(myCart.myBankingDisabled); + myBankWidgets[0]->setEnabled(!myCartMDM.myBankingDisabled); + myBankDisabled->setState(myCartMDM.myBankingDisabled); - CartDebugWidget::loadConfig(); + CartridgeEnhancedWidget::loadConfig(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeMDMWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { - if(cmd == kBankChanged) + if(cmd == kBankDisabled) { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } - else if(cmd == kBankDisabled) - { - myCart.myBankingDisabled = myBankDisabled->getState(); - myBank->setEnabled(!myCart.myBankingDisabled); + myCartMDM.myBankingDisabled = myBankDisabled->getState(); + myBankWidgets[0]->setEnabled(!myCartMDM.myBankingDisabled); } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeMDMWidget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << "$" << Common::Base::HEX4 - << (myCart.getBank()+0x800); - - return buf.str(); + else + CartridgeEnhancedWidget::handleCommand(sender, cmd, data, id); } diff --git a/src/debugger/gui/CartMDMWidget.hxx b/src/debugger/gui/CartMDMWidget.hxx index adf242b68..c7add24d7 100644 --- a/src/debugger/gui/CartMDMWidget.hxx +++ b/src/debugger/gui/CartMDMWidget.hxx @@ -20,11 +20,10 @@ class CartridgeMDM; class CheckboxWidget; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeMDMWidget : public CartDebugWidget +class CartridgeMDMWidget : public CartridgeEnhancedWidget { public: CartridgeMDMWidget(GuiObject* boss, const GUI::Font& lfont, @@ -34,18 +33,24 @@ class CartridgeMDMWidget : public CartDebugWidget virtual ~CartridgeMDMWidget() = default; private: - CartridgeMDM& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Edwin Blink"; } + + string description() override; + + void bankSelect(int& ypos) override; + + CartridgeMDM& myCartMDM; CheckboxWidget* myBankDisabled{nullptr}; - enum { kBankChanged = 'bkCH', kBankDisabled = 'bkDI' }; + enum { + kBankDisabled = 'bkDI' + }; private: void loadConfig() override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - string bankState() override; - + private: // Following constructors and assignment operators not supported CartridgeMDMWidget() = delete; CartridgeMDMWidget(const CartridgeMDMWidget&) = delete; diff --git a/src/debugger/gui/CartSBWidget.cxx b/src/debugger/gui/CartSBWidget.cxx index 7a82ba8e0..b564781bc 100644 --- a/src/debugger/gui/CartSBWidget.cxx +++ b/src/debugger/gui/CartSBWidget.cxx @@ -16,86 +16,27 @@ //============================================================================ #include "CartSB.hxx" -#include "PopUpWidget.hxx" #include "CartSBWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeSBWidget::CartridgeSBWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, CartridgeSB& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart) { - VariantList items; - ostringstream info, bank; - size_t size; - - myCart.getImage(size); - info << "SB SUPERbanking, 32 or 64 4K banks\n" - << "Hotspots are from $800 to $" - << Common::Base::HEX2 << (0x800 + myCart.romBankCount() - 1) << ", including\n" - << "mirrors ($900, $A00, $B00, ...)\n" - << "Startup bank = " << std::dec << cart.startBank() << "\n"; - - // Eventually, we should query this from the debugger/disassembler - for(uInt32 i = 0, offset = 0xFFC, spot = 0x800; i < myCart.romBankCount(); - ++i, offset += 0x1000, ++spot) - { - uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; - start -= start % 0x1000; - info << "Bank " << std::dec << i << " @ $" << Common::Base::HEX4 << start << " - " - << "$" << (start + 0xFFF) << " (hotspot = $" << spot << ")\n"; - - bank << std::dec << std::setw(2) << std::setfill(' ') << i << " ($" - << Common::Base::HEX2 << spot << ")"; - VarList::push_back(items, bank.str()); - bank.str(""); - } - - int xpos = 2, - ypos = addBaseInformation(size, "Fred X. Quimby", info.str()) + myLineHeight; - - myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("XX ($800)"), - myLineHeight, items, "Set bank ", - 0, kBankChanged); - myBank->setTarget(this); - addFocusWidget(myBank); + initialize(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeSBWidget::loadConfig() +string CartridgeSBWidget::description() { - Debugger& dbg = instance().debugger(); - CartDebug& cart = dbg.cartDebug(); - const CartState& state = static_cast(cart.getState()); - const CartState& oldstate = static_cast(cart.getOldState()); + ostringstream info; - myBank->setSelectedIndex(myCart.getBank(), state.bank != oldstate.bank); + info << "SB SUPERbanking, " << myCart.romBankCount() << " 4K banks\n" + << "Hotspots are from $800 to $" + << Common::Base::HEX2 << (0x800 + myCart.romBankCount() - 1) << ", including\n" + << "mirrors ($900, $" << 0xA00 << ", $" << 0xB00 << ", ...)\n"; + info << CartridgeEnhancedWidget::description(); - CartDebugWidget::loadConfig(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeSBWidget::handleCommand(CommandSender* sender, - int cmd, int data, int id) -{ - if(cmd == kBankChanged) - { - myCart.unlockBank(); - myCart.bank(myBank->getSelected()); - myCart.lockBank(); - invalidate(); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartridgeSBWidget::bankState() -{ - ostringstream& buf = buffer(); - - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = $" << Common::Base::HEX2 << (myCart.getBank() + 0x800); - - return buf.str(); + return info.str(); } diff --git a/src/debugger/gui/CartSBWidget.hxx b/src/debugger/gui/CartSBWidget.hxx index 5819dec02..91cc90ec1 100644 --- a/src/debugger/gui/CartSBWidget.hxx +++ b/src/debugger/gui/CartSBWidget.hxx @@ -19,11 +19,10 @@ #define CARTRIDGESB_WIDGET_HXX class CartridgeSB; -class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class CartridgeSBWidget : public CartDebugWidget +class CartridgeSBWidget : public CartridgeEnhancedWidget { public: CartridgeSBWidget(GuiObject* boss, const GUI::Font& lfont, @@ -33,17 +32,11 @@ class CartridgeSBWidget : public CartDebugWidget virtual ~CartridgeSBWidget() = default; private: - CartridgeSB& myCart; - PopUpWidget* myBank{nullptr}; + string manufacturer() override { return "Fred X. Quimby"; } - enum { kBankChanged = 'bkCH' }; + string description() override; private: - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - // Following constructors and assignment operators not supported CartridgeSBWidget() = delete; CartridgeSBWidget(const CartridgeSBWidget&) = delete; diff --git a/src/emucore/CartMDM.hxx b/src/emucore/CartMDM.hxx index 6fd7435a3..4b0786e42 100644 --- a/src/emucore/CartMDM.hxx +++ b/src/emucore/CartMDM.hxx @@ -100,6 +100,8 @@ class CartridgeMDM : public CartridgeEnhanced */ string name() const override { return "CartridgeMDM"; } + uInt16 hotspot() const override { return 0x0800; } + #ifdef DEBUGGER_SUPPORT /** Get debugger widget responsible for accessing the inner workings diff --git a/src/emucore/CartSB.hxx b/src/emucore/CartSB.hxx index 1e8a363a9..85c8e9ccb 100644 --- a/src/emucore/CartSB.hxx +++ b/src/emucore/CartSB.hxx @@ -98,7 +98,7 @@ class CartridgeSB : public CartridgeEnhanced private: bool checkSwitchBank(uInt16 address, uInt8 value = 0) override; - uInt16 hotspot() const override { return 0x0840; } + uInt16 hotspot() const override { return 0x0800; } uInt16 getStartBank() const override { return romBankCount() - 1; } From 34b57d4205b23ff4644a62f4ab100e79676dc1f6 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 23 Apr 2020 12:34:27 +0200 Subject: [PATCH 48/52] refactored Cart3EPlus widget --- src/debugger/gui/Cart3EPlusWidget.cxx | 210 +++++++++--------------- src/debugger/gui/Cart3EPlusWidget.hxx | 42 ++--- src/debugger/gui/Cart3EWidget.hxx | 2 +- src/debugger/gui/Cart3FWidget.hxx | 2 +- src/debugger/gui/CartE0Widget.hxx | 2 +- src/debugger/gui/CartEnhancedWidget.cxx | 8 +- src/debugger/gui/CartEnhancedWidget.hxx | 2 +- src/debugger/gui/CartWDWidget.hxx | 2 +- src/emucore/Cart3EPlus.cxx | 16 +- src/emucore/Cart3EPlus.hxx | 15 +- 10 files changed, 106 insertions(+), 195 deletions(-) diff --git a/src/debugger/gui/Cart3EPlusWidget.cxx b/src/debugger/gui/Cart3EPlusWidget.cxx index a93cb8f98..8e7cdf063 100644 --- a/src/debugger/gui/Cart3EPlusWidget.cxx +++ b/src/debugger/gui/Cart3EPlusWidget.cxx @@ -18,116 +18,124 @@ #include "Cart3EPlus.hxx" #include "EditTextWidget.hxx" #include "PopUpWidget.hxx" -#include "Cart3EPlusWidget.hxx" +#include "CartEnhancedWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3EPlusWidget::Cartridge3EPlusWidget( GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont, int x, int y, int w, int h, Cartridge3EPlus& cart) - : CartDebugWidget(boss, lfont, nfont, x, y, w, h), - myCart(cart) + : CartridgeEnhancedWidget(boss, lfont, nfont, x, y, w, h, cart), + myCart3EP(cart) { - size_t size = cart.mySize; + initialize(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Cartridge3EPlusWidget::description() +{ ostringstream info; - info << "3EPlus cartridge - (4..64K ROM + RAM)\n" - << " 4..64K ROM (1K banks), ..32K RAM (512b banks)\n" - << "Each 1K ROM selected by writing to $3F\n" - "Each 512b RAM selected by writing to $3E\n" - " Lower 512b of bank x (R)\n" - " Upper 512b of bank x (+$200) (W)\n" - << "Startup bank = 0/-1/-1/0 (ROM)\n"; + size_t size; + const uInt8* image = myCart.getImage(size); + uInt16 numRomBanks = myCart.romBankCount(); + uInt16 numRamBanks = myCart.ramBankCount(); + + info << "3E+ cartridge - (4..64K ROM + RAM)\n" + << " " << numRomBanks << " 1K ROM banks + " << numRamBanks << " 512b RAM banks\n" + << " mapped into four segments\n" + "ROM bank & segment selected by writing to $3F\n" + "RAM bank & segment selected by writing to $3E\n" + " Lower 512b of segment for read access\n" + " Upper 512b of segment for write access\n" + "Startup bank = 0/-1/-1/0 (ROM)\n"; // Eventually, we should query this from the debugger/disassembler - // Currently the cart starts at bank 0. If we change that, we have to change this too. - uInt16 start = (cart.myImage[0x400-3] << 8) | cart.myImage[0x400 - 4]; - start &= 0xF000; - info << "Bank RORG = $" << Common::Base::HEX4 << start << "\n"; + uInt16 start = (image[0x400 - 3] << 8) | image[0x400 - 4]; + start -= start % 0x1000; + info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n"; - int xpos = 2, - ypos = addBaseInformation(size, "Thomas Jentzsch", info.str()) + 8; - - VariantList bankno; - for(uInt32 i = 0; i < myCart.romBankCount(); ++i) - VarList::push_back(bankno, i, i); + return info.str(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Cartridge3EPlusWidget::bankSelect(int& ypos) +{ + size_t size; + const uInt8* image = myCart.getImage(size); VariantList banktype; + VarList::push_back(banktype, "ROM", "ROM"); VarList::push_back(banktype, "RAM", "RAM"); - for(uInt32 seg = 0; seg < myCart.myBankSegs; ++seg) - { - int xpos_s, ypos_s = ypos + 1; + myBankWidgets = make_unique(bankSegs()); + for(uInt32 seg = 0; seg < bankSegs(); ++seg) + { + int xpos = 2, xpos_s, ypos_s = ypos + 1, width; ostringstream label; + VariantList items; + label << "Set segment " << seg << " as "; - new StaticTextWidget(boss, _font, xpos, ypos, label.str()); + new StaticTextWidget(_boss, _font, xpos, ypos, label.str()); ypos += myLineHeight + 8; xpos += _font.getMaxCharWidth() * 2; - myBankNumber[seg] = - new PopUpWidget(boss, _font, xpos, ypos-2, 2 *_font.getMaxCharWidth(), - myLineHeight, bankno, "Bank "); - addFocusWidget(myBankNumber[seg]); - xpos += myBankNumber[seg]->getWidth(); + CartridgeEnhancedWidget::bankList(myCart.romBankCount(), seg, items, width); + myBankWidgets[seg] = + new PopUpWidget(_boss, _font, xpos, ypos - 2, width, + myLineHeight, items, "Bank "); + addFocusWidget(myBankWidgets[seg]); + + xpos += myBankWidgets[seg]->getWidth(); myBankType[seg] = - new PopUpWidget(boss, _font, xpos, ypos-2, 3 *_font.getMaxCharWidth(), + new PopUpWidget(_boss, _font, xpos, ypos - 2, 3 * _font.getMaxCharWidth(), myLineHeight, banktype, " of "); addFocusWidget(myBankType[seg]); xpos = myBankType[seg]->getRight() + _font.getMaxCharWidth(); // add "Commit" button (why required?) - myBankCommit[seg] = new ButtonWidget(boss, _font, xpos, ypos-4, - _font.getStringWidth(" Commit "), myButtonHeight, - "Commit", bankEnum[seg]); + myBankCommit[seg] = new ButtonWidget(_boss, _font, xpos, ypos - 4, + _font.getStringWidth(" Commit "), myButtonHeight, + "Commit", bankEnum[seg]); myBankCommit[seg]->setTarget(this); addFocusWidget(myBankCommit[seg]); xpos_s = myBankCommit[seg]->getRight() + _font.getMaxCharWidth() * 2; StaticTextWidget* t; + uInt16 start = (image[0x400 - 3] << 8) | image[0x400 - 4]; + start -= start % 0x1000; int addr1 = start + (seg * 0x400), addr2 = addr1 + 0x200; label.str(""); label << "$" << Common::Base::HEX4 << addr1 << "-$" << Common::Base::HEX4 << (addr1 + 0x1FF); - t = new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, label.str()); + t = new StaticTextWidget(_boss, _font, xpos_s, ypos_s + 2, label.str()); int xoffset = t->getRight() + _font.getMaxCharWidth(); - myBankState[2*seg] = new EditTextWidget(boss, _font, xoffset, ypos_s, - w - xoffset - 10, myLineHeight, ""); - myBankState[2*seg]->setEditable(false, true); + myBankState[2 * seg] = new EditTextWidget(_boss, _font, xoffset, ypos_s, + _w - xoffset - 10, myLineHeight, ""); + myBankState[2 * seg]->setEditable(false, true); ypos_s += myLineHeight + 4; label.str(""); label << "$" << Common::Base::HEX4 << addr2 << "-$" << Common::Base::HEX4 << (addr2 + 0x1FF); - new StaticTextWidget(boss, _font, xpos_s, ypos_s+2, label.str()); + new StaticTextWidget(_boss, _font, xpos_s, ypos_s + 2, label.str()); - myBankState[2*seg+1] = new EditTextWidget(boss, _font, xoffset, ypos_s, - w - xoffset - 10, myLineHeight, ""); - myBankState[2*seg+1]->setEditable(false, true); + myBankState[2 * seg + 1] = new EditTextWidget(_boss, _font, xoffset, ypos_s, + _w - xoffset - 10, myLineHeight, ""); + myBankState[2 * seg + 1]->setEditable(false, true); - xpos = 2; ypos += 2 * myLineHeight; } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EPlusWidget::saveOldState() -{ - myOldState.internalram.clear(); - - for(uInt32 i = 0; i < internalRamSize(); ++i) - myOldState.internalram.push_back(myCart.myRAM[i]); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EPlusWidget::loadConfig() { + CartridgeEnhancedWidget::loadConfig(); updateUIState(); - CartDebugWidget::loadConfig(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -154,11 +162,11 @@ void Cartridge3EPlusWidget::handleCommand(CommandSender* sender, } // Ignore bank if either number or type hasn't been selected - if(myBankNumber[segment]->getSelected() < 0 || + if(myBankWidgets[segment]->getSelected() < 0 || myBankType[segment]->getSelected() < 0) return; - uInt8 bank = myBankNumber[segment]->getSelected(); + uInt8 bank = myBankWidgets[segment]->getSelected(); myCart.unlockBank(); @@ -172,123 +180,61 @@ void Cartridge3EPlusWidget::handleCommand(CommandSender* sender, updateUIState(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Cartridge3EPlusWidget::bankState() -{ - ostringstream& buf = buffer(); - - for(int seg = 0; seg < myCart.myBankSegs; ++seg) - { - int bank = myCart.getSegmentBank(seg); - - if(bank >= myCart.romBankCount()) // was RAM mapped here? - buf << " RAM " << bank - myCart.romBankCount(); - else - buf << " ROM " << bank; - if(seg < myCart.myBankSegs - 1) - buf << " /"; - } - - return buf.str(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Cartridge3EPlusWidget::updateUIState() { - // Set description for each 1K bank state (@ each index) + // Set description for each 1K segment state (@ each index) // Set contents for actual banks number and type (@ each even index) - for(int seg = 0; seg < myCart.myBankSegs; ++seg) + for(int seg = 0; seg < myCart3EP.myBankSegs; ++seg) { uInt16 bank = myCart.getSegmentBank(seg); ostringstream buf; - if(bank >= myCart.romBankCount()) // was RAM mapped here? + if(bank >= myCart.romBankCount()) // was RAM mapped here? { uInt16 ramBank = bank - myCart.romBankCount(); - buf << "RAM " << std::dec << ramBank << " @ $" << Common::Base::HEX4 - << (ramBank << myCart.myBankShift) << "(R)"; + buf << "RAM @ $" << Common::Base::HEX4 + << (ramBank << myCart3EP.myBankShift) << " (R)"; myBankState[seg * 2]->setText(buf.str()); buf.str(""); - buf << "RAM " << std::dec << ramBank << " @ $" << Common::Base::HEX4 - << ((ramBank << myCart.myBankShift) + myCart.myBankSize) << "(W)"; + buf << "RAM @ $" << Common::Base::HEX4 + << ((ramBank << myCart3EP.myBankShift) + myCart3EP.myBankSize) << " (W)"; myBankState[seg * 2 + 1]->setText(buf.str()); - myBankNumber[seg]->setSelected(ramBank); + myBankWidgets[seg]->setSelectedIndex(ramBank); myBankType[seg]->setSelected("RAM"); } else { - buf << "ROM " << std::dec << bank << " @ $" << Common::Base::HEX4 - << ((bank << myCart.myBankShift)); + buf << "ROM @ $" << Common::Base::HEX4 + << ((bank << myCart3EP.myBankShift)); myBankState[seg * 2]->setText(buf.str()); buf.str(""); - buf << "ROM " << std::dec << bank << " @ $" << Common::Base::HEX4 - << ((bank << myCart.myBankShift) + myCart.myBankSize); + buf << "ROM @ $" << Common::Base::HEX4 + << ((bank << myCart3EP.myBankShift) + myCart3EP.myBankSize); myBankState[seg * 2 + 1]->setText(buf.str()); - myBankNumber[seg]->setSelected(bank); + myBankWidgets[seg]->setSelectedIndex(bank); myBankType[seg]->setSelected("ROM"); } } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 Cartridge3EPlusWidget::internalRamSize() -{ - return 32*1024; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 Cartridge3EPlusWidget::internalRamRPort(int start) -{ - return 0x0000 + start; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string Cartridge3EPlusWidget::internalRamDescription() { ostringstream desc; desc << "Accessible 512b at a time via:\n" - << " $f000/$f400/$f800/$fc00 for Read Access\n" - << " $f200/$f600/$fa00/$fe00 for Write Access"; + << " $f000/$f400/$f800/$fc00 for read access\n" + << " $f200/$f600/$fa00/$fe00 for write access"; return desc.str(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& Cartridge3EPlusWidget::internalRamOld(int start, int count) -{ - myRamOld.clear(); - for(int i = 0; i < count; i++) - myRamOld.push_back(myOldState.internalram[start + i]); - return myRamOld; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const ByteArray& Cartridge3EPlusWidget::internalRamCurrent(int start, int count) -{ - myRamCurrent.clear(); - for(int i = 0; i < count; i++) - myRamCurrent.push_back(myCart.myRAM[start + i]); - return myRamCurrent; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EPlusWidget::internalRamSetValue(int addr, uInt8 value) -{ - myCart.myRAM[addr] = value; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 Cartridge3EPlusWidget::internalRamGetValue(int addr) -{ - return myCart.myRAM[addr]; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const std::array Cartridge3EPlusWidget::bankEnum = { kBank0Changed, kBank1Changed, kBank2Changed, kBank3Changed diff --git a/src/debugger/gui/Cart3EPlusWidget.hxx b/src/debugger/gui/Cart3EPlusWidget.hxx index 723003376..7cde61042 100644 --- a/src/debugger/gui/Cart3EPlusWidget.hxx +++ b/src/debugger/gui/Cart3EPlusWidget.hxx @@ -23,9 +23,9 @@ class ButtonWidget; class EditTextWidget; class PopUpWidget; -#include "CartDebugWidget.hxx" +#include "CartEnhancedWidget.hxx" -class Cartridge3EPlusWidget : public CartDebugWidget +class Cartridge3EPlusWidget : public CartridgeEnhancedWidget { public: Cartridge3EPlusWidget(GuiObject* boss, const GUI::Font& lfont, @@ -35,21 +35,27 @@ class Cartridge3EPlusWidget : public CartDebugWidget virtual ~Cartridge3EPlusWidget() = default; private: + string manufacturer() override { return "Thomas Jentzsch"; } + + string description() override; + + void bankSelect(int& ypos) override; + + void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + void updateUIState(); - private: - Cartridge3EPlus& myCart; + void loadConfig() override; + + string internalRamDescription() override; + + private: + Cartridge3EPlus& myCart3EP; - std::array myBankNumber{nullptr}; std::array myBankType{nullptr}; std::array myBankCommit{nullptr}; std::array myBankState{nullptr}; - struct CartState { - ByteArray internalram; - }; - CartState myOldState; - enum BankID { kBank0Changed = 'b0CH', kBank1Changed = 'b1CH', @@ -59,22 +65,6 @@ class Cartridge3EPlusWidget : public CartDebugWidget static const std::array bankEnum; private: - void saveOldState() override; - void loadConfig() override; - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - string bankState() override; - - // start of functions for Cartridge RAM tab - uInt32 internalRamSize() override; - uInt32 internalRamRPort(int start) override; - string internalRamDescription() override; - const ByteArray& internalRamOld(int start, int count) override; - const ByteArray& internalRamCurrent(int start, int count) override; - void internalRamSetValue(int addr, uInt8 value) override; - uInt8 internalRamGetValue(int addr) override; - // end of functions for Cartridge RAM tab - // Following constructors and assignment operators not supported Cartridge3EPlusWidget() = delete; Cartridge3EPlusWidget(const Cartridge3EPlusWidget&) = delete; diff --git a/src/debugger/gui/Cart3EWidget.hxx b/src/debugger/gui/Cart3EWidget.hxx index e1d4f266b..424d9a577 100644 --- a/src/debugger/gui/Cart3EWidget.hxx +++ b/src/debugger/gui/Cart3EWidget.hxx @@ -47,7 +47,7 @@ class Cartridge3EWidget : public CartridgeEnhancedWidget void bankSelect(int& ypos) override; - int bankSegs() override { return 1; } + uInt16 bankSegs() override { return 1; } void loadConfig() override; diff --git a/src/debugger/gui/Cart3FWidget.hxx b/src/debugger/gui/Cart3FWidget.hxx index e5f97a392..ad24d8e56 100644 --- a/src/debugger/gui/Cart3FWidget.hxx +++ b/src/debugger/gui/Cart3FWidget.hxx @@ -36,7 +36,7 @@ class Cartridge3FWidget : public CartridgeEnhancedWidget string description() override; - int bankSegs() override { return 1; } + uInt16 bankSegs() override { return 1; } private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/CartE0Widget.hxx b/src/debugger/gui/CartE0Widget.hxx index a9d84b461..a50893e84 100644 --- a/src/debugger/gui/CartE0Widget.hxx +++ b/src/debugger/gui/CartE0Widget.hxx @@ -40,7 +40,7 @@ class CartridgeE0Widget : public CartridgeEnhancedWidget string hotspotStr(int bank, int segment, bool noBrackets = false) override; - int bankSegs() override { return 3; } + uInt16 bankSegs() override { return 3; } private: // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index a59e4f985..8001c1292 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -253,7 +253,7 @@ string CartridgeEnhancedWidget::hotspotStr(int bank, int segment, bool prefix) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int CartridgeEnhancedWidget::bankSegs() +uInt16 CartridgeEnhancedWidget::bankSegs() { return myCart.myBankSegs; } @@ -339,18 +339,18 @@ string CartridgeEnhancedWidget::internalRamDescription() { desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) - << " used for Read Access\n"; + << " used for read Access\n"; } desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myWriteOffset) << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamMask)) - << " used for Write Access"; + << " used for write Access"; if(myCart.myReadOffset > myCart.myWriteOffset) { desc << indent << "\n$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) - << " used for Read Access"; + << " used for read Access"; } return desc.str(); diff --git a/src/debugger/gui/CartEnhancedWidget.hxx b/src/debugger/gui/CartEnhancedWidget.hxx index 1f4ae6f30..968a4bbf0 100644 --- a/src/debugger/gui/CartEnhancedWidget.hxx +++ b/src/debugger/gui/CartEnhancedWidget.hxx @@ -57,7 +57,7 @@ class CartridgeEnhancedWidget : public CartDebugWidget virtual string hotspotStr(int bank = 0, int segment = 0, bool prefix = false); - virtual int bankSegs(); // { return myCart.myBankSegs; } + virtual uInt16 bankSegs(); // { return myCart.myBankSegs; } void saveOldState() override; void loadConfig() override; diff --git a/src/debugger/gui/CartWDWidget.hxx b/src/debugger/gui/CartWDWidget.hxx index 0201cffa5..2ccdd7437 100644 --- a/src/debugger/gui/CartWDWidget.hxx +++ b/src/debugger/gui/CartWDWidget.hxx @@ -41,7 +41,7 @@ private: string hotspotStr(int bank, int seg = 0, bool prefix = false) override; - int bankSegs() override { return 1; } + uInt16 bankSegs() override { return 1; } private: // Following constructors and assignment operators not supported diff --git a/src/emucore/Cart3EPlus.cxx b/src/emucore/Cart3EPlus.cxx index 5803f2136..6c9fe7c2a 100644 --- a/src/emucore/Cart3EPlus.cxx +++ b/src/emucore/Cart3EPlus.cxx @@ -22,13 +22,11 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cartridge3EPlus::Cartridge3EPlus(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : CartridgeEnhanced(image, size, md5, settings) - + : Cartridge3E(image, size, md5, settings) { myBankShift = BANK_SHIFT; myRamSize = RAM_SIZE; myRamBankCount = RAM_BANKS; - myRamWpHigh = RAM_HIGH_WP; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -42,18 +40,6 @@ void Cartridge3EPlus::reset() bank(startBank(), 3); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Cartridge3EPlus::install(System& system) -{ - CartridgeEnhanced::install(system); - - System::PageAccess access(this, System::PageAccessType::WRITE); - - // The hotspots are in TIA address space, so we claim it here - for(uInt16 addr = 0x00; addr < 0x40; addr += System::PAGE_SIZE) - mySystem->setPageAccess(addr, access); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Cartridge3EPlus::checkSwitchBank(uInt16 address, uInt8 value) { diff --git a/src/emucore/Cart3EPlus.hxx b/src/emucore/Cart3EPlus.hxx index 209ab89dc..c2ce64cd8 100644 --- a/src/emucore/Cart3EPlus.hxx +++ b/src/emucore/Cart3EPlus.hxx @@ -21,7 +21,7 @@ class System; #include "bspf.hxx" -#include "CartEnhanced.hxx" +#include "Cart3E.hxx" #ifdef DEBUGGER_SUPPORT class Cartridge3EPlusWidget; @@ -89,7 +89,7 @@ class Cartridge3EPlusWidget; @author Thomas Jentzsch and Stephen Anthony */ -class Cartridge3EPlus: public CartridgeEnhanced +class Cartridge3EPlus: public Cartridge3E { friend class Cartridge3EPlusWidget; @@ -110,14 +110,6 @@ class Cartridge3EPlus: public CartridgeEnhanced /** Reset device to its power-on state */ void reset() override; - /** - Install cartridge in the specified system. Invoked by the system - when the cartridge is attached to it. - - @param system The system the device should install itself in - */ - void install(System& system) override; - /** Get a descriptor for the device name (used in error checking). @@ -167,9 +159,6 @@ class Cartridge3EPlus: public CartridgeEnhanced // RAM size static constexpr size_t RAM_SIZE = RAM_BANKS << (BANK_SHIFT - 1); // = 32K = 0x4000; - // Write port for extra RAM is at high address - static constexpr bool RAM_HIGH_WP = true; - private: // Following constructors and assignment operators not supported Cartridge3EPlus() = delete; From fa09f3e583b1b5e7ab18584ae851a4b337d31382 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 24 Apr 2020 11:20:01 +0200 Subject: [PATCH 49/52] refactored CartDPC class replaced DPC ROM --- src/emucore/CartDPC.cxx | 151 +++++++--------------------------------- src/emucore/CartDPC.hxx | 57 +++------------ 2 files changed, 37 insertions(+), 171 deletions(-) diff --git a/src/emucore/CartDPC.cxx b/src/emucore/CartDPC.cxx index c8a038c25..481e385be 100644 --- a/src/emucore/CartDPC.cxx +++ b/src/emucore/CartDPC.cxx @@ -22,45 +22,36 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CartridgeDPC::CartridgeDPC(const ByteBuffer& image, size_t size, const string& md5, const Settings& settings) - : Cartridge(settings, md5), - mySize(size) + : CartridgeF8(image, size, md5, settings) { - // Make a copy of the entire image - std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin()); - createRomAccessArrays(8_KB); - - // Pointer to the program ROM (8K @ 0 byte offset) - myProgramImage = myImage.data(); - - // Pointer to the display ROM (2K @ 8K offset) - myDisplayImage = myProgramImage + 8_KB; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeDPC::reset() { + CartridgeEnhanced::reset(); + myAudioCycles = 0; myFractionalClocks = 0.0; - - // Upon reset we switch to the startup bank - initializeStartBank(1); - bank(startBank()); - myDpcPitch = mySettings.getInt(AudioSettings::SETTING_DPC_PITCH); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeDPC::install(System& system) { - mySystem = &system; + CartridgeEnhanced::install(system); + + myRomOffset = 0x80; + + // Pointer to the display ROM (2K @ 8K offset) + myDisplayImage = myImage.get() + 8_KB; + + createRomAccessArrays(8_KB); // Set the page accessing method for the DPC reading & writing pages System::PageAccess access(this, System::PageAccessType::READWRITE); for(uInt16 addr = 0x1000; addr < 0x1080; addr += System::PAGE_SIZE) mySystem->setPageAccess(addr, access); - - // Install pages for the startup bank - bank(startBank()); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -128,12 +119,15 @@ inline void CartridgeDPC::updateMusicModeDataFetchers() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeDPC::peek(uInt16 address) { + uInt16 peekAddress = address; + 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[myBankOffset + address]; + return myImage[myCurrentSegOffset[0] + address]; + // Clock the random number generator. This should be done for every // cartridge access, however, we're only doing it for the DPC and @@ -232,30 +226,14 @@ uInt8 CartridgeDPC::peek(uInt16 address) return result; } else - { - // Switch banks if necessary - switch(address) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - break; - - case 0x0FF9: - // Set the current bank to the upper 4k bank - bank(1); - break; - - default: - break; - } - return myProgramImage[myBankOffset + address]; - } + return CartridgeEnhanced::peek(peekAddress); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDPC::poke(uInt16 address, uInt8 value) { + uInt16 pokeAddress = address; + address &= 0x0FFF; // Clock the random number generator. This should be done for every @@ -338,102 +316,31 @@ bool CartridgeDPC::poke(uInt16 address, uInt8 value) } } else - { - // Switch banks if necessary - switch(address) - { - case 0x0FF8: - // Set the current bank to the lower 4k bank - bank(0); - break; + CartridgeEnhanced::poke(pokeAddress, value); - case 0x0FF9: - // Set the current bank to the upper 4k bank - bank(1); - break; - - default: - break; - } - } return false; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeDPC::bank(uInt16 bank) -{ - if(bankLocked()) return false; - - // Remember what bank we're in - myBankOffset = bank << 12; - - System::PageAccess access(this, System::PageAccessType::READ); - - // Set the page accessing methods for the hot spots - for(uInt16 addr = (0x1FF8 & ~System::PAGE_MASK); addr < 0x2000; - addr += System::PAGE_SIZE) - { - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - - // Setup the page access methods for the current bank - for(uInt16 addr = 0x1080; addr < static_cast(0x1FF8U & ~System::PAGE_MASK); - addr += System::PAGE_SIZE) - { - access.directPeekBase = &myProgramImage[myBankOffset + (addr & 0x0FFF)]; - access.romAccessBase = &myRomAccessBase[myBankOffset + (addr & 0x0FFF)]; - access.romPeekCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF)]; - access.romPokeCounter = &myRomAccessCounter[myBankOffset + (addr & 0x0FFF) + myAccessSize]; - mySystem->setPageAccess(addr, access); - } - return myBankChanged = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDPC::getBank(uInt16) const -{ - return myBankOffset >> 12; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt16 CartridgeDPC::romBankCount() const -{ - return 2; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDPC::patch(uInt16 address, uInt8 value) { - address &= 0x0FFF; - // For now, we ignore attempts to patch the DPC address space - if(address >= 0x0080) + if((address & ADDR_MASK) >= ROM_OFFSET + myRomOffset) { - myProgramImage[myBankOffset + (address & 0x0FFF)] = value; - return myBankChanged = true; + return CartridgeEnhanced::patch(address, value); } else return false; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt8* CartridgeDPC::getImage(size_t& size) const -{ - size = mySize; - return myImage.data(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDPC::save(Serializer& out) const { + if(!CartridgeEnhanced::save(out)) + return false; + try { - // Indicates which bank is currently active - out.putShort(myBankOffset); - // The top registers for the data fetchers out.putByteArray(myTops.data(), myTops.size()); @@ -468,11 +375,11 @@ bool CartridgeDPC::save(Serializer& out) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool CartridgeDPC::load(Serializer& in) { + if(!CartridgeEnhanced::load(in)) + return false; + try { - // Indicates which bank is currently active - myBankOffset = in.getShort(); - // The top registers for the data fetchers in.getByteArray(myTops.data(), myTops.size()); @@ -501,9 +408,5 @@ bool CartridgeDPC::load(Serializer& in) cerr << "ERROR: CartridgeDPC::load" << endl; return false; } - - // Now, go to the current bank - bank(myBankOffset >> 12); - return true; } diff --git a/src/emucore/CartDPC.hxx b/src/emucore/CartDPC.hxx index 6c186bfdb..e0a1b866e 100644 --- a/src/emucore/CartDPC.hxx +++ b/src/emucore/CartDPC.hxx @@ -18,10 +18,7 @@ #ifndef CARTRIDGE_DPC_HXX #define CARTRIDGE_DPC_HXX -class System; - -#include "bspf.hxx" -#include "Cart.hxx" +#include "CartF8.hxx" #ifdef DEBUGGER_SUPPORT #include "CartDPCWidget.hxx" #endif @@ -35,9 +32,9 @@ class System; For complete details on the DPC chip see David P. Crane's United States Patent Number 4,644,495. - @author Bradford W. Mott + @author Bradford W. Mott, Thomas Jentzsch */ -class CartridgeDPC : public Cartridge +class CartridgeDPC : public CartridgeF8 { friend class CartridgeDPCWidget; @@ -55,11 +52,6 @@ class CartridgeDPC : public Cartridge virtual ~CartridgeDPC() = default; public: - /** - Reset device to its power-on state - */ - void reset() override; - /** Install cartridge in the specified system. Invoked by the system when the cartridge is attached to it. @@ -69,23 +61,9 @@ class CartridgeDPC : public Cartridge void install(System& system) override; /** - Install pages for the specified bank in the system. - - @param bank The bank that should be installed in the system + Reset device to its power-on state */ - bool bank(uInt16 bank) override; - - /** - Get the current bank. - - @param address The address to use when querying the bank - */ - uInt16 getBank(uInt16 address = 0) const override; - - /** - Query the number of banks supported by the cartridge. - */ - uInt16 romBankCount() const override; + void reset() override; /** Patch the cartridge ROM. @@ -96,14 +74,6 @@ class CartridgeDPC : public Cartridge */ bool patch(uInt16 address, uInt8 value) override; - /** - Access the internal ROM image for this cartridge. - - @param size Set to the size of the internal ROM image data - @return A pointer to the internal ROM image data - */ - const uInt8* getImage(size_t& size) const override; - /** Save the current state of this cart to the given Serializer. @@ -127,6 +97,11 @@ class CartridgeDPC : public Cartridge */ string name() const override { return "CartridgeDPC"; } + /** + Change the DPC audio pitch + + @param pitch The new pitch value + */ void setDpcPitch(double pitch) { myDpcPitch = pitch; } #ifdef DEBUGGER_SUPPORT @@ -171,15 +146,6 @@ class CartridgeDPC : public Cartridge void updateMusicModeDataFetchers(); private: - // The ROM image - std::array myImage; - - // (Actual) Size of the ROM image - size_t mySize{0}; - - // Pointer to the 8K program ROM image of the cartridge - uInt8* myProgramImage{nullptr}; - // Pointer to the 2K display ROM image of the cartridge uInt8* myDisplayImage{nullptr}; @@ -207,9 +173,6 @@ class CartridgeDPC : public Cartridge // Fractional DPC music OSC clocks unused during the last update double myFractionalClocks{0.0}; - // Indicates the offset into the ROM image (aligns to current bank) - uInt16 myBankOffset{0}; - // DPC pitch double myDpcPitch{0.0}; From 6ae8d92ebfa9f3daa3afe790b718d738852eddf4 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 24 Apr 2020 12:42:52 +0200 Subject: [PATCH 50/52] replaced "slice" with "bank" in many Cart(Widget) classes minor UI fixed for CartDPCWidget --- src/debugger/gui/CartDPCWidget.cxx | 72 ++++++++++++------------- src/debugger/gui/CartDPCWidget.hxx | 1 + src/debugger/gui/CartDebugWidget.cxx | 2 +- src/debugger/gui/CartDebugWidget.hxx | 3 +- src/debugger/gui/CartE78KWidget.cxx | 27 +++++----- src/debugger/gui/CartE7Widget.cxx | 17 +++--- src/debugger/gui/CartEnhancedWidget.cxx | 8 +-- src/debugger/gui/CartMNetworkWidget.cxx | 26 ++++----- src/debugger/gui/CartRamWidget.cxx | 2 +- src/debugger/gui/DebuggerDialog.cxx | 2 +- src/debugger/gui/RomWidget.cxx | 7 +-- src/emucore/Cart.hxx | 2 +- src/emucore/CartE0.cxx | 2 +- src/emucore/CartE0.hxx | 6 +-- src/emucore/CartEnhanced.cxx | 2 +- src/emucore/CartMNetwork.cxx | 44 +++++++-------- src/emucore/CartMNetwork.hxx | 14 +++-- src/emucore/CartWD.cxx | 2 +- src/emucore/CartWD.hxx | 4 +- 19 files changed, 120 insertions(+), 123 deletions(-) diff --git a/src/debugger/gui/CartDPCWidget.cxx b/src/debugger/gui/CartDPCWidget.cxx index c07ae8739..681b3692d 100644 --- a/src/debugger/gui/CartDPCWidget.cxx +++ b/src/debugger/gui/CartDPCWidget.cxx @@ -27,12 +27,13 @@ CartridgeDPCWidget::CartridgeDPCWidget( : CartDebugWidget(boss, lfont, nfont, x, y, w, h), myCart(cart) { + const int V_GAP = 4; size_t size = cart.mySize; - ostringstream info; + info << "DPC cartridge, two 4K banks + 2K display bank\n" - << "DPC registers accessible @ $F000 - $F07F\n" - << " $F000 - $F03F (R), $F040 - $F07F (W)\n" + << "DPC registers accessible @ $" << Common::Base::HEX4 << 0xF000 << " - $" << 0xF07F << "\n" + << " $" << 0xF000 << " - " << 0xF03F << " (R), $" << 0xF040 << " - $" << 0xF07F << " (W)\n" << "Startup bank = " << cart.startBank() << " or undetermined\n"; @@ -42,7 +43,7 @@ CartridgeDPCWidget::CartridgeDPCWidget( uInt16 start = (cart.myImage[offset+1] << 8) | cart.myImage[offset]; start -= start % 0x1000; info << "Bank " << i << " @ $" << Common::Base::HEX4 << (start + 0x80) << " - " - << "$" << (start + 0xFFF) << " (hotspot = $F" << (spot+i) << ")\n"; + << "$" << (start + 0xFFF) << " (hotspot = $" << (0xF000 + spot + i) << ")\n"; } int xpos = 2, @@ -50,26 +51,30 @@ CartridgeDPCWidget::CartridgeDPCWidget( myLineHeight; VariantList items; - VarList::push_back(items, "0 ($FFF8)"); - VarList::push_back(items, "1 ($FFF9)"); + for(int bank = 0; bank < 2; ++bank) + { + ostringstream buf; + + buf << "#" << std::dec << bank << " ($" << Common::Base::HEX4 << (0xFFF8 + bank) << ")"; + VarList::push_back(items, buf.str()); + } + myBank = - new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($FFFx)"), + new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("#0 ($FFFx)"), myLineHeight, items, "Set bank ", 0, kBankChanged); myBank->setTarget(this); addFocusWidget(myBank); - ypos += myLineHeight + 8; + ypos += myLineHeight + V_GAP * 3; // Data fetchers - int lwidth = _font.getStringWidth("Data Fetchers "); - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Data Fetchers ", TextAlign::Left); + int lwidth = _font.getStringWidth("Data fetchers "); + new StaticTextWidget(boss, _font, xpos, ypos, "Data fetchers "); // Top registers - lwidth = _font.getStringWidth("Counter Registers "); - xpos = 18; ypos += myLineHeight + 4; - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Top Registers ", TextAlign::Left); + lwidth = _font.getStringWidth("Counter registers "); + xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4; + new StaticTextWidget(boss, _font, xpos, ypos, "Top registers "); xpos += lwidth; myTops = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16); @@ -77,9 +82,8 @@ CartridgeDPCWidget::CartridgeDPCWidget( myTops->setEditable(false); // Bottom registers - xpos = 10; ypos += myLineHeight + 4; - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Bottom Registers ", TextAlign::Left); + xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4; + new StaticTextWidget(boss, _font, xpos, ypos, "Bottom registers "); xpos += lwidth; myBottoms = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16); @@ -87,9 +91,8 @@ CartridgeDPCWidget::CartridgeDPCWidget( myBottoms->setEditable(false); // Counter registers - xpos = 10; ypos += myLineHeight + 4; - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Counter Registers ", TextAlign::Left); + xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4; + new StaticTextWidget(boss, _font, xpos, ypos, "Counter registers "); xpos += lwidth; myCounters = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 4, 16, Common::Base::Fmt::_16_4); @@ -97,9 +100,8 @@ CartridgeDPCWidget::CartridgeDPCWidget( myCounters->setEditable(false); // Flag registers - xpos = 10; ypos += myLineHeight + 4; - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Flag Registers ", TextAlign::Left); + xpos = 2 + _font.getMaxCharWidth() * 2; ypos += myLineHeight + 4; + new StaticTextWidget(boss, _font, xpos, ypos, "Flag registers "); xpos += lwidth; myFlags = new DataGridWidget(boss, _nfont, xpos, ypos-2, 8, 1, 2, 8, Common::Base::Fmt::_16); @@ -107,10 +109,9 @@ CartridgeDPCWidget::CartridgeDPCWidget( myFlags->setEditable(false); // Music mode - xpos = 2; ypos += myLineHeight + 12; + xpos = 2; ypos += myLineHeight + V_GAP * 3; lwidth = _font.getStringWidth("Music mode (DF5/DF6/DF7) "); - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Music mode (DF5/DF6/DF7) ", TextAlign::Left); + new StaticTextWidget(boss, _font, xpos, ypos, "Music mode (DF5/DF6/DF7) "); xpos += lwidth; myMusicMode = new DataGridWidget(boss, _nfont, xpos, ypos-2, 3, 1, 2, 8, Common::Base::Fmt::_16); @@ -118,9 +119,8 @@ CartridgeDPCWidget::CartridgeDPCWidget( myMusicMode->setEditable(false); // Current random number - xpos = 10; ypos += myLineHeight + 4; - new StaticTextWidget(boss, _font, xpos, ypos, lwidth, - myFontHeight, "Current random number ", TextAlign::Left); + xpos = 2; ypos += myLineHeight + V_GAP * 3; + new StaticTextWidget(boss, _font, xpos, ypos, "Current random number "); xpos += lwidth; myRandom = new DataGridWidget(boss, _nfont, xpos, ypos-2, 1, 1, 2, 8, Common::Base::Fmt::_16); @@ -229,9 +229,8 @@ string CartridgeDPCWidget::bankState() { ostringstream& buf = buffer(); - static constexpr std::array spot = { "$FFF8", "$FFF9" }; - buf << "Bank = " << std::dec << myCart.getBank() - << ", hotspot = " << spot[myCart.getBank()]; + buf << "Bank #" << std::dec << myCart.getBank() + << " (hotspot $" << Common::Base::HEX4 << (0xFFF8 + myCart.getBank()) << ")"; return buf.str(); } @@ -252,10 +251,9 @@ uInt32 CartridgeDPCWidget::internalRamRPort(int start) string CartridgeDPCWidget::internalRamDescription() { ostringstream desc; - desc << "$0000 - $07FF - 2K display data\n" - << " indirectly accessible to 6507\n" - << " via DPC+'s Data Fetcher\n" - << " registers\n"; + desc << "2K display data @ $0000 - $" << Common::Base::HEX4 << 0x07FF << "\n" + << " indirectly accessible to 6507 via DPC's\n" + << " data fetcher registers\n"; return desc.str(); } diff --git a/src/debugger/gui/CartDPCWidget.hxx b/src/debugger/gui/CartDPCWidget.hxx index ff57ddc1d..0a675a2c8 100644 --- a/src/debugger/gui/CartDPCWidget.hxx +++ b/src/debugger/gui/CartDPCWidget.hxx @@ -75,6 +75,7 @@ class CartridgeDPCWidget : public CartDebugWidget const ByteArray& internalRamCurrent(int start, int count) override; void internalRamSetValue(int addr, uInt8 value) override; uInt8 internalRamGetValue(int addr) override; + string tabLabel() override { return " DPC Display Data "; } // end of functions for Cartridge RAM tab // Following constructors and assignment operators not supported diff --git a/src/debugger/gui/CartDebugWidget.cxx b/src/debugger/gui/CartDebugWidget.cxx index 25423ebd7..5d0bb5c98 100644 --- a/src/debugger/gui/CartDebugWidget.cxx +++ b/src/debugger/gui/CartDebugWidget.cxx @@ -49,7 +49,7 @@ int CartDebugWidget::addBaseInformation(size_t bytes, const string& manufacturer int x = 2, y = 8; // Add ROM size, manufacturer and bankswitch info - new StaticTextWidget(_boss, _font, x, y + 1, "ROM Size "); + new StaticTextWidget(_boss, _font, x, y + 1, "ROM size "); buf << bytes << " bytes"; if(bytes >= 1024) buf << " / " << (bytes/1024) << "KB"; diff --git a/src/debugger/gui/CartDebugWidget.hxx b/src/debugger/gui/CartDebugWidget.hxx index 7789cbb16..7bdcbf472 100644 --- a/src/debugger/gui/CartDebugWidget.hxx +++ b/src/debugger/gui/CartDebugWidget.hxx @@ -58,7 +58,7 @@ class CartDebugWidget : public Widget, public CommandSender virtual string bankState() { return "0 (non-bankswitched)"; } // To make the Cartridge RAM show up in the debugger, implement - // the following 8 functions for cartridges with internal RAM + // the following 9 functions for cartridges with internal RAM virtual uInt32 internalRamSize() { return 0; } virtual uInt32 internalRamRPort(int start) { return 0; } virtual string internalRamDescription() { return EmptyString; } @@ -67,6 +67,7 @@ class CartDebugWidget : public Widget, public CommandSender virtual void internalRamSetValue(int addr, uInt8 value) { } virtual uInt8 internalRamGetValue(int addr) { return 0; } virtual string internalRamLabel(int addr) { return "Not available/applicable"; } + virtual string tabLabel() { return " Cartridge RAM "; } protected: // Arrays used to hold current and previous internal RAM values diff --git a/src/debugger/gui/CartE78KWidget.cxx b/src/debugger/gui/CartE78KWidget.cxx index b14d24809..2ad1c012e 100644 --- a/src/debugger/gui/CartE78KWidget.cxx +++ b/src/debugger/gui/CartE78KWidget.cxx @@ -27,17 +27,18 @@ CartridgeE78KWidget::CartridgeE78KWidget( : CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart) { ostringstream info; - info << "E78K cartridge, 4 2K slices ROM + 2 1K RAM\n" - << "Lower 2K accessible @ $F000 - $F7FF\n" - << " Slice 0 - 2 of ROM (hotspots $FE4 to $FE6)\n" - << " Slice 7 (1K) of RAM (hotspot $FE7)\n" - << " $F400 - $F7FF (R), $F000 - $F3FF (W)\n" - << "256B RAM accessible @ $F800 - $F9FF\n" - << " Hotspots $FE8 - $FEB (256B of RAM slice 1)\n" - << " $F900 - $F9FF (R), $F800 - $F8FF (W)\n" - << "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n" - << " Always points to last 1.5K of ROM\n" - << "Startup slices = 0 / 0 or undetermined\n"; + info << "E78K cartridge, four 2K banks ROM + 2K RAM,\n" + << " mapped into three segments\n" + << "Lower 2K accessible @ $F000 - $F7FF\n" + << " ROM banks 0 - 2 (hotspots $FFE4 to $FFE6)\n" + << " 1K RAM bank 3 (hotspot $FFE7)\n" + << " $F400 - $F7FF (R), $F000 - $F3FF (W)\n" + << "256B RAM accessible @ $F800 - $F9FF\n" + << " RAM banks 0 - 3 (hotspots $FFE8 - $FFEB)\n" + << " $F900 - $F9FF (R), $F800 - $F8FF (W)\n" + << "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n" + << " Always points to last 1.5K of ROM\n" + << "Startup segments = 0 / 0 or undetermined\n"; #if 0 // Eventually, we should query this from the debugger/disassembler @@ -53,7 +54,7 @@ CartridgeE78KWidget::CartridgeE78KWidget( const char* CartridgeE78KWidget::getSpotLower(int idx) { static constexpr std::array spot_lower = { - "0 - ROM ($FFE4)", "1 - ROM ($FFE5)", "2 - ROM ($FFE6)", "3 - RAM ($FFE7)" + "#0 - ROM ($FFE4)", "#1 - ROM ($FFE5)", "#2 - ROM ($FFE6)", "#3 - RAM ($FFE7)" }; return spot_lower[idx]; @@ -63,7 +64,7 @@ const char* CartridgeE78KWidget::getSpotLower(int idx) const char* CartridgeE78KWidget::getSpotUpper(int idx) { static constexpr std::array spot_upper = { - "0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)" + "#0 - RAM ($FFE8)", "#1 - RAM ($FFE9)", "#2 - RAM ($FFEA)", "#3 - RAM ($FFEB)" }; return spot_upper[idx]; diff --git a/src/debugger/gui/CartE7Widget.cxx b/src/debugger/gui/CartE7Widget.cxx index f4a5ea3dd..8546e84eb 100644 --- a/src/debugger/gui/CartE7Widget.cxx +++ b/src/debugger/gui/CartE7Widget.cxx @@ -26,17 +26,18 @@ CartridgeE7Widget::CartridgeE7Widget( : CartridgeMNetworkWidget(boss, lfont, nfont, x, y, w, h, cart) { ostringstream info; - info << "E7 cartridge, 8 2K slices ROM + 2 1K RAM\n" + info << "E7 cartridge, eight 2K banks ROM + 2K RAM,\n" + << " mapped into three segments\n" << "Lower 2K accessible @ $F000 - $F7FF\n" - << " Slice 0 - 6 of ROM (hotspots $FE0 to $FE6)\n" - << " Slice 7 (1K) of RAM (hotspot $FE7)\n" + << " ROM Banks 0 - 6 (hotspots $FFE0 to $FFE6)\n" + << " 1K RAM Bank 7 (hotspot $FFE7)\n" << " $F400 - $F7FF (R), $F000 - $F3FF (W)\n" << "256B RAM accessible @ $F800 - $F9FF\n" - << " Hotspots $FE8 - $FEB (256B of RAM slice 1)\n" + << " RAM banks 0 - 3 (hotspots $FFE8 - $FFEB)\n" << " $F900 - $F9FF (R), $F800 - $F8FF (W)\n" << "Upper 1.5K ROM accessible @ $FA00 - $FFFF\n" << " Always points to last 1.5K of ROM\n" - << "Startup slices = 0 / 0 or undetermined\n"; + << "Startup segments = 0 / 0 or undetermined\n"; #if 0 // Eventually, we should query this from the debugger/disassembler @@ -52,8 +53,8 @@ CartridgeE7Widget::CartridgeE7Widget( const char* CartridgeE7Widget::getSpotLower(int idx) { static constexpr std::array spot_lower = { - "0 - ROM ($FFE0)", "1 - ROM ($FFE1)", "2 - ROM ($FFE2)", "3 - ROM ($FFE3)", - "4 - ROM ($FFE4)", "5 - ROM ($FFE5)", "6 - ROM ($FFE6)", "7 - RAM ($FFE7)" + "#0 - ROM ($FFE0)", "#1 - ROM ($FFE1)", "#2 - ROM ($FFE2)", "#3 - ROM ($FFE3)", + "#4 - ROM ($FFE4)", "#5 - ROM ($FFE5)", "#6 - ROM ($FFE6)", "#7 - RAM ($FFE7)" }; return spot_lower[idx]; @@ -63,7 +64,7 @@ const char* CartridgeE7Widget::getSpotLower(int idx) const char* CartridgeE7Widget::getSpotUpper(int idx) { static constexpr std::array spot_upper = { - "0 - RAM ($FFE8)", "1 - RAM ($FFE9)", "2 - RAM ($FFEA)", "3 - RAM ($FFEB)" + "#0 - RAM ($FFE8)", "#1 - RAM ($FFE9)", "#2 - RAM ($FFEA)", "#3 - RAM ($FFEB)" }; return spot_upper[idx]; diff --git a/src/debugger/gui/CartEnhancedWidget.cxx b/src/debugger/gui/CartEnhancedWidget.cxx index 8001c1292..f864a21c0 100644 --- a/src/debugger/gui/CartEnhancedWidget.cxx +++ b/src/debugger/gui/CartEnhancedWidget.cxx @@ -233,7 +233,7 @@ string CartridgeEnhancedWidget::bankState() } return buf.str(); } - return "0 (non-bankswitched)"; + return "non-bankswitched"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -339,18 +339,18 @@ string CartridgeEnhancedWidget::internalRamDescription() { desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) - << " used for read Access\n"; + << " used for read access\n"; } desc << indent << "$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myWriteOffset) << " - $" << (ADDR_BASE | (myCart.myWriteOffset + myCart.myRamMask)) - << " used for write Access"; + << " used for write access"; if(myCart.myReadOffset > myCart.myWriteOffset) { desc << indent << "\n$" << Common::Base::HEX4 << (ADDR_BASE | myCart.myReadOffset) << " - $" << (ADDR_BASE | (myCart.myReadOffset + myCart.myRamMask)) - << " used for read Access"; + << " used for read access"; } return desc.str(); diff --git a/src/debugger/gui/CartMNetworkWidget.cxx b/src/debugger/gui/CartMNetworkWidget.cxx index 37d382a7e..e9cc68869 100644 --- a/src/debugger/gui/CartMNetworkWidget.cxx +++ b/src/debugger/gui/CartMNetworkWidget.cxx @@ -47,18 +47,18 @@ void CartridgeMNetworkWidget::initialize(GuiObject* boss, CartridgeMNetwork& car for(int i = 0; i < 4; ++i) VarList::push_back(items1, getSpotUpper(i)); - const int lwidth = _font.getStringWidth("Set slice for upper 256B "), - fwidth = _font.getStringWidth("3 - RAM ($FFEB)"); + const int lwidth = _font.getStringWidth("Set bank for upper 256B segment "), + fwidth = _font.getStringWidth("#3 - RAM ($FFEB)"); myLower2K = new PopUpWidget(boss, _font, xpos, ypos - 2, fwidth, myLineHeight, items0, - "Set slice for lower 2K ", lwidth, kLowerChanged); + "Set bank for lower 2K segment", lwidth, kLowerChanged); myLower2K->setTarget(this); addFocusWidget(myLower2K); ypos += myLower2K->getHeight() + 4; myUpper256B = new PopUpWidget(boss, _font, xpos, ypos - 2, fwidth, myLineHeight, items1, - "Set slice for upper 256B ", lwidth, kUpperChanged); + "Set bank for upper 256B segment ", lwidth, kUpperChanged); myUpper256B->setTarget(this); addFocusWidget(myUpper256B); } @@ -71,14 +71,14 @@ void CartridgeMNetworkWidget::saveOldState() for(uInt32 i = 0; i < internalRamSize(); ++i) myOldState.internalram.push_back(myCart.myRAM[i]); - myOldState.lowerBank = myCart.myCurrentSlice[0]; + myOldState.lowerBank = myCart.myCurrentBank[0]; myOldState.upperBank = myCart.myCurrentRAM; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeMNetworkWidget::loadConfig() { - myLower2K->setSelectedIndex(myCart.myCurrentSlice[0], myCart.myCurrentSlice[0] != myOldState.lowerBank); + myLower2K->setSelectedIndex(myCart.myCurrentBank[0], myCart.myCurrentBank[0] != myOldState.lowerBank); myUpper256B->setSelectedIndex(myCart.myCurrentRAM, myCart.myCurrentRAM != myOldState.upperBank); CartDebugWidget::loadConfig(); @@ -111,8 +111,8 @@ string CartridgeMNetworkWidget::bankState() { ostringstream& buf = buffer(); - buf << "Slices: " << std::dec - << getSpotLower(myCart.myCurrentSlice[0]) << " / " + buf << "Segments: " << std::dec + << getSpotLower(myCart.myCurrentBank[0]) << " / " << getSpotUpper(myCart.myCurrentRAM); return buf.str(); @@ -135,11 +135,11 @@ string CartridgeMNetworkWidget::internalRamDescription() { ostringstream desc; desc << "First 1K accessible via:\n" - << " $F000 - $F3FF used for Write Access\n" - << " $F400 - $F7FF used for Read Access\n" - << "256K of second 1K accessible via:\n" - << " $F800 - $F8FF used for Write Access\n" - << " $F900 - $F9FF used for Read Access"; + << " $F000 - $F3FF used for write access\n" + << " $F400 - $F7FF used for read access\n" + << "256 bytes of second 1K accessible via:\n" + << " $F800 - $F8FF used for write access\n" + << " $F900 - $F9FF used for read access"; return desc.str(); } diff --git a/src/debugger/gui/CartRamWidget.cxx b/src/debugger/gui/CartRamWidget.cxx index cfed3d3e5..10bfb5c23 100644 --- a/src/debugger/gui/CartRamWidget.cxx +++ b/src/debugger/gui/CartRamWidget.cxx @@ -47,7 +47,7 @@ CartRamWidget::CartRamWidget( int xpos = 2, ypos = 8; // Add RAM size - new StaticTextWidget(_boss, _font, xpos, ypos + 1, "RAM Size "); + new StaticTextWidget(_boss, _font, xpos, ypos + 1, "RAM size "); uInt32 ramsize = cartDebug.internalRamSize(); buf << ramsize << " bytes"; diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index 3143dbc10..ed98fa879 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -640,7 +640,7 @@ void DebuggerDialog::addRomArea() // The cartridge RAM tab if (myCartDebug->internalRamSize() > 0) { - tabID = myRomTab->addTab(" Cartridge RAM ", TabWidget::AUTO_WIDTH); + tabID = myRomTab->addTab(myCartDebug->tabLabel(), TabWidget::AUTO_WIDTH); myCartRam = new CartRamWidget(myRomTab, *myLFont, *myNFont, 2, 2, tabWidth - 1, tabHeight - myRomTab->getTabHeight() - 2, *myCartDebug); diff --git a/src/debugger/gui/RomWidget.cxx b/src/debugger/gui/RomWidget.cxx index e62fe0a17..3279ca5d9 100644 --- a/src/debugger/gui/RomWidget.cxx +++ b/src/debugger/gui/RomWidget.cxx @@ -41,12 +41,9 @@ RomWidget::RomWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n // Show current bank state xpos = x; ypos = y + 7; - t = new StaticTextWidget(boss, lfont, xpos, ypos, - lfont.getStringWidth("Bank"), - lfont.getFontHeight(), - "Bank", TextAlign::Left); + t = new StaticTextWidget(boss, lfont, xpos, ypos, "Info "); - xpos += t->getWidth() + 5; + xpos += t->getRight(); myBank = new EditTextWidget(boss, nfont, xpos, ypos-2, _w - 2 - xpos, nfont.getLineHeight()); myBank->setEditable(false); diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index a7488f551..6fbf1a68d 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -189,7 +189,7 @@ class Cartridge : public Device cases where ROMs have 2K blocks in some preset area, the bankCount is the number of such blocks. Finally, in some esoteric schemes, the number of ways that the addressing can change (multiple ROM and - RAM slices at multiple access points) is so complicated that the + RAM segments at multiple access points) is so complicated that the cart will report having only one 'virtual' bank. */ virtual uInt16 romBankCount() const { return 1; } diff --git a/src/emucore/CartE0.cxx b/src/emucore/CartE0.cxx index d9c37d7e4..07afae5a2 100644 --- a/src/emucore/CartE0.cxx +++ b/src/emucore/CartE0.cxx @@ -29,7 +29,7 @@ CartridgeE0::CartridgeE0(const ByteBuffer& image, size_t size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeE0::reset() { - // Setup segments to some default slices + // Setup segments to some default banks if(randomStartBank()) { bank(mySystem->randGenerator().next() % 8, 0); diff --git a/src/emucore/CartE0.hxx b/src/emucore/CartE0.hxx index 7c1fe18e3..84c9ae667 100644 --- a/src/emucore/CartE0.hxx +++ b/src/emucore/CartE0.hxx @@ -29,10 +29,10 @@ class System; /** This is the cartridge class for Parker Brothers' 8K games. In this bankswitching scheme the 2600's 4K cartridge address space - is broken into four 1K segments. The desired 1K slice of the + is broken into four 1K segments. The desired 1K bank of the ROM is selected by accessing $1FE0 to $1FE7 for the first 1K. - $1FE8 to $1FEF selects the slice for the second 1K, and $1FF0 to - $1FF7 selects the slice for the third 1K. The last 1K segment + $1FE8 to $1FEF selects the bank for the second 1K, and $1FF0 to + $1FF7 selects the bank for the third 1K. The last 1K segment always points to the last 1K of the ROM image. Because of the complexity of this scheme, the cart reports having diff --git a/src/emucore/CartEnhanced.cxx b/src/emucore/CartEnhanced.cxx index 0bb6f54fb..d5ccf6591 100644 --- a/src/emucore/CartEnhanced.cxx +++ b/src/emucore/CartEnhanced.cxx @@ -48,7 +48,7 @@ void CartridgeEnhanced::install(System& system) createRomAccessArrays(mySize + (myRomOffset > 0 ? 0 : myRamSize)); - // Allocate array for the current bank segments slices + // Allocate array for the segment's current bank offset myCurrentSegOffset = make_unique(myBankSegs); // Allocate array for the RAM area diff --git a/src/emucore/CartMNetwork.cxx b/src/emucore/CartMNetwork.cxx index 984769b17..c6542b2b8 100644 --- a/src/emucore/CartMNetwork.cxx +++ b/src/emucore/CartMNetwork.cxx @@ -36,7 +36,7 @@ void CartridgeMNetwork::initialize(const ByteBuffer& image, size_t size) std::copy_n(image.get(), std::min(romSize(), size), myImage.get()); createRomAccessArrays(romSize() + myRAM.size()); - myRAMSlice = romBankCount() - 1; + myRAMBank = romBankCount() - 1; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -96,10 +96,10 @@ void CartridgeMNetwork::install(System& system) /*setAccess(0x1FE0 & ~System::PAGE_MASK, System::PAGE_SIZE, 0, nullptr, 0x1fc0, System::PA_NONE, 0x1fc0);*/ - // Setup the second segment to always point to the last ROM slice + // Setup the second segment to always point to the last ROM bank setAccess(0x1A00, 0x1FE0U & (~System::PAGE_MASK - 0x1A00), - myRAMSlice * BANK_SIZE, myImage.get(), myRAMSlice * BANK_SIZE, System::PageAccessType::READ, BANK_SIZE - 1); - myCurrentSlice[1] = myRAMSlice; + myRAMBank * BANK_SIZE, myImage.get(), myRAMBank * BANK_SIZE, System::PageAccessType::READ, BANK_SIZE - 1); + myCurrentBank[1] = myRAMBank; // Install some default banks for the RAM and first segment bankRAM(0); @@ -115,7 +115,7 @@ uInt8 CartridgeMNetwork::peek(uInt16 address) // Switch banks if necessary checkSwitchBank(address); - if((myCurrentSlice[0] == myRAMSlice) && (address < BANK_SIZE / 2)) + if((myCurrentBank[0] == myRAMBank) && (address < BANK_SIZE / 2)) { // Reading from the 1K write port @ $1000 triggers an unwanted write return peekRAM(myRAM[address & (BANK_SIZE / 2 - 1)], peekAddress); @@ -126,7 +126,7 @@ uInt8 CartridgeMNetwork::peek(uInt16 address) return peekRAM(myRAM[0x0400 + (myCurrentRAM << 8) + (address & 0x00FF)], peekAddress); } else - return myImage[(myCurrentSlice[address >> 11] << 11) + (address & (BANK_SIZE - 1))]; + return myImage[(myCurrentBank[address >> 11] << 11) + (address & (BANK_SIZE - 1))]; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -139,9 +139,9 @@ bool CartridgeMNetwork::poke(uInt16 address, uInt8 value) checkSwitchBank(address); // All RAM writes are mapped here - if((myCurrentSlice[0] == myRAMSlice) && (address < BANK_SIZE / 2)) + if((myCurrentBank[0] == myRAMBank) && (address < BANK_SIZE / 2)) { - // RAM slices + // RAM banks if(!(address & 0x0400)) { pokeRAM(myRAM[address & (BANK_SIZE / 2 - 1)], pokeAddress, value); @@ -189,7 +189,7 @@ void CartridgeMNetwork::bankRAM(uInt16 bank) // Remember what bank we're in myCurrentRAM = bank; - uInt16 offset = bank << 8; // * RAM_SLICE_SIZE (256) + uInt16 offset = bank << 8; // * RAM_BANK_SIZE (256) // Setup the page access methods for the current bank // Set the page accessing method for the 256 bytes of RAM reading pages @@ -201,26 +201,26 @@ void CartridgeMNetwork::bankRAM(uInt16 bank) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool CartridgeMNetwork::bank(uInt16 slice) +bool CartridgeMNetwork::bank(uInt16 bank) { if(bankLocked()) return false; // Remember what bank we're in - myCurrentSlice[0] = slice; + myCurrentBank[0] = bank; // Setup the page access methods for the current bank - if(slice != myRAMSlice) + if(bank != myRAMBank) { - uInt16 offset = slice << 11; // * BANK_SIZE (2048) + uInt16 offset = bank << 11; // * BANK_SIZE (2048) // Map ROM image into first segment setAccess(0x1000, BANK_SIZE, offset, myImage.get(), offset, System::PageAccessType::READ); } else { - // Set the page accessing method for the 1K slice of RAM writing pages + // Set the page accessing method for the 1K bank of RAM writing pages setAccess(0x1000, BANK_SIZE / 2, 0, myRAM.data(), romSize(), System::PageAccessType::WRITE); - // Set the page accessing method for the 1K slice of RAM reading pages + // Set the page accessing method for the 1K bank of RAM reading pages setAccess(0x1000 + BANK_SIZE / 2, BANK_SIZE / 2, 0, myRAM.data(), romSize(), System::PageAccessType::READ); } return myBankChanged = true; @@ -229,7 +229,7 @@ bool CartridgeMNetwork::bank(uInt16 slice) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt16 CartridgeMNetwork::getBank(uInt16 address) const { - return myCurrentSlice[(address & 0xFFF) >> 11]; // 2K slices + return myCurrentBank[(address & 0xFFF) >> 11]; // 2K segments } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -239,7 +239,7 @@ bool CartridgeMNetwork::patch(uInt16 address, uInt8 value) if(address < 0x0800) { - if(myCurrentSlice[0] == myRAMSlice) + if(myCurrentBank[0] == myRAMBank) { // Normally, a write to the read port won't do anything // However, the patch command is special in that ignores such @@ -247,7 +247,7 @@ bool CartridgeMNetwork::patch(uInt16 address, uInt8 value) myRAM[address & 0x03FF] = value; } else - myImage[(myCurrentSlice[0] << 11) + (address & (BANK_SIZE-1))] = value; + myImage[(myCurrentBank[0] << 11) + (address & (BANK_SIZE-1))] = value; } else if(address < 0x0900) { @@ -257,7 +257,7 @@ bool CartridgeMNetwork::patch(uInt16 address, uInt8 value) myRAM[0x0400 + (myCurrentRAM << 8) + (address & 0x00FF)] = value; } else - myImage[(myCurrentSlice[address >> 11] << 11) + (address & (BANK_SIZE-1))] = value; + myImage[(myCurrentBank[address >> 11] << 11) + (address & (BANK_SIZE-1))] = value; return myBankChanged = true; } @@ -274,7 +274,7 @@ bool CartridgeMNetwork::save(Serializer& out) const { try { - out.putShortArray(myCurrentSlice.data(), myCurrentSlice.size()); + out.putShortArray(myCurrentBank.data(), myCurrentBank.size()); out.putShort(myCurrentRAM); out.putByteArray(myRAM.data(), myRAM.size()); } @@ -292,7 +292,7 @@ bool CartridgeMNetwork::load(Serializer& in) { try { - in.getShortArray(myCurrentSlice.data(), myCurrentSlice.size()); + in.getShortArray(myCurrentBank.data(), myCurrentBank.size()); myCurrentRAM = in.getShort(); in.getByteArray(myRAM.data(), myRAM.size()); } @@ -304,7 +304,7 @@ bool CartridgeMNetwork::load(Serializer& in) // Set up the previously used banks for the RAM and segment bankRAM(myCurrentRAM); - bank(myCurrentSlice[0]); + bank(myCurrentBank[0]); return true; } diff --git a/src/emucore/CartMNetwork.hxx b/src/emucore/CartMNetwork.hxx index dd9443390..95cd24b56 100644 --- a/src/emucore/CartMNetwork.hxx +++ b/src/emucore/CartMNetwork.hxx @@ -51,7 +51,7 @@ here by accessing 1FE8 to 1FEB. This cart reports having 8 banks; 1 for each of the possible 7 - slices in the lower 2K area, and the last for RAM in the lower + bank in the lower 2K area, and the last for RAM in the lower 2K area." There are 8K, 12K and 16K variations, with or without RAM. @@ -179,7 +179,7 @@ class CartridgeMNetwork : public Cartridge private: // Size of RAM in the cart static constexpr uInt32 RAM_SIZE = 0x800; // 1K + 4 * 256B = 2K - // Number of slices with 4K address space + // Number of segment within the 4K address space static constexpr uInt32 NUM_SEGMENTS = 2; /** @@ -198,8 +198,6 @@ class CartridgeMNetwork : public Cartridge private: // Pointer to a dynamically allocated ROM image of the cartridge ByteBuffer myImage; - // The 16K ROM image of the cartridge (works for E78K too) - //uInt8 myImage[BANK_SIZE * 8]; // Size of the ROM image size_t mySize{0}; @@ -207,14 +205,14 @@ class CartridgeMNetwork : public Cartridge // The 2K of RAM std::array myRAM; - // Indicates which slice is in the segment - std::array myCurrentSlice; + // Indicates which bank is in the segment + std::array myCurrentBank; // Indicates which 256 byte bank of RAM is being used uInt16 myCurrentRAM{0}; - // The number of the RAM slice (== bankCount() - 1) - uInt32 myRAMSlice{0}; + // The number of the RAM bank (== bankCount() - 1) + uInt32 myRAMBank{0}; private: // Following constructors and assignment operators not supported diff --git a/src/emucore/CartWD.cxx b/src/emucore/CartWD.cxx index ff72a2b38..11ebc653e 100644 --- a/src/emucore/CartWD.cxx +++ b/src/emucore/CartWD.cxx @@ -28,7 +28,7 @@ CartridgeWD::CartridgeWD(const ByteBuffer& image, size_t size, // Copy the ROM image into my buffer if (mySize == 8_KB + 3) { - // swap slices 2 & 3 of bad dump and correct size + // swap banks 2 & 3 of bad dump and correct size std::copy_n(image.get() + 1_KB * 3, 1_KB * 1, myImage.get() + 1_KB * 2); std::copy_n(image.get() + 1_KB * 2, 1_KB * 1, myImage.get() + 1_KB * 3); mySize = 8_KB; diff --git a/src/emucore/CartWD.hxx b/src/emucore/CartWD.hxx index 6feb6be63..398571a52 100644 --- a/src/emucore/CartWD.hxx +++ b/src/emucore/CartWD.hxx @@ -30,8 +30,8 @@ class System; This is the cartridge class for a "Wickstead Design" prototype cart. The ROM has 64 bytes of RAM. In this bankswitching scheme the 2600's 4K cartridge address space - is broken into four 1K segments. The desired arrangement of 1K slices - is selected by accessing $30 - $3F of TIA address space. The slices + is broken into four 1K segments. The desired arrangement of 1K banks + is selected by accessing $30 - $3F of TIA address space. The banks are mapped into all 4 segments at once as follows: $0030, $0038: 0,0,1,3 From 07dcdc83b0ae271c67f9923d158fec51245a2739 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 30 Apr 2020 23:45:14 +0200 Subject: [PATCH 51/52] fix disassembly for segmented bankswitching types --- src/debugger/CartDebug.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index ef6924187..5192f84e8 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -71,18 +71,19 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem) } // Create bank information for each potential bank, and an extra one for ZP RAM + // ROM sizes greater than 4096 indicate multi-bank ROMs, but we handle only + // 4K pieces at a time + // ROM sizes less than 4K use the actual value + size_t romSize = 0; + myConsole.cartridge().getImage(romSize); + BankInfo info; + info.size = std::min(romSize, 4_KB); for(uInt32 i = 0; i < myConsole.cartridge().romBankCount(); ++i) - { - info.size = myConsole.cartridge().bankSize(i); myBankInfo.push_back(info); - } for(uInt32 i = 0; i < myConsole.cartridge().ramBankCount(); ++i) - { - info.size = myConsole.cartridge().bankSize(i) >> 1; myBankInfo.push_back(info); - } info.size = 128; // ZP RAM myBankInfo.push_back(info); From f2caf9509c2256aa2dd19e0caefe6e5e346bf74b Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 2 May 2020 09:20:22 +0200 Subject: [PATCH 52/52] added some more MDM test ROMs and their properties --- src/emucore/DefProps.hxx | 5 ++++- src/emucore/stella.pro | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/emucore/DefProps.hxx b/src/emucore/DefProps.hxx index d5bb3533e..354f68d30 100644 --- a/src/emucore/DefProps.hxx +++ b/src/emucore/DefProps.hxx @@ -25,7 +25,7 @@ regenerated and the application recompiled. */ -static constexpr uInt32 DEF_PROPS_SIZE = 3510; +static constexpr uInt32 DEF_PROPS_SIZE = 3513; static const BSPF::array2D DefProps = {{ { "000509d1ed2b8d30a9d94be1b3b5febb", "Greg Zumwalt", "", "Jungle Jane (2003) (Greg Zumwalt) (Hack)", "Hack of Pitfall!", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -1032,6 +1032,7 @@ static const BSPF::array2D DefProps = {{ { "4904a2550759b9b4570e886374f9d092", "Parker Brothers, Charlie Heath", "931506", "Reactor (1983) (Parker Bros) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "YES", "" }, { "490e3cc59d82f85fae817cdf767ea7a0", "", "", "Berzerk (Unknown) (PAL) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "490eed07d4691b27f473953fbea6541a", "Activision, Steve Cartwright, David Crane", "AB-035-04", "Pitfall II (1983) (Activision) [a]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "49366f41aa7a54baf263426e99ce4312", "", "", "POP-MDM-Test (PAL) (63 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "493daaf9fb1ba450eba6b8ed53ffb37d", "", "", "3-D Corridor Demo (27-03-2003) (MP)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "493de059b32f84ab29cde6213964aeee", "Atari, Bill Aspromonte, Andrew Fuchs", "CX26120", "Stargate (1984) (Atari) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "493e90602a4434b117c91c95e73828d1", "Telegames", "", "Lock 'n' Chase (1988) (Telegames) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -1366,6 +1367,7 @@ static const BSPF::array2D DefProps = {{ { "61719a8bdafbd8dab3ca9ce7b171b9e2", "", "", "Enduro (Unknown) (PAL)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "61728c6cfb052e62a9ed088c5bf407ba", "", "", "Sprite Demo 4 (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "619de46281eb2e0adbb98255732483b4", "", "", "Time Warp (Unknown)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "61baadddc2c8f6e5faa57d4d0f285462", "", "", "208-in-1 MDM-Test (PAL) (127 games)", "", "", "", "", "MDM", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "61dbe94f110f30ca4ec524ae5ce2d026", "CCE", "C-820", "Space Invaders (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "61e0f5e1cc207e98704d0758c68df317", "Star Game", "007", "Tennis (Star Game)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "61ef8c2fc43be9a04fe13fdb79ff2bd9", "", "", "Gas Gauge Demo - Revisited (2001) (Joe Grand) (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, @@ -2326,6 +2328,7 @@ static const BSPF::array2D DefProps = {{ { "a89a3e0547d6887279c34aba4b17a560", "M Network, Steve Crandall, Patricia Lewis Du Long", "MT4646", "Rocky & Bullwinkle (1983) (Mattel) (Prototype)", "", "Prototype", "", "", "4K", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "a8a703e073183a89c94d4d99b9661b7f", "Franklin Cruz", "", "Spice Invaders (Franklin Cruz) (Hack)", "Hack of Space Invaders", "Hack", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "a8b3ea6836b99bea77c8f603cf1ea187", "CCE", "C-861", "Boxing (1983) (CCE)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, + { "a8c447efbec3a2b5d08b05a09999bd92", "", "", "MegaCart Menu", "", "", "", "", "", "", "", "", "", "JOYSTICK", "JOYSTICK", "", "", "", "", "", "", "", "" }, { "a8c48b4e0bf35fe97cc84fdd2c507f78", "Puzzy - Bit Corporation", "PG201", "Seamonster (1982) (Puzzy)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "a8d0a4a77cd71ac601bd71df5a060e4c", "", "", "Space Shuttle (1983) (Activision) [t2] (Fuel)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, { "a8d4a9500b18b0a067a1f272f869e094", "", "", "Red And White Checkerboard Demo (PD)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, diff --git a/src/emucore/stella.pro b/src/emucore/stella.pro index 4a8ba020e..ef12c4369 100644 --- a/src/emucore/stella.pro +++ b/src/emucore/stella.pro @@ -6131,6 +6131,13 @@ "Cart.Name" "Pitfall II (1983) (Activision) [a]" "" +"Cart.MD5" "49366f41aa7a54baf263426e99ce4312" +"Cart.Name" "POP-MDM-Test (PAL) (63 games)" +"Cart.Type" "MDM" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "493daaf9fb1ba450eba6b8ed53ffb37d" "Cart.Name" "3-D Corridor Demo (27-03-2003) (MP)" "" @@ -8158,6 +8165,13 @@ "Cart.Name" "Time Warp (Unknown)" "" +"Cart.MD5" "61baadddc2c8f6e5faa57d4d0f285462" +"Cart.Name" "208-in-1 MDM-Test (PAL) (127 games)" +"Cart.Type" "MDM" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "61dbe94f110f30ca4ec524ae5ce2d026" "Cart.Manufacturer" "CCE" "Cart.ModelNo" "C-820" @@ -13974,6 +13988,12 @@ "Cart.Name" "Boxing (1983) (CCE)" "" +"Cart.MD5" "a8c447efbec3a2b5d08b05a09999bd92" +"Cart.Name" "MegaCart Menu" +"Controller.Left" "JOYSTICK" +"Controller.Right" "JOYSTICK" +"" + "Cart.MD5" "a8c48b4e0bf35fe97cc84fdd2c507f78" "Cart.Manufacturer" "Puzzy - Bit Corporation" "Cart.ModelNo" "PG201"
Cartridge.Name:
128IN1 ¹256/512K Multicart .128, .128N1
2K 32-2048 byte Atari .2K
3E 32K Tigervision .3E
3E+ 3E+ (TJ modified DASH) .3EP, .3E+
3E+ 3E+ (TJ modified 3E) .3EP, .3E+
3F 512K Tigervision .3F
4A50 ²64K 4A50 + RAM .4A5, .4A50
4K 4K Atari .4K
CM ¹Spectravideo CompuMate .CM
CTY ²CDW - Chetiry .CTY
CV CommaVid extra RAM .CV
DASH Boulder Dash 2 .DAS, .DASH
DF CPUWIZ 128K .DF
DFSC CPUWIZ 128K + RAM.DFS, .DFSC
DPC Pitfall II .DPC
Control + i
Toggle 'Turbo' modeControl + tControl + t
Toggle sound on/off Control + ]Control the emulation speed (as a percentage, 10 - 1000).
-turbo <1|0>
Enable 'Turbo' mode for maximum emulation speed.
-uimessages <1|0>
Enable or disable display of message in the UI. Note that messages @@ -2063,29 +2074,29 @@ Set the pitch o f Pitfall II music.
-tia.zoom <zoom>
Use the specified zoom level (integer) while in TIA/emulation mode. -
-tia.zoom <zoom>
Use the specified zoom level (integer) while in TIA/emulation mode. +
-tia.vsizeadjust <-5 - 5>
Adjust the display height of the TIA image -
-tia.vsizeadjust <-5 - 5>
Adjust the display height of the TIA image +
-tia.inter <1|0>
Use interpolation for the TIA image (results in blending/smoothing - of the image).
-tia.inter <1|0>
Use interpolation for the TIA image (results in blending/smoothing + of the image).
-tia.fs_stretch <1|0>
Stretch TIA image completely while in fullscreen mode, vs. keeping the correct - aspect ratio.
-tia.fs_stretch <1|0>
Stretch TIA image completely while in fullscreen mode, vs. keeping the correct + aspect ratio.
-tia.fs_overscan <0 - 10>
32IN1 ¹64-128K Multicart (32 games) .32N, .32N1
64IN1 ¹64/128K Multicart .64N, .64N1
128IN1 ¹256/512K Multicart .128, .128N1
2K 32-2048 byte Atari .2K
3E 32K Tigervision .3E
2K 32-2048 bytes Atari .2K
3E 512K Tigervision + 32K RAM.3E
3EX 512K Tigervision + 256K RAM.3EX
3E+ 3E+ (TJ modified 3E) .3EP, .3E+
3F 512K Tigervision .3F
4A50 ²64K 4A50 + RAM .4A5, .4A50
FC Amiga Power Play Aracde 16/32K .FC
FE 8K Decathlon .FE
MDM Menu Driven Megacart .MDM
SB 128-256k SUPERbanking .SB
SB 128-256K SUPERbanking .SB
UA 8K UA Ltd. .UA
UASW 8K UA Ltd. (swapped banks).UASW
WD Wickstead Design (Pink Panther) .WD