[stella] 01/07: Imported Upstream version 4.7.2

Stephen Kitt skitt at moszumanska.debian.org
Tue Apr 19 21:57:37 UTC 2016


This is an automated email from the git hooks/post-receive script.

skitt pushed a commit to branch master
in repository stella.

commit b931f9e31c2916ef675b2326537be7635f1b4289
Author: Stephen Kitt <steve at sk2.org>
Date:   Mon Mar 28 21:13:00 2016 +0200

    Imported Upstream version 4.7.2
---
 Announce.txt                        |   22 +-
 Changes.txt                         |   20 +-
 configure                           |   62 +-
 debian/changelog                    |    7 +
 docs/index.html                     |    5 +-
 src/common/Version.hxx              |    6 +-
 src/common/bspf.hxx                 |    6 +-
 src/debugger/CpuDebug.cxx           |   14 +-
 src/debugger/gui/DebuggerDialog.cxx |    9 +-
 src/debugger/gui/PromptWidget.cxx   |   40 +-
 src/debugger/gui/PromptWidget.hxx   |    8 +-
 src/emucore/Cart.cxx                |    5 +-
 src/emucore/Cart.hxx                |    6 +-
 src/emucore/Device.hxx              |   13 +-
 src/emucore/EventHandler.cxx        |    4 +-
 src/emucore/EventHandler.hxx        |   14 +-
 src/emucore/TIA.hxx                 |    6 +-
 src/emucore/Thumbulator.cxx         | 1991 ++++++++++++++++++-----------------
 src/emucore/Thumbulator.hxx         |   84 +-
 src/gui/Rect.hxx                    |   10 +-
 src/macosx/Info-Stella.plist        |    2 +-
 src/unix/FSNodePOSIX.cxx            |    4 +-
 src/unix/stella.spec                |    5 +-
 src/windows/stella.rc               |    8 +-
 24 files changed, 1250 insertions(+), 1101 deletions(-)

diff --git a/Announce.txt b/Announce.txt
index 66c1e1b..0c30805 100644
--- a/Announce.txt
+++ b/Announce.txt
@@ -9,7 +9,7 @@
      SSSS     ttt  eeeee llll llll  aaaaa
 
 ===========================================================================
-                Release 4.7.1 for Linux, MacOSX and Windows
+                Release 4.7.2 for Linux, MacOSX and Windows
 ===========================================================================
 
 The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
@@ -21,30 +21,30 @@ all of your favourite Atari 2600 games again!  Stella was originally
 developed for Linux by Bradford W. Mott, however, it has been ported to a
 number of other platforms and is currently maintained by Stephen Anthony.
 
-This is the 4.7.1 release of Stella for Linux, Mac OSX and Windows.  The
+This is the 4.7.2 release of Stella for Linux, Mac OSX and Windows.  The
 distributions currently available are:
 
   * Binaries for Windows XP_SP3(*)/Vista/7/8/10 :
-      Stella-4.7.1-win32.exe   (32-bit EXE installer)
-      Stella-4.7.1-x64.exe     (64-bit EXE installer)
-      Stella-4.7.1-windows.zip (32/64 bit versions)
+      Stella-4.7.2-win32.exe   (32-bit EXE installer)
+      Stella-4.7.2-x64.exe     (64-bit EXE installer)
+      Stella-4.7.2-windows.zip (32/64 bit versions)
 
       (*) Note: Support for Windows XP is problematic on some systems,
           and will probably be discontinued in a future release.
 
   * Binary distribution for MacOS X 10.7 and above :
-      Stella-4.7.1-macosx.dmg (64-bit Intel)
+      Stella-4.7.2-macosx.dmg (64-bit Intel)
 
   * Binary distribution in 32-bit & 64-bit Ubuntu DEB format :
-      stella_4.7.1-1_i386.deb
-      stella_4.7.1-1_amd64.deb
+      stella_4.7.2-1_i386.deb
+      stella_4.7.2-1_amd64.deb
 
   * Binary distribution in 32-bit & 64-bit RPM format :
-      stella-4.7.1-2.i386.rpm
-      stella-4.7.1-2.x86_64.rpm
+      stella-4.7.2-2.i386.rpm
+      stella-4.7.2-2.x86_64.rpm
 
   * Source code distribution for all platforms :
-      stella-4.7.1-src.tar.xz
+      stella-4.7.2-src.tar.xz
 
 
 Distribution Site
diff --git a/Changes.txt b/Changes.txt
index 2c2d2da..60d1c65 100644
--- a/Changes.txt
+++ b/Changes.txt
@@ -12,6 +12,24 @@
                                Release History
 ===========================================================================
 
+4.7.1 to 4.7.2: (Mar. 25, 2016)
+
+  * Fixed bug when entering and exiting the debugger; sometimes the
+    character corresponding to the '`' key would be output in the
+    prompt area.
+
+  * Updated DPC+ Thumb ARM emulation code to latest from David Welch.
+    In particular, this fixes incorrect handling of the V flag when
+    adding and subtracting, but also fixes compile-time warnings that
+    I couldn't get rid of before.
+
+  * Updated UNIX configure script to work with GCC 6.x compilers, and to
+    remove references to obsolete compiler versions that can no longer
+    be used to compile Stella.
+
+-Have fun!
+
+
 4.7 to 4.7.1: (Feb. 13, 2016)
 
   * Improved TV 'jitter' emulation; the recovery time can now be spread
@@ -40,8 +58,6 @@
     (thanks go to RomHunter for his tireless research in this area).
     Related to this, updated the snapshot collection.
 
--Have fun!
-
 
 4.6.7 to 4.7: (January 25, 2016)
 
diff --git a/configure b/configure
index 1e4011b..0d90a4f 100755
--- a/configure
+++ b/configure
@@ -94,13 +94,13 @@ echocheck () {
 test_compiler ()
 {
 cat <<EOF >tmp_cxx_compiler.cpp
+#include <memory>
 class Foo {
 	int a;
 };
-int main(int argc, char **argv)
+int main(int argc, char* argv[])
 {
-	Foo *a = new Foo();
-	delete a;
+	std::shared_ptr<Foo> a = std::make_shared<Foo>();
 	return 0;
 }
 EOF
@@ -363,7 +363,7 @@ else
 fi
 
 for compiler in $compilers; do
-	if test_compiler $compiler; then
+	if test_compiler "$compiler -std=c++11"; then
 		CXX=$compiler
 		echo $CXX
 		break
@@ -379,34 +379,53 @@ fi
 
 echocheck "compiler version"
 
+have_clang=no
+cc_check_define __clang_version__ && have_clang=yes
 have_gcc=no
 cc_check_define __GNUC__ && have_gcc=yes
 
-if test "$have_gcc" = yes; then
+if test "$have_clang" = yes; then
 	cxx_name=`( $cc -v ) 2>&1 | tail -n 1 | cut -d ' ' -f 1`
-	cxx_version=`( $CXX -dumpversion ) 2>&1`
+	cxx_version=$( $CXX -dM -E -x c /dev/null | grep __clang_version__ | sed 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/g' 2>&1)
 	if test "$?" -gt 0; then
 		cxx_version="not found"
 	fi
 
 	case $cxx_version in
-		2.95.[2-9]|2.95.[2-9][-.]*|3.[0-9]|3.[0-9].[0-9]|3.[0-9].[0-9][-.]*|4.[0-9]|4.[0-9].[0-9]|4.[0-9].[0-9][-.]*|5.[0-9]|5.[0-9].[0-9]|5.[0-9].[0-9][-.]*)
+		[3].[4-9]|[3].[4-9].[0-9]|[3].[4-9].[0-9][-.]*)
 			_cxx_major=`echo $cxx_version | cut -d '.' -f 1`
 			_cxx_minor=`echo $cxx_version | cut -d '.' -f 2`
 			cxx_version="$cxx_version, ok"
 			cxx_verc_fail=no
 			;;
-		# whacky beos version strings
-		2.9-beos-991026*|2.9-beos-000224*)	
-			_cxx_major=2
-			_cxx_minor=95
+		'not found')
+			cxx_verc_fail=yes
+			;;
+		*)
+			cxx_version="$cxx_version, bad"
+			cxx_verc_fail=yes
+			;;
+	esac
+	CXXFLAGS="$CXXFLAGS"
+	_make_def_HAVE_GCC3='HAVE_GCC3 = 1'
+	add_line_to_config_mk 'CXX_UPDATE_DEP_FLAG = -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" -MQ "$@" -MP'
+	_make_def_HAVE_GCC='HAVE_GCC = 1'
+	echo "$cxx_version"
+
+elif test "$have_gcc" = yes; then
+	cxx_name=`( $cc -v ) 2>&1 | tail -n 1 | cut -d ' ' -f 1`
+	cxx_version=`( $CXX -dumpversion ) 2>&1`
+	if test "$?" -gt 0; then
+		cxx_version="not found"
+	fi
+
+	case $cxx_version in
+		4.[7-9]|4.[7-9].[0-9]|4.[7-9].[0-9][-.]*|[5-6].[0-9]|[5-6].[0-9].[0-9]|[5-6].[0-9].[0-9][-.]*)
+			_cxx_major=`echo $cxx_version | cut -d '.' -f 1`
+			_cxx_minor=`echo $cxx_version | cut -d '.' -f 2`
 			cxx_version="$cxx_version, ok"
 			cxx_verc_fail=no
 			;;
-		3_4)
-			_cxx_major=3
-			_mxx_minor=4
-			;;
 		'not found')
 			cxx_verc_fail=yes
 			;;
@@ -415,13 +434,12 @@ if test "$have_gcc" = yes; then
 			cxx_verc_fail=yes
 			;;
 	esac
-	if test "$_cxx_major" -ge "3" ; then
-		CXXFLAGS="$CXXFLAGS"
-		_make_def_HAVE_GCC3='HAVE_GCC3 = 1'
-		add_line_to_config_mk 'CXX_UPDATE_DEP_FLAG = -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" -MQ "$@" -MP'
-	fi;
+	CXXFLAGS="$CXXFLAGS"
+	_make_def_HAVE_GCC3='HAVE_GCC3 = 1'
+	add_line_to_config_mk 'CXX_UPDATE_DEP_FLAG = -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" -MQ "$@" -MP'
 	_make_def_HAVE_GCC='HAVE_GCC = 1'
 	echo "$cxx_version"
+
 else
 	cxx_version=`( $CXX -version ) 2>&1`
 	if test "$?" -eq 0; then
@@ -467,8 +485,8 @@ fi
 if test "$cxx_verc_fail" = yes ; then
 	echo
 	echo "The version of your compiler is not supported at this time"
-	echo "Please ensure you are using GCC 2.95.x or GCC 3.x"
-	#exit 1	
+	echo "Please ensure you are using GCC 4.7 / Clang 3.4 or above"
+	exit 1	
 fi
 
 #
diff --git a/debian/changelog b/debian/changelog
index 6dbeb49..be5fb9a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+stella (4.7.2-1) stable; urgency=high
+
+  * Version 4.7.2 release
+
+ -- Stephen Anthony <stephena at users.sf.net>  Fri, 25 Mar 2016 17:09:59 -0230
+
+
 stella (4.7.1-1) stable; urgency=high
 
   * Version 4.7.1 release
diff --git a/docs/index.html b/docs/index.html
index 8bbc4bb..efa3be6 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -10,7 +10,7 @@
   <br><br>
   <center><h2><b>A multi-platform Atari 2600 VCS emulator</b></h2></center>
 
-  <center><h4><b>Release 4.7.1</b></h4></center>
+  <center><h4><b>Release 4.7.2</b></h4></center>
   <br><br>
 
   <center><h2><b>User's Guide</b></h2></center>
@@ -54,7 +54,7 @@
 
   <br><br><br>
 
-  <center><b>February 1999 - February 2016</b></center>
+  <center><b>February 1999 - March 2016</b></center>
     <center><b>The Stella Team</b></center>
   <center><b><a href="http://stella.sourceforge.net">Stella Homepage</a></b></center>
 
@@ -3236,6 +3236,7 @@ Ms Pac-Man (Stella extended codes):
         <tr><td>BF </td><td>CPUWIZ 256K </td></tr>
         <tr><td>BFSC </td><td>CPUWIZ 256K + ram</td></tr>
         <tr><td>CM ¹</td><td>Spectravideo CompuMate </td></tr>
+        <tr><td>CTY ¹²</td><td>CDW - Chetiry </td></tr>
         <tr><td>CV </td><td>Commavid extra ram </td></tr>
         <tr><td>CV+ </td><td>Extended Commavid extra ram</td></tr>
         <tr><td>DASH </td><td>Boulder Dash 2 </td></tr>
diff --git a/src/common/Version.hxx b/src/common/Version.hxx
index 00c3d73..8ce86af 100644
--- a/src/common/Version.hxx
+++ b/src/common/Version.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Version.hxx 3279 2016-02-13 01:21:28Z stephena $
+// $Id: Version.hxx 3297 2016-03-25 20:51:28Z stephena $
 //============================================================================
 
 #ifndef VERSION_HXX
@@ -22,7 +22,7 @@
 
 #include <cstdlib>
 
-#define STELLA_VERSION "4.7.1"
-#define STELLA_BUILD atoi("$Rev: 3279 $" + 6)
+#define STELLA_VERSION "4.7.2"
+#define STELLA_BUILD atoi("$Rev: 3297 $" + 6)
 
 #endif
diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx
index f5a3c35..4b182bd 100644
--- a/src/common/bspf.hxx
+++ b/src/common/bspf.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: bspf.hxx 3239 2015-12-29 19:22:46Z stephena $
+// $Id: bspf.hxx 3294 2016-03-05 18:35:25Z stephena $
 //============================================================================
 
 #ifndef BSPF_HXX
@@ -25,7 +25,7 @@
   that need to be defined for different operating systems.
 
   @author Bradford W. Mott
-  @version $Id: bspf.hxx 3239 2015-12-29 19:22:46Z stephena $
+  @version $Id: bspf.hxx 3294 2016-03-05 18:35:25Z stephena $
 */
 
 #include <cstdint>
@@ -160,7 +160,7 @@ inline size_t BSPF_findIgnoreCase(const string& s1, const string& s2, int startp
     s2.begin(), s2.end(), [](char ch1, char ch2) {
       return toupper(uInt8(ch1)) == toupper(uInt8(ch2));
     });
-  return pos == s1.end() ? string::npos : pos - (s1.begin()+startpos);
+  return pos == s1.end() ? string::npos : size_t(pos - (s1.begin()+startpos));
 }
 
 // Test whether the first string ends with the second one (case insensitive)
diff --git a/src/debugger/CpuDebug.cxx b/src/debugger/CpuDebug.cxx
index dde8c39..b777576 100644
--- a/src/debugger/CpuDebug.cxx
+++ b/src/debugger/CpuDebug.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: CpuDebug.cxx 3239 2015-12-29 19:22:46Z stephena $
+// $Id: CpuDebug.cxx 3292 2016-02-27 22:18:30Z stephena $
 //============================================================================
 
 #include <sstream>
@@ -74,13 +74,13 @@ void CpuDebug::saveOldState()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CpuDebug::setPC(int pc)
 {
-  my6502.PC = pc;
+  my6502.PC = uInt16(pc);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CpuDebug::setSP(int sp)
 {
-  my6502.SP = sp;
+  my6502.SP = uInt8(sp);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -92,19 +92,19 @@ void CpuDebug::setPS(int ps)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CpuDebug::setA(int a)
 {
-  my6502.A = a;
+  my6502.A = uInt8(a);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CpuDebug::setX(int x)
 {
-  my6502.X = x;
+  my6502.X = uInt8(x);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void CpuDebug::setY(int y)
 {
-  my6502.Y = y;
+  my6502.Y = uInt8(y);
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -120,7 +120,7 @@ void CpuDebug::setV(bool on)
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void CpuDebug::setB(bool on)
+void CpuDebug::setB(bool)
 {
   // nop - B is always true
 }
diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx
index 1d550f7..c332f3e 100644
--- a/src/debugger/gui/DebuggerDialog.cxx
+++ b/src/debugger/gui/DebuggerDialog.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: DebuggerDialog.cxx 3242 2015-12-29 22:39:08Z stephena $
+// $Id: DebuggerDialog.cxx 3295 2016-03-07 15:36:09Z stephena $
 //============================================================================
 
 #include "Widget.hxx"
@@ -80,7 +80,12 @@ void DebuggerDialog::loadConfig()
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void DebuggerDialog::handleKeyDown(StellaKey key, StellaMod mod)
 {
-  if(instance().eventHandler().kbdControl(mod))
+  if(key == KBDK_GRAVE && !instance().eventHandler().kbdShift(mod))
+  {
+    // Swallow backtick, so we don't see it when exiting the debugger
+    instance().eventHandler().enableTextEvents(false);
+  }
+  else if(instance().eventHandler().kbdControl(mod))
   {
     switch(key)
     {
diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx
index 775d9a7..0aeac3e 100644
--- a/src/debugger/gui/PromptWidget.cxx
+++ b/src/debugger/gui/PromptWidget.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: PromptWidget.cxx 3242 2015-12-29 22:39:08Z stephena $
+// $Id: PromptWidget.cxx 3295 2016-03-07 15:36:09Z stephena $
 //============================================================================
 
 #include <iostream>
@@ -524,15 +524,9 @@ void PromptWidget::specialKeys(StellaKey key)
 
   switch(key)
   {
-    case KBDK_A:
-      _currentPos = _promptStartPos;
-      break;
     case KBDK_D:
       killChar(+1);
       break;
-    case KBDK_E:
-      _currentPos = _promptEndPos;
-      break;
     case KBDK_K:
       killLine(+1);
       break;
@@ -542,6 +536,18 @@ void PromptWidget::specialKeys(StellaKey key)
     case KBDK_W:
       killLastWord();
       break;
+    case KBDK_A:
+      textSelectAll();
+      break;
+    case KBDK_X:
+      textCut();
+      break;
+    case KBDK_C:
+      textCopy();
+      break;
+    case KBDK_V:
+      textPaste();
+      break;
     default:
       handled = false;
       break;
@@ -629,6 +635,26 @@ void PromptWidget::killLastWord()
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PromptWidget::textSelectAll()
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PromptWidget::textCut()
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PromptWidget::textCopy()
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void PromptWidget::textPaste()
+{
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void PromptWidget::addToHistory(const char* str)
 {
   strncpy(_history[_historyIndex], str, kLineBufferSize-1);
diff --git a/src/debugger/gui/PromptWidget.hxx b/src/debugger/gui/PromptWidget.hxx
index 15c4b37..2baa0d8 100644
--- a/src/debugger/gui/PromptWidget.hxx
+++ b/src/debugger/gui/PromptWidget.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: PromptWidget.hxx 3242 2015-12-29 22:39:08Z stephena $
+// $Id: PromptWidget.hxx 3287 2016-02-24 20:49:49Z stephena $
 //============================================================================
 
 #ifndef PROMPT_WIDGET_HXX
@@ -62,6 +62,12 @@ class PromptWidget : public Widget, public CommandSender
     void killLine(int direction);
     void killLastWord();
 
+    // Clipboard
+    void textSelectAll();
+    void textCut();
+    void textCopy();
+    void textPaste();
+
     // History
     void addToHistory(const char *str);
     void historyScroll(int direction);
diff --git a/src/emucore/Cart.cxx b/src/emucore/Cart.cxx
index 33c0043..38caf8b 100644
--- a/src/emucore/Cart.cxx
+++ b/src/emucore/Cart.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Cart.cxx 3263 2016-01-25 20:49:21Z stephena $
+// $Id: Cart.cxx 3294 2016-03-05 18:35:25Z stephena $
 //============================================================================
 
 #include <cstring>
@@ -981,9 +981,10 @@ Cartridge::BankswitchType Cartridge::ourBSList[ourNumBSTypes] = {
   { "AR",       "AR (Supercharger)"             },
   { "BF",       "BF (CPUWIZ 256K)"              },
   { "BFSC",     "BFSC (CPUWIZ 256K + ram)"      },
+  { "CM",       "CM (SpectraVideo CompuMate)"   },
+  { "CTY",      "CTY (CDW - Chetiry)"           },
   { "CV",       "CV (Commavid extra ram)"       },
   { "CV+",      "CV+ (Extended Commavid)"       },
-  { "CM",       "CM (SpectraVideo CompuMate)"   },
   { "DASH",     "DASH (Experimental)"           },
   { "DF",       "DF (CPUWIZ 128K)"              },
   { "DFSC",     "DFSC (CPUWIZ 128K + ram)"      },
diff --git a/src/emucore/Cart.hxx b/src/emucore/Cart.hxx
index bdd7f9f..a9357f0 100644
--- a/src/emucore/Cart.hxx
+++ b/src/emucore/Cart.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Cart.hxx 3258 2016-01-23 22:56:16Z stephena $
+// $Id: Cart.hxx 3294 2016-03-05 18:35:25Z stephena $
 //============================================================================
 
 #ifndef CARTRIDGE_HXX
@@ -41,7 +41,7 @@ class GuiObject;
   0x1000-0x2000 area (or its mirrors).
 
   @author  Bradford W. Mott
-  @version $Id: Cart.hxx 3258 2016-01-23 22:56:16Z stephena $
+  @version $Id: Cart.hxx 3294 2016-03-05 18:35:25Z stephena $
 */
 class Cartridge : public Device
 {
@@ -190,7 +190,7 @@ class Cartridge : public Device
       const char* type;
       const char* desc;
     };
-    enum { ourNumBSTypes = 46 };
+    enum { ourNumBSTypes = 47 };
     static BankswitchType ourBSList[ourNumBSTypes];
 
   protected:
diff --git a/src/emucore/Device.hxx b/src/emucore/Device.hxx
index ac86e24..610f8d6 100644
--- a/src/emucore/Device.hxx
+++ b/src/emucore/Device.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Device.hxx 3240 2015-12-29 21:28:10Z stephena $
+// $Id: Device.hxx 3292 2016-02-27 22:18:30Z stephena $
 //============================================================================
 
 #ifndef DEVICE_HXX
@@ -30,7 +30,7 @@ class System;
   based system.
 
   @author  Bradford W. Mott
-  @version $Id: Device.hxx 3240 2015-12-29 21:28:10Z stephena $
+  @version $Id: Device.hxx 3292 2016-02-27 22:18:30Z stephena $
 */
 class Device : public Serializable
 {
@@ -112,12 +112,17 @@ class Device : public Serializable
     virtual bool poke(uInt16 address, uInt8 value) = 0;
 
     /**
-      Query/change the given address type to use the given disassembly flags
+      Query the given address for its disassembly flags
 
       @param address The address to modify
-      @param flags A bitfield of DisasmType directives for the given address
     */
     virtual uInt8 getAccessFlags(uInt16 address) const { return 0; }
+    /**
+      Change the given address type to use the given disassembly flags
+
+      @param address The address to modify
+      @param flags   A bitfield of DisasmType directives for the given address
+    */
     virtual void setAccessFlags(uInt16 address, uInt8 flags) { }
 
   protected:
diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx
index fe8f6ef..6151225 100644
--- a/src/emucore/EventHandler.cxx
+++ b/src/emucore/EventHandler.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: EventHandler.cxx 3270 2016-01-31 03:42:23Z stephena $
+// $Id: EventHandler.cxx 3287 2016-02-24 20:49:49Z stephena $
 //============================================================================
 
 #include <sstream>
@@ -541,7 +541,7 @@ void EventHandler::handleKeyEvent(StellaKey key, StellaMod mod, bool state)
   // Handle keys which switch eventhandler state
   // Arrange the logic to take advantage of short-circuit evaluation
   if(!(kbdControl(mod) || kbdShift(mod) || kbdAlt(mod)) &&
-      state && eventStateChange(myKeyTable[key][kEmulationMode]))
+      !state && eventStateChange(myKeyTable[key][kEmulationMode]))
     return;
 
   // Otherwise, let the event handler deal with it
diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx
index 60cf178..e8f4928 100644
--- a/src/emucore/EventHandler.hxx
+++ b/src/emucore/EventHandler.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: EventHandler.hxx 3270 2016-01-31 03:42:23Z stephena $
+// $Id: EventHandler.hxx 3287 2016-02-24 20:49:49Z stephena $
 //============================================================================
 
 #ifndef EVENTHANDLER_HXX
@@ -76,7 +76,7 @@ enum EventMode {
   mapping can take place.
 
   @author  Stephen Anthony
-  @version $Id: EventHandler.hxx 3270 2016-01-31 03:42:23Z stephena $
+  @version $Id: EventHandler.hxx 3287 2016-02-24 20:49:49Z stephena $
 */
 class EventHandler
 {
@@ -329,6 +329,11 @@ class EventHandler
     */
     void removeJoystickFromDatabase(const string& name);
 
+    /**
+      Enable/disable text events (distinct from single-key events).
+    */
+    virtual void enableTextEvents(bool enable) = 0;
+
   protected:
     // Global OSystem object
     OSystem& myOSystem;
@@ -346,11 +351,6 @@ class EventHandler
     void handleJoyHatEvent(int stick, int hat, int value);
 
     /**
-      Enable/disable text events (distinct from single-key events).
-    */
-    virtual void enableTextEvents(bool enable) = 0;
-
-    /**
       Returns the human-readable name for a StellaKey.
     */
     virtual const char* nameForKey(StellaKey key) const { return EmptyString.c_str(); }
diff --git a/src/emucore/TIA.hxx b/src/emucore/TIA.hxx
index cd13b6a..fcf5d3a 100644
--- a/src/emucore/TIA.hxx
+++ b/src/emucore/TIA.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: TIA.hxx 3276 2016-02-12 14:23:40Z stephena $
+// $Id: TIA.hxx 3292 2016-02-27 22:18:30Z stephena $
 //============================================================================
 
 #ifndef TIA_HXX
@@ -41,7 +41,7 @@ class Sound;
   be displayed on screen.
 
   @author  Bradford W. Mott
-  @version $Id: TIA.hxx 3276 2016-02-12 14:23:40Z stephena $
+  @version $Id: TIA.hxx 3292 2016-02-27 22:18:30Z stephena $
 */
 class TIA : public Device
 {
@@ -217,7 +217,7 @@ class TIA : public Device
       based on how many frames of out the total count are PAL frames.
     */
     bool isPAL() const
-      { return float(myPALFrameCounter) / myFrameCounter >= (25.0/60.0); }
+      { return double(myPALFrameCounter) / myFrameCounter >= (25.0/60.0); }
 
     /**
       Answers the current color clock we've gotten to on this scanline.
diff --git a/src/emucore/Thumbulator.cxx b/src/emucore/Thumbulator.cxx
index 3ef06bc..9f6188e 100644
--- a/src/emucore/Thumbulator.cxx
+++ b/src/emucore/Thumbulator.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Thumbulator.cxx 3240 2015-12-29 21:28:10Z stephena $
+// $Id: Thumbulator.cxx 3290 2016-02-27 19:58:20Z stephena $
 //============================================================================
 
 //============================================================================
@@ -58,26 +58,20 @@ using namespace Common;
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, bool traponfatal)
   : rom(rom_ptr),
-    ram(ram_ptr),
-    halfadd(0),
-    cpsr(0),
-    mamcr(0),
-    instructions(0),
-    fetches(0),
-    reads(0),
-    writes(0)
+    ram(ram_ptr)
 {
   trapFatalErrors(traponfatal);
+  reset();
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-string Thumbulator::run( void )
+string Thumbulator::run()
 {
   reset();
   for(;;)
   {
-    if (execute()) break;
-    if (instructions > 500000) // way more than would otherwise be possible
+    if(execute()) break;
+    if(instructions > 500000) // way more than would otherwise be possible
       throw runtime_error("instructions > 500000");
   }
 #if defined(THUMB_DISS) || defined(THUMB_DBUG)
@@ -111,107 +105,105 @@ inline int Thumbulator::fatalError(const char* opcode, uInt32 v1, uInt32 v2,
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::dump_counters ( void )
+void Thumbulator::dump_counters()
 {
   cout << endl << endl
        << "instructions " << instructions << endl
        << "fetches      " << fetches << endl
        << "reads        " << reads << endl
        << "writes       " << writes << endl
-       << "memcycles    " << (fetches+reads+writes) << endl;
+       << "memcycles    " << (fetches+reads+writes) << endl
+       << "systick_ints " << systick_ints << endl;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::dump_regs( void )
+void Thumbulator::dump_regs()
 {
   for (int cnt = 1; cnt < 14; cnt++)
   {
-    statusMsg << "R" << cnt << " = " << Base::HEX8 << reg_sys[cnt-1] << "  ";
+    statusMsg << "R" << cnt << " = " << Base::HEX8 << reg_norm[cnt-1] << "  ";
     if(cnt % 4 == 0) statusMsg << endl;
   }
   statusMsg << endl
-            << "SP = " << Base::HEX8 << reg_svc[13] << "  "
-            << "LR = " << Base::HEX8 << reg_svc[14] << "  "
-            << "PC = " << Base::HEX8 << reg_sys[15] << "  "
+            << "SP = " << Base::HEX8 << reg_norm[13] << "  "
+            << "LR = " << Base::HEX8 << reg_norm[14] << "  "
+            << "PC = " << Base::HEX8 << reg_norm[15] << "  "
             << endl;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Thumbulator::fetch16 ( uInt32 addr )
+uInt32 Thumbulator::fetch16(uInt32 addr)
 {
   fetches++;
 
   uInt32 data;
-  switch(addr&0xF0000000)
+  switch(addr & 0xF0000000)
   {
     case 0x00000000: //ROM
       addr &= ROMADDMASK;
-      if(addr<0x50)
+      if(addr < 0x50)
         fatalError("fetch16", addr, "abort");
 
-      addr>>=1;
-      data=CONV_RAMROM(rom[addr]);
+      addr >>= 1;
+      data = CONV_RAMROM(rom[addr]);
       DO_DBUG(statusMsg << "fetch16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
-      return(data);
+      return data;
 
     case 0x40000000: //RAM
       addr &= RAMADDMASK;
-      addr>>=1;
+      addr >>= 1;
       data=CONV_RAMROM(ram[addr]);
       DO_DBUG(statusMsg << "fetch16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
-      return(data);
+      return data;
   }
   return fatalError("fetch16", addr, "abort");
 }
 
-#if 0  // Currently not used anywhere in this class
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Thumbulator::fetch32 ( uInt32 addr )
+uInt32 Thumbulator::fetch32(uInt32 addr)
 {
   uInt32 data;
-  switch(addr&0xF0000000)
+  switch(addr & 0xF0000000)
   {
     case 0x00000000: //ROM
-      if(addr<0x50)
+      if(addr < 0x50)
       {
-        data=read32(addr);
+        data = read32(addr);
         DO_DBUG(statusMsg << "fetch32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
-        if(addr==0x00000000) return(data);
-        if(addr==0x00000004) return(data);
+        if(addr == 0x00000000) return data;
+        if(addr == 0x00000004) return data;
+        if(addr == 0x0000003C) return data;
         fatalError("fetch32", addr, "abort");
       }
 
     case 0x40000000: //RAM
-      data =fetch16(addr+2);
-      data<<=16;
-      data|=fetch16(addr+0);
+      data = read32(addr);
       DO_DBUG(statusMsg << "fetch32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
-      return(data);
+      return data;
   }
   return fatalError("fetch32", addr, "abort");
 }
-#endif
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::write16 ( uInt32 addr, uInt32 data )
+void Thumbulator::write16(uInt32 addr, uInt32 data)
 {
-  if((addr>0x40001fff)&&(addr<0x50000000))
+  if((addr > 0x40001fff) && (addr < 0x50000000))
     fatalError("write16", addr, "abort - out of range");
-  else if((addr>0x40000028)&&(addr<0x40000c00))
+  else if((addr > 0x40000028) && (addr < 0x40000c00))
     fatalError("write16", addr, "to bankswitch code area");
-  if(addr&1)
+  if(addr & 1)
     fatalError("write16", addr, "abort - misaligned");
 
   writes++;
 
   DO_DBUG(statusMsg << "write16(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")" << endl);
 
-  switch(addr&0xF0000000)
+  switch(addr & 0xF0000000)
   {
     case 0x40000000: //RAM
-      addr&=RAMADDMASK;
-      addr>>=1;
-      ram[addr]=CONV_DATA(data);
+      addr &= RAMADDMASK;
+      addr >>= 1;
+      ram[addr] = CONV_DATA(data);
       return;
 
     case 0xE0000000: //MAMCR
@@ -226,18 +218,18 @@ void Thumbulator::write16 ( uInt32 addr, uInt32 data )
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::write32 ( uInt32 addr, uInt32 data )
+void Thumbulator::write32(uInt32 addr, uInt32 data)
 {
-  if(addr&3)
+  if(addr & 3)
     fatalError("write32", addr, "abort - misaligned");
 
   DO_DBUG(statusMsg << "write32(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")" << endl);
 
-  switch(addr&0xF0000000)
+  switch(addr & 0xF0000000)
   {
     case 0xF0000000: //halt
       dump_counters();
-      throw runtime_error("HALT");// exit(0);
+      throw runtime_error("HALT");
 
     case 0xE0000000: //periph
       switch(addr)
@@ -245,51 +237,88 @@ void Thumbulator::write32 ( uInt32 addr, uInt32 data )
         case 0xE0000000:
           DO_DISS(statusMsg << "uart: [" << char(data&0xFF) << "]" << endl);
           break;
+
+        case 0xE000E010:
+        {
+          uInt32 old = systick_ctrl;
+          systick_ctrl = data & 0x00010007;
+          if(((old & 1) == 0) && (systick_ctrl & 1))
+          {
+            // timer started, load count
+            systick_count = systick_reload;
+          }
+          break;
+        }
+
+        case 0xE000E014:
+          systick_reload = data & 0x00FFFFFF;
+          break;
+
+        case 0xE000E018:
+          systick_count = data & 0x00FFFFFF;
+          break;
+
+        case 0xE000E01C:
+          systick_calibrate = data & 0x00FFFFFF;
+          break;
       }
       return;
 
     case 0xD0000000: //debug
-      statusMsg << "[" << Base::HEX8 << read_register(14) << "]["
-                << addr << "] " << data << endl;
+      switch(addr & 0xFF)
+      {
+        case 0x00:
+          statusMsg << "[" << Base::HEX8 << read_register(14) << "]["
+                    << addr << "] " << data << endl;
+          return;
+
+        case 0x10:
+          statusMsg << Base::HEX8 << data << endl;
+          return;
+
+        case 0x20:
+          statusMsg << Base::HEX8 << data << endl;
+          return;
+      }
       return;
-
+      
     case 0x40000000: //RAM
-      write16(addr+0,(data>> 0)&0xFFFF);
-      write16(addr+2,(data>>16)&0xFFFF);
+      write16(addr+0, (data >>  0) & 0xFFFF);
+      write16(addr+2, (data >> 16) & 0xFFFF);
       return;
   }
   fatalError("write32", addr, data, "abort");
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Thumbulator::read16 ( uInt32 addr )
+uInt32 Thumbulator::read16(uInt32 addr)
 {
   uInt32 data;
 
-  if((addr>0x40001fff)&&(addr<0x50000000))
+  if((addr > 0x40001fff) && (addr < 0x50000000))
     fatalError("read16", addr, "abort - out of range");
-  else if((addr>0x7fff)&&(addr<0x10000000))
+  else if((addr > 0x7fff) && (addr < 0x10000000))
     fatalError("read16", addr, "abort - out of range");
-  if(addr&1)
+  if(addr & 1)
     fatalError("read16", addr, "abort - misaligned");
 
   reads++;
 
-  switch(addr&0xF0000000)
+  switch(addr & 0xF0000000)
   {
     case 0x00000000: //ROM
-      addr&=ROMADDMASK;
-      addr>>=1;
-      data=CONV_RAMROM(rom[addr]);
+      addr &= ROMADDMASK;
+      addr >>= 1;
+      data = CONV_RAMROM(rom[addr]);
       DO_DBUG(statusMsg << "read16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
-      return(data);
+      return data;
 
     case 0x40000000: //RAM
-      addr&=RAMADDMASK;
-      addr>>=1;
-      data=CONV_RAMROM(ram[addr]);
+      addr &= RAMADDMASK;
+      addr >>= 1;
+      data = CONV_RAMROM(ram[addr]);
       DO_DBUG(statusMsg << "read16(" << Base::HEX8 << addr << ")=" << Base::HEX4 << data << endl);
-      return(data);
+      return data;
 
     case 0xE0000000: //MAMCR
       if(addr == 0xE01FC000)
@@ -302,187 +331,237 @@ uInt32 Thumbulator::read16 ( uInt32 addr )
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Thumbulator::read32 ( uInt32 addr )
+uInt32 Thumbulator::read32(uInt32 addr)
 {
-  if(addr&3)
+  if(addr & 3)
     fatalError("read32", addr, "abort - misaligned");
 
   uInt32 data;
-  switch(addr&0xF0000000)
+  switch(addr & 0xF0000000)
   {
     case 0x00000000: //ROM
     case 0x40000000: //RAM
-      data =read16(addr+2);
-      data<<=16;
-      data|=read16(addr+0);
+      data = read16(addr+0);
+      data |= (uInt32(read16(addr+2))) << 16;
       DO_DBUG(statusMsg << "read32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << endl);
-      return(data);
+      return data;
+
+    case 0xE0000000:
+    {
+      switch(addr)
+      {
+        case 0xE000E010:
+          data = systick_ctrl;
+          systick_ctrl &= (~0x00010000);
+          return data;
+
+        case 0xE000E014:
+          data = systick_reload;
+          return data;
+
+        case 0xE000E018:
+          data = systick_count;
+          return data;
+
+        case 0xE000E01C:
+          data = systick_calibrate;
+          return data;
+      }
+    }
   }
   return fatalError("read32", addr, "abort");
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Thumbulator::read_register ( uInt32 reg )
+uInt32 Thumbulator::read_register(uInt32 reg)
 {
-  reg&=0xF;
+  reg &= 0xF;
 
-  uInt32 data;
-  switch(cpsr&0x1F)
+  uInt32 data = reg_norm[reg];
+  DO_DBUG(statusMsg << "read_register(" << dec << reg << ")=" << Base::HEX8 << data << endl);
+  if(reg == 15)
   {
-    case MODE_SVC:
-      switch(reg) // TODO (SA) - does this do anything other than default?
-      {
-        default: data=reg_sys[reg]; break;
-        case 13: case 14: data=reg_svc[reg]; break;
-      }
-      DO_DBUG(statusMsg << "read_register(" << dec << reg << ")=" << Base::HEX8 << data << endl);
-      return(data);
+    if(data & 1)
+    {
+      DO_DBUG(statusMsg << "pc has lsbit set 0x" << Base::HEX8 << data << endl);
+    }
+    data &= ~1;
   }
-  return fatalError("read_register", cpsr, "invalid cpsr mode");
+  return data;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-uInt32 Thumbulator::write_register ( uInt32 reg, uInt32 data )
+void Thumbulator::write_register(uInt32 reg, uInt32 data)
 {
-  reg&=0xF;
+  reg &= 0xF;
 
   DO_DBUG(statusMsg << "write_register(" << dec << reg << "," << Base::HEX8 << data << ")" << endl);
-  switch(cpsr&0x1F)
-  {
-    case MODE_SVC:
-      switch(reg) // TODO (SA) - does this do anything other than default?
-      {
-        default: reg_sys[reg]=data; break;
-        case 13: case 14: reg_svc[reg]=data; break;
-      }
-      return(data);
-  }
-  return fatalError("write_register", cpsr, "invalid cpsr mode");
+  if(reg == 15) data &= ~1;
+  reg_norm[reg] = data;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_zflag ( uInt32 x )
+void Thumbulator::do_zflag(uInt32 x)
 {
-  if(x==0) cpsr|=CPSR_Z;
-  else     cpsr&=~CPSR_Z;
+  if(x == 0) cpsr |= CPSR_Z;  else cpsr &= ~CPSR_Z;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_nflag ( uInt32 x )
+void Thumbulator::do_nflag(uInt32 x)
 {
-  if(x&0x80000000) cpsr|=CPSR_N;
-  else             cpsr&=~CPSR_N;
+  if(x & 0x80000000) cpsr|=CPSR_N;  else cpsr&=~CPSR_N;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_cflag ( uInt32 a, uInt32 b, uInt32 c )
+void Thumbulator::do_cflag(uInt32 a, uInt32 b, uInt32 c)
 {
   uInt32 rc;
 
-  cpsr&=~CPSR_C;
-  rc=(a&0x7FFFFFFF)+(b&0x7FFFFFFF)+c; //carry in
-  rc = (rc>>31)+(a>>31)+(b>>31);  //carry out
-  if(rc&2)
-    cpsr|=CPSR_C;
+  cpsr &= ~CPSR_C;
+  rc = (a & 0x7FFFFFFF) + (b & 0x7FFFFFFF) + c; //carry in
+  rc = (rc >> 31) + (a >> 31) + (b >> 31);      //carry out
+  if(rc & 2)
+    cpsr |= CPSR_C;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_sub_vflag ( uInt32 a, uInt32 b, uInt32 c )
+void Thumbulator::do_vflag(uInt32 a, uInt32 b, uInt32 c)
 {
-  cpsr&=~CPSR_V;
-
-  //if the sign bits are different
-  if((a&0x80000000)^(b&0x80000000))
-  {
-    //and result matches b
-    if((b&0x80000000)==(c&0x80000000))
-      cpsr|=CPSR_V;
-  }
+  uInt32 rc, rd;
+
+  cpsr &= ~CPSR_V;
+  rc = (a & 0x7FFFFFFF) + (b & 0x7FFFFFFF) + c; //carry in
+  rc >>= 31; //carry in in lsbit
+  rd = (rc & 1) + ((a >> 31) & 1) + ((b >> 31) & 1); //carry out
+  rd >>= 1; //carry out in lsbit
+  rc = (rc^rd) & 1; //if carry in != carry out then signed overflow
+  if(rc)
+    cpsr |= CPSR_V;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_add_vflag ( uInt32 a, uInt32 b, uInt32 c )
+void Thumbulator::do_cflag_bit(uInt32 x)
 {
-  cpsr&=~CPSR_V;
-
-  //if sign bits are the same
-  if((a&0x80000000)==(b&0x80000000))
-  {
-    //and the result is different
-    if((b&0x80000000)!=(c&0x80000000))
-      cpsr|=CPSR_V;
-  }
+  if(x) cpsr |= CPSR_C;  else cpsr &= ~CPSR_C;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_cflag_bit ( uInt32 x )
+void Thumbulator::do_vflag_bit(uInt32 x)
 {
-  if(x) cpsr|=CPSR_C;
-  else  cpsr&=~CPSR_C;
+  if(x) cpsr |= CPSR_V;  else cpsr &= ~CPSR_V;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void Thumbulator::do_vflag_bit ( uInt32 x )
+int Thumbulator::execute()
 {
-  if(x) cpsr|=CPSR_V;
-  else  cpsr&=~CPSR_V;
-}
+  uInt32 pc, sp, inst, ra, rb, rc, rm, rd, rn, rs, op;
 
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int Thumbulator::execute ( void )
-{
-  uInt32 pc, sp, inst,
-         ra,rb,rc,
-         rm,rd,rn,rs,
-         op;
-
-  pc=read_register(15);
-  inst=fetch16(pc-2);
-  pc+=2;
-  write_register(15,pc);
+  pc = read_register(15);
+
+#if 0  // FIXME SA - not sure if this should be enabled
+  if(handler_mode)
+  {
+    if((pc & 0xF0000000) == 0xF0000000)
+    {
+      uInt32 sp = read_register(13);
+      handler_mode = false;
+      write_register(0,  read32(sp)); sp += 4;
+      write_register(1,  read32(sp)); sp += 4;
+      write_register(2,  read32(sp)); sp += 4;
+      write_register(3,  read32(sp)); sp += 4;
+      write_register(12, read32(sp)); sp += 4;
+      write_register(14, read32(sp)); sp += 4;
+      pc = read32(sp); sp += 4;
+      cpsr = read32(sp); sp += 4;
+      write_register(13, sp);
+    }
+  }
+  if(systick_ctrl & 1)
+  {
+    if(systick_count)
+    {
+      systick_count--;
+    }
+    else
+    {
+      systick_count = systick_reload;
+      systick_ctrl |= 0x00010000;
+    }
+  }
+
+  if((systick_ctrl & 3) == 3)
+  {
+    if(systick_ctrl & 0x00010000)
+    {
+      if(!handler_mode)
+      {
+        systick_ints++;
+        uInt32 sp = read_register(13);
+        sp -= 4; write32(sp, cpsr);
+        sp -= 4; write32(sp, pc);
+        sp -= 4; write32(sp, read_register(14));
+        sp -= 4; write32(sp, read_register(12));
+        sp -= 4; write32(sp, read_register(3));
+        sp -= 4; write32(sp, read_register(2));
+        sp -= 4; write32(sp, read_register(1));
+        sp -= 4; write32(sp, read_register(0));
+        write_register(13, sp);
+        pc = fetch32(0x0000003C); //systick vector
+        pc += 2;
+        //write_register(14, 0xFFFFFF00);
+        write_register(14, 0xFFFFFFF9);
+
+        handler_mode = true;
+      }
+    }
+  }
+#endif
+
+  inst = fetch16(pc-2);
+  pc += 2;
+  write_register(15, pc);
   DO_DISS(statusMsg << Base::HEX8 << (pc-5) << ": " << Base::HEX4 << inst << " ");
 
   instructions++;
 
   //ADC
-  if((inst&0xFFC0)==0x4140)
+  if((inst & 0xFFC0) == 0x4140)
   {
-    rd=(inst>>0)&0x07;
-    rm=(inst>>3)&0x07;
+    rd = (inst >> 0) & 0x07;
+    rm = (inst >> 3) & 0x07;
     DO_DISS(statusMsg << "adc r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra+rb;
-    if(cpsr&CPSR_C)
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra + rb;
+    if(cpsr & CPSR_C)
       rc++;
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    if(cpsr&CPSR_C) do_cflag(ra,rb,1);
-    else            do_cflag(ra,rb,0);
-    do_add_vflag(ra,rb,rc);
-    return(0);
+    if(cpsr & CPSR_C) { do_cflag(ra, rb, 1); do_vflag(ra, rb, 1); }
+    else              { do_cflag(ra, rb, 0); do_vflag(ra, rb, 0); }
+    return 0;
   }
 
   //ADD(1) small immediate two registers
-  if((inst&0xFE00)==0x1C00)
+  if((inst & 0xFE00) == 0x1C00)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rb=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rb = (inst >> 6) & 0x7;
     if(rb)
     {
       DO_DISS(statusMsg << "adds r" << dec << rd << ",r" << dec << rn << ","
                         << "#0x" << Base::HEX2 << rb << endl);
-      ra=read_register(rn);
-      rc=ra+rb;
+      ra = read_register(rn);
+      rc = ra + rb;
       //fprintf(stderr,"0x%08X = 0x%08X + 0x%08X\n",rc,ra,rb);
-      write_register(rd,rc);
+      write_register(rd, rc);
       do_nflag(rc);
       do_zflag(rc);
-      do_cflag(ra,rb,0);
-      do_add_vflag(ra,rb,rc);
-      return(0);
+      do_cflag(ra, rb, 0);
+      do_vflag(ra, rb, 0);
+      return 0;
     }
     else
     {
@@ -491,326 +570,304 @@ int Thumbulator::execute ( void )
   }
 
   //ADD(2) big immediate one register
-  if((inst&0xF800)==0x3000)
+  if((inst & 0xF800) == 0x3000)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x7;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x7;
     DO_DISS(statusMsg << "adds r" << dec << rd << ",#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(rd);
-    rc=ra+rb;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rc = ra + rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,rb,0);
-    do_add_vflag(ra,-rb,rc);
-    return(0);
+    do_cflag(ra, rb, 0);
+    do_vflag(ra, rb, 0);
+    return 0;
   }
 
   //ADD(3) three registers
-  if((inst&0xFE00)==0x1800)
+  if((inst & 0xFE00) == 0x1800)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "adds r" << dec << rd << ",r" << dec << rn << ",r" << rm << endl);
-    ra=read_register(rn);
-    rb=read_register(rm);
-    rc=ra+rb;
-    write_register(rd,rc);
+    ra = read_register(rn);
+    rb = read_register(rm);
+    rc = ra + rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,rb,0);
-    do_add_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, rb, 0);
+    do_vflag(ra, rb, 0);
+    return 0;
   }
 
   //ADD(4) two registers one or both high no flags
-  if((inst&0xFF00)==0x4400)
+  if((inst & 0xFF00) == 0x4400)
   {
-    if((inst>>6)&3)
+    if((inst >> 6) & 3)
     {
       //UNPREDICTABLE
     }
-    rd=(inst>>0)&0x7;
-    rd|=(inst>>4)&0x8;
-    rm=(inst>>3)&0xF;
+    rd  = (inst >> 0) & 0x7;
+    rd |= (inst >> 4) & 0x8;
+    rm  = (inst >> 3) & 0xF;
     DO_DISS(statusMsg << "add r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra+rb;
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra + rb;
+    if(rd == 15)
+    {
+      if((rc & 1) == 0)
+        fatalError("add pc", pc, rc, " produced an arm address");
+
+      rc &= ~1; //write_register may do this as well
+      rc += 2;  //The program counter is special
+    }
     //fprintf(stderr,"0x%08X = 0x%08X + 0x%08X\n",rc,ra,rb);
-    write_register(rd,rc);
-    return(0);
+    write_register(rd, rc);
+    return 0;
   }
 
   //ADD(5) rd = pc plus immediate
-  if((inst&0xF800)==0xA000)
+  if((inst & 0xF800) == 0xA000)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x7;
-    rb<<=2;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x7;
+    rb <<= 2;
     DO_DISS(statusMsg << "add r" << dec << rd << ",PC,#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(15);
-    rc=(ra&(~3))+rb;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(15);
+    rc = (ra & (~3u)) + rb;
+    write_register(rd, rc);
+    return 0;
   }
 
   //ADD(6) rd = sp plus immediate
-  if((inst&0xF800)==0xA800)
+  if((inst & 0xF800) == 0xA800)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x7;
-    rb<<=2;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x7;
+    rb <<= 2;
     DO_DISS(statusMsg << "add r" << dec << rd << ",SP,#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(13);
-    rc=ra+rb;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(13);
+    rc = ra + rb;
+    write_register(rd, rc);
+    return 0;
   }
 
   //ADD(7) sp plus immediate
-  if((inst&0xFF80)==0xB000)
+  if((inst & 0xFF80) == 0xB000)
   {
-    rb=(inst>>0)&0x7F;
-    rb<<=2;
+    rb = (inst >> 0) & 0x7F;
+    rb <<= 2;
     DO_DISS(statusMsg << "add SP,#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(13);
-    rc=ra+rb;
-    write_register(13,rc);
-    return(0);
+    ra = read_register(13);
+    rc = ra + rb;
+    write_register(13, rc);
+    return 0;
   }
 
   //AND
-  if((inst&0xFFC0)==0x4000)
+  if((inst & 0xFFC0) == 0x4000)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "ands r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra&rb;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra & rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //ASR(1) two register immediate
-  if((inst&0xF800)==0x1000)
+  if((inst & 0xF800) == 0x1000)
   {
-    rd=(inst>>0)&0x07;
-    rm=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
+    rd = (inst >> 0) & 0x07;
+    rm = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
     DO_DISS(statusMsg << "asrs r" << dec << rd << ",r" << dec << rm << ",#0x" << Base::HEX2 << rb << endl);
-    rc=read_register(rm);
-    if(rb==0)
+    rc = read_register(rm);
+    if(rb == 0)
     {
-      if(rc&0x80000000)
+      if(rc & 0x80000000)
       {
         do_cflag_bit(1);
-        rc=~0;
+        rc = ~0;
       }
       else
       {
         do_cflag_bit(0);
-        rc=0;
+        rc = 0;
       }
     }
     else
     {
-      do_cflag_bit(rc&(1<<(rb-1)));
-      ra=rc&0x80000000;
-      rc>>=rb;
+      do_cflag_bit(rc & (1 << (rb-1)));
+      ra = rc & 0x80000000;
+      rc >>= rb;
       if(ra) //asr, sign is shifted in
-      {
-        rc|=(~0)<<(32-rb);
-      }
+        rc |= (~0u) << (32-rb);
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //ASR(2) two register
-  if((inst&0xFFC0)==0x4100)
+  if((inst & 0xFFC0) == 0x4100)
   {
-    rd=(inst>>0)&0x07;
-    rs=(inst>>3)&0x07;
+    rd = (inst >> 0) & 0x07;
+    rs = (inst >> 3) & 0x07;
     DO_DISS(statusMsg << "asrs r" << dec << rd << ",r" << dec << rs << endl);
-    rc=read_register(rd);
-    rb=read_register(rs);
-    rb&=0xFF;
-    if(rb==0)
+    rc = read_register(rd);
+    rb = read_register(rs);
+    rb &= 0xFF;
+    if(rb == 0)
     {
     }
-    else if(rb<32)
+    else if(rb < 32)
     {
-      do_cflag_bit(rc&(1<<(rb-1)));
-      ra=rc&0x80000000;
-      rc>>=rb;
+      do_cflag_bit(rc & (1 << (rb-1)));
+      ra = rc & 0x80000000;
+      rc >>= rb;
       if(ra) //asr, sign is shifted in
       {
-        rc|=(~0)<<(32-rb);
+        rc |= (~0u) << (32-rb);
       }
     }
     else
     {
-      if(rc&0x80000000)
+      if(rc & 0x80000000)
       {
         do_cflag_bit(1);
-        rc=(~0);
+        rc = (~0u);
       }
       else
       {
         do_cflag_bit(0);
-        rc=0;
+        rc = 0;
       }
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //B(1) conditional branch
-  if((inst&0xF000)==0xD000)
-  {
-    rb=(inst>>0)&0xFF;
-    if(rb&0x80)
-      rb|=(~0)<<8;  // FIXME - shifting a negative signed value is undefined
-    op=(inst>>8)&0xF;
-    rb<<=1;
-    rb+=pc;
-    rb+=2;
+  if((inst & 0xF000) == 0xD000)
+  {
+    rb = (inst >> 0) & 0xFF;
+    if(rb & 0x80)
+      rb |= (~0u) << 8;
+    op=(inst >> 8) & 0xF;
+    rb <<= 1;
+    rb += pc;
+    rb += 2;
     switch(op)
     {
       case 0x0: //b eq  z set
         DO_DISS(statusMsg << "beq 0x" << Base::HEX8 << (rb-3) << endl);
-        if(cpsr&CPSR_Z)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(cpsr & CPSR_Z)
+          write_register(15, rb);
+        return 0;
 
       case 0x1: //b ne  z clear
         DO_DISS(statusMsg << "bne 0x" << Base::HEX8 << (rb-3) << endl);
-        if(!(cpsr&CPSR_Z))
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(!(cpsr & CPSR_Z))
+          write_register(15, rb);
+        return 0;
 
       case 0x2: //b cs c set
         DO_DISS(statusMsg << "bcs 0x" << Base::HEX8 << (rb-3) << endl);
-        if(cpsr&CPSR_C)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(cpsr & CPSR_C)
+          write_register(15, rb);
+        return 0;
 
       case 0x3: //b cc c clear
         DO_DISS(statusMsg << "bcc 0x" << Base::HEX8 << (rb-3) << endl);
-        if(!(cpsr&CPSR_C))
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(!(cpsr & CPSR_C))
+          write_register(15, rb);
+        return 0;
 
       case 0x4: //b mi n set
         DO_DISS(statusMsg << "bmi 0x" << Base::HEX8 << (rb-3) << endl);
-        if(cpsr&CPSR_N)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(cpsr & CPSR_N)
+          write_register(15, rb);
+        return 0;
 
       case 0x5: //b pl n clear
         DO_DISS(statusMsg << "bpl 0x" << Base::HEX8 << (rb-3) << endl);
-        if(!(cpsr&CPSR_N))
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(!(cpsr & CPSR_N))
+          write_register(15, rb);
+        return 0;
 
       case 0x6: //b vs v set
         DO_DISS(statusMsg << "bvs 0x" << Base::HEX8 << (rb-3) << endl);
-        if(cpsr&CPSR_V)
-        {
+        if(cpsr & CPSR_V)
           write_register(15,rb);
-        }
-        return(0);
+        return 0;
 
       case 0x7: //b vc v clear
         DO_DISS(statusMsg << "bvc 0x" << Base::HEX8 << (rb-3) << endl);
-        if(!(cpsr&CPSR_V))
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if(!(cpsr & CPSR_V))
+          write_register(15, rb);
+        return 0;
 
       case 0x8: //b hi c set z clear
         DO_DISS(statusMsg << "bhi 0x" << Base::HEX8 << (rb-3) << endl);
-        if((cpsr&CPSR_C)&&(!(cpsr&CPSR_Z)))
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if((cpsr & CPSR_C) && (!(cpsr & CPSR_Z)))
+          write_register(15, rb);
+        return 0;
 
       case 0x9: //b ls c clear or z set
         DO_DISS(statusMsg << "bls 0x" << Base::HEX8 << (rb-3) << endl);
-        if((cpsr&CPSR_Z)||(!(cpsr&CPSR_C)))
-        {
-          write_register(15,rb);
-        }
-        return(0);
+        if((cpsr & CPSR_Z) || (!(cpsr & CPSR_C)))
+          write_register(15, rb);
+        return 0;
 
       case 0xA: //b ge N == V
         DO_DISS(statusMsg << "bge 0x" << Base::HEX8 << (rb-3) << endl);
-        ra=0;
-        if(  (cpsr&CPSR_N) &&  (cpsr&CPSR_V) ) ra++;
-        if((!(cpsr&CPSR_N))&&(!(cpsr&CPSR_V))) ra++;
+        ra = 0;
+        if(  (cpsr & CPSR_N)  &&   (cpsr & CPSR_V) ) ra++;
+        if((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))) ra++;
         if(ra)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+          write_register(15, rb);
+        return 0;
 
       case 0xB: //b lt N != V
         DO_DISS(statusMsg << "blt 0x" << Base::HEX8 << (rb-3) << endl);
-        ra=0;
-        if((!(cpsr&CPSR_N))&&(cpsr&CPSR_V)) ra++;
-        if((!(cpsr&CPSR_V))&&(cpsr&CPSR_N)) ra++;
+        ra = 0;
+        if((!(cpsr & CPSR_N)) && (cpsr & CPSR_V)) ra++;
+        if((!(cpsr & CPSR_V)) && (cpsr & CPSR_N)) ra++;
         if(ra)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+          write_register(15, rb);
+        return 0;
 
       case 0xC: //b gt Z==0 and N == V
         DO_DISS(statusMsg << "bgt 0x" << Base::HEX8 << (rb-3) << endl);
-        ra=0;
-        if(  (cpsr&CPSR_N) &&  (cpsr&CPSR_V) ) ra++;
-        if((!(cpsr&CPSR_N))&&(!(cpsr&CPSR_V))) ra++;
-        if(cpsr&CPSR_Z) ra=0;
+        ra = 0;
+        if(  (cpsr & CPSR_N)  &&   (cpsr & CPSR_V) ) ra++;
+        if((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))) ra++;
+        if(cpsr & CPSR_Z) ra = 0;
         if(ra)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+          write_register(15, rb);
+        return 0;
 
       case 0xD: //b le Z==1 or N != V
         DO_DISS(statusMsg << "ble 0x" << Base::HEX8 << (rb-3) << endl);
-        ra=0;
-        if((!(cpsr&CPSR_N))&&(cpsr&CPSR_V)) ra++;
-        if((!(cpsr&CPSR_V))&&(cpsr&CPSR_N)) ra++;
-        if(cpsr&CPSR_Z) ra++;
+        ra = 0;
+        if((!(cpsr & CPSR_N)) && (cpsr & CPSR_V)) ra++;
+        if((!(cpsr & CPSR_V)) && (cpsr & CPSR_N)) ra++;
+        if(cpsr & CPSR_Z) ra++;
         if(ra)
-        {
-          write_register(15,rb);
-        }
-        return(0);
+          write_register(15, rb);
+        return 0;
 
       case 0xE:
         //undefined instruction
@@ -823,238 +880,239 @@ int Thumbulator::execute ( void )
   }
 
   //B(2) unconditional branch
-  if((inst&0xF800)==0xE000)
-  {
-    rb=(inst>>0)&0x7FF;
-    if(rb&(1<<10))
-      rb|=(~0)<<11; // FIXME - shifting a negative signed value is undefined
-    rb<<=1;
-    rb+=pc;
-    rb+=2;
+  if((inst & 0xF800) == 0xE000)
+  {
+    rb = (inst >> 0) & 0x7FF;
+    if(rb & (1 << 10))
+      rb |= (~0u) << 11;
+    rb <<= 1;
+    rb += pc;
+    rb += 2;
     DO_DISS(statusMsg << "B 0x" << Base::HEX8 << (rb-3) << endl);
-    write_register(15,rb);
-    return(0);
+    write_register(15, rb);
+    return 0;
   }
 
   //BIC
-  if((inst&0xFFC0)==0x4380)
+  if((inst & 0xFFC0) == 0x4380)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "bics r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra&(~rb);
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra & (~rb);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //BKPT
-  if((inst&0xFF00)==0xBE00)
+  if((inst & 0xFF00) == 0xBE00)
   {
-    rb=(inst>>0)&0xFF;
+    rb = (inst >> 0) & 0xFF;
     statusMsg << "bkpt 0x" << Base::HEX2 << rb << endl;
-    return(1);
+    return 1;
   }
 
   //BL/BLX(1)
-  if((inst&0xE000)==0xE000) //BL,BLX
+  if((inst & 0xE000) == 0xE000) //BL,BLX
   {
-    if((inst&0x1800)==0x1000) //H=b10
+    if((inst & 0x1800) == 0x1000) //H=b10
     {
       DO_DISS(statusMsg << endl);
-      halfadd=inst;
-      return(0);
+      rb = inst & ((1 << 11) - 1);
+      if(rb & 1<<10) rb |= (~((1 << 11) - 1)); //sign extend
+      rb <<= 12;
+      rb += pc;
+      write_register(14, rb);
+      return 0;
     }
-    else if((inst&0x1800)==0x1800) //H=b11
+    else if((inst & 0x1800) == 0x1800) //H=b11
     {
       //branch to thumb
-      rb=halfadd&((1<<11)-1);
-      if(rb&1<<10)
-        rb|=(~((1<<11)-1)); //sign extend
-      rb<<=11;
-      rb|=inst&((1<<11)-1);
-      rb<<=1;
-      rb+=pc;
+      rb = read_register(14);
+      rb += (inst & ((1 << 11) - 1)) << 1;;
+      rb += 2;
       DO_DISS(statusMsg << "bl 0x" << Base::HEX8 << (rb-3) << endl);
-      write_register(14,pc-2);
-      write_register(15,rb);
-      return(0);
+      write_register(14, (pc-2) | 1);
+      write_register(15, rb);
+      return 0;
     }
-    else if((inst&0x1800)==0x0800) //H=b01
+    else if((inst & 0x1800) == 0x0800) //H=b01
     {
       //fprintf(stderr,"cannot branch to arm 0x%08X 0x%04X\n",pc,inst);
       // fxq: this should exit the code without having to detect it
-      return(1);
+      rb = read_register(14);
+      rb += (inst & ((1 << 11) - 1)) << 1;;
+      rb &= 0xFFFFFFFC;
+      rb += 2;
+      DO_DISS(statusMsg << "bl 0x" << Base::HEX8 << (rb-3) << endl);
+      write_register(14, (pc-2) | 1);
+      write_register(15, rb);
+      return 0;
     }
   }
 
   //BLX(2)
-  if((inst&0xFF87)==0x4780)
+  if((inst & 0xFF87) == 0x4780)
   {
-    rm=(inst>>3)&0xF;
+    rm = (inst >> 3) & 0xF;
     DO_DISS(statusMsg << "blx r" << dec << rm << endl);
-    rc=read_register(rm);
+    rc = read_register(rm);
     //fprintf(stderr,"blx r%u 0x%X 0x%X\n",rm,rc,pc);
-    rc+=2;
-    if(rc&1)
+    rc += 2;
+    if(rc & 1)
     {
-      write_register(14,pc-2);
-      write_register(15,rc);
-      return(0);
+      write_register(14, (pc-2) | 1);
+      rc &= ~1;
+      write_register(15, rc);
+      return 0;
     }
     else
     {
       //fprintf(stderr,"cannot branch to arm 0x%08X 0x%04X\n",pc,inst);
       // fxq: this could serve as exit code
-      return(1);
+      return 1;
     }
   }
 
   //BX
-  if((inst&0xFF87)==0x4700)
+  if((inst & 0xFF87) == 0x4700)
   {
-    rm=(inst>>3)&0xF;
+    rm = (inst >> 3) & 0xF;
     DO_DISS(statusMsg << "bx r" << dec << rm << endl);
-    rc=read_register(rm);
-    rc+=2;
+    rc = read_register(rm);
+    rc += 2;
     //fprintf(stderr,"bx r%u 0x%X 0x%X\n",rm,rc,pc);
-    if(rc&1)
+    if(rc & 1)
     {
-      write_register(15,rc);
-      return(0);
+      rc &= ~1;
+      write_register(15, rc);
+      return 0;
     }
     else
     {
       //fprintf(stderr,"cannot branch to arm 0x%08X 0x%04X\n",pc,inst);
       // fxq: or maybe this one??
-      return(1);
+      return 1;
     }
   }
 
   //CMN
-  if((inst&0xFFC0)==0x42C0)
+  if((inst & 0xFFC0) == 0x42C0)
   {
-    rn=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rn = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "cmns r" << dec << rn << ",r" << dec << rm << endl);
-    ra=read_register(rn);
-    rb=read_register(rm);
-    rc=ra+rb;
+    ra = read_register(rn);
+    rb = read_register(rm);
+    rc = ra + rb;
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,rb,0);
-    do_add_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, rb, 0);
+    do_vflag(ra, rb, 0);
+    return 0;
   }
 
   //CMP(1) compare immediate
-  if((inst&0xF800)==0x2800)
+  if((inst & 0xF800) == 0x2800)
   {
-    rb=(inst>>0)&0xFF;
-    rn=(inst>>8)&0x07;
+    rb = (inst >> 0) & 0xFF;
+    rn = (inst >> 8) & 0x07;
     DO_DISS(statusMsg << "cmp r" << dec << rn << ",#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(rn);
-    rc=ra-rb;
+    ra = read_register(rn);
+    rc = ra - rb;
     //fprintf(stderr,"0x%08X 0x%08X\n",ra,rb);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,~rb,1);
-    do_sub_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, ~rb, 1);
+    do_vflag(ra, ~rb, 1);
+    return 0;
   }
 
   //CMP(2) compare register
-  if((inst&0xFFC0)==0x4280)
+  if((inst & 0xFFC0) == 0x4280)
   {
-    rn=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rn = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "cmps r" << dec << rn << ",r" << dec << rm << endl);
-    ra=read_register(rn);
-    rb=read_register(rm);
-    rc=ra-rb;
+    ra = read_register(rn);
+    rb = read_register(rm);
+    rc = ra - rb;
     //fprintf(stderr,"0x%08X 0x%08X\n",ra,rb);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,~rb,1);
-    do_sub_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, ~rb, 1);
+    do_vflag(ra, ~rb, 1);
+    return 0;
   }
 
   //CMP(3) compare high register
-  if((inst&0xFF00)==0x4500)
+  if((inst & 0xFF00) == 0x4500)
   {
-    if(((inst>>6)&3)==0x0)
+    if(((inst >> 6) & 3) == 0x0)
     {
       //UNPREDICTABLE
     }
-    rn=(inst>>0)&0x7;
-    rn|=(inst>>4)&0x8;
-    if(rn==0xF)
+    rn = (inst >> 0) & 0x7;
+    rn |= (inst >> 4) & 0x8;
+    if(rn == 0xF)
     {
       //UNPREDICTABLE
     }
-    rm=(inst>>3)&0xF;
+    rm = (inst >> 3) & 0xF;
     DO_DISS(statusMsg << "cmps r" << dec << rn << ",r" << dec << rm << endl);
-    ra=read_register(rn);
-    rb=read_register(rm);
-    rc=ra-rb;
+    ra = read_register(rn);
+    rb = read_register(rm);
+    rc = ra - rb;
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,~rb,1);
-    do_sub_vflag(ra,rb,rc);
-
-#if 0
-    if(cpsr&CPSR_N) statusMsg << "N"; else statusMsg << "n";
-    if(cpsr&CPSR_Z) statusMsg << "Z"; else statusMsg << "z";
-    if(cpsr&CPSR_C) statusMsg << "C"; else statusMsg << "c";
-    if(cpsr&CPSR_V) statusMsg << "V"; else statusMsg << "v";
-    statusMsg << " -- 0x" << Base::HEX8 << ra << " 0x" << Base::HEX8 << rb << endl;
-#endif
-    return(0);
+    do_cflag(ra, ~rb, 1);
+    do_vflag(ra, ~rb, 1);
+    return 0;
   }
 
   //CPS
-  if((inst&0xFFE8)==0xB660)
+  if((inst & 0xFFE8) == 0xB660)
   {
     DO_DISS(statusMsg << "cps TODO" << endl);
-    return(1);
+    return 1;
   }
 
   //CPY copy high register
-  if((inst&0xFFC0)==0x4600)
+  if((inst & 0xFFC0) == 0x4600)
   {
     //same as mov except you can use both low registers
     //going to let mov handle high registers
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "cpy r" << dec << rd << ",r" << dec << rm << endl);
-    rc=read_register(rm);
-    write_register(rd,rc);
-    return(0);
+    rc = read_register(rm);
+    write_register(rd, rc);
+    return 0;
   }
 
   //EOR
-  if((inst&0xFFC0)==0x4040)
+  if((inst & 0xFFC0) == 0x4040)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "eors r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra^rb;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra ^ rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //LDMIA
-  if((inst&0xF800)==0xC800)
+  if((inst & 0xF800) == 0xC800)
   {
-    rn=(inst>>8)&0x7;
+    rn = (inst >> 8) & 0x7;
   #if defined(THUMB_DISS)
     statusMsg << "ldmia r" << dec << rn << "!,{";
     for(ra=0,rb=0x01,rc=0;rb;rb=(rb<<1)&0xFF,ra++)
@@ -1068,402 +1126,414 @@ int Thumbulator::execute ( void )
     }
     statusMsg << "}" << endl;
   #endif
-    sp=read_register(rn);
-    for(ra=0,rb=0x01;rb;rb=(rb<<1)&0xFF,ra++)
+    sp = read_register(rn);
+    for(ra = 0, rb = 0x01; rb; rb = (rb << 1) & 0xFF, ra++)
     {
-      if(inst&rb)
+      if(inst & rb)
       {
-        write_register(ra,read32(sp));
-        sp+=4;
+        write_register(ra, read32(sp));
+        sp += 4;
       }
     }
-    write_register(rn,sp);
-    return(0);
+    //there is a write back exception.
+    if((inst & (1 << rn)) == 0)
+      write_register(rn, sp);
+
+    return 0;
   }
 
   //LDR(1) two register immediate
-  if((inst&0xF800)==0x6800)
+  if((inst & 0xF800) == 0x6800)
   {
-    rd=(inst>>0)&0x07;
-    rn=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
-    rb<<=2;
+    rd = (inst >> 0) & 0x07;
+    rn = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
+    rb <<= 2;
     DO_DISS(statusMsg << "ldr r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX2 << rb << "]" << endl);
-    rb=read_register(rn)+rb;
-    rc=read32(rb);
-    write_register(rd,rc);
-    return(0);
+    rb = read_register(rn) + rb;
+    rc = read32(rb);
+    write_register(rd, rc);
+    return 0;
   }
 
   //LDR(2) three register
-  if((inst&0xFE00)==0x5800)
+  if((inst & 0xFE00) == 0x5800)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "ldr r" << dec << rd << ",[r" << dec << rn << ",r" << dec << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read32(rb);
-    write_register(rd,rc);
-    return(0);
+    rb = read_register(rn) + read_register(rm);
+    rc = read32(rb);
+    write_register(rd, rc);
+    return 0;
   }
 
   //LDR(3)
-  if((inst&0xF800)==0x4800)
+  if((inst & 0xF800) == 0x4800)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x07;
-    rb<<=2;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x07;
+    rb <<= 2;
     DO_DISS(statusMsg << "ldr r" << dec << rd << ",[PC+#0x" << Base::HEX2 << rb << "] ");
-    ra=read_register(15);
-    ra&=~3;
-    rb+=ra;
+    ra = read_register(15);
+    ra &= ~3;
+    rb += ra;
     DO_DISS(statusMsg << ";@ 0x" << Base::HEX2 << rb << endl);
-    rc=read32(rb);
-    write_register(rd,rc);
-    return(0);
+    rc = read32(rb);
+    write_register(rd, rc);
+    return 0;
   }
 
   //LDR(4)
-  if((inst&0xF800)==0x9800)
+  if((inst & 0xF800) == 0x9800)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x07;
-    rb<<=2;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x07;
+    rb <<= 2;
     DO_DISS(statusMsg << "ldr r" << dec << rd << ",[SP+#0x" << Base::HEX2 << rb << "]" << endl);
-    ra=read_register(13);
+    ra = read_register(13);
     //ra&=~3;
-    rb+=ra;
-    rc=read32(rb);
-    write_register(rd,rc);
-    return(0);
+    rb += ra;
+    rc = read32(rb);
+    write_register(rd, rc);
+    return 0;
   }
 
   //LDRB(1)
-  if((inst&0xF800)==0x7800)
+  if((inst & 0xF800) == 0x7800)
   {
-    rd=(inst>>0)&0x07;
-    rn=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
+    rd = (inst >> 0) & 0x07;
+    rn = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
     DO_DISS(statusMsg << "ldrb r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX2 << rb << "]" << endl);
-    rb=read_register(rn)+rb;
-    rc=read16(rb&(~1));
-    if(rb&1)
+    rb = read_register(rn) + rb;
+    rc = read16(rb & (~1u));
+    if(rb & 1)
     {
-      rc>>=8;
+      rc >>= 8;
     }
     else
     {
     }
-    write_register(rd,rc&0xFF);
-    return(0);
+    write_register(rd, rc & 0xFF);
+    return 0;
   }
 
   //LDRB(2)
-  if((inst&0xFE00)==0x5C00)
+  if((inst & 0xFE00) == 0x5C00)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "ldrb r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read16(rb&(~1));
-    if(rb&1)
+    rb = read_register(rn) + read_register(rm);
+    rc = read16(rb & (~1u));
+    if(rb & 1)
     {
-      rc>>=8;
+      rc >>= 8;
     }
     else
     {
     }
-    write_register(rd,rc&0xFF);
-    return(0);
+    write_register(rd, rc & 0xFF);
+    return 0;
   }
 
   //LDRH(1)
-  if((inst&0xF800)==0x8800)
+  if((inst & 0xF800) == 0x8800)
   {
-    rd=(inst>>0)&0x07;
-    rn=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
-    rb<<=1;
+    rd = (inst >> 0) & 0x07;
+    rn = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
+    rb <<= 1;
     DO_DISS(statusMsg << "ldrh r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX2 << rb << "]" << endl);
-    rb=read_register(rn)+rb;
-    rc=read16(rb);
-    write_register(rd,rc&0xFFFF);
-    return(0);
+    rb=read_register(rn) + rb;
+    rc = read16(rb);
+    write_register(rd, rc & 0xFFFF);
+    return 0;
   }
 
   //LDRH(2)
-  if((inst&0xFE00)==0x5A00)
+  if((inst & 0xFE00) == 0x5A00)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "ldrh r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read16(rb);
-    write_register(rd,rc&0xFFFF);
-    return(0);
+    rb = read_register(rn) + read_register(rm);
+    rc = read16(rb);
+    write_register(rd, rc & 0xFFFF);
+    return 0;
   }
 
   //LDRSB
-  if((inst&0xFE00)==0x5600)
+  if((inst & 0xFE00) == 0x5600)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "ldrsb r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read16(rb&(~1));
-    if(rb&1)
+    rb = read_register(rn) + read_register(rm);
+    rc = read16(rb & (~1u));
+    if(rb & 1)
     {
-      rc>>=8;
+      rc >>= 8;
     }
     else
     {
     }
-    rc&=0xFF;
-    if(rc&0x80)
-      rc|=((~0)<<8);  // FIXME - shifting a negative signed value is undefined
-    write_register(rd,rc);
-    return(0);
+    rc &= 0xFF;
+    if(rc & 0x80)
+      rc |= ((~0u) << 8);
+    write_register(rd, rc);
+    return 0;
   }
 
   //LDRSH
-  if((inst&0xFE00)==0x5E00)
+  if((inst & 0xFE00) == 0x5E00)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "ldrsh r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read16(rb);
-    rc&=0xFFFF;
-    if(rc&0x8000)
-      rc|=((~0)<<16);  // FIXME - shifting a negative signed value is undefined
-    write_register(rd,rc);
-    return(0);
+    rb = read_register(rn) + read_register(rm);
+    rc = read16(rb);
+    rc &= 0xFFFF;
+    if(rc & 0x8000)
+      rc |= ((~0u) << 16);
+    write_register(rd, rc);
+    return 0;
   }
 
   //LSL(1)
-  if((inst&0xF800)==0x0000)
+  if((inst & 0xF800) == 0x0000)
   {
-    rd=(inst>>0)&0x07;
-    rm=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
+    rd = (inst >> 0) & 0x07;
+    rm = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
     DO_DISS(statusMsg << "lsls r" << dec << rd << ",r" << dec << rm << ",#0x" << Base::HEX2 << rb << endl);
-    rc=read_register(rm);
-    if(rb==0)
+    rc = read_register(rm);
+    if(rb == 0)
     {
       //if immed_5 == 0
-      //C unnaffected
+      //C unaffected
       //result not shifted
     }
     else
     {
       //else immed_5 > 0
-      do_cflag_bit(rc&(1<<(32-rb)));
-      rc<<=rb;
+      do_cflag_bit(rc & (1 << (32-rb)));
+      rc <<= rb;
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //LSL(2) two register
-  if((inst&0xFFC0)==0x4080)
+  if((inst & 0xFFC0) == 0x4080)
   {
-    rd=(inst>>0)&0x07;
-    rs=(inst>>3)&0x07;
+    rd = (inst >> 0) & 0x07;
+    rs = (inst >> 3) & 0x07;
     DO_DISS(statusMsg << "lsls r" << dec << rd << ",r" << dec << rs << endl);
-    rc=read_register(rd);
-    rb=read_register(rs);
-    rb&=0xFF;
-    if(rb==0)
+    rc = read_register(rd);
+    rb = read_register(rs);
+    rb &= 0xFF;
+    if(rb == 0)
     {
     }
-    else if(rb<32)
+    else if(rb < 32)
     {
-      do_cflag_bit(rc&(1<<(32-rb)));
-      rc<<=rb;
+      do_cflag_bit(rc & (1 << (32-rb)));
+      rc <<= rb;
     }
-    else if(rb==32)
+    else if(rb == 32)
     {
-      do_cflag_bit(rc&1);
-      rc=0;
+      do_cflag_bit(rc & 1);
+      rc = 0;
     }
     else
     {
       do_cflag_bit(0);
-      rc=0;
+      rc = 0;
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //LSR(1) two register immediate
-  if((inst&0xF800)==0x0800)
+  if((inst & 0xF800) == 0x0800)
   {
-    rd=(inst>>0)&0x07;
-    rm=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
+    rd = (inst >> 0) & 0x07;
+    rm = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
     DO_DISS(statusMsg << "lsrs r" << dec << rd << ",r" << dec << rm << ",#0x" << Base::HEX2 << rb << endl);
-    rc=read_register(rm);
-    if(rb==0)
+    rc = read_register(rm);
+    if(rb == 0)
     {
-      do_cflag_bit(rc&0x80000000);
-      rc=0;
+      do_cflag_bit(rc & 0x80000000);
+      rc = 0;
     }
     else
     {
-      do_cflag_bit(rc&(1<<(rb-1)));
-      rc>>=rb;
+      do_cflag_bit(rc & (1 << (rb-1)));
+      rc >>= rb;
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //LSR(2) two register
-  if((inst&0xFFC0)==0x40C0)
+  if((inst & 0xFFC0) == 0x40C0)
   {
-    rd=(inst>>0)&0x07;
-    rs=(inst>>3)&0x07;
+    rd = (inst >> 0) & 0x07;
+    rs = (inst >> 3) & 0x07;
     DO_DISS(statusMsg << "lsrs r" << dec << rd << ",r" << dec << rs << endl);
-    rc=read_register(rd);
-    rb=read_register(rs);
-    rb&=0xFF;
-    if(rb==0)
+    rc = read_register(rd);
+    rb = read_register(rs);
+    rb &= 0xFF;
+    if(rb == 0)
     {
     }
-    else if(rb<32)
+    else if(rb < 32)
     {
-      do_cflag_bit(rc&(1<<(32-rb)));
-      rc>>=rb;
+      do_cflag_bit(rc & (1 << (rb-1)));
+      rc >>= rb;
     }
-    else if(rb==32)
+    else if(rb == 32)
     {
-      do_cflag_bit(rc&0x80000000);
-      rc=0;
+      do_cflag_bit(rc & 0x80000000);
+      rc = 0;
     }
     else
     {
       do_cflag_bit(0);
-      rc=0;
+      rc = 0;
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //MOV(1) immediate
-  if((inst&0xF800)==0x2000)
+  if((inst & 0xF800) == 0x2000)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x07;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x07;
     DO_DISS(statusMsg << "movs r" << dec << rd << ",#0x" << Base::HEX2 << rb << endl);
-    write_register(rd,rb);
+    write_register(rd, rb);
     do_nflag(rb);
     do_zflag(rb);
-    return(0);
+    return 0;
   }
 
   //MOV(2) two low registers
-  if((inst&0xFFC0)==0x1C00)
+  if((inst & 0xFFC0) == 0x1C00)
   {
-    rd=(inst>>0)&7;
-    rn=(inst>>3)&7;
+    rd = (inst >> 0) & 7;
+    rn = (inst >> 3) & 7;
     DO_DISS(statusMsg << "movs r" << dec << rd << ",r" << dec << rn << endl);
-    rc=read_register(rn);
+    rc = read_register(rn);
     //fprintf(stderr,"0x%08X\n",rc);
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
     do_cflag_bit(0);
     do_vflag_bit(0);
-    return(0);
+    return 0;
   }
 
   //MOV(3)
-  if((inst&0xFF00)==0x4600)
+  if((inst & 0xFF00) == 0x4600)
   {
-    rd=(inst>>0)&0x7;
-    rd|=(inst>>4)&0x8;
-    rm=(inst>>3)&0xF;
+    rd  = (inst >> 0) & 0x7;
+    rd |= (inst >> 4) & 0x8;
+    rm  = (inst >> 3) & 0xF;
     DO_DISS(statusMsg << "mov r" << dec << rd << ",r" << dec << rm << endl);
-    rc=read_register(rm);
-    if (rd==15) rc+=2; // fxq fix for MOV R15
-    write_register(rd,rc);
-    return(0);
+    rc = read_register(rm);
+    if((rd == 14) && (rm == 15))
+    {
+      //printf("mov lr,pc warning 0x%08X\n",pc-2);
+      //rc|=1;
+    }
+    if(rd == 15)
+    {
+      rc &= ~1; //write_register may do this as well
+      rc += 2;  //The program counter is special
+    }
+    write_register(rd, rc);
+    return 0;
   }
 
   //MUL
-  if((inst&0xFFC0)==0x4340)
+  if((inst & 0xFFC0) == 0x4340)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "muls r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra*rb;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra * rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //MVN
-  if((inst&0xFFC0)==0x43C0)
+  if((inst & 0xFFC0) == 0x43C0)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "mvns r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rm);
-    rc=(~ra);
-    write_register(rd,rc);
+    ra = read_register(rm);
+    rc = (~ra);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //NEG
-  if((inst&0xFFC0)==0x4240)
+  if((inst & 0xFFC0) == 0x4240)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "negs r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rm);
-    rc=0-ra;
-    write_register(rd,rc);
+    ra = read_register(rm);
+    rc = 0 - ra;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(0,~ra,1);
-    do_sub_vflag(0,ra,rc);
-    return(0);
+    do_cflag(0, ~ra, 1);
+    do_vflag(0, ~ra, 1);
+    return 0;
   }
 
   //ORR
-  if((inst&0xFFC0)==0x4300)
+  if((inst & 0xFFC0) == 0x4300)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "orrs r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra|rb;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra | rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //POP
-  if((inst&0xFE00)==0xBC00)
+  if((inst & 0xFE00) == 0xBC00)
   {
   #if defined(THUMB_DISS)
     statusMsg << "pop {";
@@ -1484,28 +1554,28 @@ int Thumbulator::execute ( void )
     statusMsg << "}" << endl;
   #endif
 
-    sp=read_register(13);
-    for(ra=0,rb=0x01;rb;rb=(rb<<1)&0xFF,ra++)
+    sp = read_register(13);
+    for(ra = 0, rb = 0x01; rb; rb = (rb << 1) & 0xFF, ra++)
     {
-      if(inst&rb)
+      if(inst & rb)
       {
-        write_register(ra,read32(sp));
-        sp+=4;
+        write_register(ra, read32(sp));
+        sp += 4;
       }
     }
-    if(inst&0x100)
+    if(inst & 0x100)
     {
-      rc=read32(sp);
-      rc+=2;
-      write_register(15,rc);
-      sp+=4;
+      rc = read32(sp);
+      rc += 2;
+      write_register(15, rc);
+      sp += 4;
     }
-    write_register(13,sp);
-    return(0);
+    write_register(13, sp);
+    return 0;
   }
 
   //PUSH
-  if((inst&0xFE00)==0xB400)
+  if((inst & 0xFE00) == 0xB400)
   {
   #if defined(THUMB_DISS)
     statusMsg << "push {";
@@ -1526,147 +1596,160 @@ int Thumbulator::execute ( void )
     statusMsg << "}" << endl;
   #endif
 
-    sp=read_register(13);
+    sp = read_register(13);
     //fprintf(stderr,"sp 0x%08X\n",sp);
-    for(ra=0,rb=0x01,rc=0;rb;rb=(rb<<1)&0xFF,ra++)
+    for(ra = 0, rb = 0x01, rc = 0; rb; rb = (rb << 1) & 0xFF, ra++)
     {
-      if(inst&rb)
+      if(inst & rb)
       {
         rc++;
       }
     }
-    if(inst&0x100) rc++;
-    rc<<=2;
-    sp-=rc;
-    rd=sp;
-    for(ra=0,rb=0x01;rb;rb=(rb<<1)&0xFF,ra++)
+    if(inst & 0x100) rc++;
+    rc <<= 2;
+    sp -= rc;
+    rd = sp;
+    for(ra = 0, rb = 0x01; rb; rb = (rb << 1) & 0xFF, ra++)
     {
-      if(inst&rb)
+      if(inst & rb)
       {
-        write32(rd,read_register(ra));
-        rd+=4;
+        write32(rd, read_register(ra));
+        rd += 4;
       }
     }
-    if(inst&0x100)
+    if(inst & 0x100)
     {
-      write32(rd,read_register(14));
+      rc = read_register(14);
+      write32(rd, rc);
+      if((rc & 1) == 0)
+      {
+        // FIXME fprintf(stderr,"push {lr} with an ARM address pc 0x%08X popped 0x%08X\n",pc,rc);
+      }
     }
-    write_register(13,sp);
-    return(0);
+    write_register(13, sp);
+    return 0;
   }
 
   //REV
-  if((inst&0xFFC0)==0xBA00)
+  if((inst & 0xFFC0) == 0xBA00)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "rev r" << dec << rd << ",r" << dec << rn << endl);
-    ra=read_register(rn);
-    rc =((ra>> 0)&0xFF)<<24;
-    rc|=((ra>> 8)&0xFF)<<16;
-    rc|=((ra>>16)&0xFF)<< 8;
-    rc|=((ra>>24)&0xFF)<< 0;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rn);
+    rc  = ((ra >>  0) & 0xFF) << 24;
+    rc |= ((ra >>  8) & 0xFF) << 16;
+    rc |= ((ra >> 16) & 0xFF) <<  8;
+    rc |= ((ra >> 24) & 0xFF) <<  0;
+    write_register(rd, rc);
+    return 0;
   }
 
   //REV16
-  if((inst&0xFFC0)==0xBA40)
+  if((inst & 0xFFC0) == 0xBA40)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "rev16 r" << dec << rd << ",r" << dec << rn << endl);
-    ra=read_register(rn);
-    rc =((ra>> 0)&0xFF)<< 8;
-    rc|=((ra>> 8)&0xFF)<< 0;
-    rc|=((ra>>16)&0xFF)<<24;
-    rc|=((ra>>24)&0xFF)<<16;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rn);
+    rc  = ((ra >>  0) & 0xFF) <<  8;
+    rc |= ((ra >>  8) & 0xFF) <<  0;
+    rc |= ((ra >> 16) & 0xFF) << 24;
+    rc |= ((ra >> 24) & 0xFF) << 16;
+    write_register(rd, rc);
+    return 0;
   }
 
   //REVSH
-  if((inst&0xFFC0)==0xBAC0)
+  if((inst & 0xFFC0) == 0xBAC0)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "revsh r" << dec << rd << ",r" << dec << rn << endl);
-    ra=read_register(rn);
-    rc =((ra>> 0)&0xFF)<< 8;
-    rc|=((ra>> 8)&0xFF)<< 0;
-    if(rc&0x8000) rc|=0xFFFF0000;
-    else          rc&=0x0000FFFF;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rn);
+    rc  = ((ra >> 0) & 0xFF) << 8;
+    rc |= ((ra >> 8) & 0xFF) << 0;
+    if(rc & 0x8000) rc |= 0xFFFF0000;
+    else            rc &= 0x0000FFFF;
+    write_register(rd, rc);
+    return 0;
   }
 
   //ROR
-  if((inst&0xFFC0)==0x41C0)
+  if((inst & 0xFFC0) == 0x41C0)
   {
-    rd=(inst>>0)&0x7;
-    rs=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rs = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "rors r" << dec << rd << ",r" << dec << rs << endl);
-    rc=read_register(rd);
-    ra=read_register(rs);
-    ra&=0xFF;
-    if(ra==0)
+    rc = read_register(rd);
+    ra = read_register(rs);
+    ra &= 0xFF;
+    if(ra == 0)
     {
     }
     else
     {
-      ra&=0x1F;
-      if(ra==0)
+      ra &= 0x1F;
+      if(ra == 0)
       {
-        do_cflag_bit(rc&0x80000000);
+        do_cflag_bit(rc & 0x80000000);
       }
       else
       {
-        do_cflag_bit(rc&(1<<(ra-1)));
-        rb=rc<<(32-ra);
-        rc>>=ra;
-        rc|=rb;
+        do_cflag_bit(rc & (1 << (ra-1)));
+        rb = rc << (32-ra);
+        rc >>= ra;
+        rc |= rb;
       }
     }
-    write_register(rd,rc);
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //SBC
-  if((inst&0xFFC0)==0x4180)
+  if((inst & 0xFFC0) == 0x4180)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "sbc r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rd);
-    rb=read_register(rm);
-    rc=ra-rb;
-    if(!(cpsr&CPSR_C)) rc--;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rb = read_register(rm);
+    rc = ra - rb;
+    if(!(cpsr & CPSR_C)) rc--;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,rb,0);
-    do_sub_vflag(ra,rb,rc);
-    return(0);
+    if(cpsr & CPSR_C)
+    {
+      do_cflag(ra, ~rb, 1);
+      do_vflag(ra, ~rb, 1);
+    }
+    else
+    {
+      do_cflag(ra, ~rb, 0);
+      do_vflag(ra, ~rb, 0);
+    }
+    return 0;
   }
 
   //SETEND
-  if((inst&0xFFF7)==0xB650)
+  if((inst & 0xFFF7) == 0xB650)
   {
     statusMsg << "setend not implemented" << endl;
-    return(1);
+    return 1;
   }
 
   //STMIA
-  if((inst&0xF800)==0xC000)
+  if((inst & 0xF800) == 0xC000)
   {
-    rn=(inst>>8)&0x7;
+    rn = (inst >> 8) & 0x7;
   #if defined(THUMB_DISS)
     statusMsg << "stmia r" << dec << rn << "!,{";
     for(ra=0,rb=0x01,rc=0;rb;rb=(rb<<1)&0xFF,ra++)
     {
-      if(inst&rb)
+      if(inst & rb)
       {
         if(rc) statusMsg << ",";
         statusMsg << "r" << dec << ra;
@@ -1676,298 +1759,308 @@ int Thumbulator::execute ( void )
     statusMsg << "}" << endl;
   #endif
 
-    sp=read_register(rn);
-    for(ra=0,rb=0x01;rb;rb=(rb<<1)&0xFF,ra++)
+    sp = read_register(rn);
+    for(ra = 0, rb = 0x01; rb; rb = (rb << 1) & 0xFF, ra++)
     {
-      if(inst&rb)
+      if(inst & rb)
       {
-        write32(sp,read_register(ra));
-        sp+=4;
+        write32(sp, read_register(ra));
+        sp += 4;
       }
     }
-    write_register(rn,sp);
-    return(0);
+    write_register(rn, sp);
+    return 0;
   }
 
   //STR(1)
-  if((inst&0xF800)==0x6000)
+  if((inst & 0xF800) == 0x6000)
   {
-    rd=(inst>>0)&0x07;
-    rn=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
-    rb<<=2;
+    rd = (inst >> 0) & 0x07;
+    rn = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
+    rb <<= 2;
     DO_DISS(statusMsg << "str r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX2 << rb << "]" << endl);
-    rb=read_register(rn)+rb;
-    rc=read_register(rd);
-    write32(rb,rc);
-    return(0);
+    rb = read_register(rn) + rb;
+    rc = read_register(rd);
+    write32(rb, rc);
+    return 0;
   }
 
   //STR(2)
-  if((inst&0xFE00)==0x5000)
+  if((inst & 0xFE00) == 0x5000)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "str r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read_register(rd);
-    write32(rb,rc);
-    return(0);
+    rb = read_register(rn) + read_register(rm);
+    rc = read_register(rd);
+    write32(rb, rc);
+    return 0;
   }
 
   //STR(3)
-  if((inst&0xF800)==0x9000)
+  if((inst & 0xF800) == 0x9000)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x07;
-    rb<<=2;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x07;
+    rb <<= 2;
     DO_DISS(statusMsg << "str r" << dec << rd << ",[SP,#0x" << Base::HEX2 << rb << "]" << endl);
-    rb=read_register(13)+rb;
+    rb = read_register(13) + rb;
     //fprintf(stderr,"0x%08X\n",rb);
-    rc=read_register(rd);
-    write32(rb,rc);
-    return(0);
+    rc = read_register(rd);
+    write32(rb, rc);
+    return 0;
   }
 
   //STRB(1)
-  if((inst&0xF800)==0x7000)
+  if((inst & 0xF800) == 0x7000)
   {
-    rd=(inst>>0)&0x07;
-    rn=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
+    rd = (inst >> 0) & 0x07;
+    rn = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
     DO_DISS(statusMsg << "strb r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX8 << rb << "]" << endl);
-    rb=read_register(rn)+rb;
-    rc=read_register(rd);
-    ra=read16(rb&(~1));
-    if(rb&1)
+    rb = read_register(rn) + rb;
+    rc = read_register(rd);
+    ra = read16(rb & (~1u));
+    if(rb & 1)
     {
-      ra&=0x00FF;
-      ra|=rc<<8;
+      ra &= 0x00FF;
+      ra |= rc << 8;
     }
     else
     {
-      ra&=0xFF00;
-      ra|=rc&0x00FF;
+      ra &= 0xFF00;
+      ra |= rc & 0x00FF;
     }
-    write16(rb&(~1),ra&0xFFFF);
-    return(0);
+    write16(rb & (~1u), ra & 0xFFFF);
+    return 0;
   }
 
   //STRB(2)
-  if((inst&0xFE00)==0x5400)
+  if((inst & 0xFE00) == 0x5400)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "strb r" << dec << rd << ",[r" << dec << rn << ",r" << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read_register(rd);
-    ra=read16(rb&(~1));
-    if(rb&1)
+    rb = read_register(rn) + read_register(rm);
+    rc = read_register(rd);
+    ra = read16(rb & (~1u));
+    if(rb & 1)
     {
-      ra&=0x00FF;
-      ra|=rc<<8;
+      ra &= 0x00FF;
+      ra |= rc << 8;
     }
     else
     {
-      ra&=0xFF00;
-      ra|=rc&0x00FF;
+      ra &= 0xFF00;
+      ra |= rc & 0x00FF;
     }
-    write16(rb&(~1),ra&0xFFFF);
-    return(0);
+    write16(rb & (~1u), ra & 0xFFFF);
+    return 0;
   }
 
   //STRH(1)
-  if((inst&0xF800)==0x8000)
+  if((inst & 0xF800) == 0x8000)
   {
-    rd=(inst>>0)&0x07;
-    rn=(inst>>3)&0x07;
-    rb=(inst>>6)&0x1F;
-    rb<<=1;
+    rd = (inst >> 0) & 0x07;
+    rn = (inst >> 3) & 0x07;
+    rb = (inst >> 6) & 0x1F;
+    rb <<= 1;
     DO_DISS(statusMsg << "strh r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX2 << rb << "]" << endl);
-    rb=read_register(rn)+rb;
-    rc=read_register(rd);
-    write16(rb,rc&0xFFFF);
-    return(0);
+    rb = read_register(rn) + rb;
+    rc=  read_register(rd);
+    write16(rb, rc & 0xFFFF);
+    return 0;
   }
 
   //STRH(2)
-  if((inst&0xFE00)==0x5200)
+  if((inst & 0xFE00) == 0x5200)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "strh r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]" << endl);
-    rb=read_register(rn)+read_register(rm);
-    rc=read_register(rd);
-    write16(rb,rc&0xFFFF);
-    return(0);
+    rb = read_register(rn) + read_register(rm);
+    rc = read_register(rd);
+    write16(rb, rc & 0xFFFF);
+    return 0;
   }
 
   //SUB(1)
-  if((inst&0xFE00)==0x1E00)
+  if((inst & 0xFE00) == 0x1E00)
   {
-    rd=(inst>>0)&7;
-    rn=(inst>>3)&7;
-    rb=(inst>>6)&7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rb = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "subs r" << dec << rd << ",r" << dec << rn << ",#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(rn);
-    rc=ra-rb;
-    write_register(rd,rc);
+    ra = read_register(rn);
+    rc = ra - rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,~rb,1);
-    do_sub_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, ~rb, 1);
+    do_vflag(ra, ~rb, 1);
+    return 0;
   }
 
   //SUB(2)
-  if((inst&0xF800)==0x3800)
+  if((inst & 0xF800) == 0x3800)
   {
-    rb=(inst>>0)&0xFF;
-    rd=(inst>>8)&0x07;
+    rb = (inst >> 0) & 0xFF;
+    rd = (inst >> 8) & 0x07;
     DO_DISS(statusMsg << "subs r" << dec << rd << ",#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(rd);
-    rc=ra-rb;
-    write_register(rd,rc);
+    ra = read_register(rd);
+    rc = ra - rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,~rb,1);
-    do_sub_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, ~rb, 1);
+    do_vflag(ra, ~rb, 1);
+    return 0;
   }
 
   //SUB(3)
-  if((inst&0xFE00)==0x1A00)
+  if((inst & 0xFE00) == 0x1A00)
   {
-    rd=(inst>>0)&0x7;
-    rn=(inst>>3)&0x7;
-    rm=(inst>>6)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rn = (inst >> 3) & 0x7;
+    rm = (inst >> 6) & 0x7;
     DO_DISS(statusMsg << "subs r" << dec << rd << ",r" << dec << rn << ",r" << dec << rm << endl);
-    ra=read_register(rn);
-    rb=read_register(rm);
-    rc=ra-rb;
-    write_register(rd,rc);
+    ra = read_register(rn);
+    rb = read_register(rm);
+    rc = ra - rb;
+    write_register(rd, rc);
     do_nflag(rc);
     do_zflag(rc);
-    do_cflag(ra,~rb,1);
-    do_sub_vflag(ra,rb,rc);
-    return(0);
+    do_cflag(ra, ~rb, 1);
+    do_vflag(ra, ~rb, 1);
+    return 0;
   }
 
   //SUB(4)
-  if((inst&0xFF80)==0xB080)
+  if((inst & 0xFF80) == 0xB080)
   {
-    rb=inst&0x7F;
-    rb<<=2;
+    rb = inst & 0x7F;
+    rb <<= 2;
     DO_DISS(statusMsg << "sub SP,#0x" << Base::HEX2 << rb << endl);
-    ra=read_register(13);
-    ra-=rb;
-    write_register(13,ra);
-    return(0);
+    ra = read_register(13);
+    ra -= rb;
+    write_register(13, ra);
+    return 0;
   }
 
   //SWI
-  if((inst&0xFF00)==0xDF00)
+  if((inst & 0xFF00) == 0xDF00)
   {
-    rb=inst&0xFF;
+    rb = inst & 0xFF;
     DO_DISS(statusMsg << "swi 0x" << Base::HEX2 << rb << endl);
-    statusMsg << endl << endl << "swi 0x" << Base::HEX2 << rb << endl;
-    return(1);
+
+    if((inst & 0xFF) == 0xCC)
+    {
+      write_register(0, cpsr);
+      return 0;
+    }
+    else
+    {
+      statusMsg << endl << endl << "swi 0x" << Base::HEX2 << rb << endl;
+      return 1;
+    }
   }
 
   //SXTB
-  if((inst&0xFFC0)==0xB240)
+  if((inst & 0xFFC0) == 0xB240)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "sxtb r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rm);
-    rc=ra&0xFF;
-    if(rc&0x80)
-      rc|=(~0)<<8;  // FIXME - shifting a negative signed value is undefined
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rm);
+    rc = ra & 0xFF;
+    if(rc & 0x80)
+      rc |= (~0u) << 8;
+    write_register(rd, rc);
+    return 0;
   }
 
   //SXTH
-  if((inst&0xFFC0)==0xB200)
+  if((inst & 0xFFC0) == 0xB200)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "sxth r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rm);
-    rc=ra&0xFFFF;
-    if(rc&0x8000)
-      rc|=(~0)<<16;  // FIXME - shifting a negative signed value is undefined
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rm);
+    rc = ra & 0xFFFF;
+    if(rc & 0x8000)
+      rc |= (~0u) << 16;
+    write_register(rd, rc);
+    return 0;
   }
 
   //TST
-  if((inst&0xFFC0)==0x4200)
+  if((inst & 0xFFC0) == 0x4200)
   {
-    rn=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rn = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "tst r" << dec << rn << ",r" << dec << rm << endl);
-    ra=read_register(rn);
-    rb=read_register(rm);
-    rc=ra&rb;
+    ra = read_register(rn);
+    rb = read_register(rm);
+    rc = ra & rb;
     do_nflag(rc);
     do_zflag(rc);
-    return(0);
+    return 0;
   }
 
   //UXTB
-  if((inst&0xFFC0)==0xB2C0)
+  if((inst & 0xFFC0) == 0xB2C0)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "uxtb r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rm);
-    rc=ra&0xFF;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rm);
+    rc = ra & 0xFF;
+    write_register(rd, rc);
+    return 0;
   }
 
   //UXTH
-  if((inst&0xFFC0)==0xB280)
+  if((inst & 0xFFC0) == 0xB280)
   {
-    rd=(inst>>0)&0x7;
-    rm=(inst>>3)&0x7;
+    rd = (inst >> 0) & 0x7;
+    rm = (inst >> 3) & 0x7;
     DO_DISS(statusMsg << "uxth r" << dec << rd << ",r" << dec << rm << endl);
-    ra=read_register(rm);
-    rc=ra&0xFFFF;
-    write_register(rd,rc);
-    return(0);
+    ra = read_register(rm);
+    rc = ra & 0xFFFF;
+    write_register(rd, rc);
+    return 0;
   }
 
   statusMsg << "invalid instruction " << Base::HEX8 << pc << " " << Base::HEX4 << inst << endl;
-  return(1);
+  return 1;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-int Thumbulator::reset ( void )
+int Thumbulator::reset()
 {
-  //memset(ram,0xFF,sizeof(ram));
-  cpsr=CPSR_T|CPSR_I|CPSR_F|MODE_SVC;
+  std::fill(reg_norm, reg_norm+12, 0);
+  reg_norm[13] = 0x40001FB4;
+  reg_norm[14] = 0x00000C00;
+  reg_norm[15] = 0x00000C0B;
 
-  reg_svc[13]=0x40001fb4; //sp
-  reg_svc[14]=0x00000c00; //lr (duz this use odd addrs)
-	reg_sys[15]=0x00000c0b; // entry point of 0xc09+2
-  //  reg_sys[15]+=2;
-  mamcr = 0;
+  cpsr = mamcr = 0;
+  handler_mode = false;
+
+  systick_ctrl = 0x00000004;
+  systick_reload = 0x00000000;
+  systick_count = 0x00000000;
+  systick_calibrate = 0x00ABCDEF;
 
   // fxq: don't care about below so much (maybe to guess timing???)
-  instructions=0;
-  fetches=0;
-  reads=0;
-  writes=0;
+  instructions = fetches = reads = writes = systick_ints = 0;
 
   statusMsg.str("");
 
-  return(0);
+  return 0;
 }
 
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/emucore/Thumbulator.hxx b/src/emucore/Thumbulator.hxx
index 0f41b47..862ede0 100644
--- a/src/emucore/Thumbulator.hxx
+++ b/src/emucore/Thumbulator.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Thumbulator.hxx 3258 2016-01-23 22:56:16Z stephena $
+// $Id: Thumbulator.hxx 3290 2016-02-27 19:58:20Z stephena $
 //============================================================================
 
 //============================================================================
@@ -37,30 +37,10 @@
 #define ROMSIZE (ROMADDMASK+1)
 #define RAMSIZE (RAMADDMASK+1)
 
-//0b10000 User       PC, R14 to R0, CPSR
-//0b10001 FIQ        PC, R14_fiq to R8_fiq, R7 to R0, CPSR, SPSR_fiq
-//0b10010 IRQ        PC, R14_irq, R13_irq, R12 to R0, CPSR, SPSR_irq
-//0b10011 Supervisor PC, R14_svc, R13_svc, R12 to R0, CPSR, SPSR_svc
-//0b10111 Abort      PC, R14_abt, R13_abt, R12 to R0, CPSR, SPSR_abt
-//0b11011 Undefined  PC, R14_und, R13_und, R12 to R0, CPSR, SPSR_und
-//0b11111 System
-
-#define MODE_USR 0x10
-#define MODE_FIQ 0x11
-#define MODE_IRQ 0x12
-#define MODE_SVC 0x13
-#define MODE_ABT 0x17
-#define MODE_UND 0x1B
-#define MODE_SYS 0x1F
-
-#define CPSR_T (1<<5)
-#define CPSR_F (1<<6)
-#define CPSR_I (1<<7)
 #define CPSR_N (1<<31)
 #define CPSR_Z (1<<30)
 #define CPSR_C (1<<29)
 #define CPSR_V (1<<28)
-#define CPSR_Q (1<<27)
 
 class Thumbulator
 {
@@ -92,22 +72,21 @@ class Thumbulator
     static void trapFatalErrors(bool enable) { trapOnFatal = enable; }
 
   private:
-    uInt32 read_register ( uInt32 reg );
-    uInt32 write_register ( uInt32 reg, uInt32 data );
-    uInt32 fetch16 ( uInt32 addr );
-    //uInt32 fetch32 ( uInt32 addr );
-    uInt32 read16 ( uInt32 addr );
-    uInt32 read32 ( uInt32 );
-    void write16 ( uInt32 addr, uInt32 data );
-    void write32 ( uInt32 addr, uInt32 data );
-
-    void do_zflag ( uInt32 x );
-    void do_nflag ( uInt32 x );
-    void do_cflag ( uInt32 a, uInt32 b, uInt32 c );
-    void do_sub_vflag ( uInt32 a, uInt32 b, uInt32 c );
-    void do_add_vflag ( uInt32 a, uInt32 b, uInt32 c );
-    void do_cflag_bit ( uInt32 x );
-    void do_vflag_bit ( uInt32 x );
+    uInt32 read_register(uInt32 reg);
+    void write_register(uInt32 reg, uInt32 data);
+    uInt32 fetch16(uInt32 addr);
+    uInt32 fetch32(uInt32 addr);
+    uInt32 read16(uInt32 addr);
+    uInt32 read32(uInt32 addr);
+    void write16(uInt32 addr, uInt32 data);
+    void write32(uInt32 addr, uInt32 data);
+
+    void do_zflag(uInt32 x);
+    void do_nflag(uInt32 x);
+    void do_cflag(uInt32 a, uInt32 b, uInt32 c);
+    void do_vflag(uInt32 a, uInt32 b, uInt32 c);
+    void do_cflag_bit(uInt32 x);
+    void do_vflag_bit(uInt32 x);
 
     // Throw a runtime_error exception containing an error referencing the
     // given message and variables
@@ -115,31 +94,20 @@ class Thumbulator
     int fatalError(const char* opcode, uInt32 v1, const char* msg);
     int fatalError(const char* opcode, uInt32 v1, uInt32 v2, const char* msg);
 
-    void dump_counters ( void );
-    void dump_regs( void );
-    int execute ( void );
-    int reset ( void );
+    void dump_counters();
+    void dump_regs();
+    int execute();
+    int reset();
 
   private:
     const uInt16* rom;
     uInt16* ram;
-    //Int32 copydata;
-
-    uInt32 halfadd;
-    uInt32 cpsr;
-    //uInt32 reg_usr[16]; //User mode
-    uInt32 reg_sys[16]; //System mode
-    uInt32 reg_svc[16]; //Supervisor mode
-    //uInt32 reg_abt[16]; //Abort mode
-    //uInt32 reg_und[16]; //Undefined mode
-    //uInt32 reg_irq[16]; //Interrupt mode
-    //uInt32 reg_fiq[16]; //Fast Interrupt mode
-    uInt32 mamcr;
-
-    uInt64 instructions;
-    uInt64 fetches;
-    uInt64 reads;
-    uInt64 writes;
+
+    uInt32 reg_norm[16]; // normal execution mode, do not have a thread mode
+    uInt32 cpsr, mamcr;
+    bool handler_mode;
+    uInt32 systick_ctrl, systick_reload, systick_count, systick_calibrate;
+    uInt64 instructions, fetches, reads, writes, systick_ints;
 
     ostringstream statusMsg;
 
diff --git a/src/gui/Rect.hxx b/src/gui/Rect.hxx
index 3f21e11..08a1f7e 100644
--- a/src/gui/Rect.hxx
+++ b/src/gui/Rect.hxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: Rect.hxx 3239 2015-12-29 19:22:46Z stephena $
+// $Id: Rect.hxx 3292 2016-02-27 22:18:30Z stephena $
 //
 //   Based on code from ScummVM - Scumm Interpreter
 //   Copyright (C) 2002-2004 The ScummVM project
@@ -34,15 +34,15 @@ namespace GUI {
 */
 struct Point
 {
-  int x;  //!< The horizontal part of the point
-  int y;  //!< The vertical part of the point
+  uInt32 x;  //!< The horizontal part of the point
+  uInt32 y;  //!< The vertical part of the point
 
   Point() : x(0), y(0) { }
   Point(const Point& p) : x(p.x), y(p.y) { }
-  explicit Point(int x1, int y1) : x(x1), y(y1) { }
+  explicit Point(uInt32 x1, uInt32 y1) : x(x1), y(y1) { }
   Point(const string& p) {
     char c = '\0';
-    x = y = -1;
+    x = y = 0;
     istringstream buf(p);
     buf >> x >> c >> y;
     if(c != 'x')
diff --git a/src/macosx/Info-Stella.plist b/src/macosx/Info-Stella.plist
index 620bd8b..4e2bc4d 100644
--- a/src/macosx/Info-Stella.plist
+++ b/src/macosx/Info-Stella.plist
@@ -53,7 +53,7 @@
 	<key>CFBundleSignature</key>
 	<string>StLa</string>
 	<key>CFBundleVersion</key>
-	<string>4.7.1</string>
+	<string>4.7.2</string>
 	<key>LSApplicationCategoryType</key>
 	<string>public.app-category.games</string>
 	<key>LSMinimumSystemVersionByArchitecture</key>
diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx
index c64c835..78dab33 100644
--- a/src/unix/FSNodePOSIX.cxx
+++ b/src/unix/FSNodePOSIX.cxx
@@ -14,7 +14,7 @@
 // See the file "License.txt" for information on usage and redistribution of
 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
 //
-// $Id: FSNodePOSIX.cxx 3239 2015-12-29 19:22:46Z stephena $
+// $Id: FSNodePOSIX.cxx 3294 2016-03-05 18:35:25Z stephena $
 //============================================================================
 
 #include "FSNodePOSIX.hxx"
@@ -236,5 +236,5 @@ AbstractFSNode* FilesystemNodePOSIX::getParent() const
   const char* start = _path.c_str();
   const char* end = lastPathComponent(_path);
 
-  return new FilesystemNodePOSIX(string(start, end - start));
+  return new FilesystemNodePOSIX(string(start, size_t(end - start)));
 }
diff --git a/src/unix/stella.spec b/src/unix/stella.spec
index 9262c8c..f1dac3c 100644
--- a/src/unix/stella.spec
+++ b/src/unix/stella.spec
@@ -1,5 +1,5 @@
 %define name    stella
-%define version 4.7.1
+%define version 4.7.2
 %define rel     1
 
 %define enable_sound 1
@@ -101,6 +101,9 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
 %_datadir/icons/large/%{name}.png
 
 %changelog
+* Fri Mar 25 2016 Stephen Anthony <stephena at users.sf.net> 4.7.2-1
+- Version 4.7.2 release
+
 * Sat Feb 13 2016 Stephen Anthony <stephena at users.sf.net> 4.7.1-1
 - Version 4.7.1 release
 
diff --git a/src/windows/stella.rc b/src/windows/stella.rc
index daed07e..c4b3a0d 100755
--- a/src/windows/stella.rc
+++ b/src/windows/stella.rc
@@ -36,8 +36,8 @@ IDI_ICON                ICON                    "stella.ico"
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,7,1,0
- PRODUCTVERSION 4,7,1,0
+ FILEVERSION 4,7,2,0
+ PRODUCTVERSION 4,7,2,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -55,12 +55,12 @@ BEGIN
             VALUE "Comments", "The multi-platform Atari 2600 emulator.  Stella is released under the GPLv2."
             VALUE "CompanyName", "The Stella Team (http://stella.sourceforge.net)"
             VALUE "FileDescription", "Stella"
-            VALUE "FileVersion", "4.7.1"
+            VALUE "FileVersion", "4.7.2"
             VALUE "InternalName", "Stella"
             VALUE "LegalCopyright", "Copyright (C) 1995-2016 The Stella Team"
             VALUE "OriginalFilename", "Stella.exe"
             VALUE "ProductName", "Stella"
-            VALUE "ProductVersion", "4.7.1"
+            VALUE "ProductVersion", "4.7.2"
         END
     END
     BLOCK "VarFileInfo"

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/stella.git



More information about the Pkg-games-commits mailing list