diff --git a/Resources/Germany/Messages b/Resources/Germany/Messages
index e0d9e26a7b3083e2a748c630ac75783066940835..040f012adf2d22472773f27ce68aad0993ddc8cc 100644
Binary files a/Resources/Germany/Messages and b/Resources/Germany/Messages differ
diff --git a/Resources/UK/Messages b/Resources/UK/Messages
index 3583545a6551a76f09e59357283695d5e3fc2e21..8a0c070ac5539d170f895d44d0ef94662f6abe1e 100644
Binary files a/Resources/UK/Messages and b/Resources/UK/Messages differ
diff --git a/VersionASM b/VersionASM
index 08b7a4595eb095574f5a71b1c6eda5d27f24b74e..518821e07e165c1e2883466102efe82c567473a8 100644
--- a/VersionASM
+++ b/VersionASM
@@ -9,12 +9,12 @@
                         GBLS    Module_ApplicationDate
                         GBLS    Module_HelpVersion
                         GBLS    Module_ComponentName
-Module_MajorVersion     SETS    "2.03"
-Module_Version          SETA    203
+Module_MajorVersion     SETS    "2.04"
+Module_Version          SETA    204
 Module_MinorVersion     SETS    ""
-Module_Date             SETS    "06 Jul 2019"
-Module_ApplicationDate  SETS    "06-Jul-19"
+Module_Date             SETS    "16 Oct 2019"
+Module_ApplicationDate  SETS    "16-Oct-19"
 Module_ComponentName    SETS    "Debugger"
-Module_FullVersion      SETS    "2.03"
-Module_HelpVersion      SETS    "2.03 (06 Jul 2019)"
+Module_FullVersion      SETS    "2.04"
+Module_HelpVersion      SETS    "2.04 (16 Oct 2019)"
                         END
diff --git a/VersionNum b/VersionNum
index f811a639dcf8436cf729fba8a70e1da7e4e19d66..315bdaf5b60fe49675b97f44a1b131fb37f1f2bd 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,21 +1,21 @@
-/* (2.03)
+/* (2.04)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  *
  */
-#define Module_MajorVersion_CMHG        2.03
+#define Module_MajorVersion_CMHG        2.04
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                06 Jul 2019
+#define Module_Date_CMHG                16 Oct 2019
 
-#define Module_MajorVersion             "2.03"
-#define Module_Version                  203
+#define Module_MajorVersion             "2.04"
+#define Module_Version                  204
 #define Module_MinorVersion             ""
-#define Module_Date                     "06 Jul 2019"
+#define Module_Date                     "16 Oct 2019"
 
-#define Module_ApplicationDate          "06-Jul-19"
+#define Module_ApplicationDate          "16-Oct-19"
 
 #define Module_ComponentName            "Debugger"
 
-#define Module_FullVersion              "2.03"
-#define Module_HelpVersion              "2.03 (06 Jul 2019)"
-#define Module_LibraryVersionInfo       "2:3"
+#define Module_FullVersion              "2.04"
+#define Module_HelpVersion              "2.04 (16 Oct 2019)"
+#define Module_LibraryVersionInfo       "2:4"
diff --git a/s/ARM b/s/ARM
index ebf7e857d404528978fbccb02d68150a2ae5c6e7..ecea32dd3f5ca48618c75d46e8ea3254eaf2e955 100644
--- a/s/ARM
+++ b/s/ARM
@@ -2547,16 +2547,16 @@ MemoryI_Code Entry "r6-r11", 8+8
 
         MOV     r0, r9
         BL      do_readW
-        EXIT    VS
+        BVS     %FT91
 
         MOV     r4, r1
         BL      DisplayCharactersR      ; Display R6 chars contained in R4
-        EXIT    VS
+        BVS     %FT91
 
         SWI     XOS_WriteS
         DCB     " : ", 0
         ALIGN
-        EXIT    VS
+        BVS     %FT91
 
         MOV     r10, r1
         BL      DisplayHexWord
@@ -2578,7 +2578,7 @@ MemoryI_Code Entry "r6-r11", 8+8
         MOV     r0, sp
         BL      do_readW
         ADD     sp, sp, #8
-        EXIT    VS
+        BVS     %FT91
         LDR     lr, [r9]
         TST     lr, #2
         MOVNE   r1, r1, LSR #16
@@ -2586,17 +2586,17 @@ MemoryI_Code Entry "r6-r11", 8+8
         ; ARMv5+, safe to LDRH
         MOV     r0, r9
         BL      do_readH
-        EXIT    VS
+        BVS     %FT91
  ]
 
         MOV     r4, r1
         BL      DisplayCharactersR      ; Display R6 chars contained in R4
-        EXIT    VS
+        BVS     %FT91
 
         SWI     XOS_WriteS
         DCB     " : ", 0
         ALIGN
-        EXIT    VS
+        BVS     %FT91
 
         MOV     r10, r1
         BL      DisplayHexHalfword
@@ -2609,7 +2609,7 @@ MemoryI_Code Entry "r6-r11", 8+8
 
         SWIVC   XOS_Write0
         SWIVC   XOS_NewLine
-        EXIT    VS
+        BVS     %FT91
 
         LDMIA   r9, {r3-r4}
         LDMIA   r7, {r5,lr}
@@ -2623,6 +2623,7 @@ MemoryI_Code Entry "r6-r11", 8+8
 
 
 90      BL      SwapAllBreakpoints
+91      BL      mapout
         EXIT
 
 95      BL      AckEscape
diff --git a/s/Debugger b/s/Debugger
index 95cc6054302cfe31cb46cde5e7d79130b514d7b9..af0c0458d9cd1e7ce3d9628cf2196eaa78d1e5d9 100644
--- a/s/Debugger
+++ b/s/Debugger
@@ -160,6 +160,9 @@ OldAddress      #       4               ;address of last instruction
 OldThumbAddress #       4               ;address of last Thumb instruction
 OldThumbInst    #       4               ; last Thumb instruction disassembled
 PhysAddrWrd     #       4
+PhysMapRoutine  #       4               ; OS_Memory 14, 22, or logical mapping?
+PhysMapped      #       4               ; nonzero => mapping needs to be released
+PhysMapKey      #       4               ; for releasing mapping when done
 
 MessageFile_Block #     16              ; File handle for MessageTrans
 MessageFile_Open  #     4               ; Opened message file flag
@@ -494,6 +497,9 @@ Debug_Init Entry
         STR     R3, OldThumbAddress
         STR     R3, OldThumbInst
         STR     R3, PhysAddrWrd
+        STR     R3, PhysMapped          ; indicate nothing mapped yet
+        ADRL    R3, mapin_osmemory22
+        STR     R3, PhysMapRoutine
         MRS     R3, CPSR
         ANDS    R3, R3, #2_11100        ; non-zero if in a 32-bit mode
         STRB    R3, SysIs32bit
@@ -984,6 +990,7 @@ Memory_Code Entry "r6-r11",8+8+8+8 ; 3 * address buffers + 1 * doubleword data b
 
 
 90      BL      SwapAllBreakpoints
+        BL      mapout
         EXIT
 
 95      BL      AckEscape
@@ -997,239 +1004,171 @@ Memory_Code Entry "r6-r11",8+8+8+8 ; 3 * address buffers + 1 * doubleword data b
 ; the system is an IOMD-based non-HAL system, where the 512MB
 ; of physical address space is mapped in at &80000000.
 
-; in: r0 -> address, r1 -> buffer to hold (double-word) data
-do_readD ROUT
-        Push    "r0-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        BNE     %FT50
-        LDR     r0, [r0]
-        LDRD    r2, [r0]         ;read to r2,r3
-        STMIA   r1, {r2,r3}
-        Pull    "r0-r3, pc"
-50
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
-        SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r1-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDR     lr, [sp, #4]
-        LDRD    r0, [r2]         ;read from logical mapping into r0,r1
-        STMIA   lr, {r0,r1}
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r1, r2, #0       ;clear V
-        Pull    "r0-r3, pc"
+; in: r0 -> address, out: r1 = (byte) data
+do_readB
+        Entry   "r0-r5"
+        MOV     r4, pc
+        B       common
+        LDRB    r2, [r2]
+        FramSTR r2,,r1
+        MOV     pc, lr
+
+; in: r0 -> address, out: r1 = (half-word) data
+do_readH
+        AltEntry
+        MOV     r4, pc
+        B       common
+        LDRH    r2, [r2]
+        FramSTR r2,,r1
+        MOV     pc, lr
 
 ; in: r0 -> address, out: r1 = (word) data
-do_readW ROUT
-        Push    "r0,r2-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        LDREQ   r0, [r0]
-        LDREQ   r1, [r0]
-        Pull    "r0,r2-r3, pc",EQ
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
-        SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r2-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDR     r2, [r2]         ;read from logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r1, r2, #0       ;clear V
-        Pull    "r0,r2-r3, pc"
+do_readW
+        AltEntry
+        MOV     r4, pc
+        B       common
+        LDR     r2, [r2]
+        FramSTR r2,,r1
+        MOV     pc, lr
 
-; in: r0 -> address, out: r1 = (half-word) data
-do_readH ROUT
-        Push    "r0,r2-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        BNE     %FT50
-        LDR     r0, [r0]
-        LDRH    r1, [r0]
-        Pull    "r0,r2-r3, pc"
-50
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
-        SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r2-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDRH    r2, [r2]         ;read from logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r1, r2, #0       ;clear V
-        Pull    "r0,r2-r3, pc"
+; in: r0 -> address, r1 -> buffer to hold (double-word) data
+do_readD
+        AltEntry
+        MOV     r4, pc
+        B       common
+        LDRD    r2, [r2]
+        FramLDR r4,,r1
+        STRD    r2, [r4]
+        MOV     pc, lr
 
-; in: r0 -> address, out: r1 = (byte) data
-do_readB ROUT
-        Push    "r0,r2-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        LDREQ   r0, [r0]
-        LDREQB  r1, [r0]
-        Pull    "r0,r2-r3, pc",EQ
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
-        SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r2-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDRB    r2, [r2]         ;read from logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r1, r2, #0       ;clear V
-        Pull    "r0,r2-r3, pc"
-
-; in: r0 -> address, r1 -> buffer holding (double-word) data
-do_writeD ROUT
-        Push    "r0-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        BNE     %FT50
-        LDR     r0, [r0]
-        LDMIA   r1, {r2,r3}
-        STRD    r2, [r0]         ;write from r2,r3
-        Pull    "r0-r3, pc"
-50
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
-        SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r1-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDR     lr, [sp, #4]
-        LDMIA   lr, {r0,r1}
-        STRD    r0, [r2]         ;store from r0,r1 into logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r0, r0, #0       ;clear V
-        Pull    "r0-r3, pc"
+; in: r0 -> address, r1 = (byte) data
+do_writeB
+        AltEntry
+        MOV     r4, pc
+        B       common
+        FramLDR r4,,r1
+        STRB    r4, [r2]
+        MOV     pc, lr
+
+; in: r0 -> address, r1 = (half-word) data
+do_writeH
+        AltEntry
+        MOV     r4, pc
+        B       common
+        FramLDR r4,,r1
+        STRH    r4, [r2]
+        MOV     pc, lr
 
 ; in: r0 -> address, r1 = (word) data
-do_writeW ROUT
-        Push    "r0-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        LDREQ   r0, [r0]
-        STREQ   r1, [r0]
-        Pull    "r0-r3, pc",EQ
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
-        SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r1-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDR     r1, [sp, #4]
-        STR     r1, [r2]         ;write to logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r0, r0, #0       ;clear V
-        Pull    "r0-r3, pc"
+do_writeW
+        AltEntry
+        MOV     r4, pc
+        B       common
+        FramLDR r4,,r1
+        STR     r4, [r2]
+        MOV     pc, lr
 
-; in: r0 -> address, r1 = (half-word) data
-do_writeH ROUT
-        Push    "r0-r3, r14"
+; in: r0 -> address, r1 -> buffer containing (double-word) data
+do_writeD
+        AltEntry
+        MOV     r4, pc
+        B       common
+        FramLDR r4,,r1
+        LDRD    r4, [r4]
+        STRD    r4, [r2]
+        MOV     pc, lr
+
+; Called with:
+;   R0 -> address to access (32bit if logical, 64bit if physical)
+;   R4 -> read/write routine
+; Read/write routine behaves as follows:
+;   In: R2 = logical address to access
+;   Out: R2-R5 corrupt, flags unchanged, stacked return value updated (for read operations)
+; It's our job to map in/out the memory around the call to the read/write routine
+common
         LDR     r14, PhysAddrWrd
         CMP     r14, #0
-        BNE     %FT50
-        LDR     r0, [r0]
-        STRH    r1, [r0]
-        Pull    "r0-r3, pc"
-50
+        BNE     %FT10
+        LDR     r2, [r0]
+        MOV     lr, pc
+        MOV     pc, r4
+        Exit
+10
         LDMIA   r0, {r1,r2}
+        MOV     lr, pc
+        LDR     pc, PhysMapRoutine
+        MOVVC   lr, pc
+        MOVVC   pc, r4
+        FramSTR r0, VS
+        Exit
+
+mapin_osmemory22
+        Entry
         MOV     r0, #OSMemReason_AccessPhysAddr64
         SWI     XOS_Memory
-        BVC     %FT90
+        BVS     %FT10
+        LDR     lr, PhysMapped
+        TEQ     lr, #0
+        STREQ   pc, PhysMapped
+        STREQ   r3, PhysMapKey
+        Exit
+10
         LDR     lr, [r0]
         TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r1-r3, pc", NE
+        Exit    NE
+        ; Fall back to OS_Memory 14 instead
+        ADR     lr, mapin_osmemory14
+        STR     lr, PhysMapRoutine
+        B       %FT20
+
+mapin_osmemory14
+        AltEntry
+20      TEQ     r2, #0
+        BNE     %FT90
         MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDR     r1, [sp, #4]
-        STRH    r1, [r2]         ;write to logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r0, r0, #0       ;clear V
-        Pull    "r0-r3, pc"
+        SWI     XOS_Memory
+        BVS     %FT30
+        LDR     lr, PhysMapped
+        TEQ     lr, #0
+        STREQ   pc, PhysMapped
+        STREQ   r3, PhysMapKey
+        Exit
+30
+        ; Fall back to flat logical mapping instead
+        CLRV
+        ADR     lr, mapin_flat
+        STR     lr, PhysMapRoutine
+        B       %FT40
 
-; in: r0 -> address, r1 = (byte) data
-do_writeB ROUT
-        Push    "r0-r3, r14"
-        LDR     r14, PhysAddrWrd
-        CMP     r14, #0
-        LDREQ   r0, [r0]
-        STREQB  r1, [r0]
-        Pull    "r0-r3, pc",EQ
-        LDMIA   r0, {r1,r2}
-        MOV     r0, #OSMemReason_AccessPhysAddr64
+mapin_flat
+        AltEntry
+        TEQ     r2, #0
+        BNE     %FT90
+40      BIC     r2, r1, #&E0000000
+        ORR     r2, r2, #&80000000
+        Exit
+
+90      ; >4 GB address requested on kernel that doesn't support them
+        ; so generate the error that it would have done
+        ADR     r0, ErrorBlock_CantGetPhysMem
+        BL      CopyError
+        Exit
+
+        MakeInternatErrorBlock CantGetPhysMem,, M98
+
+mapout
+        EntryS  "r0,r1"
+        LDR     r0, PhysAddrWrd
+        LDR     r1, PhysMapped
+        TEQ     r0, #0
+        TEQNE   r1, #0
+        Exit    EQ
+        LDR     r1, PhysMapKey
+        MOV     r0, #OSMemReason_ReleasePhysAddr
         SWI     XOS_Memory
-        BVC     %FT90
-        LDR     lr, [r0]
-        TEQ     lr, #ErrorNumber_HeapBadReason
-        ADDNE   sp, sp, #4
-        Pull    "r1-r3, pc", NE
-        MOV     r0, #OSMemReason_AccessPhysAddr
-        SWI     XOS_Memory       ;access physical address
-        BICVS   r2, r1, #&E0000000
-        ORRVS   r2, r2, #&80000000
-90      LDR     r1, [sp, #4]
-        STRB    r1, [r2]         ;write to logical mapping
-        MOVVC   r0, #OSMemReason_ReleasePhysAddr
-        MOVVC   r1, r3
-        SWIVC   XOS_Memory       ;release physical address
-        ADDS    r0, r0, #0       ;clear V
-        Pull    "r0-r3, pc"
+        MOV     r0, #0
+        STR     r0, PhysMapped
+        ExitS
 
 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
@@ -1702,6 +1641,7 @@ mai_cont
         SWIVC   XOS_NewLine
 
         BL      SwapAllBreakpoints
+        BL      mapout
         EXIT
 
 40
@@ -1720,6 +1660,7 @@ mai_cont
 
 99      ADR     r0, MemoryA_Error
         BL      CopyError
+        BL      mapout
         EXIT
 
 
@@ -1917,6 +1858,7 @@ int_byte
 
 90      ADD     sp, sp, #256
         BL      SwapAllBreakpoints
+        BL      mapout
         EXIT
 
 95      BL      AckEscape