diff --git a/Makefile b/Makefile
index 618ba613d8d7f03cca306244706d9e09e6f16944..22f1044e6ba19d3d2a2a642b444972a112d4c45c 100644
--- a/Makefile
+++ b/Makefile
@@ -53,7 +53,7 @@ LIBDIR  = <Lib$Dir>
 #
 # Generic options:
 #
-AS      = aasm
+AS      = objasm
 CC      = cc
 CMHG    = cmhg
 CP      = copy
@@ -71,8 +71,9 @@ XTENT   = perl build:xtentries >
 
 DIFF    = gnu.diff -df >null:
 
-AFLAGS  = -depend !Depend -Stamp -quit
-CFLAGS  = -c -depend !Depend ${INCLUDES} -DDDE -fK
+AFLAGS  = -depend !Depend
+# The zz switch stops library static data being placed in a zero-init area
+CFLAGS  = -c -depend !Depend ${INCLUDES} -DDDE -fK -zz10000000
 CPFLAGS = ~cfr~v
 WFLAGS  = ~c~r~v
 
@@ -632,8 +633,13 @@ lib.clib: ${CLIB_MOD_OBJS}
 	${MODSQZ} $@
 
 # Derived headers:
-derived.swis: s.makehswis h.swisheader s.swioptions
-	${AS} ${AFLAGS} -from s.makehswis -to $@
+derived.swis: o.swis
+	${LD} -bin -o $@ o.SWIs
+	stripnulls $@
+	settype $@ text
+
+o.swis: s.makehswis h.swisheader s.swioptions
+	${AS} ${AFLAGS} s.makehswis -o $@
 	settype $@ text
 
 s.swioptions:
diff --git a/VersionASM b/VersionASM
index 87252b7522c415cd15cda9a768ab6caa28231640..c5a8945e42eeab8fc257af884b109728c65885d4 100644
--- a/VersionASM
+++ b/VersionASM
@@ -1,6 +1,6 @@
 ;
 ; This file is automatically maintained by srccommit, do not edit manually.
-; Last processed by srccommit version: 1.68.
+; Last processed by srccommit version: 1.2.
 ;
                         GBLS    Module_MajorVersion
                         GBLA    Module_Version
@@ -11,13 +11,13 @@
                         GBLS    Module_HelpVersion
                         GBLS    Module_ComponentName
                         GBLS    Module_ComponentPath
-Module_MajorVersion     SETS    "5.47"
-Module_Version          SETA    547
+Module_MajorVersion     SETS    "5.48"
+Module_Version          SETA    548
 Module_MinorVersion     SETS    ""
-Module_Date             SETS    "03 Nov 2003"
-Module_ApplicationDate  SETS    "03-Nov-03"
+Module_Date             SETS    "02 Dec 2003"
+Module_ApplicationDate  SETS    "02-Dec-03"
 Module_ComponentName    SETS    "RISC_OSLib"
 Module_ComponentPath    SETS    "RiscOS/Sources/Lib/RISC_OSLib"
-Module_FullVersion      SETS    "5.47"
-Module_HelpVersion      SETS    "5.47 (03 Nov 2003)"
+Module_FullVersion      SETS    "5.48"
+Module_HelpVersion      SETS    "5.48 (02 Dec 2003)"
                         END
diff --git a/VersionNum b/VersionNum
index 96f7a4077c509044d24bd4cde54041f48c73bb5b..83bd420c090e67a400730e2b0e374c13efa1e926 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,23 +1,23 @@
-/* (5.47)
+/* (5.48)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
- * Last processed by srccommit version: 1.68.
+ * Last processed by srccommit version: 1.2.
  *
  */
-#define Module_MajorVersion_CMHG        5.47
+#define Module_MajorVersion_CMHG        5.48
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                03 Nov 2003
+#define Module_Date_CMHG                02 Dec 2003
 
-#define Module_MajorVersion             "5.47"
-#define Module_Version                  547
+#define Module_MajorVersion             "5.48"
+#define Module_Version                  548
 #define Module_MinorVersion             ""
-#define Module_Date                     "03 Nov 2003"
+#define Module_Date                     "02 Dec 2003"
 
-#define Module_ApplicationDate          "03-Nov-03"
+#define Module_ApplicationDate          "02-Dec-03"
 
 #define Module_ComponentName            "RISC_OSLib"
 #define Module_ComponentPath            "RiscOS/Sources/Lib/RISC_OSLib"
 
-#define Module_FullVersion              "5.47"
-#define Module_HelpVersion              "5.47 (03 Nov 2003)"
-#define Module_LibraryVersionInfo       "5:47"
+#define Module_FullVersion              "5.48"
+#define Module_HelpVersion              "5.48 (02 Dec 2003)"
+#define Module_LibraryVersionInfo       "5:48"
diff --git a/c/alloc b/c/alloc
index 446a080eca4c27fd1a39a77aaee44aaec1d41212..33ad2a5aec8bbf8dde772b2903b7b36fe8ceeabb 100644
--- a/c/alloc
+++ b/c/alloc
@@ -248,37 +248,23 @@ static char sys_message[60];
 /* Mutex-y things */
 
 static int heapMutex;
-static jmp_buf *swpNotAvailable = NULL; /* boolean also used to pass jmp_buf to sig handler */
+extern int _swp_available;
 
+#ifndef __APCS_32
 static int arm2_swp(int newValue, int *location);
+#endif
 
 static inline int swp(int newValue, int *location)
 {
 #ifndef __APCS_32
-  if (swpNotAvailable) return arm2_swp(newValue, location);
+  if (!_swp_available) return arm2_swp(newValue, location);
 #endif
   int oldValue;
   __asm { SWP oldValue, newValue, [location] }
   return oldValue;
 }
 
-#ifdef __APCS_32
 #define INITMUTEX heapMutex = 1
-#else
-#define INITMUTEX \
-  do { \
-    heapMutex = 1; \
-    jmp_buf jb; \
-    swpNotAvailable = &jb; \
-    void (*old_sig_handler)(int) = signal(SIGILL, temp_sig_handler); \
-    if (setjmp(jb) == 0) { \
-      int temp; \
-      __asm { SWP temp, 1, [&heapMutex] } \
-      swpNotAvailable = NULL; \
-    } \
-    signal(SIGILL, old_sig_handler); \
-  } while (0)
-#endif
 
 #define ACQUIREMUTEX \
   do { \
@@ -1077,7 +1063,7 @@ extern void *malloc(size_t size)
 
   ENTRYTOALLOC(ptr);
   ptr = (void *)_primitive_alloc(BYTESTOWORDS(size));
-  if ((int)ptr < OK) {
+  if ((unsigned)ptr >= MINHEAPERROR) {
 #ifdef STATS
     ShowStats();
 #endif
@@ -1162,11 +1148,6 @@ extern void _init_user_alloc(void)
 }
 
 #ifndef __APCS_32
-static void temp_sig_handler(int sig)
-{
-  longjmp(*swpNotAvailable, 1);
-}
-
 static int arm2_swp(int newValue, int *location)
 {
   int irqs_off = _kernel_irqs_disabled();
diff --git a/clib/s/cl_spare b/clib/s/cl_spare
index e2c330dd0ebe804518d3465b2f95796ab6319197..21060a863241ae19d40e3b10bf2720b7defbd1f6 100644
--- a/clib/s/cl_spare
+++ b/clib/s/cl_spare
@@ -25,7 +25,7 @@
 
         EXPORT  |CLib_data_end|
 
-        %       112*4
+        %       124*4
 |CLib_data_end|
 
         END
diff --git a/h/alloc b/h/alloc
index f6625f7dc07d8cc22129400d012d729c9c69308a..13b4966423548d6cd453a8e82c525a5df227b999 100644
--- a/h/alloc
+++ b/h/alloc
@@ -56,6 +56,7 @@ typedef struct BlockStruct {
 #define OK       0
 #define FAILED  -1
 #define CORRUPT -2
+#define MINHEAPERROR -2 /* ensure you update this if you add any new errors */
 
 #define SIZEMASK      0xfffffffc /* all except bottom two bits, when applied */
                                  /* to block.size yields no of address units */
diff --git a/kernel/s/k_body b/kernel/s/k_body
index e3859316463df9ff8b4b445ab5d335b53a9d73cd..f64e10c3f2940dea516a9063fa234c6cf7f0b6e6 100644
--- a/kernel/s/k_body
+++ b/kernel/s/k_body
@@ -408,6 +408,14 @@ uwb_size        #       0
         ; this chunk - they won't ever be used.  We must set mark (to be
         ; not IsAStackChunk) and SL_xxx_Offset. Also prev.
         STR     sp, [v6, #O_extendChunk]
+      [ {CONFIG}<>26
+        MOV     r0, #1
+        STR     r0, [v6, #O__swp_available]
+      |
+        BL      CheckIfSwpAvailable
+      ]
+        MOV     r0, #1
+        STR     r0, [v6, #O_extendChunkNotInUse]
         ADD     r0, sl, #SL_Lib_Offset
         LDMIA   r0, {r1, r2}
         ADD     r0, sp, #SC_SLOffset+SL_Lib_Offset
@@ -512,6 +520,41 @@ NoMainProgram
 FatalError Keep
         SWI     GenerateError
 
+ [ {CONFIG}=26
+; v6 = static base
+; sp -> extendChunk, which we will use as workspace
+; assumed entered in USR mode with SVC stack empty
+CheckIfSwpAvailable
+        STMIA   sp!, {r0-r12,r14}      ; error handler might corrupt anything
+        MOV     r0, #0                 ; start off assuming error will happen
+        STR     r0, [v6, #O__swp_available]
+
+        MOV     r0, #6
+        MOV     r1, #0
+        MOV     r2, #0
+        MOV     r3, #0
+        SWI     XOS_ChangeEnvironment           ; read existing error handler
+        STMIA   sp!, {r1-r3}
+        MOV     r0, #6
+        ADR     r1, %FT01
+        MOV     r2, sp
+        MOV     r3, sp
+        SWI     XOS_ChangeEnvironment           ; set temp error handler
+
+        SWP     r0, r0, [sp]                    ; try a SWP
+
+        MOV     r0, #1
+        STR     r0, [v6, #O__swp_available]     ; note we were successful
+        B       %FT02
+01
+        MOV     sp, r0                          ; put back sp after error
+02
+        MOV     r0, #6
+        LDMDB   sp!, {r1-r3}
+        SWI     XOS_ChangeEnvironment           ; restore error handler
+        LDMDB   sp!, {r0-r12,pc}
+ ]
+
 ;StrongARM - there is dynamic code here, but this is sorted in _kernel_init, after
 ;all calls to CopyHandler
 CopyHandler
@@ -2624,8 +2667,8 @@ alloc_return_block
 ; as only ip is free.
 ; We can save things on the stack a distance below fp which allows the
 ; largest possible list of saved work registers (r0-r3, r4-r9 inclusive,
-; plus fp, sp, lr, entry pc, = 14 regs in total) plus a minimal stack
-; frame for return from StkOvfExit (a further 4 words, giving 18 in total)
+; plus fp, sp, lr = 13 regs in total) plus a minimal stack
+; frame for return from StkOvfExit (a further 4 words, giving 17 in total)
 ; plus 4 extended floating point registers (a further 3*4 words)
         MOV     ip, sp
 |_kernel_stkovf_split|
@@ -2849,6 +2892,19 @@ StkOvfGetNewChunk Keep
         ; Now we swap to the special extension chunk (to give a reasonable
         ; stack size to malloc).
         LoadStaticBase v2, ip
+03      MOV     a1, #0
+        ADD     a2, v2, #O_extendChunkNotInUse
+      [ {CONFIG}=26
+        LDR     lr, [v2, #O__swp_available]
+        TEQ     lr, #0
+        SWPNE   a1, a1, [a2]
+        BLEQ    Arm2Swp
+      |
+        SWP     a1, a1, [a2]
+      ]
+        TEQ     a1, #0
+        BLEQ    Sleep                     ; preserves Z
+        BEQ     %BT03
         LDR     a2, [v2, #O_extendChunk]
         LDR     a3, [a2, #SC_size]
         ADD     a3, a2, a3                ; new sp
@@ -2863,14 +2919,17 @@ StkOvfGetNewChunk Keep
         LDR     ip, [v2, #O_allocProc]
         CMPS    ip, #0
         BEQ     %F01                    ; (restore stack chunk, then error)
-        LDR     v2, [v2, #O_freeProc]
-        STMFD   sp!, {a1, v2}           ; chunk size in bytes, dealloc proc
+        LDR     lr, [v2, #O_freeProc]
+        STMFD   sp!, {a1, lr}           ; chunk size in bytes, dealloc proc
         MOV     lr, pc
         MOV     pc, ip
+        MOV     lr, v2
         MOVS    v2, a1
         LDMFD   sp!, {v3, ip}           ; size in bytes, dealloc
 01
         LDMFD   sp, {sl, fp, sp}        ; back to old chunk
+        MOV     a1, #1
+        STR     a1, [lr, #O_extendChunkNotInUse]
         BEQ     StkOvfError
         STR     v3, [v2, #SC_size]
         STR     ip, [v2, #SC_deallocate]
@@ -2913,6 +2972,24 @@ StackOverflowFault Keep
 
         ErrorBlock StackOverflow, "Stack overflow", C45
 
+ [ {CONFIG}=26
+Arm2Swp ; like SWP a1,a1,[a2] but corrupts a3, lr and flags
+        SWI     IntOff
+        LDR     a3, [a2]
+        STR     a1, [a2]
+        SWI     IntOn
+        MOV     a1, a3
+        MOV     pc, lr
+ ]
+
+Sleep
+; a2 -> pollword
+; must exit with Z set
+        MOV     a1, #6
+        SWI     &20033 ; XOS_UpCall
+        CMP     a1, a1
+        MOV     pc, lr
+
  ;*-------------------------------------------------------------------*
  ;* Arithmetic                                                        *
  ;*-------------------------------------------------------------------*
diff --git a/kernel/s/k_data b/kernel/s/k_data
index fb0fb773222acfdd70a6d756cc6a7326438fc388..e2d59c821c853bccbac0ffb04687512a65485b79 100644
--- a/kernel/s/k_data
+++ b/kernel/s/k_data
@@ -104,6 +104,8 @@ initSlotSize            Variable
 
 lk_RestoreOSHandlers    Variable
 extendChunk             Variable
+extendChunkNotInUse     Variable
+_swp_available          ExportedVariable
 rootStackChunk          Variable
 
 ; Tmp space for expanding PC value in fatal error handler
@@ -117,6 +119,6 @@ reg_hex_buff            Variable        3
 
 disable_stack_extension ExportedVariable 1
 
-unused                  Variable        16
+unused                  Variable        14
 
         END
diff --git a/s/makehswis b/s/makehswis
index 55e4d97f483e1b6a850c43603e6fb5ed7a7bb977..9670b350ab64d3fc85f09de81349c43aa8ebcf90 100644
--- a/s/makehswis
+++ b/s/makehswis
@@ -104,6 +104,8 @@ string2 SETS    "&":CC:(:STR:value)
 ;SoundWorkSpace * &01F04000
         GET     Hdr:PublicWS
 
+        AREA    |Text$Data|, DATA
+
 ; First output the file header
 	BIN	h.swisheader