diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx index 6c704ae48..c659e3548 100644 --- a/src/emucore/Cart.hxx +++ b/src/emucore/Cart.hxx @@ -254,6 +254,13 @@ class Cartridge : public Device */ virtual uInt16 ramBankCount() const { return 0; } + /** + Query wether the current PC allows code execution. + + @return true, if code execution is allowed + */ + virtual bool canExecute(uInt16 PC) const { return true; } + /** Get the number of segments supported by the cartridge. */ diff --git a/src/emucore/CartEnhanced.hxx b/src/emucore/CartEnhanced.hxx index 39b312cae..928303e50 100644 --- a/src/emucore/CartEnhanced.hxx +++ b/src/emucore/CartEnhanced.hxx @@ -99,6 +99,22 @@ class CartridgeEnhanced : public Cartridge */ uInt16 ramBankCount() const override; + /** + Query wether the current PC allows code execution. + + @return true, if code execution is allowed + */ + bool canExecute(uInt16 PC) const override { + return !(PC & 0x1000) || (PC & ROM_MASK) >= myRomOffset || executableCartRam(); + } + + /** + Query wether the cart RAM allows code execution. + + @return true, if code execution is allowed + */ + virtual bool executableCartRam() const { return true; } + /** Get the number of segments supported by the cartridge. */ diff --git a/src/emucore/CartF4SC.hxx b/src/emucore/CartF4SC.hxx index cbc8f2461..66e9d08ba 100644 --- a/src/emucore/CartF4SC.hxx +++ b/src/emucore/CartF4SC.hxx @@ -49,6 +49,13 @@ class CartridgeF4SC : public CartridgeF4 ~CartridgeF4SC() override = default; public: + /** + Query wether the cart RAM allows code execution. + + @return true, if code execution is allowed + */ + bool executableCartRam() const override { return false; } + /** Get a descriptor for the device name (used in error checking). diff --git a/src/emucore/CartF6SC.hxx b/src/emucore/CartF6SC.hxx index 0dc6be2ae..746e6a8c2 100644 --- a/src/emucore/CartF6SC.hxx +++ b/src/emucore/CartF6SC.hxx @@ -49,6 +49,13 @@ class CartridgeF6SC : public CartridgeF6 ~CartridgeF6SC() override = default; public: + /** + Query wether the cart RAM allows code execution. + + @return true, if code execution is allowed + */ + bool executableCartRam() const override { return false; } + /** Get a descriptor for the device name (used in error checking). diff --git a/src/emucore/CartF8SC.hxx b/src/emucore/CartF8SC.hxx index d1338e5ee..f145954e5 100644 --- a/src/emucore/CartF8SC.hxx +++ b/src/emucore/CartF8SC.hxx @@ -49,6 +49,13 @@ class CartridgeF8SC : public CartridgeF8 ~CartridgeF8SC() override = default; public: + /** + Query wether the cart RAM allows code execution. + + @return true, if code execution is allowed + */ + bool executableCartRam() const override { return false; } + /** Get a descriptor for the device name (used in error checking). diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index 98fdf9b4a..ddc4be7f1 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -339,6 +339,10 @@ inline void M6502::_execute(uInt64 cycles, DispatchResult& result) icycles = 0; #ifdef DEBUGGER_SUPPORT const uInt16 oldPC = PC; + + // Only check for code in RAM execution if we have debugger support + if(!mySystem->cart().canExecute(PC)) + FatalEmulationError::raise("cannot run code from cart RAM"); #endif // Fetch instruction at the program counter