mirror of https://github.com/stella-emu/stella.git
Bus snooping.
This commit is contained in:
parent
ba75f72826
commit
f4b25da4cd
|
@ -330,7 +330,9 @@ inline uInt8 CartridgeELF::driveBus(uInt16 address, uInt8 value)
|
|||
|
||||
if (myIsBusDriven) value |= myDriveBusValue;
|
||||
|
||||
runArm();
|
||||
myVcsLib.updateBus(address, value);
|
||||
|
||||
if (!myVcsLib.isSuspended()) runArm();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -493,7 +495,7 @@ void CartridgeELF::runArm()
|
|||
|
||||
const CortexM0::err_t err = myCortexEmu.run(cyclesGoal, cycles);
|
||||
|
||||
if (err && (CortexM0::getErrCustom(err) != ERR_QUEUE_FULL))
|
||||
if (err && (CortexM0::getErrCustom(err) != ERR_STOP_EXECUTION))
|
||||
FatalEmulationError::raise("error executing ARM code: " + CortexM0::describeError(err));
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,8 @@ namespace elfEnvironment {
|
|||
|
||||
constexpr uInt32 RETURN_ADDR_MAIN = 0xffffdead;
|
||||
|
||||
constexpr uInt32 ERR_QUEUE_FULL = 1;
|
||||
constexpr uInt32 ERR_STOP_EXECUTION = 1;
|
||||
|
||||
constexpr uInt32 QUEUE_SIZE_LIMIT = 10;
|
||||
|
||||
enum class Palette: uInt8 {pal, ntsc};
|
||||
|
|
|
@ -60,6 +60,10 @@ VcsLib::VcsLib(BusTransactionQueue& transactionQueue) : myTransactionQueue(trans
|
|||
void VcsLib::reset()
|
||||
{
|
||||
myStuffMaskA = myStuffMaskX = myStuffMaskY = 0x00;
|
||||
myIsWaitingForRead = false;
|
||||
myWaitingForReadAddress = 0;
|
||||
myCurrentAddress = 0;
|
||||
myCurrentValue = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -124,7 +128,7 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
|
|||
CortexM0::err_t err;
|
||||
|
||||
if (myTransactionQueue.size() >= elfEnvironment::QUEUE_SIZE_LIMIT)
|
||||
return CortexM0::errCustom(ERR_QUEUE_FULL);
|
||||
return CortexM0::errCustom(ERR_STOP_EXECUTION);
|
||||
|
||||
myTransactionQueue.setTimestamp(cortex.getCycles());
|
||||
|
||||
|
@ -170,7 +174,8 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
|
|||
return returnFromStub(value, op);
|
||||
|
||||
case ADDR_VCS_NOP2:
|
||||
FatalEmulationError::raise("unimplemented: vcsNop2");
|
||||
myTransactionQueue.injectROM(0xea);
|
||||
return returnFromStub(value, op);
|
||||
|
||||
case ADDR_VCS_NOP2N:
|
||||
vcsNop2n(cortex.getRegister(0));
|
||||
|
@ -234,7 +239,28 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
|
|||
return returnFromStub(value, op);
|
||||
|
||||
case ADDR_VCS_READ4:
|
||||
FatalEmulationError::raise("unimplemented: vcsRead4");
|
||||
if (myIsWaitingForRead) {
|
||||
if (myTransactionQueue.size() > 0 || myCurrentAddress != myWaitingForReadAddress)
|
||||
return CortexM0::errCustom(ERR_STOP_EXECUTION);
|
||||
|
||||
myIsWaitingForRead = false;
|
||||
cortex.setRegister(0, myCurrentValue);
|
||||
|
||||
return returnFromStub(value, op);
|
||||
} else {
|
||||
arg = cortex.getRegister(0);
|
||||
|
||||
myIsWaitingForRead = true;
|
||||
myWaitingForReadAddress = arg;
|
||||
|
||||
myTransactionQueue
|
||||
.injectROM(0xad)
|
||||
.injectROM(arg & 0xff)
|
||||
.injectROM(arg >> 8)
|
||||
.yield(arg);
|
||||
|
||||
return CortexM0::errCustom(ERR_STOP_EXECUTION);
|
||||
}
|
||||
|
||||
case ADDR_RANDINT:
|
||||
FatalEmulationError::raise("unimplemented: randint ");
|
||||
|
@ -277,6 +303,12 @@ CortexM0::err_t VcsLib::fetch16(uInt32 address, uInt16& value, uInt8& op, Cortex
|
|||
}
|
||||
}
|
||||
|
||||
void VcsLib::updateBus(uInt16 address, uInt8 value)
|
||||
{
|
||||
myCurrentAddress = address;
|
||||
myCurrentValue = value;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CortexM0::err_t VcsLib::returnFromStub(uInt16& value, uInt8& op)
|
||||
{
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
|
||||
#include "bspf.hxx"
|
||||
#include "CortexM0.hxx"
|
||||
|
||||
class BusTransactionQueue;
|
||||
#include "BusTransactionQueue.hxx"
|
||||
|
||||
class VcsLib: public CortexM0::BusTransactionDelegate {
|
||||
public:
|
||||
|
@ -31,6 +30,13 @@ class VcsLib: public CortexM0::BusTransactionDelegate {
|
|||
|
||||
CortexM0::err_t fetch16(uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex) override;
|
||||
|
||||
void updateBus(uInt16 address, uInt8 value);
|
||||
|
||||
inline bool isSuspended() const {
|
||||
return
|
||||
myIsWaitingForRead && (myTransactionQueue.size() > 0 || (myWaitingForReadAddress != myCurrentAddress));
|
||||
}
|
||||
|
||||
void vcsWrite5(uInt8 zpAddress, uInt8 value);
|
||||
void vcsCopyOverblankToRiotRam();
|
||||
void vcsStartOverblank();
|
||||
|
@ -48,6 +54,12 @@ class VcsLib: public CortexM0::BusTransactionDelegate {
|
|||
uInt8 myStuffMaskX{0x00};
|
||||
uInt8 myStuffMaskY{0x00};
|
||||
|
||||
bool myIsWaitingForRead{false};
|
||||
uInt16 myWaitingForReadAddress{0};
|
||||
|
||||
uInt16 myCurrentAddress{0};
|
||||
uInt8 myCurrentValue{0};
|
||||
|
||||
private:
|
||||
VcsLib(const VcsLib&) = delete;
|
||||
VcsLib(VcsLib&&) = delete;
|
||||
|
|
Loading…
Reference in New Issue