mirror of https://github.com/stella-emu/stella.git
Refactoring.
This commit is contained in:
parent
239c307f91
commit
54e65a9c03
|
@ -176,7 +176,8 @@ namespace {
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5,
|
CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5,
|
||||||
const Settings& settings)
|
const Settings& settings)
|
||||||
: Cartridge(settings, md5), myImageSize(size), myVcslibDelegate(*this)
|
: Cartridge(settings, md5), myImageSize(size), myTransactionQueue(TRANSACTION_QUEUE_CAPACITY),
|
||||||
|
myVcsLib(myTransactionQueue)
|
||||||
{
|
{
|
||||||
myImage = make_unique<uInt8[]>(size);
|
myImage = make_unique<uInt8[]>(size);
|
||||||
std::memcpy(myImage.get(), image.get(), size);
|
std::memcpy(myImage.get(), image.get(), size);
|
||||||
|
@ -203,13 +204,14 @@ void CartridgeELF::reset()
|
||||||
myIsBusDriven = false;
|
myIsBusDriven = false;
|
||||||
myDriveBusValue = 0;
|
myDriveBusValue = 0;
|
||||||
|
|
||||||
myTransactionQueue.reset();
|
myTransactionQueue
|
||||||
myTransactionQueue.injectROM(0x00, 0x1ffc);
|
.reset()
|
||||||
myTransactionQueue.injectROM(0x10);
|
.injectROM(0x00, 0x1ffc)
|
||||||
myTransactionQueue.setNextInjectAddress(0x1000);
|
.injectROM(0x10)
|
||||||
|
.setNextInjectAddress(0x1000);
|
||||||
|
|
||||||
vcsCopyOverblankToRiotRam();
|
myVcsLib.vcsCopyOverblankToRiotRam();
|
||||||
vcsStartOverblank();
|
myVcsLib.vcsStartOverblank();
|
||||||
|
|
||||||
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);
|
||||||
|
@ -299,7 +301,7 @@ uInt8 CartridgeELF::overdrivePoke(uInt16 address, uInt8 value)
|
||||||
|
|
||||||
inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
||||||
{
|
{
|
||||||
BusTransaction* nextTransaction = myTransactionQueue.getNextTransaction(address);
|
auto* nextTransaction = myTransactionQueue.getNextTransaction(address);
|
||||||
if (nextTransaction) nextTransaction->setBusState(myIsBusDriven, myDriveBusValue);
|
if (nextTransaction) nextTransaction->setBusState(myIsBusDriven, myDriveBusValue);
|
||||||
|
|
||||||
if (myIsBusDriven) value |= myDriveBusValue;
|
if (myIsBusDriven) value |= myDriveBusValue;
|
||||||
|
@ -307,266 +309,6 @@ inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::vcsWrite5(uInt8 zpAddress, uInt8 value)
|
|
||||||
{
|
|
||||||
myTransactionQueue.injectROM(0xa9);
|
|
||||||
myTransactionQueue.injectROM(value);
|
|
||||||
myTransactionQueue.injectROM(0x85);
|
|
||||||
myTransactionQueue.injectROM(zpAddress);
|
|
||||||
myTransactionQueue.yield(zpAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::vcsCopyOverblankToRiotRam()
|
|
||||||
{
|
|
||||||
for (uInt8 i = 0; i < OVERBLANK_PROGRAM_SIZE; i++)
|
|
||||||
vcsWrite5(0x80 + i, OVERBLANK_PROGRAM[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::vcsStartOverblank()
|
|
||||||
{
|
|
||||||
myTransactionQueue.injectROM(0x4c);
|
|
||||||
myTransactionQueue.injectROM(0x80);
|
|
||||||
myTransactionQueue.injectROM(0x00);
|
|
||||||
myTransactionQueue.yield(0x0080);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeELF::BusTransaction CartridgeELF::BusTransaction::transactionYield(uInt16 address)
|
|
||||||
{
|
|
||||||
address &= 0x1fff;
|
|
||||||
return {.address = address, .value = 0, .yield = true};
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeELF::BusTransaction CartridgeELF::BusTransaction::transactionDrive(uInt16 address, uInt8 value)
|
|
||||||
{
|
|
||||||
address &= 0x1fff;
|
|
||||||
return {.address = address, .value = value, .yield = false};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransaction::setBusState(bool& bs_drive, uInt8& bs_value) const
|
|
||||||
{
|
|
||||||
if (yield) {
|
|
||||||
bs_drive = false;
|
|
||||||
} else {
|
|
||||||
bs_drive = true;
|
|
||||||
bs_value = this->value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeELF::BusTransactionQueue::BusTransactionQueue()
|
|
||||||
{
|
|
||||||
myQueue = make_unique<BusTransaction[]>(TRANSACTION_QUEUE_CAPACITY);
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransactionQueue::reset()
|
|
||||||
{
|
|
||||||
myQueueNext = myQueueSize = 0;
|
|
||||||
myNextInjectAddress = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransactionQueue::setNextInjectAddress(uInt16 address)
|
|
||||||
{
|
|
||||||
myNextInjectAddress = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransactionQueue::injectROM(uInt8 value)
|
|
||||||
{
|
|
||||||
injectROM(value, myNextInjectAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransactionQueue::injectROM(uInt8 value, uInt16 address)
|
|
||||||
{
|
|
||||||
push(BusTransaction::transactionDrive(address, value));
|
|
||||||
myNextInjectAddress = address + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransactionQueue::yield(uInt16 address)
|
|
||||||
{
|
|
||||||
push(BusTransaction::transactionYield(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool CartridgeELF::BusTransactionQueue::hasPendingTransaction() const
|
|
||||||
{
|
|
||||||
return myQueueSize > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
CartridgeELF::BusTransaction* CartridgeELF::BusTransactionQueue::getNextTransaction(uInt16 address)
|
|
||||||
{
|
|
||||||
if (myQueueSize == 0) return nullptr;
|
|
||||||
|
|
||||||
BusTransaction* nextTransaction = &myQueue[myQueueNext];
|
|
||||||
if (nextTransaction->address != (address & 0x1fff)) return nullptr;
|
|
||||||
|
|
||||||
myQueueNext = (myQueueNext + 1) % TRANSACTION_QUEUE_CAPACITY;
|
|
||||||
myQueueSize--;
|
|
||||||
|
|
||||||
return nextTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void CartridgeELF::BusTransactionQueue::push(const BusTransaction& transaction)
|
|
||||||
{
|
|
||||||
if (myQueueSize > 0) {
|
|
||||||
BusTransaction& lastTransaction = myQueue[(myQueueNext + myQueueSize - 1) % TRANSACTION_QUEUE_CAPACITY];
|
|
||||||
|
|
||||||
if (lastTransaction.address == transaction.address) {
|
|
||||||
lastTransaction = transaction;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myQueueSize == TRANSACTION_QUEUE_CAPACITY)
|
|
||||||
throw FatalEmulationError("read stream overflow");
|
|
||||||
|
|
||||||
myQueue[(myQueueNext + myQueueSize++) % TRANSACTION_QUEUE_CAPACITY] = transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
CortexM0::err_t CartridgeELF::VcslibDelegate::fetch16(uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex)
|
|
||||||
{
|
|
||||||
switch (address) {
|
|
||||||
case ADDR_MEMSET:
|
|
||||||
FatalEmulationError::raise("unimplemented: memset");
|
|
||||||
|
|
||||||
case ADDR_MEMCPY:
|
|
||||||
FatalEmulationError::raise("unimplemented: memcpy");
|
|
||||||
|
|
||||||
case ADDR_VCS_LDA_FOR_BUS_STUFF2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsLdaForBusStuff2");
|
|
||||||
|
|
||||||
case ADDR_VCS_LDX_FOR_BUS_STUFF2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsLdxForBusStuff2");
|
|
||||||
|
|
||||||
case ADDR_VCS_LDY_FOR_BUS_STUFF2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsLdyForBusStuff2");
|
|
||||||
|
|
||||||
case ADDR_VCS_WRITE3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsWrite3");
|
|
||||||
|
|
||||||
case ADDR_VCS_JMP3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsJump3");
|
|
||||||
|
|
||||||
case ADDR_VCS_NOP2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsNop2");
|
|
||||||
|
|
||||||
case ADDR_VCS_NOP2N:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsNop2n");
|
|
||||||
|
|
||||||
case ADDR_VCS_WRITE5:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsWrite5");
|
|
||||||
|
|
||||||
case ADDR_VCS_WRITE6:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsWrite6");
|
|
||||||
|
|
||||||
case ADDR_VCS_LDA2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsLda2");
|
|
||||||
|
|
||||||
case ADDR_VCS_LDX2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsLdx2");
|
|
||||||
|
|
||||||
case ADDR_VCS_LDY2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsLdy2");
|
|
||||||
|
|
||||||
case ADDR_VCS_SAX3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsSax3");
|
|
||||||
|
|
||||||
case ADDR_VCS_STA3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsSta3");
|
|
||||||
|
|
||||||
case ADDR_VCS_STX3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsStx3");
|
|
||||||
|
|
||||||
case ADDR_VCS_STY3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsSty3");
|
|
||||||
|
|
||||||
case ADDR_VCS_STA4:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsSta4");
|
|
||||||
|
|
||||||
case ADDR_VCS_STX4:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsStx4");
|
|
||||||
|
|
||||||
case ADDR_VCS_STY4:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsSty4");
|
|
||||||
|
|
||||||
case ADDR_VCS_COPY_OVERBLANK_TO_RIOT_RAM:
|
|
||||||
myCart.vcsCopyOverblankToRiotRam();
|
|
||||||
return returnFromStub(value, op);
|
|
||||||
|
|
||||||
case ADDR_VCS_START_OVERBLANK:
|
|
||||||
myCart.vcsStartOverblank();
|
|
||||||
return returnFromStub(value, op);
|
|
||||||
|
|
||||||
case ADDR_VCS_END_OVERBLANK:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsEndOverblank");
|
|
||||||
|
|
||||||
case ADDR_VCS_READ4:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsRead4");
|
|
||||||
|
|
||||||
case ADDR_RANDINT:
|
|
||||||
FatalEmulationError::raise("unimplemented: randint ");
|
|
||||||
|
|
||||||
case ADDR_VCS_TXS2:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsTx2");
|
|
||||||
|
|
||||||
case ADDR_VCS_JSR6:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsJsr6");
|
|
||||||
|
|
||||||
case ADDR_VCS_PHA3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsPha3");
|
|
||||||
|
|
||||||
case ADDR_VCS_PHP3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsPph3");
|
|
||||||
|
|
||||||
case ADDR_VCS_PLA4:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsPla4");
|
|
||||||
|
|
||||||
case ADDR_VCS_PLP4:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsPlp4");
|
|
||||||
|
|
||||||
case ADDR_VCS_PLA4_EX:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsPla4Ex");
|
|
||||||
|
|
||||||
case ADDR_VCS_PLP4_EX:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsPlp4Ex");
|
|
||||||
|
|
||||||
case ADDR_VCS_JMP_TO_RAM3:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsJmpToRam3");
|
|
||||||
|
|
||||||
case ADDR_VCS_WAIT_FOR_ADDRESS:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsWaitForAddress");
|
|
||||||
|
|
||||||
case ADDR_INJECT_DMA_DATA:
|
|
||||||
FatalEmulationError::raise("unimplemented: vcsInjectDmaData");
|
|
||||||
|
|
||||||
default:
|
|
||||||
return CortexM0::errIntrinsic(CortexM0::ERR_UNMAPPED_FETCH16, address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CortexM0::err_t CartridgeELF::VcslibDelegate::returnFromStub(uInt16& value, uInt8& op)
|
|
||||||
{
|
|
||||||
constexpr uInt16 BX_LR = 0x7047;
|
|
||||||
|
|
||||||
value = BX_LR;
|
|
||||||
op = CortexM0::decodeInstructionWord(BX_LR);
|
|
||||||
|
|
||||||
return CortexM0::ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CartridgeELF::parseAndLinkElf()
|
void CartridgeELF::parseAndLinkElf()
|
||||||
{
|
{
|
||||||
ElfParser elfParser;
|
ElfParser elfParser;
|
||||||
|
@ -635,7 +377,7 @@ void CartridgeELF::setupMemoryMap()
|
||||||
.mapRegionData(ADDR_TABLES_BASE / CortexM0::PAGE_SIZE,
|
.mapRegionData(ADDR_TABLES_BASE / CortexM0::PAGE_SIZE,
|
||||||
TABLES_SIZE / CortexM0::PAGE_SIZE, true, mySectionTables.get())
|
TABLES_SIZE / CortexM0::PAGE_SIZE, true, mySectionTables.get())
|
||||||
.mapRegionDelegate(ADDR_STUB_BASE / CortexM0::PAGE_SIZE,
|
.mapRegionDelegate(ADDR_STUB_BASE / CortexM0::PAGE_SIZE,
|
||||||
STUB_SIZE / CortexM0::PAGE_SIZE, true, &myVcslibDelegate);
|
STUB_SIZE / CortexM0::PAGE_SIZE, true, &myVcsLib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Cart.hxx"
|
#include "Cart.hxx"
|
||||||
#include "CortexM0.hxx"
|
#include "CortexM0.hxx"
|
||||||
|
#include "BusTransactionQueue.hxx"
|
||||||
|
#include "VcsLib.hxx"
|
||||||
|
|
||||||
class ElfLinker;
|
class ElfLinker;
|
||||||
|
|
||||||
|
@ -64,63 +66,6 @@ class CartridgeELF: public Cartridge {
|
||||||
private:
|
private:
|
||||||
uInt8 driveBus(uInt16 address, uInt8 value);
|
uInt8 driveBus(uInt16 address, uInt8 value);
|
||||||
|
|
||||||
void vcsWrite5(uInt8 zpAddress, uInt8 value);
|
|
||||||
void vcsCopyOverblankToRiotRam();
|
|
||||||
void vcsStartOverblank();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct BusTransaction {
|
|
||||||
static BusTransaction transactionYield(uInt16 address);
|
|
||||||
static BusTransaction transactionDrive(uInt16 address, uInt8 value);
|
|
||||||
|
|
||||||
void setBusState(bool& drive, uInt8& value) const;
|
|
||||||
|
|
||||||
uInt16 address;
|
|
||||||
uInt8 value;
|
|
||||||
bool yield;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BusTransactionQueue {
|
|
||||||
public:
|
|
||||||
BusTransactionQueue();
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void setNextInjectAddress(uInt16 address);
|
|
||||||
void injectROM(uInt8 value);
|
|
||||||
void injectROM(uInt8 value, uInt16 address);
|
|
||||||
|
|
||||||
void yield(uInt16 address);
|
|
||||||
|
|
||||||
bool hasPendingTransaction() const;
|
|
||||||
BusTransaction* getNextTransaction(uInt16 address);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void push(const BusTransaction& transaction);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unique_ptr<BusTransaction[]> myQueue;
|
|
||||||
size_t myQueueNext{0};
|
|
||||||
size_t myQueueSize{0};
|
|
||||||
|
|
||||||
uInt16 myNextInjectAddress{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
class VcslibDelegate: public CortexM0::BusTransactionDelegate {
|
|
||||||
public:
|
|
||||||
VcslibDelegate(CartridgeELF& cart) : myCart(cart) {}
|
|
||||||
|
|
||||||
CortexM0::err_t fetch16(uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CortexM0::err_t returnFromStub(uInt16& value, uInt8& op);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CartridgeELF& myCart;
|
|
||||||
};
|
|
||||||
|
|
||||||
friend VcslibDelegate;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseAndLinkElf();
|
void parseAndLinkElf();
|
||||||
void setupMemoryMap();
|
void setupMemoryMap();
|
||||||
|
@ -148,7 +93,7 @@ class CartridgeELF: public Cartridge {
|
||||||
unique_ptr<uInt8[]> mySectionRodata;
|
unique_ptr<uInt8[]> mySectionRodata;
|
||||||
unique_ptr<uInt8[]> mySectionTables;
|
unique_ptr<uInt8[]> mySectionTables;
|
||||||
|
|
||||||
VcslibDelegate myVcslibDelegate;
|
VcsLib myVcsLib;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CARTRIDGE_ELF
|
#endif // CARTRIDGE_ELF
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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-2024 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 "BusTransactionQueue.hxx"
|
||||||
|
|
||||||
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionYield(uInt16 address)
|
||||||
|
{
|
||||||
|
address &= 0x1fff;
|
||||||
|
return {.address = address, .value = 0, .yield = true};
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionDrive(uInt16 address, uInt8 value)
|
||||||
|
{
|
||||||
|
address &= 0x1fff;
|
||||||
|
return {.address = address, .value = value, .yield = false};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void BusTransactionQueue::Transaction::setBusState(bool& bs_drive, uInt8& bs_value) const
|
||||||
|
{
|
||||||
|
if (yield) {
|
||||||
|
bs_drive = false;
|
||||||
|
} else {
|
||||||
|
bs_drive = true;
|
||||||
|
bs_value = this->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue::BusTransactionQueue(size_t capacity) : myQueueCapacity(capacity)
|
||||||
|
{
|
||||||
|
myQueue = make_unique<Transaction[]>(myQueueCapacity);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue& BusTransactionQueue::reset()
|
||||||
|
{
|
||||||
|
myQueueNext = myQueueSize = 0;
|
||||||
|
myNextInjectAddress = 0;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue& BusTransactionQueue::setNextInjectAddress(uInt16 address)
|
||||||
|
{
|
||||||
|
myNextInjectAddress = address;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue& BusTransactionQueue::injectROM(uInt8 value)
|
||||||
|
{
|
||||||
|
injectROM(value, myNextInjectAddress);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue& BusTransactionQueue::injectROM(uInt8 value, uInt16 address)
|
||||||
|
{
|
||||||
|
push(Transaction::transactionDrive(address, value));
|
||||||
|
myNextInjectAddress = address + 1;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue& BusTransactionQueue::yield(uInt16 address)
|
||||||
|
{
|
||||||
|
push(Transaction::transactionYield(address));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool BusTransactionQueue::hasPendingTransaction() const
|
||||||
|
{
|
||||||
|
return myQueueSize > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
BusTransactionQueue::Transaction* BusTransactionQueue::getNextTransaction(uInt16 address)
|
||||||
|
{
|
||||||
|
if (myQueueSize == 0) return nullptr;
|
||||||
|
|
||||||
|
Transaction* nextTransaction = &myQueue[myQueueNext];
|
||||||
|
if (nextTransaction->address != (address & 0x1fff)) return nullptr;
|
||||||
|
|
||||||
|
myQueueNext = (myQueueNext + 1) % myQueueCapacity;
|
||||||
|
myQueueSize--;
|
||||||
|
|
||||||
|
return nextTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void BusTransactionQueue::push(const Transaction& transaction)
|
||||||
|
{
|
||||||
|
if (myQueueSize > 0) {
|
||||||
|
Transaction& lastTransaction = myQueue[(myQueueNext + myQueueSize - 1) % myQueueCapacity];
|
||||||
|
|
||||||
|
if (lastTransaction.address == transaction.address) {
|
||||||
|
lastTransaction = transaction;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myQueueSize == myQueueCapacity)
|
||||||
|
throw FatalEmulationError("read stream overflow");
|
||||||
|
|
||||||
|
myQueue[(myQueueNext + myQueueSize++) % myQueueCapacity] = transaction;
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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-2024 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 BUS_TRANSACTION_QUEUE
|
||||||
|
#define BUS_TRANSACTION_QUEUE
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
class BusTransactionQueue {
|
||||||
|
public:
|
||||||
|
struct Transaction {
|
||||||
|
static Transaction transactionYield(uInt16 address);
|
||||||
|
static Transaction transactionDrive(uInt16 address, uInt8 value);
|
||||||
|
|
||||||
|
void setBusState(bool& drive, uInt8& value) const;
|
||||||
|
|
||||||
|
uInt16 address;
|
||||||
|
uInt8 value;
|
||||||
|
bool yield;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit BusTransactionQueue(size_t capacity);
|
||||||
|
|
||||||
|
BusTransactionQueue& reset();
|
||||||
|
|
||||||
|
BusTransactionQueue& setNextInjectAddress(uInt16 address);
|
||||||
|
BusTransactionQueue& injectROM(uInt8 value);
|
||||||
|
BusTransactionQueue& injectROM(uInt8 value, uInt16 address);
|
||||||
|
|
||||||
|
BusTransactionQueue& yield(uInt16 address);
|
||||||
|
|
||||||
|
bool hasPendingTransaction() const;
|
||||||
|
Transaction* getNextTransaction(uInt16 address);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void push(const Transaction& transaction);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const size_t myQueueCapacity;
|
||||||
|
|
||||||
|
unique_ptr<Transaction[]> myQueue;
|
||||||
|
size_t myQueueNext{0};
|
||||||
|
size_t myQueueSize{0};
|
||||||
|
|
||||||
|
uInt16 myNextInjectAddress{0};
|
||||||
|
|
||||||
|
private:
|
||||||
|
BusTransactionQueue(const BusTransactionQueue&) = delete;
|
||||||
|
BusTransactionQueue(BusTransactionQueue&&) = delete;
|
||||||
|
BusTransactionQueue& operator=(const BusTransactionQueue&) = delete;
|
||||||
|
BusTransactionQueue& operator=(BusTransactionQueue&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BUS_TRANSACTION_QUEUE
|
|
@ -0,0 +1,189 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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-2024 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 "VcsLib.hxx"
|
||||||
|
|
||||||
|
#include "BusTransactionQueue.hxx"
|
||||||
|
#include "ElfEnvironment.hxx"
|
||||||
|
#include "exception/FatalEmulationError.hxx"
|
||||||
|
|
||||||
|
using namespace elfEnvironment;
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
VcsLib::VcsLib(BusTransactionQueue& transactionQueue) : myTransactionQueue(transactionQueue)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void VcsLib::vcsWrite5(uInt8 zpAddress, uInt8 value)
|
||||||
|
{
|
||||||
|
myTransactionQueue
|
||||||
|
.injectROM(0xa9)
|
||||||
|
.injectROM(value)
|
||||||
|
.injectROM(0x85)
|
||||||
|
.injectROM(zpAddress)
|
||||||
|
.yield(zpAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void VcsLib::vcsCopyOverblankToRiotRam()
|
||||||
|
{
|
||||||
|
for (uInt8 i = 0; i < OVERBLANK_PROGRAM_SIZE; i++)
|
||||||
|
vcsWrite5(0x80 + i, OVERBLANK_PROGRAM[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void VcsLib::vcsStartOverblank()
|
||||||
|
{
|
||||||
|
myTransactionQueue
|
||||||
|
.injectROM(0x4c)
|
||||||
|
.injectROM(0x80)
|
||||||
|
.injectROM(0x00)
|
||||||
|
.yield(0x0080);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex)
|
||||||
|
{
|
||||||
|
switch (address) {
|
||||||
|
case ADDR_MEMSET:
|
||||||
|
FatalEmulationError::raise("unimplemented: memset");
|
||||||
|
|
||||||
|
case ADDR_MEMCPY:
|
||||||
|
FatalEmulationError::raise("unimplemented: memcpy");
|
||||||
|
|
||||||
|
case ADDR_VCS_LDA_FOR_BUS_STUFF2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsLdaForBusStuff2");
|
||||||
|
|
||||||
|
case ADDR_VCS_LDX_FOR_BUS_STUFF2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsLdxForBusStuff2");
|
||||||
|
|
||||||
|
case ADDR_VCS_LDY_FOR_BUS_STUFF2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsLdyForBusStuff2");
|
||||||
|
|
||||||
|
case ADDR_VCS_WRITE3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsWrite3");
|
||||||
|
|
||||||
|
case ADDR_VCS_JMP3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsJump3");
|
||||||
|
|
||||||
|
case ADDR_VCS_NOP2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsNop2");
|
||||||
|
|
||||||
|
case ADDR_VCS_NOP2N:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsNop2n");
|
||||||
|
|
||||||
|
case ADDR_VCS_WRITE5:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsWrite5");
|
||||||
|
|
||||||
|
case ADDR_VCS_WRITE6:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsWrite6");
|
||||||
|
|
||||||
|
case ADDR_VCS_LDA2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsLda2");
|
||||||
|
|
||||||
|
case ADDR_VCS_LDX2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsLdx2");
|
||||||
|
|
||||||
|
case ADDR_VCS_LDY2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsLdy2");
|
||||||
|
|
||||||
|
case ADDR_VCS_SAX3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsSax3");
|
||||||
|
|
||||||
|
case ADDR_VCS_STA3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsSta3");
|
||||||
|
|
||||||
|
case ADDR_VCS_STX3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsStx3");
|
||||||
|
|
||||||
|
case ADDR_VCS_STY3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsSty3");
|
||||||
|
|
||||||
|
case ADDR_VCS_STA4:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsSta4");
|
||||||
|
|
||||||
|
case ADDR_VCS_STX4:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsStx4");
|
||||||
|
|
||||||
|
case ADDR_VCS_STY4:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsSty4");
|
||||||
|
|
||||||
|
case ADDR_VCS_COPY_OVERBLANK_TO_RIOT_RAM:
|
||||||
|
vcsCopyOverblankToRiotRam();
|
||||||
|
return returnFromStub(value, op);
|
||||||
|
|
||||||
|
case ADDR_VCS_START_OVERBLANK:
|
||||||
|
vcsStartOverblank();
|
||||||
|
return returnFromStub(value, op);
|
||||||
|
|
||||||
|
case ADDR_VCS_END_OVERBLANK:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsEndOverblank");
|
||||||
|
|
||||||
|
case ADDR_VCS_READ4:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsRead4");
|
||||||
|
|
||||||
|
case ADDR_RANDINT:
|
||||||
|
FatalEmulationError::raise("unimplemented: randint ");
|
||||||
|
|
||||||
|
case ADDR_VCS_TXS2:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsTx2");
|
||||||
|
|
||||||
|
case ADDR_VCS_JSR6:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsJsr6");
|
||||||
|
|
||||||
|
case ADDR_VCS_PHA3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsPha3");
|
||||||
|
|
||||||
|
case ADDR_VCS_PHP3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsPph3");
|
||||||
|
|
||||||
|
case ADDR_VCS_PLA4:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsPla4");
|
||||||
|
|
||||||
|
case ADDR_VCS_PLP4:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsPlp4");
|
||||||
|
|
||||||
|
case ADDR_VCS_PLA4_EX:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsPla4Ex");
|
||||||
|
|
||||||
|
case ADDR_VCS_PLP4_EX:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsPlp4Ex");
|
||||||
|
|
||||||
|
case ADDR_VCS_JMP_TO_RAM3:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsJmpToRam3");
|
||||||
|
|
||||||
|
case ADDR_VCS_WAIT_FOR_ADDRESS:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsWaitForAddress");
|
||||||
|
|
||||||
|
case ADDR_INJECT_DMA_DATA:
|
||||||
|
FatalEmulationError::raise("unimplemented: vcsInjectDmaData");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CortexM0::errIntrinsic(CortexM0::ERR_UNMAPPED_FETCH16, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
CortexM0::err_t VcsLib::returnFromStub(uInt16& value, uInt8& op)
|
||||||
|
{
|
||||||
|
constexpr uInt16 BX_LR = 0x7047;
|
||||||
|
|
||||||
|
value = BX_LR;
|
||||||
|
op = CortexM0::decodeInstructionWord(BX_LR);
|
||||||
|
|
||||||
|
return CortexM0::ERR_NONE;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// 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-2024 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 VCSLIB_H
|
||||||
|
#define VCSLIB_H
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
#include "CortexM0.hxx"
|
||||||
|
|
||||||
|
class BusTransactionQueue;
|
||||||
|
|
||||||
|
class VcsLib: public CortexM0::BusTransactionDelegate {
|
||||||
|
public:
|
||||||
|
explicit VcsLib(BusTransactionQueue& transactionQueue);
|
||||||
|
|
||||||
|
CortexM0::err_t fetch16(uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex) override;
|
||||||
|
|
||||||
|
void vcsWrite5(uInt8 zpAddress, uInt8 value);
|
||||||
|
void vcsCopyOverblankToRiotRam();
|
||||||
|
void vcsStartOverblank();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CortexM0::err_t returnFromStub(uInt16& value, uInt8& op);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BusTransactionQueue& myTransactionQueue;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VcsLib(const VcsLib&) = delete;
|
||||||
|
VcsLib(VcsLib&&) = delete;
|
||||||
|
const VcsLib& operator=(const VcsLib&) = delete;
|
||||||
|
const VcsLib& operator=(VcsLib&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VCSLIB_H
|
|
@ -4,7 +4,9 @@ MODULE_OBJS = \
|
||||||
src/emucore/elf/ElfParser.o \
|
src/emucore/elf/ElfParser.o \
|
||||||
src/emucore/elf/ElfLinker.o \
|
src/emucore/elf/ElfLinker.o \
|
||||||
src/emucore/elf/ElfUtil.o \
|
src/emucore/elf/ElfUtil.o \
|
||||||
src/emucore/elf/ElfEnvironment.o
|
src/emucore/elf/ElfEnvironment.o \
|
||||||
|
src/emucore/elf/BusTransactionQueue.o \
|
||||||
|
src/emucore/elf/VcsLib.o
|
||||||
|
|
||||||
MODULE_TEST_OBJS = \
|
MODULE_TEST_OBJS = \
|
||||||
src/emucore/elf/ElfUtil.o \
|
src/emucore/elf/ElfUtil.o \
|
||||||
|
|
|
@ -695,6 +695,8 @@
|
||||||
<ClCompile Include="..\..\emucore\elf\ElfLinker.cxx" />
|
<ClCompile Include="..\..\emucore\elf\ElfLinker.cxx" />
|
||||||
<ClCompile Include="..\..\emucore\elf\ElfUtil.cxx" />
|
<ClCompile Include="..\..\emucore\elf\ElfUtil.cxx" />
|
||||||
<ClCompile Include="..\..\emucore\elf\ElfEnvironment.cxx" />
|
<ClCompile Include="..\..\emucore\elf\ElfEnvironment.cxx" />
|
||||||
|
<ClCompile Include="..\..\emucore\elf\BusTransactionQueue.cxx" />
|
||||||
|
<ClCompile Include="..\..\emucore\elf\VcsLib.cxx" />
|
||||||
<ClCompile Include="..\..\emucore\CortexM0.cxx" />
|
<ClCompile Include="..\..\emucore\CortexM0.cxx" />
|
||||||
<ClCompile Include="..\..\emucore\EmulationTiming.cxx" />
|
<ClCompile Include="..\..\emucore\EmulationTiming.cxx" />
|
||||||
<ClCompile Include="..\..\emucore\EmulationWorker.cxx" />
|
<ClCompile Include="..\..\emucore\EmulationWorker.cxx" />
|
||||||
|
@ -1671,6 +1673,8 @@
|
||||||
<ClInclude Include="..\..\emucore\elf\ElfLinker.hxx" />
|
<ClInclude Include="..\..\emucore\elf\ElfLinker.hxx" />
|
||||||
<ClInclude Include="..\..\emucore\elf\ElfUtil.hxx" />
|
<ClInclude Include="..\..\emucore\elf\ElfUtil.hxx" />
|
||||||
<ClInclude Include="..\..\emucore\elf\ElfEnvironment.hxx" />
|
<ClInclude Include="..\..\emucore\elf\ElfEnvironment.hxx" />
|
||||||
|
<ClCompile Include="..\..\emucore\elf\BusTransactionQueue.hxx" />
|
||||||
|
<ClCompile Include="..\..\emucore\elf\VcsLib.hxx" />
|
||||||
<ClInclude Include="..\..\emucore\CortexM0.hxx" />
|
<ClInclude Include="..\..\emucore\CortexM0.hxx" />
|
||||||
<ClInclude Include="..\..\emucore\EmulationTiming.hxx" />
|
<ClInclude Include="..\..\emucore\EmulationTiming.hxx" />
|
||||||
<ClInclude Include="..\..\emucore\EmulationWorker.hxx" />
|
<ClInclude Include="..\..\emucore\EmulationWorker.hxx" />
|
||||||
|
|
|
@ -1260,6 +1260,12 @@
|
||||||
<ClCompile Include="..\..\emucore\elf\ElfEnvironment.cxx">
|
<ClCompile Include="..\..\emucore\elf\ElfEnvironment.cxx">
|
||||||
<Filter>Source Files\emucore\elf</Filter>
|
<Filter>Source Files\emucore\elf</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\emucore\elf\BusTransactionCode.cxx">
|
||||||
|
<Filter>Source Files\emucore\elf</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\emucore\elf\VcsLib.cxx">
|
||||||
|
<Filter>Source Files\emucore\elf</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\emucore\AtariVox.hxx">
|
<ClInclude Include="..\..\emucore\AtariVox.hxx">
|
||||||
|
@ -2552,6 +2558,12 @@
|
||||||
<ClInclude Include="..\..\emucore\elf\ElfEnvironment.hxx">
|
<ClInclude Include="..\..\emucore\elf\ElfEnvironment.hxx">
|
||||||
<Filter>Header Files\emucore\elf</Filter>
|
<Filter>Header Files\emucore\elf</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClCompile Include="..\..\emucore\elf\BusTransactionCode.hxx">
|
||||||
|
<Filter>Source Files\emucore\elf</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\emucore\elf\VcsLib.hxx">
|
||||||
|
<Filter>Source Files\emucore\elf</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="stella.ico">
|
<None Include="stella.ico">
|
||||||
|
|
Loading…
Reference in New Issue