diff --git a/src/rp2_common/pico_bootrom/bootrom.c b/src/rp2_common/pico_bootrom/bootrom.c
index 84fbffd06..d417794fe 100644
--- a/src/rp2_common/pico_bootrom/bootrom.c
+++ b/src/rp2_common/pico_bootrom/bootrom.c
@@ -7,6 +7,9 @@
 #include "pico/bootrom.h"
 #include "boot/picoboot.h"
 #include "boot/picobin.h"
+#if !PICO_RP2040
+#include "hardware/rcp.h"
+#endif
 
 /// \tag::table_lookup[]
 
@@ -59,6 +62,23 @@ void __attribute__((noreturn)) rom_reset_usb_boot(uint32_t usb_activity_gpio_pin
 }
 
 #if !PICO_RP2040
+
+
+// Generated from adding the following code into the bootrom
+// scan_workarea_t* scan_workarea = (scan_workarea_t*)workarea;
+// printf("VERSION_DOWNGRADE_ERASE_ADDR %08x\n", &(always->zero_init.version_downgrade_erase_flash_addr));
+// printf("TBYB_FLAG_ADDR %08x\n", &(always->zero_init.tbyb_flag_flash_addr));
+// printf("IMAGE_DEF_VERIFIED %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.verified) - (uint32_t)scan_workarea);
+// printf("IMAGE_DEF_TBYB_FLAGGED %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.tbyb_flagged) - (uint32_t)scan_workarea);
+// printf("IMAGE_DEF_BASE %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.enclosing_window.base) - (uint32_t)scan_workarea);
+// printf("IMAGE_DEF_REL_BLOCK_OFFSET %08x\n", (uint32_t)&(scan_workarea->parsed_block_loops[0].image_def.core.window_rel_block_offset) - (uint32_t)scan_workarea);
+#define VERSION_DOWNGRADE_ERASE_ADDR *(uint32_t*)0x400e0338
+#define TBYB_FLAG_ADDR *(uint32_t*)0x400e0348
+#define IMAGE_DEF_VERIFIED(scan_workarea) *(uint32_t*)(0x64 + (uint32_t)scan_workarea)
+#define IMAGE_DEF_TBYB_FLAGGED(scan_workarea) *(bool*)(0x4c + (uint32_t)scan_workarea)
+#define IMAGE_DEF_BASE(scan_workarea) *(uint32_t*)(0x54 + (uint32_t)scan_workarea)
+#define IMAGE_DEF_REL_BLOCK_OFFSET(scan_workarea) *(uint32_t*)(0x5c + (uint32_t)scan_workarea)
+
 bool rom_get_boot_random(uint32_t out[4]) {
     uint32_t result[5];
     rom_get_sys_info_fn func = (rom_get_sys_info_fn) rom_func_lookup_inline(ROM_FUNC_GET_SYS_INFO);
@@ -99,4 +119,62 @@ int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32
     }
     return PICO_ERROR_INSUFFICIENT_RESOURCES;
 }
+
+int rom_pick_ab_update_partition(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num) {
+    uint32_t flash_update_base = 0;
+    bool tbyb_boot = false;
+    uint32_t saved_erase_addr = 0;
+    if (rom_get_last_boot_type() == BOOT_TYPE_FLASH_UPDATE) {
+        // For a flash update boot, get the flash update base
+        boot_info_t boot_info = {};
+        int ret = rom_get_boot_info(&boot_info);
+        if (ret) {
+            flash_update_base = boot_info.reboot_params[0];
+            if (boot_info.tbyb_and_update_info & BOOT_TBYB_AND_UPDATE_FLAG_BUY_PENDING) {
+                // A buy is pending, so the main software has not been bought
+                tbyb_boot = true;
+                // Save the erase address, as this will be overwritten by rom_pick_ab_partition
+                saved_erase_addr = VERSION_DOWNGRADE_ERASE_ADDR;
+            }
+        }
+    }
+
+    int rc = rom_pick_ab_partition((uint8_t*)workarea_base, workarea_size, partition_a_num, flash_update_base);
+
+    if (IMAGE_DEF_VERIFIED(workarea_base) != RCP_MASK_TRUE) {
+        // Chosen partition failed verification
+        return BOOTROM_ERROR_NOT_FOUND;
+    }
+
+    if (IMAGE_DEF_TBYB_FLAGGED(workarea_base)) {
+        // The chosen partition is TBYB
+        if (tbyb_boot) {
+            // The boot partition is also TBYB - cannot update both, so prioritise boot partition
+            // Restore the erase address saved earlier
+            VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr;
+            return BOOTROM_ERROR_NOT_PERMITTED;
+        } else {
+            // Update the tbyb flash address, so that explicit_buy will clear the flag for the chosen partition
+            TBYB_FLAG_ADDR =
+                    IMAGE_DEF_BASE(workarea_base)
+                    + IMAGE_DEF_REL_BLOCK_OFFSET(workarea_base) + 4;
+        }
+    } else {
+        // The chosen partition is not TBYB
+        if (tbyb_boot && saved_erase_addr) {
+            // The boot partition was TBYB, and requires an erase
+            if (VERSION_DOWNGRADE_ERASE_ADDR) {
+                // But both the chosen partition requires an erase too
+                // As before, prioritise the boot partition, and restore it's saved erase_address
+                VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr;
+                return BOOTROM_ERROR_NOT_PERMITTED;
+            } else {
+                // The chosen partition doesn't require an erase, so we're fine
+                VERSION_DOWNGRADE_ERASE_ADDR = saved_erase_addr;
+            }
+        }
+    }
+
+    return rc;
+}
 #endif
\ No newline at end of file
diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h
index 05bf1aa2f..dc9b6fb63 100644
--- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h
+++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h
@@ -1071,6 +1071,22 @@ static inline int rom_get_last_boot_type(void) {
  */
 int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32_t permissions);
 
+/*! \brief  Pick A/B partition for a separate partition
+ * \ingroup pico_bootrom
+ *
+ * This will perform extra checks to prevent disrupting a main image TBYB, and return errors
+ * 
+ * Also checks that the chosen partition contained a valid image
+ *
+ * \param workarea_base base address of work area
+ * \param workarea_size size of work area
+ * @param partition_a_num the A partition of the pair
+ * @return >= 0 the partition number picked
+ *         BOOTROM_ERROR_NOT_PERMITTED if not possible to do an update correctly, eg if both main image and data image are TBYB
+ *         BOOTROM_ERROR_NOT_FOUND if the chosen partition failed verification
+ */
+int rom_pick_ab_update_partition(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num);
+
 #endif
 
 #ifdef __cplusplus