diff --git a/Makefile b/Makefile
index c533e6f260c0f530fb5ceb897832a0019c9ac079..dea0dd26bd42462c385a61879417806ce746e7ee 100644
--- a/Makefile
+++ b/Makefile
@@ -133,12 +133,11 @@ ${GPADBG}: ${AIFDBG}
 s.TMOSHelp: ${TOKENS} HelpStrs
 	${TOKENISE} ${TOKENS} HelpStrs $@
 
-s.Time+Date:
-	@echo |IGBLS Builddate|JBuilddate SETS "<Sys$Date> <Sys$Year>.<Sys$Time>" |J|IEND { > s.Time+Date }
-	settype s.Time+Date FFF
+#s.Time+Date:
+#        @echo |IGBLS Builddate|JBuilddate SETS "<Sys$Date> <Sys$Year>.<Sys$Time>" |J|IEND { > s.Time+Date }
+#        settype s.Time+Date FFF
 	
-o.GetAll: s.TMOSHelp \
-          s.Time+Date
+o.GetAll: s.TMOSHelp
 
 #
 # Exported interface headers
diff --git a/Version b/Version
index 21cb71af3a5c8d414c94b5210915c2083488cb44..7fc672001fe52ffca11c752108579c92fa2cc50f 100644
--- a/Version
+++ b/Version
@@ -16,12 +16,17 @@ Date    SETS    Module_Date      ; version for STB/NC OS
         |
 Version SETA    517
 VString SETS    "5.17"
+   [ (Version :AND: 1) = 1
+Date    SETS    Module_Date      ; Odd-numbered (i.e. development) build, use
+                                 ; date of last source checkin
+   |
 Date    SETS    "19 Jan 2010"    ; version for RISC OS on desktop computers
 
                                  ; you may also wish to update the welcome
                                  ; and OS information dialogue box templates
                                  ; in the sources for Desktop and Switcher
 				 ; (especially for year change)
+   ]
         ]
 
         END
diff --git a/VersionASM b/VersionASM
index 50dd703dbf778992ab63398255a31304117a503b..9233a8c171263f6064b44f3b366d597a12974ed6 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.98.2.40"
-Module_Date             SETS    "24 Jul 2011"
-Module_ApplicationDate  SETS    "24-Jul-11"
+Module_MinorVersion     SETS    "4.79.2.98.2.41"
+Module_Date             SETS    "31 Jul 2011"
+Module_ApplicationDate  SETS    "31-Jul-11"
 Module_ComponentName    SETS    "Kernel"
 Module_ComponentPath    SETS    "castle/RiscOS/Sources/Kernel"
-Module_FullVersion      SETS    "5.35 (4.79.2.98.2.40)"
-Module_HelpVersion      SETS    "5.35 (24 Jul 2011) 4.79.2.98.2.40"
+Module_FullVersion      SETS    "5.35 (4.79.2.98.2.41)"
+Module_HelpVersion      SETS    "5.35 (31 Jul 2011) 4.79.2.98.2.41"
                         END
diff --git a/VersionNum b/VersionNum
index 73a395bae9913361bbc6efb00762beb24f582e91..dd9d434a826325c076209e219428a22724fa4d87 100644
--- a/VersionNum
+++ b/VersionNum
@@ -5,19 +5,19 @@
  *
  */
 #define Module_MajorVersion_CMHG        5.35
-#define Module_MinorVersion_CMHG        4.79.2.98.2.40
-#define Module_Date_CMHG                24 Jul 2011
+#define Module_MinorVersion_CMHG        4.79.2.98.2.41
+#define Module_Date_CMHG                31 Jul 2011
 
 #define Module_MajorVersion             "5.35"
 #define Module_Version                  535
-#define Module_MinorVersion             "4.79.2.98.2.40"
-#define Module_Date                     "24 Jul 2011"
+#define Module_MinorVersion             "4.79.2.98.2.41"
+#define Module_Date                     "31 Jul 2011"
 
-#define Module_ApplicationDate          "24-Jul-11"
+#define Module_ApplicationDate          "31-Jul-11"
 
 #define Module_ComponentName            "Kernel"
 #define Module_ComponentPath            "castle/RiscOS/Sources/Kernel"
 
-#define Module_FullVersion              "5.35 (4.79.2.98.2.40)"
-#define Module_HelpVersion              "5.35 (24 Jul 2011) 4.79.2.98.2.40"
+#define Module_FullVersion              "5.35 (4.79.2.98.2.41)"
+#define Module_HelpVersion              "5.35 (31 Jul 2011) 4.79.2.98.2.41"
 #define Module_LibraryVersionInfo       "5:35"
diff --git a/hdr/KernelWS b/hdr/KernelWS
index ea2a8123cabedd26d5cb5037c14cb7f2e5f2d3f4..c8eb8cccf11f9a019a832a9a1566ca15a7a16e70 100644
--- a/hdr/KernelWS
+++ b/hdr/KernelWS
@@ -1317,6 +1317,8 @@ AplWorkSize * AppSpaceDANode + DANode_Size
 EnvString          #    256
   ]
 
+ExtendedROMFooter # 4 ; Pointer to the extended ROM footer structure. 0 if not initialised, -1 if not found.
+
  [ :DEF: ShowWS
         ! 0, "Free space after EnvString = ":CC::STR:(&500-@)
  ]
@@ -1939,6 +1941,11 @@ GSVarWSpace           #  GSVarWSpace_Size
 SysVarWorkSpace	      #  40		; used by the sys$* variables for reading the current time into
  ]
 
+ROMBuildDate          #  128
+ [ UseNewFX0Error
+NewFX0Error           #  64
+ ]
+
 KbuffsEnd             #  0
 KbuffsSize            *  KbuffsEnd - KbuffsBaseAddress  ;size of Kernel buffers area
 
diff --git a/hdr/Options b/hdr/Options
index 3db81b186541074c8b4ea5075c3eb574bf8f9277..32f3c50505eeb02ae7aeb35ab53cf6e30ce5bf16 100644
--- a/hdr/Options
+++ b/hdr/Options
@@ -390,6 +390,9 @@ PollMouse               SETL    {FALSE}         ; Poll mouse.
                         GBLL    ProcessorVectors
 ProcessorVectors        SETL    {TRUE}          ; Processor vectors indirected through 0 page.
 
+               GBLL  UseNewFX0Error
+UseNewFX0Error SETL (:LNOT: Embedded_UI) :LAND: ((Version :AND: 1) = 1) ; Whether *FX 0 should show the ROM link date instead of the UtilityModule date
+
                     GBLS  GetUnsqueeze
  [ SqueezeMods
 GetUnsqueeze        SETS  "GET s.Unsqueeze"
diff --git a/s/Middle b/s/Middle
index b37a483d56258c9e0b5aa72338fb1039e297ae43..aa1e07f230fa624f55c3132197dc528b891db897 100644
--- a/s/Middle
+++ b/s/Middle
@@ -1960,9 +1960,33 @@ osri6_maxvalue * (.-4-osri6_table) :SHR: 2
         CMP     R1, #0
         ADREQ   R0, RSI9_OSname     ; The OS name
         BEQ     %FT95
-        CMP     R1, #2
-        ADREQ   R0, RSI9_Builddate  ; The build date (dynamically generated)
+        CMP     R1, #2              ; The build date (dynamically generated)
         MOVNE   R0, #0              ; Other ones are unimplemented
+        BNE     %FT95
+        LDR     R0, =ROMBuildDate
+        LDRB    R1, [R0]
+        CMP     R1, #0
+        BNE     %FT94
+        ; Build date string hasn't been generated yet. Generate it.
+        Push    "r0,r2-r3,lr"
+        MOV     R0, #0
+        BL      ExtendedROMFooter_FindTag
+        CMP     R0, #0              ; Found it?
+        STREQ   R0, [R13]
+        BEQ     %FT93
+        ; For compatability, make this string match the same format as the old
+        ; string. Conveniently, this matches the format string used by OS_Word
+        ; 14
+        LDR     R1, [R13]
+        MOV     R2, #?ROMBuildDate
+        ADRL    R3, TimeFormat
+        SWI     XOS_ConvertDateAndTime
+        MOVVS   R0, #0
+        STRVS   R0, [R13]
+93
+        Pull    "r0,r2-r3,lr"
+94
+        MOV     R1, #2
 95
         ExitSWIHandler
 
@@ -2032,9 +2056,82 @@ RSI_DebugRX
         Pull    "r1-r3,r9,r14"
         ExitSWIHandler
 
-        GET    s.Time+Date
+;
+; Extended ROM footer functions
+;
+; These operate on a new tag-based structure located at the end of the ROM
+; image. Each entry consists of a one-byte ID, a one-byte length, and then N
+; bytes of data. The length byte doesn't count the two initial header bytes.
+;
+; The end of the list is implicity terminated by a footer word; the footer word
+; contains the length of the structure in the low two bytes (minus the length of
+; the footer word), and a 16-bit CRC in the top two bytes (again, minus the
+; footer word). The footer word will be word-aligned, but everything else is
+; assumed to be byte aligned.
+;
+; Current tags:
+;
+; 0     ROM build date, stored as 5-byte time (length = 5)
+;
+
+ExtendedROMFooter_Find  ROUT
+        ; Find the header word for the extended ROM footer. Returns -1 if not found.
+        Push    "r1-r4,lr"
+        LDR     r4, =ZeroPage
+        LDR     r0, [r4, #ExtendedROMFooter]
+        CMP     r0, #0
+        BNE     %FT10
+        ; Examine the end of the ROM image
+        ; Footer should be located just before the standard 20 byte footer
+        LDR     r2, =ROM+OSROM_ImageSize*1024-24
+        LDR     r1, [r2]
+        CMP     r1, #-1
+        MOVEQ   r0, r1
+        BEQ     %FT09
+        ; Check CRC
+        MOV     r1, r1, LSL #16
+        SUB     r1, r2, r1, LSR #16
+        MOV     r3, #1
+        SWI     XOS_CRC
+        MOVVS   r0, #-1
+        BVS     %FT09
+        LDR     r1, [r2]
+        CMP     r0, r1, LSR #16
+        MOVNE   r0, #-1
+        MOVEQ   r0, r2
+09
+        STR     r0, [r4, #ExtendedROMFooter]
+10
+        Pull    "r1-r4,pc"
+
+ExtendedROMFooter_FindTag  ROUT
+        ; Find the tag number given in R0.
+        ; Returns data pointer in R0 & length in R1 on success.
+        ; Returns 0 in R0 (and corrupt R1) for failure.
+        Push    "r2-r3,lr"
+        MOV     r2, r0
+        BL      ExtendedROMFooter_Find
+        CMP     r0, #-1
+        BEQ     %FT09
+        MOV     r3, r0
+        LDR     r0, [r0]
+        MOV     r0, r0, LSL #16
+        SUB     r0, r3, r0, LSR #16
+05
+        CMP     r0, r3
+        BEQ     %FT09
+        LDRB    lr, [r0], #1
+        LDRB    r1, [r0], #1
+        CMP     lr, r2
+        BEQ     %FT10
+        ADD     r0, r0, r1
+        B       %BT05
+09
+        MOV     r0, #0
+10
+        Pull    "r2-r3,pc"
+
 RSI9_OSname    = "$SystemName $VString",0
-RSI9_Builddate = "$Builddate",0
 
         ALIGN
         LTORG
diff --git a/s/NewReset b/s/NewReset
index 49e92a2fa59741142d5f5d5509aa595037e97439..f9764e8c5dfcb6b8736132fa89d6ad5ce613200b 100644
--- a/s/NewReset
+++ b/s/NewReset
@@ -1919,6 +1919,22 @@ ResetPart1Done                          ; R0 is reset type
         MOV     R0, #FSControl_SelectFS ; set configured filing system
         SWI     XOS_FSControl
 
+        ; OS_ReadSysInfo 9,2 now relies on the Territory module, which may
+        ; enable IRQs. But the PRMs say OS_ReadSysInfo shouldn't alter the IRQ
+        ; state. So call it once here just to initialise the string which it
+        ; uses the Territory module to generate.
+        ; This won't account for any modules using it during ModuleInit, but
+        ; that should be pretty rare (or at least rare from within IRQ-sensitive
+        ; code)
+        MOV     R0, #9
+        MOV     R1, #2
+        SWI     XOS_ReadSysInfo
+
+  [ UseNewFX0Error
+        ; Also, *FX 0
+        BL      InitNewFX0Error
+  ]
+
   [ DebugROMInit
         SWI     XOS_WriteS
         =       "Service_PostInit",0
diff --git a/s/PMF/osbyte b/s/PMF/osbyte
index f598f6904f2cdb1db2d60ae6f0d1b76b40307184..c8d1627a31e4b449bffaa2b4eca6190e0e001b34 100644
--- a/s/PMF/osbyte
+++ b/s/PMF/osbyte
@@ -231,13 +231,45 @@ Osbyte00 ROUT
         TEQ     R1, #0
         MOVNE   R1, #MosVer
         MyOsbyte NE
+      [ UseNewFX0Error
+        LDR     R0, =NewFX0Error
+        LDR     LR, [R0]
+        CMP     LR, #0
+        ADREQ   R0, FX0Error ; Fall back to hardcoded string if new one isn't ready yet
+      |
         ADR     R0, FX0Error
+      ]
         SWI     XOS_GenerateError
         ByteReturnV
 
+      [ UseNewFX0Error
+InitNewFX0Error ROUT
+        Push    "r0-r4,lr"
+        MOV     r0, #0
+        BL      ExtendedROMFooter_FindTag
+        CMP     r0, #0
+        BEQ     %FT10
+        MOV     r1, r0
+        MOV     r0, #-1
+        LDR     r2, =NewFX0Error+4
+        MOV     r3, #?NewFX0Error - 4
+        ADR     r4, NewFX0ErrorFormat
+        SWI     XTerritory_ConvertDateAndTime
+        ; Fill in error number on success
+        LDRVC   r2, =NewFX0Error
+        MOVVC   r3, #&7F
+        STRVC   r3, [r2]
+10
+        Pull    "r0-r4,pc"
+      ]
+
 FX0Error
         &       &F7
         =       "$MosTitle",0
+      [ UseNewFX0Error
+NewFX0ErrorFormat
+        =       "$SystemName $VString (%dy %m3 %ce%yr)",0
+      ]
         ALIGN
 
 ; *****************************************************************************