From bb63ea3dd193cc569edfa4af1c88962ccc255910 Mon Sep 17 00:00:00 2001 From: stephena Date: Mon, 7 Nov 2011 22:50:23 +0000 Subject: [PATCH] Reverted TIA changes that affect late NUSIZx changes. More work is needed in this area. Added commandline argument 'thumb.trapfatal', which causes fatal errors in the Thumb ARM emulation to really be treated as fatal (ie, the emulation stops and throws an exception). This is enabled by default (as it always should be). When disabled, fatal errors simply log the error and continue with emulation. This was added because the current HarmonyCart ARM code isn't always exactly compatible with the emulation in Stella, and there is a lagtime from when Harmony implements something to when the same functionality is added to Stella. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2279 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/common/Version.hxx | 2 +- src/emucore/CartDPCPlus.cxx | 3 +- src/emucore/Settings.cxx | 3 ++ src/emucore/TIATables.cxx | 4 +-- src/emucore/Thumbulator.cxx | 58 +++++++++++++++++-------------------- src/emucore/Thumbulator.hxx | 22 ++++++++++++-- 6 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/common/Version.hxx b/src/common/Version.hxx index 4064098cc..0e51c5855 100644 --- a/src/common/Version.hxx +++ b/src/common/Version.hxx @@ -22,7 +22,7 @@ #include -#define STELLA_VERSION "3.5_svn_test1" +#define STELLA_VERSION "3.5_svn_test2" #define STELLA_BUILD atoi("$Rev$" + 6) #endif diff --git a/src/emucore/CartDPCPlus.cxx b/src/emucore/CartDPCPlus.cxx index 8011b1148..2cc4adc8c 100644 --- a/src/emucore/CartDPCPlus.cxx +++ b/src/emucore/CartDPCPlus.cxx @@ -68,7 +68,8 @@ CartridgeDPCPlus::CartridgeDPCPlus(const uInt8* image, uInt32 size, #ifdef THUMB_SUPPORT // Create Thumbulator ARM emulator myThumbEmulator = new Thumbulator((uInt16*)(myProgramImage-0xC00), - (uInt16*)myDPCRAM); + (uInt16*)myDPCRAM, + settings.getBool("thumb.trapfatal")); #endif // Copy DPC display data to Harmony RAM diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index c430b8113..d36980121 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -137,6 +137,9 @@ Settings::Settings(OSystem* osystem) setInternal("resolvedata", "auto"); setInternal("gfxformat", "2"); setInternal("showaddr", "true"); + + // Thumb ARM emulation options + setInternal("thumb.trapfatal", "true"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/TIATables.cxx b/src/emucore/TIATables.cxx index 43f0e848e..a329d2ad6 100644 --- a/src/emucore/TIATables.cxx +++ b/src/emucore/TIATables.cxx @@ -620,8 +620,8 @@ const Int16 TIATables::PokeDelay[64] = { 1, // VBLANK (0) / 1 0, // WSYNC 0, // RSYNC - 0, // NUSIZ0 (0) / 8 TODO - calculate this instead of hardcoding - 0, // NUSIZ1 (0) / 8 TODO - calculate this instead of hardcoding + 8, // NUSIZ0 (0) / 8 TODO - calculate this instead of hardcoding + 8, // NUSIZ1 (0) / 8 TODO - calculate this instead of hardcoding 0, // COLUP0 0, // COLUP1 0, // COLUPF diff --git a/src/emucore/Thumbulator.cxx b/src/emucore/Thumbulator.cxx index b97fd7c98..d1385e246 100644 --- a/src/emucore/Thumbulator.cxx +++ b/src/emucore/Thumbulator.cxx @@ -31,13 +31,14 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Thumbulator::Thumbulator(uInt16* rom_ptr, uInt16* ram_ptr) +Thumbulator::Thumbulator(uInt16* rom_ptr, uInt16* ram_ptr, bool traponfatal) : rom(rom_ptr), ram(ram_ptr), copydata(0), DBUG(0), // dump detailed execution trace DISS(0) // dump Thumb instruction trace { + trapFatalErrors(traponfatal); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -74,7 +75,9 @@ inline int Thumbulator::fatalError(const char* opcode, uInt32 v1, const char* ms statusMsg << "Thumb ARM emulation fatal error: " << endl << opcode << "(" << HEX8 << v1 << "), " << msg << endl; dump_regs(); - throw statusMsg.str(); + if(trapOnFatal) + throw statusMsg.str(); + return 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -84,7 +87,9 @@ inline int Thumbulator::fatalError(const char* opcode, uInt32 v1, uInt32 v2, statusMsg << "Thumb ARM emulation fatal error: " << endl << opcode << "(" << HEX8 << v1 << "," << v2 << "), " << msg << endl; dump_regs(); - throw statusMsg.str(); + if(trapOnFatal) + throw statusMsg.str(); + return 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -116,13 +121,9 @@ void Thumbulator::dump_regs( void ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 Thumbulator::fetch16 ( uInt32 addr ) { - uInt32 data; - fetches++; - if(DBUG) - statusMsg << "fetch16(" << HEX8 << addr << ")="; - + uInt32 data; switch(addr&0xF0000000) { case 0x00000000: //ROM @@ -137,7 +138,7 @@ uInt32 Thumbulator::fetch16 ( uInt32 addr ) data=rom[addr]; #endif if(DBUG) - statusMsg << HEX4 << data << endl; + statusMsg << "fetch16(" << HEX8 << addr << ")=" << HEX4 << data << endl; return(data); case 0x40000000: //RAM @@ -149,7 +150,7 @@ uInt32 Thumbulator::fetch16 ( uInt32 addr ) data=ram[addr]; #endif if(DBUG) - statusMsg << HEX4 << data << endl; + statusMsg << "fetch16(" << HEX8 << addr << ")=" << HEX4 << data << endl; return(data); } return fatalError("fetch16", addr, "abort"); @@ -159,10 +160,6 @@ uInt32 Thumbulator::fetch16 ( uInt32 addr ) uInt32 Thumbulator::fetch32 ( uInt32 addr ) { uInt32 data; - - if(DBUG) - statusMsg << "fetch32(" << HEX8 << addr << ")="; - switch(addr&0xF0000000) { case 0x00000000: //ROM @@ -170,7 +167,7 @@ uInt32 Thumbulator::fetch32 ( uInt32 addr ) { data=read32(addr); if(DBUG) - statusMsg << HEX8 << data << endl; + statusMsg << "fetch32(" << HEX8 << addr << ")=" << HEX8 << data << endl; if(addr==0x00000000) return(data); if(addr==0x00000004) return(data); fatalError("fetch32", addr, "abort"); @@ -181,7 +178,7 @@ uInt32 Thumbulator::fetch32 ( uInt32 addr ) data<<=16; data|=fetch16(addr+0); if(DBUG) - statusMsg << HEX8 << data << endl;; + statusMsg << "fetch32(" << HEX8 << addr << ")=" << HEX8 << data << endl;; return(data); } return fatalError("fetch32", addr, "abort"); @@ -217,6 +214,8 @@ void Thumbulator::write16 ( uInt32 addr, uInt32 data ) case 0xE0000000: //MAMCR if(addr == 0xE01FC000) { + if(DBUG) + statusMsg << "write16(" << HEX8 << "MAMCR" << "," << HEX8 << data << ") *" << endl; mamcr = data; return; } @@ -277,9 +276,6 @@ uInt32 Thumbulator::read16 ( uInt32 addr ) reads++; - if(DBUG) - statusMsg << "read16(" << HEX8 << addr << ")="; - switch(addr&0xF0000000) { case 0x00000000: //ROM @@ -291,7 +287,7 @@ uInt32 Thumbulator::read16 ( uInt32 addr ) data=rom[addr]; #endif if(DBUG) - statusMsg << HEX4 << data << endl; + statusMsg << "read16(" << HEX8 << addr << ")=" << HEX4 << data << endl; return(data); case 0x40000000: //RAM @@ -303,12 +299,16 @@ uInt32 Thumbulator::read16 ( uInt32 addr ) data=ram[addr]; #endif if(DBUG) - statusMsg << HEX4 << data << endl; + statusMsg << "read16(" << HEX8 << addr << ")=" << HEX4 << data << endl; return(data); case 0xE0000000: //MAMCR if(addr == 0xE01FC000) + { + if(DBUG) + statusMsg << "read16(" << "MAMCR" << addr << ")=" << mamcr << " *"; return mamcr; + } } return fatalError("read16", addr, "abort"); } @@ -319,9 +319,6 @@ uInt32 Thumbulator::read32 ( uInt32 addr ) if(addr&3) fatalError("read32", addr, "abort - misaligned"); - if(DBUG) - statusMsg << "read32(" << HEX8 << addr << ")="; - uInt32 data; switch(addr&0xF0000000) { @@ -331,7 +328,7 @@ uInt32 Thumbulator::read32 ( uInt32 addr ) data<<=16; data|=read16(addr+0); if(DBUG) - statusMsg << HEX8 << data << endl; + statusMsg << "read32(" << HEX8 << addr << ")=" << HEX8 << data << endl; return(data); } return fatalError("read32", addr, "abort"); @@ -340,12 +337,9 @@ uInt32 Thumbulator::read32 ( uInt32 addr ) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 Thumbulator::read_register ( uInt32 reg ) { - uInt32 data; - reg&=0xF; - if(DBUG) - statusMsg << "read_register(" << dec << reg << ")="; + uInt32 data; switch(cpsr&0x1F) { case MODE_SVC: @@ -355,7 +349,7 @@ uInt32 Thumbulator::read_register ( uInt32 reg ) case 13: case 14: data=reg_svc[reg]; break; } if(DBUG) - statusMsg << HEX8 << data << endl; + statusMsg << "read_register(" << dec << reg << ")=" << HEX8 << data << endl; return(data); } return fatalError("read_register", cpsr, "invalid cpsr mode"); @@ -369,7 +363,6 @@ uInt32 Thumbulator::write_register ( uInt32 reg, uInt32 data ) if(DBUG) statusMsg << "write_register(" << dec << reg << "," << HEX8 << data << ")" << endl; - switch(cpsr&0x1F) { case MODE_SVC: @@ -2096,4 +2089,7 @@ int Thumbulator::reset ( void ) return(0); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool Thumbulator::trapOnFatal = true; + #endif diff --git a/src/emucore/Thumbulator.hxx b/src/emucore/Thumbulator.hxx index c4296eb74..340da0550 100644 --- a/src/emucore/Thumbulator.hxx +++ b/src/emucore/Thumbulator.hxx @@ -62,19 +62,33 @@ class Thumbulator { public: - Thumbulator(uInt16* rom, uInt16* ram); + Thumbulator(uInt16* rom, uInt16* ram, bool traponfatal); ~Thumbulator(); /** Run the ARM code, and return when finished. A string exception is - thrown in case of any fatal errors/aborts, containing the actual error, - and the contents of the registers at that point in time. + thrown in case of any fatal errors/aborts (if enabled), containing the + actual error, and the contents of the registers at that point in time. @return The results of any debugging output (if enabled), otherwise an empty string */ string run(); + /** + Normally when a fatal error is encountered, the ARM emulation + immediately throws an exception and exits. This method allows execution + to continue, and simply log the error. + + Note that this is meant for developers only, and should normally be + always enabled. It can be used to temporarily ignore illegal reads + and writes, but a ROM which consistently performs these operations + should be fixed, as it can cause crashes on real hardware. + + @param enable Enable (the default) or disable exceptions on fatal errors + */ + static void trapFatalErrors(bool enable) { trapOnFatal = enable; } + private: uInt32 read_register ( uInt32 reg ); uInt32 write_register ( uInt32 reg, uInt32 data ); @@ -128,6 +142,8 @@ class Thumbulator Int32 DBUG; // dump detailed execution trace Int32 DISS; // dump Thumb instruction trace ostringstream statusMsg; + + static bool trapOnFatal; }; #endif