Implement most of vcslib.

This commit is contained in:
Christian Speckner 2024-08-08 22:45:46 +02:00
parent 948ad8d67e
commit e7de075b20
4 changed files with 67 additions and 17 deletions

View File

@ -21,10 +21,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionYield(
uInt16 address, uInt64 timestamp
uInt16 address, uInt64 timestamp, uInt16 mask
) {
address &= 0x1fff;
return {.address = address, .value = 0, .timestamp = timestamp, .yield = true};
return {.address = address, .mask = mask, .value = 0, .timestamp = timestamp, .yield = true};
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -32,7 +32,7 @@ BusTransactionQueue::Transaction BusTransactionQueue::Transaction::transactionDr
uInt16 address, uInt8 value, uInt64 timestamp
) {
address &= 0x1fff;
return {.address = address, .value = value, .timestamp = timestamp, .yield = false};
return {.address = address, .mask = 0xffff, .value = value, .timestamp = timestamp, .yield = false};
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -112,9 +112,9 @@ BusTransactionQueue& BusTransactionQueue::stuffByte(uInt8 value, uInt16 address)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BusTransactionQueue& BusTransactionQueue::yield(uInt16 address)
BusTransactionQueue& BusTransactionQueue::yield(uInt16 address, uInt16 mask)
{
push(Transaction::transactionYield(address, myTimestamp));
push(Transaction::transactionYield(address, myTimestamp, mask));
return *this;
}
@ -131,7 +131,10 @@ BusTransactionQueue::Transaction* BusTransactionQueue::getNextTransaction(uInt16
if (myQueueSize == 0) return nullptr;
Transaction* nextTransaction = &myQueue[myQueueNext];
if (nextTransaction->address != (address & 0x1fff) || nextTransaction->timestamp > timestamp) return nullptr;
if (
nextTransaction->address != (address & 0x1fff & nextTransaction->mask) ||
nextTransaction->timestamp > timestamp
) return nullptr;
myQueueNext = (myQueueNext + 1) % myQueueCapacity;
myQueueSize--;

View File

@ -23,12 +23,13 @@
class BusTransactionQueue {
public:
struct Transaction {
static Transaction transactionYield(uInt16 address, uInt64 timestamp);
static Transaction transactionYield(uInt16 address, uInt64 timestamp, uInt16 mask);
static Transaction transactionDrive(uInt16 address, uInt8 value, uInt64 timestamp);
void setBusState(bool& drive, uInt8& value) const;
uInt16 address{0};
uInt16 mask{0xffff};
uInt8 value{0};
uInt64 timestamp{0};
bool yield{false};
@ -48,7 +49,7 @@ class BusTransactionQueue {
BusTransactionQueue& injectROMAt(uInt8 value, uInt16 address);
BusTransactionQueue& stuffByte(uInt8 value, uInt16 address);
BusTransactionQueue& yield(uInt16 address);
BusTransactionQueue& yield(uInt16 address, uInt16 mask = 0xffff);
bool hasPendingTransaction() const;
Transaction* getNextTransaction(uInt16 address, uInt64 timestamp);

View File

@ -176,6 +176,15 @@ void VcsLib::vcsLda2(uInt8 value)
.injectROM(value);
}
CortexM0::err_t VcsLib::stackOperation(uInt16& value, uInt8& op, uInt8 opcode)
{
myTransactionQueue
.injectROM(opcode)
.yield(0, 0x1000);
return returnFromStub(value, op);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex)
{
@ -244,7 +253,17 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
return returnFromStub(value, op);
case ADDR_VCS_WRITE6:
FatalEmulationError::raise("unimplemented: vcsWrite6");
arg = cortex.getRegister(0);
myTransactionQueue
.injectROM(0xa9)
.injectROM(cortex.getRegister(1))
.injectROM(0x8d)
.injectROM(arg)
.injectROM(arg >> 8)
.yield(arg);
return returnFromStub(value, op);
case ADDR_VCS_LDA2:
vcsLda2(cortex.getRegister(0));
@ -265,7 +284,14 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
return returnFromStub(value, op);
case ADDR_VCS_SAX3:
FatalEmulationError::raise("unimplemented: vcsSax3");
arg = cortex.getRegister(0);
myTransactionQueue
.injectROM(0x87)
.injectROM(arg)
.yield(arg);
return returnFromStub(value, op);
case ADDR_VCS_STA3:
arg = cortex.getRegister(0);
@ -371,22 +397,32 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
return returnFromStub(value, op);
case ADDR_VCS_TXS2:
FatalEmulationError::raise("unimplemented: vcsTx2");
myTransactionQueue.injectROM(0x9a);
return returnFromStub(value, op);
case ADDR_VCS_JSR6:
FatalEmulationError::raise("unimplemented: vcsJsr6");
arg = cortex.getRegister(0);
myTransactionQueue
.injectROM(0x20)
.injectROM(arg)
.yield(0, 0x1000)
.injectROM(arg >> 8)
.setNextInjectAddress(arg & 0x1fff);
return returnFromStub(value, op);
case ADDR_VCS_PHA3:
FatalEmulationError::raise("unimplemented: vcsPha3");
return stackOperation(value, op, 0x48);
case ADDR_VCS_PHP3:
FatalEmulationError::raise("unimplemented: vcsPph3");
return stackOperation(value, op, 0x08);
case ADDR_VCS_PLA4:
FatalEmulationError::raise("unimplemented: vcsPla4");
return stackOperation(value, op, 0x68);
case ADDR_VCS_PLP4:
FatalEmulationError::raise("unimplemented: vcsPlp4");
return stackOperation(value, op, 0x28);
case ADDR_VCS_PLA4_EX:
FatalEmulationError::raise("unimplemented: vcsPla4Ex");
@ -395,7 +431,15 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
FatalEmulationError::raise("unimplemented: vcsPlp4Ex");
case ADDR_VCS_JMP_TO_RAM3:
FatalEmulationError::raise("unimplemented: vcsJmpToRam3");
arg = cortex.getRegister(0);
myTransactionQueue
.injectROM(0x4c)
.injectROM(arg)
.injectROM(arg >> 8)
.yield(arg);
return returnFromStub(value, op);
case ADDR_VCS_WAIT_FOR_ADDRESS:
FatalEmulationError::raise("unimplemented: vcsWaitForAddress");

View File

@ -59,6 +59,8 @@ class VcsLib: public CortexM0::BusTransactionDelegate {
return CortexM0::ERR_NONE;
}
CortexM0::err_t stackOperation(uInt16& value, uInt8& op, uInt8 opcode);
private:
BusTransactionQueue& myTransactionQueue;