mirror of https://github.com/stella-emu/stella.git
Implement most of vcslib.
This commit is contained in:
parent
948ad8d67e
commit
e7de075b20
|
@ -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--;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue