diff --git a/VersionASM b/VersionASM
index 68e832a9063f66683e0e8fb2267d0fb4d6253484..ede294c49f6e20d235454ded87fac6acfb467d07 100644
--- a/VersionASM
+++ b/VersionASM
@@ -13,11 +13,11 @@
                         GBLS    Module_ComponentPath
 Module_MajorVersion     SETS    "5.35"
 Module_Version          SETA    535
-Module_MinorVersion     SETS    "4.79.2.269"
-Module_Date             SETS    "10 Jul 2015"
-Module_ApplicationDate  SETS    "10-Jul-15"
+Module_MinorVersion     SETS    "4.79.2.270"
+Module_Date             SETS    "13 Jul 2015"
+Module_ApplicationDate  SETS    "13-Jul-15"
 Module_ComponentName    SETS    "Kernel"
 Module_ComponentPath    SETS    "castle/RiscOS/Sources/Kernel"
-Module_FullVersion      SETS    "5.35 (4.79.2.269)"
-Module_HelpVersion      SETS    "5.35 (10 Jul 2015) 4.79.2.269"
+Module_FullVersion      SETS    "5.35 (4.79.2.270)"
+Module_HelpVersion      SETS    "5.35 (13 Jul 2015) 4.79.2.270"
                         END
diff --git a/VersionNum b/VersionNum
index 959eb470a8858b5aad3902b3b8ac3924cc7ae1dd..09e8d80a38fa8a1f9aa4b05cfa76329bfd9b65d8 100644
--- a/VersionNum
+++ b/VersionNum
@@ -5,19 +5,19 @@
  *
  */
 #define Module_MajorVersion_CMHG        5.35
-#define Module_MinorVersion_CMHG        4.79.2.269
-#define Module_Date_CMHG                10 Jul 2015
+#define Module_MinorVersion_CMHG        4.79.2.270
+#define Module_Date_CMHG                13 Jul 2015
 
 #define Module_MajorVersion             "5.35"
 #define Module_Version                  535
-#define Module_MinorVersion             "4.79.2.269"
-#define Module_Date                     "10 Jul 2015"
+#define Module_MinorVersion             "4.79.2.270"
+#define Module_Date                     "13 Jul 2015"
 
-#define Module_ApplicationDate          "10-Jul-15"
+#define Module_ApplicationDate          "13-Jul-15"
 
 #define Module_ComponentName            "Kernel"
 #define Module_ComponentPath            "castle/RiscOS/Sources/Kernel"
 
-#define Module_FullVersion              "5.35 (4.79.2.269)"
-#define Module_HelpVersion              "5.35 (10 Jul 2015) 4.79.2.269"
+#define Module_FullVersion              "5.35 (4.79.2.270)"
+#define Module_HelpVersion              "5.35 (13 Jul 2015) 4.79.2.270"
 #define Module_LibraryVersionInfo       "5:35"
diff --git a/s/Middle b/s/Middle
index 29696f03daadf3533bfc9382ee974e83d8b00103..3f65be41cbb038595db9168ecafb87b9df785b28 100644
--- a/s/Middle
+++ b/s/Middle
@@ -712,12 +712,13 @@ UNDEF2
         MOV     R14, R4                 ; corrupt R14_SVC (but already saved if we were in SVC)
 ; ... and fall into
 UNDEF1
-        LDR     sp, =SVCSTK             ; Flatten superstack
-
       [ HangWatch
+        LDR     sp, =SVCSTK-SVCStackSize+512 ; HangWatch doesn't need much stack space, so use the low part, as it's the area that's least likely to contain something useful to the dump
         SWI     &59283                  ; XHangWatch_Dump
       ]
 
+        LDR     sp, =SVCSTK             ; Flatten superstack
+
         ; Check that ExceptionDump is safe to use
         Push    "R14"                   ; Preserve error ptr
         LDR     R4, =ZeroPage
diff --git a/s/vdu/vdupointer b/s/vdu/vdupointer
index 393d707a0aac6405df53a3bb3f8df52cf780d368..f977d18ca9c997494aa43e182b8904da842a4df0 100644
--- a/s/vdu/vdupointer
+++ b/s/vdu/vdupointer
@@ -632,12 +632,19 @@ RemovePointer ROUT
         BNE     %FT90
         ; Lock mutex
         MOV     r10, #1
-        STRB    r10, [WsPtr, #SWP_Restore]
         STRB    r10, [WsPtr, #SWP_Mutex]
-        ; Remove pointer if possible
+        ; We need to set SWP_Restore so that we know to release the mutex once we're done
+        ; However if the software pointer currently isn't visible (hardware pointer in use) then there might not be an image to restore
+        ; So SWP_Restore can take three values:
+        ; 0 -> not in RemovePointer block
+        ; 1 -> in RemovePointer but no restore needed
+        ; 2 -> in RemovePointer and restore needed
         LDR     r11, [WsPtr, #SWP_Pos]
-        LDR     r10, [WsPtr, #SWP_Under]
         TEQ     r11, #0
+        MOVNE   r10, #2
+        STRB    r10, [WsPtr, #SWP_Restore]
+        ; Remove pointer if necessary
+        LDRNE   r10, [WsPtr, #SWP_Under]
         BLNE    RemoveSoftwarePointer
         ; Exit with mutex still locked
 90
@@ -651,13 +658,16 @@ RemovePointer ROUT
 ;       Software pointer restore assumed to be needed
 
 RestorePointer ROUT
-        STMFD   R13!,{R0-R6,R14}
+        STMFD   R13!,{R0-R7,R14}
+        PHPSEI  R7                           ; IRQs off while we work out what to do
+        LDRB    R1, [WsPtr, #SWP_Restore]
         MOV     R0, #0
         STRB    R0, [WsPtr, #SWP_Restore]
         STRB    R0, [WsPtr, #SWP_Mutex]
         LDRB    R6, [WsPtr, #PointerShapeNumber]
-        ANDS    R6, R6, #&7F
-        BEQ     %FT10
+        TST     R1, #2                       ; Was the software pointer actually on?
+        ANDNES  R6, R6, #&7F
+        BEQ     %FT90
 
         ADD     R3, WsPtr, #PointerShapes-4
         LDR     R3, [R3, R6, LSL #2]         ; R3 -> current shape block (R6 = shape 1..4)
@@ -683,9 +693,47 @@ RestorePointer ROUT
         LDRB    R4, [R3, #PointerActiveY]
         SUB     R2, R2, R4                         ; R2 = pointer y, adjusted for active point
 
+        ; The pointer may have moved while we had it disabled.
+        ; If it has moved, it's possible the hardware pointer has taken over
+        ; and the software pointer isn't needed anymore
+        ; Potentially we could deal with this inside UpdateSoftwarePointer
+        ; (i.e. cache the new parameters if it gets called with the mutex
+        ; locked), but that will add a fair bit of complexity. So for now go
+        ; with the simpler approach of comparing the current position against
+        ; the last position used by the software pointer and calling through to
+        ; GraphicsV if it's changed (otherwise, call software pointer directly)
+
+      [ NoARMv6
+        MOV     R5, R1, LSL #16
+        MOV     LR, R2, LSL #16
+        ORR     R5, LR, R5, LSR #16
+      |
+        PKHBT   R5, R1, R2, LSL #16
+      ]
+        LDR     LR, [WsPtr, #SWP_Coords]
+        TEQ     LR, R5
+        BEQ     %FT50
+
+        ; Pointer has moved - call GraphicsV
+        LDR     R4, [WsPtr, #CurrentGraphicsVDriver]
+        MOV     R4, R4, LSL #24
+        ORR     R4, R4, #GraphicsV_UpdatePointer
+        BL      CallGraphicsV
+
+        TEQ     R4, #0
+        BEQ     %FT90
+
+50
+        ; IRQs on for software pointer call
+        ; This does open up the possibility for the pointer shape/location to
+        ; change under IRQ while we're still rendering it - so a more advanced
+        ; locking mechanism may be desirable in future
+        PLP     R7
+
         BL      UpdateSoftwarePointer
-10
-        LDMFD   R13!,{R0-R6,PC}
+90
+        PLP     R7
+        LDMFD   R13!,{R0-R7,PC}
 
 ; *****************************************************************************
 ;