diff --git a/VersionASM b/VersionASM
index 3a85ba260ebe6fe89b5570daf8e8806619645db0..704acac9341a0a99843a558951ff6497f2c01053 100644
--- a/VersionASM
+++ b/VersionASM
@@ -8,11 +8,11 @@
                         GBLS    Module_FullVersion
                         GBLS    Module_ApplicationDate2
                         GBLS    Module_ApplicationDate4
-Module_MajorVersion     SETS    "5.30"
-Module_Version          SETA    530
+Module_MajorVersion     SETS    "5.31"
+Module_Version          SETA    531
 Module_MinorVersion     SETS    ""
-Module_Date             SETS    "28 Jun 2000"
-Module_ApplicationDate2 SETS    "28-Jun-00"
-Module_ApplicationDate4 SETS    "28-Jun-2000"
-Module_FullVersion      SETS    "5.30"
+Module_Date             SETS    "15 Aug 2000"
+Module_ApplicationDate2 SETS    "15-Aug-00"
+Module_ApplicationDate4 SETS    "15-Aug-2000"
+Module_FullVersion      SETS    "5.31"
                         END
diff --git a/VersionNum b/VersionNum
index 3b7750deeab7c2fa9b5f4dc9ce279d8a09b7926f..1680115ba835bf0f7d644d7280d70219d1b55512 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,18 +1,18 @@
-/* (5.30)
+/* (5.31)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  *
  */
-#define Module_MajorVersion_CMHG        5.30
+#define Module_MajorVersion_CMHG        5.31
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                28 Jun 2000
+#define Module_Date_CMHG                15 Aug 2000
 
-#define Module_MajorVersion             "5.30"
-#define Module_Version                  530
+#define Module_MajorVersion             "5.31"
+#define Module_Version                  531
 #define Module_MinorVersion             ""
-#define Module_Date                     "28 Jun 2000"
+#define Module_Date                     "15 Aug 2000"
 
-#define Module_ApplicationDate2         "28-Jun-00"
-#define Module_ApplicationDate4         "28-Jun-2000"
+#define Module_ApplicationDate2         "15-Aug-00"
+#define Module_ApplicationDate4         "15-Aug-2000"
 
-#define Module_FullVersion              "5.30"
+#define Module_FullVersion              "5.31"
diff --git a/hdr/KernelWS b/hdr/KernelWS
index 3ac0dd6d61ed4056c131a0c8f8c9844567e269ec..ede35d283e23ebcb353abd90c8803579bf78a011 100644
--- a/hdr/KernelWS
+++ b/hdr/KernelWS
@@ -1348,6 +1348,10 @@ MOSConvertBuffer    #  12               ; Enough romm for 8 hex digits.
 AbortIndirection    #  4                ; Pointer to list of addresses and trap routines
 PreVeneerRegDump    #  17*4             ; room for r0-r15, spsr
 
+ [ CacheCommonErrors
+CachedErrorBlocks   #  4                ; pointer to sysheap node holding the error block cache
+ ]
+
  [ AssemblingArthur
  ! 0, "low space free ":CC::STR:(&FE8-@)
  ]
diff --git a/s/ModHand b/s/ModHand
index 709610f73345bd4a9db0ff5cd3cddd8bf1cd3518..db467f348ad7fbb73aaa3b5a95c2accec296b95e 100644
--- a/s/ModHand
+++ b/s/ModHand
@@ -2179,7 +2179,7 @@ CheckForSWIEntries ROUT
          CMP     R1, #0
          LDRNE   R0, [R12, #Module_SWIEntry]
          CMPNE   R0, #0
-         MOVEQ   PC, lr
+         BEQ     %FT02
          TST     R0, #3
          MOVNE   PC, lr
          Push   "R5"
diff --git a/s/MsgCode b/s/MsgCode
index 444a51ea1e4f3a4c8af93ecec61c16f9f1cfcfef..b6923ae7eda3e68e0b85c5a3970eeaf1f3ef890f 100644
--- a/s/MsgCode
+++ b/s/MsgCode
@@ -45,7 +45,7 @@ TranslateError  ROUT
         Pull    "r4,PC"
 
 TranslateError_UseR4
-        Push    "R8,LR"
+        Push    "R8,R9,LR"
         mrs    ,R8,CPSR
         ORR     R8,R8,#V_bit                    ; V set ready :)
 
@@ -54,20 +54,29 @@ TranslateError_UseR4
         TEQ     LR,#0
         BNE     %FT90
 
-        BIC     R8, R8, #&0F
-        ORR     R8, R8, #SVC_mode               ; SVC mode, preserve IRQ state
-        msr    ,CPSR_c, R8
+        BIC     R9, R8, #&0F
+        ORR     R9, R9, #SVC_mode               ; SVC mode, preserve IRQ state
+        msr    ,CPSR_c, R9
 
-        Push    "R0-R7,LR"
+        Push    "R0-R7,R8,R9,LR"
 
-        MOV     R2,#0
-        MOV     R1,#-1                          ; We are looking up an error, don't bother
-        STRB    R1, [R2, #ErrorSemaphore]       ; translating other errors.
-
-        ADR     R1,KernelMessagesBlock+4
         MOV     R5,#0
         MOV     R6,#0
         MOV     R7,#0
+        MOV     R1,#-1                          ; We are looking up an error, don't bother
+        STRB    R1, [R5, #ErrorSemaphore]       ; translating other errors.
+
+  [ CacheCommonErrors
+        BL      CheckCommonErrorCache           ; sets R9 to memory address for cached result
+        MOVNE   R1,#0
+        BNE     %FT80
+        MOV     R2,R9                           ; 0 - or our cached area!
+        MOV     R3,#256
+  |
+        MOV     R2,#0
+  ]
+
+        ADR     R1,KernelMessagesBlock+4
         SWI     XMessageTrans_ErrorLookup
         LDR     R14,[R0]
         LDR     R1,[SP]
@@ -75,13 +84,88 @@ TranslateError_UseR4
         CMP     R14,R1
         STREQ   R0,[SP]
 
-        MOV     R1,#0
+        MOV     R1,#0                           ; To clear the semaphore
+  [ CacheCommonErrors
+        TEQNE   R9,#0                           ; Did we try to cache this message?
+        STRNE   R1,[R9]                         ; blat out the error number
+80
+  ]
         STRB    R1, [R1 ,#ErrorSemaphore]       ; Clear error semaphore
 
-        Pull    "R0-R7,LR"
+        Pull    "R0-R7,R8,R9,LR"
 90
         msr    ,CPSR_cf, R8                     ; Back to original mode, V set
-        Pull    "R8,PC"
+        Pull    "R8,R9,PC"
+
+  [ CacheCommonErrors
+   ; This block MUST not be empty
+CommonErrorAddresses
+        &       ErrorBlock_BadNumb
+        &       ErrorBlock_BuffOverflow
+        &       ErrorBlock_VarNoRoom
+        &       ErrorBlock_ChDynamNotAllMoved
+        &       ErrorBlock_NaffRelease
+EndCommonErrorAddresses
+
+        GBLA    ECEACount
+ECEACount SETA  (EndCommonErrorAddresses-CommonErrorAddresses)/4
+        ASSERT  (EndCommonErrorAddresses <> CommonErrorAddresses)
+
+        ! 0, "Requiring ":CC:(:STR:(ECEACount*256)):CC:" bytes for error cache"
+        ! 0, "Cached error block pointer at ":CC::STR:CachedErrorBlocks
+
+; This routine exits with Z clear if it can supply a cached translation; else must set Z
+; so that the TranslateError_UseR4 routine continues to function and set R9 to the cache
+; block to use for the result (or set R9 to zero to indicate no cacheing for this error)
+CheckCommonErrorCache ROUT
+        Entry   "r1-r3"
+        CMP     r4, #1                      ; is R4 = 0?  If so, clear C for next instruction
+        SBCS    r9, r4, r4                  ; R9=0,Z set - if R4 was >0, else R9=-1, Z clear
+        EXIT    EQ
+        LDR     r9, [r4, #KernelMessagesBlock] ; R4 guaranteed zero from above
+        TEQ     r9, #0
+        EXIT    EQ                          ; not initialised messages yet!  Exit R9=0, Z set
+        LDR     r9, [r4, #CachedErrorBlocks]
+        TEQ     r9, #0
+        BLEQ    CommonErrorCacheInit
+        EXIT    EQ
+        ADR     lr, CommonErrorAddresses
+        MOV     r2, #ECEACount - 1
+10
+        LDR     r1, [lr, r2, LSL #2]
+        TEQ     r1, r0
+        BEQ     %FT20
+        SUBS    r2, r2, #1
+        BPL     %BT10
+        ; Set Z if message not found, set R9 zero to mark we don't want to cache this
+        MOVS    r9, #0
+        EXIT
+20
+        LDR     r1, [r9, r2, LSL #8]!
+        ; Set Z if we don't have that error cached yet, clear it and copy the cached
+        ; block to R0 if we do already have this message
+        TEQ     r1, #0
+        MOVNE   r0, r9
+        EXIT
+
+CommonErrorCacheInit
+        Entry   "r0-r9"
+        LDR     r3, =ECEACount*256
+        BL      ClaimSysHeapNode
+        MOVVS   r2, #0
+        MOV     r3, #0
+        STR     r2, [R3, #CachedErrorBlocks]
+
+        GBLA    CECLoop
+CECLoop SETA    0
+        WHILE CECLoop < ECEACount
+          STRVC r3, [r2, #CECLoop * 256]
+CECLoop SETA    CECLoop+1
+        WEND
+
+        TEQ     r2, #0
+        EXIT
+  ]
 
 ;----------------------------------------------------------------------------------------
 ;
diff --git a/s/NewReset b/s/NewReset
index fc46123c4d733e0210afa7dc489de9ff74b7f0b0..f764f23cf443f8fbb1516f25113b219a30af6046 100644
--- a/s/NewReset
+++ b/s/NewReset
@@ -1619,6 +1619,9 @@ clearmswis
         MOV     R1, #-1                                 ; We don't have a message file yet !
         STRB    R1, [R0, #ErrorSemaphore]               ; Don't translate errors.
         STR     R0, [R0, #KernelMessagesBlock]          ; No message file open.
+      [ CacheCommonErrors
+        STR     R0, [R0, #CachedErrorBlocks]            ; No cached errors
+      ]
      ]
 
         MOV     R0, #IOC