mirror of https://github.com/stella-emu/stella.git
Sync timing, limit the amount of queued transactions.
This commit is contained in:
parent
4bcc8056b9
commit
ba75f72826
|
@ -25,6 +25,7 @@
|
||||||
#include "ElfParser.hxx"
|
#include "ElfParser.hxx"
|
||||||
#include "ElfLinker.hxx"
|
#include "ElfLinker.hxx"
|
||||||
#include "ElfEnvironment.hxx"
|
#include "ElfEnvironment.hxx"
|
||||||
|
#include "Logger.hxx"
|
||||||
#include "exception/FatalEmulationError.hxx"
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
|
||||||
#include "CartELF.hxx"
|
#include "CartELF.hxx"
|
||||||
|
@ -203,7 +204,7 @@ void CartridgeELF::reset()
|
||||||
std::fill_n(myLastPeekResult.get(), 0x1000, 0);
|
std::fill_n(myLastPeekResult.get(), 0x1000, 0);
|
||||||
myIsBusDriven = false;
|
myIsBusDriven = false;
|
||||||
myDriveBusValue = 0;
|
myDriveBusValue = 0;
|
||||||
myArmCycles = 0;
|
myArmCyclesOffset = 0;
|
||||||
|
|
||||||
std::memset(mySectionStack.get(), 0, STACK_SIZE);
|
std::memset(mySectionStack.get(), 0, STACK_SIZE);
|
||||||
std::memset(mySectionText.get(), 0, TEXT_SIZE);
|
std::memset(mySectionText.get(), 0, TEXT_SIZE);
|
||||||
|
@ -223,10 +224,12 @@ void CartridgeELF::reset()
|
||||||
|
|
||||||
myTransactionQueue
|
myTransactionQueue
|
||||||
.reset()
|
.reset()
|
||||||
.injectROM(0x00, 0x1ffc)
|
.injectROMAt(0x00, 0x1ffc)
|
||||||
.injectROM(0x10)
|
.injectROM(0x10)
|
||||||
.setNextInjectAddress(0x1000);
|
.setNextInjectAddress(0x1000);
|
||||||
|
|
||||||
|
myVcsLib.reset();
|
||||||
|
|
||||||
myVcsLib.vcsCopyOverblankToRiotRam();
|
myVcsLib.vcsCopyOverblankToRiotRam();
|
||||||
myVcsLib.vcsStartOverblank();
|
myVcsLib.vcsStartOverblank();
|
||||||
myVcsLib.vcsEndOverblank();
|
myVcsLib.vcsEndOverblank();
|
||||||
|
@ -295,8 +298,6 @@ const ByteBuffer& CartridgeELF::getImage(size_t& size) const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
runArm();
|
|
||||||
|
|
||||||
value = driveBus(address, value);
|
value = driveBus(address, value);
|
||||||
|
|
||||||
if (address & 0x1000) {
|
if (address & 0x1000) {
|
||||||
|
@ -310,22 +311,41 @@ uInt8 CartridgeELF::overdrivePeek(uInt16 address, uInt8 value)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value)
|
uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
runArm();
|
|
||||||
|
|
||||||
return driveBus(address, value);
|
return driveBus(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uInt64 CartridgeELF::getArmCycles() const
|
||||||
|
{
|
||||||
|
return myCortexEmu.getCycles() + myArmCyclesOffset;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
auto* nextTransaction = myTransactionQueue.getNextTransaction(address);
|
auto* nextTransaction = myTransactionQueue.getNextTransaction(address);
|
||||||
if (nextTransaction) nextTransaction->setBusState(myIsBusDriven, myDriveBusValue);
|
if (nextTransaction) {
|
||||||
|
nextTransaction->setBusState(myIsBusDriven, myDriveBusValue);
|
||||||
|
syncClock(*nextTransaction);
|
||||||
|
}
|
||||||
|
|
||||||
if (myIsBusDriven) value |= myDriveBusValue;
|
if (myIsBusDriven) value |= myDriveBusValue;
|
||||||
|
|
||||||
|
runArm();
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CartridgeELF::syncClock(const BusTransactionQueue::Transaction& transaction)
|
||||||
|
{
|
||||||
|
const Int64 currentSystemArmCycles = mySystem->cycles() * myArmCyclesPer6502Cycle;
|
||||||
|
const Int64 transactionArmCycles = transaction.timestamp + myArmCyclesOffset;
|
||||||
|
|
||||||
|
myArmCyclesOffset += currentSystemArmCycles - transactionArmCycles;
|
||||||
|
|
||||||
|
if (transactionArmCycles > currentSystemArmCycles)
|
||||||
|
Logger::error("ARM took too many cycles between bus transitions");
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeELF::parseAndLinkElf()
|
void CartridgeELF::parseAndLinkElf()
|
||||||
{
|
{
|
||||||
|
@ -461,16 +481,20 @@ void CartridgeELF::jumpToMain()
|
||||||
|
|
||||||
void CartridgeELF::runArm()
|
void CartridgeELF::runArm()
|
||||||
{
|
{
|
||||||
if (myArmCycles >= (mySystem->cycles() + ARM_RUNAHED_MIN) * myArmCyclesPer6502Cycle) return;
|
if (
|
||||||
|
(getArmCycles() >= (mySystem->cycles() + ARM_RUNAHED_MIN) * myArmCyclesPer6502Cycle) ||
|
||||||
|
myTransactionQueue.size() >= QUEUE_SIZE_LIMIT
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
const uInt32 cyclesGoal =
|
const uInt32 cyclesGoal =
|
||||||
(mySystem->cycles() + ARM_RUNAHED_MAX) * myArmCyclesPer6502Cycle - myArmCycles;
|
(mySystem->cycles() + ARM_RUNAHED_MAX) * myArmCyclesPer6502Cycle - getArmCycles();
|
||||||
uInt32 cycles;
|
uInt32 cycles;
|
||||||
|
|
||||||
const CortexM0::err_t err = myCortexEmu.run(cyclesGoal, cycles);
|
const CortexM0::err_t err = myCortexEmu.run(cyclesGoal, cycles);
|
||||||
myArmCycles += cycles;
|
|
||||||
|
|
||||||
if (err != 0) FatalEmulationError::raise("error executing ARM code: " + CortexM0::describeError(err));
|
if (err && (CortexM0::getErrCustom(err) != ERR_QUEUE_FULL))
|
||||||
|
FatalEmulationError::raise("error executing ARM code: " + CortexM0::describeError(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,10 @@ class CartridgeELF: public Cartridge {
|
||||||
bool doesBusStuffing() override { return true; }
|
bool doesBusStuffing() override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uInt64 getArmCycles() const;
|
||||||
|
|
||||||
uInt8 driveBus(uInt16 address, uInt8 value);
|
uInt8 driveBus(uInt16 address, uInt8 value);
|
||||||
|
void syncClock(const BusTransactionQueue::Transaction& transaction);
|
||||||
|
|
||||||
void parseAndLinkElf();
|
void parseAndLinkElf();
|
||||||
void setupMemoryMap();
|
void setupMemoryMap();
|
||||||
|
@ -105,7 +108,7 @@ class CartridgeELF: public Cartridge {
|
||||||
ConsoleTiming myConsoleTiming{ConsoleTiming::ntsc};
|
ConsoleTiming myConsoleTiming{ConsoleTiming::ntsc};
|
||||||
uInt32 myArmCyclesPer6502Cycle{80};
|
uInt32 myArmCyclesPer6502Cycle{80};
|
||||||
|
|
||||||
uInt64 myArmCycles{0};
|
Int64 myArmCyclesOffset{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CARTRIDGE_ELF
|
#endif // CARTRIDGE_ELF
|
||||||
|
|
|
@ -578,6 +578,7 @@ CortexM0& CortexM0::reset()
|
||||||
{
|
{
|
||||||
reg_norm.fill(0);
|
reg_norm.fill(0);
|
||||||
znFlags = cFlag = vFlag = 0;
|
znFlags = cFlag = vFlag = 0;
|
||||||
|
myCycleCounter = 0;
|
||||||
|
|
||||||
recompileCodeRegions();
|
recompileCodeRegions();
|
||||||
|
|
||||||
|
@ -608,7 +609,7 @@ uInt8 CortexM0::decodeInstructionWord(uInt16 instructionWord)
|
||||||
|
|
||||||
CortexM0::err_t CortexM0::run(uInt32 maxCycles, uInt32& cycles)
|
CortexM0::err_t CortexM0::run(uInt32 maxCycles, uInt32& cycles)
|
||||||
{
|
{
|
||||||
for (cycles = 0; cycles < maxCycles; cycles++) {
|
for (cycles = 0; cycles < maxCycles; cycles++, myCycleCounter++) {
|
||||||
const uInt32 pc = read_register(15);
|
const uInt32 pc = read_register(15);
|
||||||
|
|
||||||
uInt16 inst;
|
uInt16 inst;
|
||||||
|
|
|
@ -120,6 +120,10 @@ class CortexM0
|
||||||
err_t write16(uInt32 address, uInt16 value);
|
err_t write16(uInt32 address, uInt16 value);
|
||||||
err_t write8(uInt32 address, uInt8 value);
|
err_t write8(uInt32 address, uInt8 value);
|
||||||
|
|
||||||
|
inline uInt64 getCycles() const {
|
||||||
|
return myCycleCounter;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum class MemoryRegionType : uInt8 {
|
enum class MemoryRegionType : uInt8 {
|
||||||
|
@ -188,6 +192,8 @@ class CortexM0
|
||||||
uInt8 myNextRegionIndex{0};
|
uInt8 myNextRegionIndex{0};
|
||||||
BusTransactionDelegate* myDefaultDelegate{nullptr};
|
BusTransactionDelegate* myDefaultDelegate{nullptr};
|
||||||
|
|
||||||
|
uInt64 myCycleCounter{0};
|
||||||
|
|
||||||
static constexpr uInt32
|
static constexpr uInt32
|
||||||
CPSR_N = 1u << 31,
|
CPSR_N = 1u << 31,
|
||||||
CPSR_Z = 1u << 30,
|
CPSR_Z = 1u << 30,
|
||||||
|
|
|
@ -20,17 +20,19 @@
|
||||||
#include "exception/FatalEmulationError.hxx"
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionYield(uInt16 address)
|
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionYield(
|
||||||
{
|
uInt16 address, uInt64 timestamp
|
||||||
|
) {
|
||||||
address &= 0x1fff;
|
address &= 0x1fff;
|
||||||
return {.address = address, .value = 0, .yield = true};
|
return {.address = address, .value = 0, .timestamp = timestamp, .yield = true};
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionDrive(uInt16 address, uInt8 value)
|
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionDrive(
|
||||||
{
|
uInt16 address, uInt8 value, uInt64 timestamp
|
||||||
|
) {
|
||||||
address &= 0x1fff;
|
address &= 0x1fff;
|
||||||
return {.address = address, .value = value, .yield = false};
|
return {.address = address, .value = value, .timestamp = timestamp, .yield = false};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,6 +60,7 @@ BusTransactionQueue& BusTransactionQueue::reset()
|
||||||
{
|
{
|
||||||
myQueueNext = myQueueSize = 0;
|
myQueueNext = myQueueSize = 0;
|
||||||
myNextInjectAddress = 0;
|
myNextInjectAddress = 0;
|
||||||
|
myTimestamp = 0;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -75,18 +78,25 @@ uInt16 BusTransactionQueue::getNextInjectAddress() const
|
||||||
return myNextInjectAddress;
|
return myNextInjectAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
BusTransactionQueue& BusTransactionQueue::setTimestamp(uInt64 timestamp)
|
||||||
BusTransactionQueue& BusTransactionQueue::injectROM(uInt8 value)
|
|
||||||
{
|
{
|
||||||
injectROM(value, myNextInjectAddress);
|
myTimestamp = timestamp;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
BusTransactionQueue& BusTransactionQueue::injectROM(uInt8 value, uInt16 address)
|
BusTransactionQueue& BusTransactionQueue::injectROM(uInt8 value)
|
||||||
{
|
{
|
||||||
push(Transaction::transactionDrive(address, value));
|
injectROMAt(value, myNextInjectAddress);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue& BusTransactionQueue::injectROMAt(uInt8 value, uInt16 address)
|
||||||
|
{
|
||||||
|
push(Transaction::transactionDrive(address, value, myTimestamp));
|
||||||
myNextInjectAddress = address + 1;
|
myNextInjectAddress = address + 1;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -94,7 +104,7 @@ BusTransactionQueue& BusTransactionQueue::injectROM(uInt8 value, uInt16 address)
|
||||||
|
|
||||||
BusTransactionQueue& BusTransactionQueue::stuffByte(uInt8 value, uInt16 address)
|
BusTransactionQueue& BusTransactionQueue::stuffByte(uInt8 value, uInt16 address)
|
||||||
{
|
{
|
||||||
push(Transaction::transactionDrive(address, value));
|
push(Transaction::transactionDrive(address, value, myTimestamp));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +112,7 @@ BusTransactionQueue& BusTransactionQueue::stuffByte(uInt8 value, uInt16 address)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
BusTransactionQueue& BusTransactionQueue::yield(uInt16 address)
|
BusTransactionQueue& BusTransactionQueue::yield(uInt16 address)
|
||||||
{
|
{
|
||||||
push(Transaction::transactionYield(address));
|
push(Transaction::transactionYield(address, myTimestamp));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,13 +23,14 @@
|
||||||
class BusTransactionQueue {
|
class BusTransactionQueue {
|
||||||
public:
|
public:
|
||||||
struct Transaction {
|
struct Transaction {
|
||||||
static Transaction transactionYield(uInt16 address);
|
static Transaction transactionYield(uInt16 address, uInt64 timestamp);
|
||||||
static Transaction transactionDrive(uInt16 address, uInt8 value);
|
static Transaction transactionDrive(uInt16 address, uInt8 value, uInt64 timestamp);
|
||||||
|
|
||||||
void setBusState(bool& drive, uInt8& value) const;
|
void setBusState(bool& drive, uInt8& value) const;
|
||||||
|
|
||||||
uInt16 address;
|
uInt16 address;
|
||||||
uInt8 value;
|
uInt8 value;
|
||||||
|
uInt64 timestamp;
|
||||||
bool yield;
|
bool yield;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,8 +42,9 @@ class BusTransactionQueue {
|
||||||
BusTransactionQueue& setNextInjectAddress(uInt16 address);
|
BusTransactionQueue& setNextInjectAddress(uInt16 address);
|
||||||
uInt16 getNextInjectAddress() const;
|
uInt16 getNextInjectAddress() const;
|
||||||
|
|
||||||
|
BusTransactionQueue& setTimestamp(uInt64 timestamp);
|
||||||
BusTransactionQueue& injectROM(uInt8 value);
|
BusTransactionQueue& injectROM(uInt8 value);
|
||||||
BusTransactionQueue& injectROM(uInt8 value, uInt16 address);
|
BusTransactionQueue& injectROMAt(uInt8 value, uInt16 address);
|
||||||
BusTransactionQueue& stuffByte(uInt8 value, uInt16 address);
|
BusTransactionQueue& stuffByte(uInt8 value, uInt16 address);
|
||||||
|
|
||||||
BusTransactionQueue& yield(uInt16 address);
|
BusTransactionQueue& yield(uInt16 address);
|
||||||
|
@ -65,6 +67,7 @@ class BusTransactionQueue {
|
||||||
size_t myQueueSize{0};
|
size_t myQueueSize{0};
|
||||||
|
|
||||||
uInt16 myNextInjectAddress{0};
|
uInt16 myNextInjectAddress{0};
|
||||||
|
uInt64 myTimestamp{0};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BusTransactionQueue(const BusTransactionQueue&) = delete;
|
BusTransactionQueue(const BusTransactionQueue&) = delete;
|
||||||
|
|
|
@ -112,6 +112,9 @@ namespace elfEnvironment {
|
||||||
|
|
||||||
constexpr uInt32 RETURN_ADDR_MAIN = 0xffffdead;
|
constexpr uInt32 RETURN_ADDR_MAIN = 0xffffdead;
|
||||||
|
|
||||||
|
constexpr uInt32 ERR_QUEUE_FULL = 1;
|
||||||
|
constexpr uInt32 QUEUE_SIZE_LIMIT = 10;
|
||||||
|
|
||||||
enum class Palette: uInt8 {pal, ntsc};
|
enum class Palette: uInt8 {pal, ntsc};
|
||||||
|
|
||||||
vector<ElfLinker::ExternalSymbol> externalSymbols(Palette palette);
|
vector<ElfLinker::ExternalSymbol> externalSymbols(Palette palette);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "BusTransactionQueue.hxx"
|
#include "BusTransactionQueue.hxx"
|
||||||
#include "ElfEnvironment.hxx"
|
#include "ElfEnvironment.hxx"
|
||||||
#include "exception/FatalEmulationError.hxx"
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
#include "ElfEnvironment.hxx"
|
||||||
|
|
||||||
using namespace elfEnvironment;
|
using namespace elfEnvironment;
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ VcsLib::VcsLib(BusTransactionQueue& transactionQueue) : myTransactionQueue(trans
|
||||||
|
|
||||||
void VcsLib::reset()
|
void VcsLib::reset()
|
||||||
{
|
{
|
||||||
myStuffMaskA = myStuffMaskX = myStuffMaskY = 0xff;
|
myStuffMaskA = myStuffMaskX = myStuffMaskY = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -93,7 +94,7 @@ void VcsLib::vcsStartOverblank()
|
||||||
void VcsLib::vcsEndOverblank()
|
void VcsLib::vcsEndOverblank()
|
||||||
{
|
{
|
||||||
myTransactionQueue
|
myTransactionQueue
|
||||||
.injectROM(0x00, 0x1fff)
|
.injectROMAt(0x00, 0x1fff)
|
||||||
.yield(0x00ac)
|
.yield(0x00ac)
|
||||||
.setNextInjectAddress(0x1000);
|
.setNextInjectAddress(0x1000);
|
||||||
}
|
}
|
||||||
|
@ -103,10 +104,9 @@ void VcsLib::vcsNop2n(uInt16 n)
|
||||||
{
|
{
|
||||||
if (n == 0) return;
|
if (n == 0) return;
|
||||||
|
|
||||||
myTransactionQueue.injectROM(0xea);
|
myTransactionQueue
|
||||||
myTransactionQueue.setNextInjectAddress(
|
.injectROM(0xea)
|
||||||
myTransactionQueue.getNextInjectAddress() + (n - 1)
|
.setNextInjectAddress(myTransactionQueue.getNextInjectAddress() + n - 1);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -123,6 +123,11 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
|
||||||
uInt32 arg;
|
uInt32 arg;
|
||||||
CortexM0::err_t err;
|
CortexM0::err_t err;
|
||||||
|
|
||||||
|
if (myTransactionQueue.size() >= elfEnvironment::QUEUE_SIZE_LIMIT)
|
||||||
|
return CortexM0::errCustom(ERR_QUEUE_FULL);
|
||||||
|
|
||||||
|
myTransactionQueue.setTimestamp(cortex.getCycles());
|
||||||
|
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case ADDR_MEMSET:
|
case ADDR_MEMSET:
|
||||||
err = memset(cortex.getRegister(0), cortex.getRegister(1), cortex.getRegister(3), cortex);
|
err = memset(cortex.getRegister(0), cortex.getRegister(1), cortex.getRegister(3), cortex);
|
||||||
|
@ -151,7 +156,7 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
|
||||||
myTransactionQueue
|
myTransactionQueue
|
||||||
.injectROM(0x85)
|
.injectROM(0x85)
|
||||||
.injectROM(arg)
|
.injectROM(arg)
|
||||||
.stuffByte(arg, cortex.getRegister(1));
|
.stuffByte(cortex.getRegister(1), arg);
|
||||||
|
|
||||||
return returnFromStub(value, op);
|
return returnFromStub(value, op);
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,9 @@ class VcsLib: public CortexM0::BusTransactionDelegate {
|
||||||
private:
|
private:
|
||||||
BusTransactionQueue& myTransactionQueue;
|
BusTransactionQueue& myTransactionQueue;
|
||||||
|
|
||||||
uInt8 myStuffMaskA{0xff};
|
uInt8 myStuffMaskA{0x00};
|
||||||
uInt8 myStuffMaskX{0xff};
|
uInt8 myStuffMaskX{0x00};
|
||||||
uInt8 myStuffMaskY{0xff};
|
uInt8 myStuffMaskY{0x00};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VcsLib(const VcsLib&) = delete;
|
VcsLib(const VcsLib&) = delete;
|
||||||
|
|
Loading…
Reference in New Issue