diff --git a/Docs/HAL/MoreEnts b/Docs/HAL/MoreEnts
index 4478620e2ca67b300dbbcac24153df826d0eb344..a13091cf84686b643c188f1833ec3c2933157c86 100644
--- a/Docs/HAL/MoreEnts
+++ b/Docs/HAL/MoreEnts
@@ -22,11 +22,54 @@ HAL_IRQEnable
 HAL_IRQDisable
 HAL_IRQClear
 HAL_IRQSource (get highest priority asserted IRQ)
+HAL_IRQDisableAll
 
 HAL_FIQEnable
 HAL_FIQDisable
 HAL_FIQClear
+HAL_FIQDisableAll
 
+Interrupt specifications are generally described by a 3-word structure.
+The 3 words correspond directly to the contents of registers R0,R3 and R4
+on entry to OS_ClaimDeviceVector.
+
+struct
+{
+    int device;
+    union {
+       struct {
+         unsigned char *addr;
+         int maskandpolarity;
+       } bit;
+       struct {
+         int (*forme)(void *handle);
+         void *handle;
+       } func;
+    } sub;
+}
+
+OS_ClaimDeviceVector changes:
+
+R3 and R4 must always be supplied. Set R3=R4=0 to claim "all" of an interrupt.
+Bit 31 of the device number indicates that a routine is being supplied instead
+of an address and a mask.
+
+When supplying a bit mask, your handler is called if
+
+       ([addr] AND maskandpolarity) EOR (maskandpolarity >> 8)
+
+is nonzero. This is a RISC OS 3.8+ backwards-compatible extension to the original
+check:
+
+      [addr] AND maskandpolarity 
+
+When supplying a routine, your handler is called if
+
+       forme(handle)
+
+returns nonzero.
+
+if 
 
 
 Timers
@@ -359,3 +402,8 @@ unsigned int HAL_TouchscreenMeasure(int meas)
   Resistance measurements can be used to compensate for large pressed areas causing
   shorts - subtract the instantaneous resistance from the instantaneous precision.
   (I think).
+
+Serial ports
+============
+
+The RS232 serial UART is a fundamental peripheral on most current hardware. All
diff --git a/Docs/HAL/NewAPI b/Docs/HAL/NewAPI
new file mode 100644
index 0000000000000000000000000000000000000000..d60c8b45ac2e5ac234565ac1b056a24a544a946d
--- /dev/null
+++ b/Docs/HAL/NewAPI
@@ -0,0 +1,27 @@
+struct peripheral
+{
+    uint32_t type;
+    uint32_t location;
+    uint32_t version;
+    const char *description;
+    uint32_t reserved[4];
+    int (*Activate)(struct peripheral *);
+    void (*Deactivate)(struct peripheral *)
+    void (*Reset)(struct peripheral *);
+    int (*Sleep)(struct peripheral *, state);
+    int (*Claim)(struct peripheral *, int intno, myfunc, handle);
+    void (*Release)(struct peripheral *, int intno, myfunc, handle);
+    uint32_t reserved[2];
+
+};
+
+
+struct serial
+{
+    struct peripheral p;
+    int (*ReadByte)(struct serial *);
+
+    // private data
+}
+
+
diff --git a/Docs/HAL/Serial b/Docs/HAL/Serial
new file mode 100644
index 0000000000000000000000000000000000000000..f73fb4f72e52136e50bd68c31c462f26fe1fbfb7
--- /dev/null
+++ b/Docs/HAL/Serial
@@ -0,0 +1,133 @@
+Features
+
+     Bit 0:  FIFOs available
+
+int ReceiveByte(int port, int *status)
+
+  Returns the next byte from the FIFO (if enabled) or the holding register.
+  If status is non-NULL, the line status associated with the byte is
+  read (see LineStatus). The return value is only meaningful if a
+  received byte is available (bit 0 of *status will be set).
+
+void TransmitByte(int port, int byte)
+
+int LineStatus(int port)
+
+     Bit 0: Receiver Data Ready
+     Bit 1: Overrun Error
+     Bit 2: Parity Error
+     Bit 3: Framing Error
+     Bit 4: Break Error
+     Bit 5: Transmitter Holding Register Empty
+     Bit 6: Transmitter Empty (including FIFO)
+     Bit 7: FIFO contains a Parity, Framing or Break error
+
+  Parity, Framing and Break errors are associated with each byte received.
+  Whether the values reported here are associated with the last byte
+  read using ReceiveByte or with the next byte to be read is undefined.
+  You should request the status using ReceiveByte to ensure accurate
+  identification of bytes with errors.
+
+  Error bits are cleared whenever status is read, using either LineStatus
+  or ReceiveByte with status non-NULL.
+
+int InterruptEnable(int port, int eor, int mask)
+
+  Enables interrupts. Bits are:
+ 
+     Bit 0: Received Data Available (and Character Timeout)
+     Bit 1: Transmitter Holding Register Empty
+     Bit 2: Received Line Status
+     Bit 3: Modem Status
+
+  Returns previous state.
+
+int Rate(int port, int baud16)
+
+  Sets the rate, in units of 1/16 of a baud. Returns the previous rate.
+  Use -1 to read.
+
+int Format(int port, int format)
+
+  Bits 0-1: Bits per word  0=>5, 1=>6, 2=>7, 3=>8
+  Bit 2:    Stop length 0=>1, 1=>2 (1.5 if 5 bits)
+  Bit 3:    Parity enabled
+  Bits 4-5: Parity:  0 => Odd (or disabled)
+                     1 => Even
+                     2 => Mark (parity bit = 1)
+                     3 => Space (parity bit = 0)
+
+  Returns previous format. -1 to read.
+
+void FIFOSize(int *rx, int *tx)
+
+  Returns the size of the RX and TX FIFOs. Either parameter may be NULL.
+  Note that the size of the TX FIFO is the total amount of data that can
+  be sent immediately when the Transmitter Holding Register Empty
+  status holds. (So an unusual UART that had a transmit threshold
+  should return total FIFO size minus threshold).
+
+void FIFOClear(int port, int flags)
+
+  Clears the input FIFO (if bit 0 set) and the output FIFO (if bit 1 set).
+
+int FIFOEnable(int port, int enable)
+
+  Enables or disables the RX and TX FIFOs: 0 => disable, 1 => enable
+  -1 => read status. Returns previous status.
+
+int FIFOThreshold(int port, int threshold)
+
+  Sets the receive threshold level for the FIFO RX interrupt. Normally
+  available values are 1,4,8 and 14 bytes. Returns previous value.
+  -1 to read.
+  
+int InterruptID(int port)
+
+  Returns the highest priority interrupt currently asserted. In order
+  of priority:
+
+  3 => Receiver Line Status (Cleared by ReceiveByte)
+  2 => Received Data Available (Cleared by reading enough data)
+  6 => Character Timeout (received data waiting)
+  1 => Transmitter Holding Register Empty (Cleared by this call)
+  0 => Modem Status (Cleared by ModemStatus)
+  -1 => No Interrupt
+
+  The Modem Status interrupt occurs when the CTS, DSR or DCD inputs
+  change, or when RI goes from high to low (ie bits 0 to 3 of ModemStatus
+  are set).
+ 
+int Break(int port, int enable)
+
+  Activates (1) or deactivates (0) a break condition. -1 to read,
+  returns previous state.
+                               
+int ModemControl(int port, int eor, int mask)
+
+  Modifies the modem control outputs.
+
+  Bit 0: DTR
+  Bit 1: RTS
+
+  Note that these are logical outputs, although the physical pins may be inverted.
+  So 1 indicates a request to send.
+
+int ModemStatus(int port)
+
+  Reads the modem status inputs.
+
+  Bit 0: CTS changed since last call
+  Bit 1: DSR changed since last call
+  Bit 2: RI changed from high to low since last call
+  Bit 3: DCD changed since last call
+  Bit 4: CTS
+  Bit 5: DSR
+  Bit 6: RI
+  Bit 7: DCD
+
+  Note that these are logical inputs, although the physical pins may be inverted.
+  So 1 indicates a Clear To Send condition.
+
+int Device(int port)
+
diff --git a/VersionASM b/VersionASM
index 9f58ba3ab2ded03e3899b6d1af536cf74e8fe0a6..c7c574cdd53667e3ece3d1bf0bbebd0f8ceefd42 100644
--- a/VersionASM
+++ b/VersionASM
@@ -13,12 +13,12 @@
                         GBLS    Module_ComponentPath
 Module_MajorVersion     SETS    "5.35"
 Module_Version          SETA    535
-Module_MinorVersion     SETS    "4.79.2.16"
-Module_Date             SETS    "01 Feb 2001"
-Module_ApplicationDate2 SETS    "01-Feb-01"
-Module_ApplicationDate4 SETS    "01-Feb-2001"
+Module_MinorVersion     SETS    "4.79.2.17"
+Module_Date             SETS    "13 Feb 2001"
+Module_ApplicationDate2 SETS    "13-Feb-01"
+Module_ApplicationDate4 SETS    "13-Feb-2001"
 Module_ComponentName    SETS    "Kernel"
 Module_ComponentPath    SETS    "RiscOS/Sources/Kernel"
-Module_FullVersion      SETS    "5.35 (4.79.2.16)"
-Module_HelpVersion      SETS    "5.35 (01 Feb 2001) 4.79.2.16"
+Module_FullVersion      SETS    "5.35 (4.79.2.17)"
+Module_HelpVersion      SETS    "5.35 (13 Feb 2001) 4.79.2.17"
                         END
diff --git a/VersionNum b/VersionNum
index eec9b9d5ba16a10e64073e9fe337219fd3815546..6a8fb5753fcddf296ab349017758d898f04edc3b 100644
--- a/VersionNum
+++ b/VersionNum
@@ -4,19 +4,19 @@
  *
  */
 #define Module_MajorVersion_CMHG        5.35
-#define Module_MinorVersion_CMHG        4.79.2.16
-#define Module_Date_CMHG                01 Feb 2001
+#define Module_MinorVersion_CMHG        4.79.2.17
+#define Module_Date_CMHG                13 Feb 2001
 
 #define Module_MajorVersion             "5.35"
 #define Module_Version                  535
-#define Module_MinorVersion             "4.79.2.16"
-#define Module_Date                     "01 Feb 2001"
+#define Module_MinorVersion             "4.79.2.17"
+#define Module_Date                     "13 Feb 2001"
 
-#define Module_ApplicationDate2         "01-Feb-01"
-#define Module_ApplicationDate4         "01-Feb-2001"
+#define Module_ApplicationDate2         "13-Feb-01"
+#define Module_ApplicationDate4         "13-Feb-2001"
 
 #define Module_ComponentName            "Kernel"
 #define Module_ComponentPath            "RiscOS/Sources/Kernel"
 
-#define Module_FullVersion              "5.35 (4.79.2.16)"
-#define Module_HelpVersion              "5.35 (01 Feb 2001) (4.79.2.16)"
+#define Module_FullVersion              "5.35 (4.79.2.17)"
+#define Module_HelpVersion              "5.35 (13 Feb 2001) (4.79.2.17)"
diff --git a/s/ARM600 b/s/ARM600
index b35cf81fc05ce058e4902c39d4af41f1a81aebcf..be110724ea1a845a831074af2ccc9773f2d30247 100644
--- a/s/ARM600
+++ b/s/ARM600
@@ -2331,8 +2331,8 @@ MMUControl_ModifyControl ROUT
         LDR     lr, [r3, #MMUControlSoftCopy]
         CMP     r5,#ARMv4
         ARM_read_control lr,HS
-        MOVHS   lr,lr,LSL #19
-        MOVHS   lr,lr,LSR #19           ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
+;        MOVHS   lr,lr,LSL #19
+;        MOVHS   lr,lr,LSR #19           ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
         AND     r2, r2, lr
         EOR     r2, r2, r1
         MOV     r1, lr
@@ -2379,8 +2379,8 @@ MMUC_modcon_readonly
         LDR     lr, [r3, #MMUControlSoftCopy]
         CMP     r5, #ARMv4
         ARM_read_control lr,HS
-        MOVHS   lr,lr,LSL #19
-        MOVHS   lr,lr,LSR #19           ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
+;        MOVHS   lr,lr,LSL #19
+;        MOVHS   lr,lr,LSR #19           ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
         STRHS   lr, [r3, #MMUControlSoftCopy]
         MOV     r1, lr
         MOV     r2, lr
diff --git a/s/ChangeDyn b/s/ChangeDyn
index 231d9e132d9c28978d3cca6d523525dc1de80e50..43c2f845ea4f15cddf46b27b755e5bfad33c300d 100644
--- a/s/ChangeDyn
+++ b/s/ChangeDyn
@@ -2635,18 +2635,9 @@ DoTheGrowPagesSpecified
         LDR     r6, [r8, #0]                    ; r6 = page number required
         LDR     lr, [r8, #PageBlockSize+0]      ; lr = page number of replacement page
         TEQ     r6, lr                          ; if the same
-        BNE     %FT21
+        Pull    "r0-r4,r7-r12", EQ              ; then restore registers
+        BEQ     %FT76                           ; and skip copy and first page move
 
-        ; if the same page, we can skip copy and just move needed page to destination
-        ;
-        Pull    "r0-r4,r7-r12"                  ; restore registers
-        LDR     r2, [r8, #0]
-        MOV     r3, r1
-        LDR     r11, DestFlags
-        BL      Call_CAM_Mapping                ; move needed page
-        B       %FT76                           ; and continue
-
-21
         ;mjs
         ; - if the old page is currently mapped in, copy normally
         ; - if the old page is not mapped in, copy via temporary mapping
@@ -2709,20 +2700,19 @@ DoTheGrowPagesSpecified
 74
         Pull    "r0-r4,r7-r12"                  ; restore registers
 
-        ; mjs: old code moved pages in wrong order for MMU, creating a temporary degeneracy
-        ; of two physical pages at same logical address - eg. undefined behaviour for cache writebacks
-        ;
-        ; so do it this way now:
-        ; first, move needed page to destination (nothing there at present)
-        ; this also moves page out of way for moving the replacement page in, see below
-        ;
-        LDR     r2, [r8, #0]
-        MOV     r3, r1
-        LDR     r11, DestFlags
-        BL      Call_CAM_Mapping
+        ; mjs
+        ; OK, what we are about to do is:
+        ;   1) move replacement page in (to replace needed page)
+        ;   2) move needed page to required destination
+        ; This order means that we don't leave a temporary hole at the logical address we're substituting,
+        ; which is vital at least in the horrendous case where the logical page is itself used for L2PT.
+        ; However, this means there is a potential temporary degeneracy in the caches, two physical pages
+        ; having been seen at the same logical address (undefined behaviour).
+        ; So, to be safe, we do a MMUChangingEntry first, for the logical page, which will clean/invalidate
+        ; caches and invalidate TLBs, to avoid degeneracy. This is slight overkill in some cases, but vital
+        ; to avoid serious grief in the awkward cases. Fortunately, these page substitutions are relatively
+        ; rare, so performance is not critical.
 
-        ; next, move replacement page in
-        ;
         MOV     lr, #0
         LDR     lr, [lr, #CamEntriesPointer]    ; lr -> soft cam map
         ADD     lr, lr, #4                      ; point at PPLs, not addresses
@@ -2732,9 +2722,20 @@ DoTheGrowPagesSpecified
 
         ADD     lr, r8, #PageBlockSize
         LDMIA   lr, {r2, r3}                    ; get page number, logical address
-        BL      Call_CAM_Mapping
 
+        Push    "r0, r4"
+        MOV     r0, r3
+        MOV     r4, #0
+        ARMop   MMU_ChangingEntry,,,r4
+        Pull    "r0, r4"
+
+        BL      Call_CAM_Mapping                ; move replacement page in
 76
+        LDR     r2, [r8, #0]
+        MOV     r3, r1
+        LDR     r11, DestFlags
+        BL      Call_CAM_Mapping                ; move needed page to destination
+
         LDR     lr, SavedPSR
         MSR     CPSR_cf, lr
 
diff --git a/s/HAL b/s/HAL
index 266fc812d48555d7a229e0536061f8ab9608e73a..8bd8f37f8bc478864157bef4f97283d4255b3e16 100644
--- a/s/HAL
+++ b/s/HAL
@@ -49,7 +49,7 @@ RISCOS_InitARM
         ORR     a1, a1, #MMUC_F+MMUC_L+MMUC_D+MMUC_P
         ; All of these bits should be off already, but just in case...
         BIC     a1, a1, #MMUC_B+MMUC_W+MMUC_C+MMUC_A+MMUC_M
-        BIC     a1, a1, #MMUC_RR+MMUC_V+MMUC_I+MMUC_Z+MMUC_R+MMUC_S+MMUC_R
+        BIC     a1, a1, #MMUC_RR+MMUC_V+MMUC_I+MMUC_Z+MMUC_R+MMUC_S
 
         ; Off we go.
         ARM_write_control a1
@@ -504,17 +504,24 @@ DoTheL2PThack
         ADD     v4, a4, #1024*1024              ; to fill the cache with rubbish
         STMIA   lr, {a4, v4}
 
-        MSR     CPSR_c, #F32_bit+I32_bit+UND32_mode ; Recover the soft copy of the CR
+        MOV     a4, a1
+        BL      Init_ARMarch                    ; corrupts a1 and ip
+        MOV     a1, a4
+        MSREQ   CPSR_c, #F32_bit+I32_bit+UND32_mode ; Recover the soft copy of the CR
+        ARM_read_control v5, NE
   [ CacheOff
-        ORR     v5, sp, #MMUC_M                 ; MMU on
+        ORR     v5, v5, #MMUC_M                 ; MMU on
         ORR     v5, v5, #MMUC_R                 ; ROM mode enable
   |
-        ORR     v5, sp, #MMUC_W+MMUC_C+MMUC_M   ; Write buffer, data cache, MMU on
+        ORR     v5, v5, #MMUC_W+MMUC_C+MMUC_M   ; Write buffer, data cache, MMU on
         ORR     v5, v5, #MMUC_R+MMUC_Z          ; ROM mode enable, branch predict enable
   ]
 MMUon_instr
         ARM_write_control v5
-        MSR     CPSR_c, #F32_bit+I32_bit+SVC32_mode
+        MSREQ   CPSR_c, #F32_bit+I32_bit+SVC32_mode
+
+        MOV     ip, #0                                          ; junk MMU-off contents of I-cache
+        MCR     ARM_config_cp,0,ip,ARMv4_cache_reg,C7           ; (works on ARMv3)
 
 ; MMU now on. Need to jump to logical copy of ourselves. Complication arises if our
 ; physical address overlaps our logical address - in that case we need to map
diff --git a/s/PMF/osinit b/s/PMF/osinit
index 0f92b008c48da64b8b687293de666baf8d5ea95c..bdabc33345ab018da8690c065a7b6d1860a4bd78 100644
--- a/s/PMF/osinit
+++ b/s/PMF/osinit
@@ -877,9 +877,10 @@ MonitorLeadList
    ] ; IOMD_C_MonitorType = 0
 	MonitorLeadItem 4_3333,  28, 3, 0                       ; VGA-capable monitors 256 colours
   | ; STB
-        MonitorLeadItem 4_3330,  27, 3, 0                       ; VGA-capable monitors
-        MonitorLeadItem 4_3111,  27, 5, 0                       ; Nothing - try LCD (fudge fudge)
-        MonitorLeadItem 4_3333,  12, 0, 1                       ; Others - assume TV standard
+        ; KJB - changed default modes to 256 colours
+        MonitorLeadItem 4_3330,  28, 3, 0                       ; VGA-capable monitors
+        MonitorLeadItem 4_3111,  28, 5, 0                       ; Nothing - try LCD (fudge fudge)
+        MonitorLeadItem 4_3333,  15, 0, 1                       ; Others - assume TV standard
   ]; STB
  | ;IO_Type = "IOMD"
 MonitorLead_MonoVGA     *       4_3101