mirror of https://github.com/stella-emu/stella.git
Merge branch 'master' of https://github.com/stella-emu/stella
This commit is contained in:
commit
ea7a20a5a0
|
@ -21,6 +21,8 @@
|
||||||
- YStart autodetection
|
- YStart autodetection
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
|
* Proper emulation of RDY during write cycles.
|
||||||
|
|
||||||
* Much improved RIOT timer emulation never before seen in any emulator.
|
* Much improved RIOT timer emulation never before seen in any emulator.
|
||||||
Special thanks to DirtyHairy for the implementation, and alex_79 for
|
Special thanks to DirtyHairy for the implementation, and alex_79 for
|
||||||
finding documentation that finally describes in more detail how the
|
finding documentation that finally describes in more detail how the
|
||||||
|
|
|
@ -58,7 +58,9 @@ M6502::M6502(const Settings& settings)
|
||||||
myLastSrcAddressA(-1),
|
myLastSrcAddressA(-1),
|
||||||
myLastSrcAddressX(-1),
|
myLastSrcAddressX(-1),
|
||||||
myLastSrcAddressY(-1),
|
myLastSrcAddressY(-1),
|
||||||
myDataAddressForPoke(0)
|
myDataAddressForPoke(0),
|
||||||
|
myOnHaltCallback(0),
|
||||||
|
myHaltRequested(false)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
myDebugger = nullptr;
|
myDebugger = nullptr;
|
||||||
|
@ -102,11 +104,18 @@ void M6502::reset()
|
||||||
myLastSrcAddressS = myLastSrcAddressA =
|
myLastSrcAddressS = myLastSrcAddressA =
|
||||||
myLastSrcAddressX = myLastSrcAddressY = -1;
|
myLastSrcAddressX = myLastSrcAddressY = -1;
|
||||||
myDataAddressForPoke = 0;
|
myDataAddressForPoke = 0;
|
||||||
|
|
||||||
|
myHaltRequested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
inline uInt8 M6502::peek(uInt16 address, uInt8 flags)
|
inline uInt8 M6502::peek(uInt16 address, uInt8 flags)
|
||||||
{
|
{
|
||||||
|
if (myHaltRequested) {
|
||||||
|
myOnHaltCallback();
|
||||||
|
myHaltRequested = false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
// TODO - move this logic directly into CartAR
|
// TODO - move this logic directly into CartAR
|
||||||
if(address != myLastAddress)
|
if(address != myLastAddress)
|
||||||
|
@ -159,6 +168,13 @@ inline void M6502::poke(uInt16 address, uInt8 value)
|
||||||
myLastPokeAddress = address;
|
myLastPokeAddress = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void M6502::requestHalt()
|
||||||
|
{
|
||||||
|
if (!myOnHaltCallback) throw runtime_error("onHaltCallback not configured");
|
||||||
|
myHaltRequested = true;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
bool M6502::execute(uInt32 number)
|
bool M6502::execute(uInt32 number)
|
||||||
{
|
{
|
||||||
|
@ -310,6 +326,8 @@ bool M6502::save(Serializer& out) const
|
||||||
out.putInt(myLastSrcAddressA);
|
out.putInt(myLastSrcAddressA);
|
||||||
out.putInt(myLastSrcAddressX);
|
out.putInt(myLastSrcAddressX);
|
||||||
out.putInt(myLastSrcAddressY);
|
out.putInt(myLastSrcAddressY);
|
||||||
|
|
||||||
|
out.putBool(myHaltRequested);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -358,6 +376,8 @@ bool M6502::load(Serializer& in)
|
||||||
myLastSrcAddressA = in.getInt();
|
myLastSrcAddressA = in.getInt();
|
||||||
myLastSrcAddressX = in.getInt();
|
myLastSrcAddressX = in.getInt();
|
||||||
myLastSrcAddressY = in.getInt();
|
myLastSrcAddressY = in.getInt();
|
||||||
|
|
||||||
|
myHaltRequested = in.getBool();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
class Settings;
|
class Settings;
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "Serializable.hxx"
|
#include "Serializable.hxx"
|
||||||
|
@ -50,6 +52,10 @@ class M6502 : public Serializable
|
||||||
friend class CartDebug;
|
friend class CartDebug;
|
||||||
friend class CpuDebug;
|
friend class CpuDebug;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using onHaltCallback = std::function<void()>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Create a new 6502 microprocessor.
|
Create a new 6502 microprocessor.
|
||||||
|
@ -83,6 +89,21 @@ class M6502 : public Serializable
|
||||||
*/
|
*/
|
||||||
void nmi() { myExecutionStatus |= NonmaskableInterruptBit; }
|
void nmi() { myExecutionStatus |= NonmaskableInterruptBit; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the callback for handling a halt condition
|
||||||
|
*/
|
||||||
|
void setOnHaltCallback(onHaltCallback callback) { myOnHaltCallback = callback; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
RDY pulled low --- halt on next read.
|
||||||
|
*/
|
||||||
|
void requestHalt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Pull RDY high again before the callback was triggered.
|
||||||
|
*/
|
||||||
|
void clearHaltRequest() { myHaltRequested = false; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Execute instructions until the specified number of instructions
|
Execute instructions until the specified number of instructions
|
||||||
is executed, someone stops execution, or an error occurs. Answers
|
is executed, someone stops execution, or an error occurs. Answers
|
||||||
|
@ -328,6 +349,12 @@ class M6502 : public Serializable
|
||||||
/// Indicates the number of system cycles per processor cycle
|
/// Indicates the number of system cycles per processor cycle
|
||||||
static constexpr uInt32 SYSTEM_CYCLES_PER_CPU = 1;
|
static constexpr uInt32 SYSTEM_CYCLES_PER_CPU = 1;
|
||||||
|
|
||||||
|
/// Called when the processor enters halt state
|
||||||
|
onHaltCallback myOnHaltCallback;
|
||||||
|
|
||||||
|
/// Indicates whether RDY was pulled low
|
||||||
|
bool myHaltRequested;
|
||||||
|
|
||||||
#ifdef DEBUGGER_SUPPORT
|
#ifdef DEBUGGER_SUPPORT
|
||||||
Int32 evalCondBreaks() {
|
Int32 evalCondBreaks() {
|
||||||
for(uInt32 i = 0; i < myBreakConds.size(); i++)
|
for(uInt32 i = 0; i < myBreakConds.size(); i++)
|
||||||
|
|
|
@ -186,6 +186,12 @@ void TIA::installDelegate(System& system, Device& device)
|
||||||
for(uInt32 i = 0; i < 8192; i += (1 << System::PAGE_SHIFT))
|
for(uInt32 i = 0; i < 8192; i += (1 << System::PAGE_SHIFT))
|
||||||
if((i & 0x1080) == 0x0000)
|
if((i & 0x1080) == 0x0000)
|
||||||
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
|
||||||
|
|
||||||
|
mySystem->m6502().setOnHaltCallback(
|
||||||
|
[this] () {
|
||||||
|
onHalt();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -428,17 +434,7 @@ bool TIA::poke(uInt16 address, uInt8 value)
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
case WSYNC:
|
case WSYNC:
|
||||||
// It appears that the 6507 only halts during a read cycle so
|
mySystem->m6502().requestHalt();
|
||||||
// we test here for follow-on writes which should be ignored as
|
|
||||||
// far as halting the processor is concerned.
|
|
||||||
// See issue #42 for more information.
|
|
||||||
if (mySystem->m6502().lastAccessWasRead())
|
|
||||||
{
|
|
||||||
mySubClock += (228 - myHctr) % 228;
|
|
||||||
mySystem->incrementCycles(mySubClock / 3);
|
|
||||||
mySubClock %= 3;
|
|
||||||
}
|
|
||||||
myShadowRegisters[address] = value;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RSYNC:
|
case RSYNC:
|
||||||
|
@ -1050,6 +1046,14 @@ void TIA::onFrameComplete()
|
||||||
myConsole.setFramerate(myFrameManager.frameRate());
|
myConsole.setFramerate(myFrameManager.frameRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void TIA::onHalt()
|
||||||
|
{
|
||||||
|
mySubClock += (228 - myHctr) % 228;
|
||||||
|
mySystem->incrementCycles(mySubClock / 3);
|
||||||
|
mySubClock %= 3;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TIA::cycle(uInt32 colorClocks)
|
void TIA::cycle(uInt32 colorClocks)
|
||||||
{
|
{
|
||||||
|
@ -1161,6 +1165,8 @@ void TIA::nextLine()
|
||||||
myFrameManager.nextLine();
|
myFrameManager.nextLine();
|
||||||
|
|
||||||
if (myFrameManager.isRendering() && myFrameManager.getY() == 0) flushLineCache();
|
if (myFrameManager.isRendering() && myFrameManager.getY() == 0) flushLineCache();
|
||||||
|
|
||||||
|
mySystem->m6502().clearHaltRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -401,6 +401,8 @@ class TIA : public Device
|
||||||
|
|
||||||
void onFrameComplete();
|
void onFrameComplete();
|
||||||
|
|
||||||
|
void onHalt();
|
||||||
|
|
||||||
void updateEmulation();
|
void updateEmulation();
|
||||||
|
|
||||||
void cycle(uInt32 colorClocks);
|
void cycle(uInt32 colorClocks);
|
||||||
|
|
Loading…
Reference in New Issue