From e2eb5ba09de3ad346ef90814a2cbaa62e95a12bb Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Thu, 20 Mar 2025 21:34:08 -0400
Subject: [PATCH 01/14] Set CIRCUITPY_DISPLAY_LIMIT in settings.toml

---
 main.c                                        |  5 ++
 shared-module/board/__init__.c                | 16 ++++-
 shared-module/displayio/__init__.c            | 59 ++++++++++++-------
 shared-module/displayio/__init__.h            |  7 ++-
 shared-module/epaperdisplay/EPaperDisplay.c   | 12 +++-
 supervisor/shared/web_workflow/web_workflow.c | 15 +++--
 6 files changed, 84 insertions(+), 30 deletions(-)

diff --git a/main.c b/main.c
index c9c7acb11f7b..60844813fa60 100644
--- a/main.c
+++ b/main.c
@@ -1057,6 +1057,11 @@ int __attribute__((used)) main(void) {
     reset_devices();
     reset_board();
 
+    #if CIRCUITPY_DISPLAYIO
+    // If number of displays has been overriden in settings.toml allocate memory and dynamic memory
+    malloc_display_memory();
+    #endif
+
     // displays init after filesystem, since they could share the flash SPI
     board_init();
 
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 96735c8dbaa4..3ccd24e36d1e 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -10,6 +10,10 @@
 #include "mpconfigboard.h"
 #include "py/runtime.h"
 
+#if CIRCUITPY_OS_GETENV
+#include "shared-module/os/__init__.h"
+#endif
+
 #if CIRCUITPY_BUSIO
 #include "shared-bindings/busio/I2C.h"
 #include "shared-bindings/busio/SPI.h"
@@ -172,11 +176,19 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) {
 #endif
 
 void reset_board_buses(void) {
+    #if CIRCUITPY_BOARD_I2C || CIRCUITPY_BOARD_SPI
+    mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
+
+    #if CIRCUITPY_OS_GETENV
+    (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
+    #endif
+    #endif
+
     #if CIRCUITPY_BOARD_I2C
     for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) {
         bool display_using_i2c = false;
         #if CIRCUITPY_I2CDISPLAYBUS
-        for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+        for (uint8_t i = 0; i < max_num_displays; i++) {
             if (display_buses[i].bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && display_buses[i].i2cdisplay_bus.bus == &i2c_obj[instance]) {
                 display_using_i2c = true;
                 break;
@@ -197,7 +209,7 @@ void reset_board_buses(void) {
     for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_SPI; instance++) {
         bool display_using_spi = false;
         #if CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER
-        for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+        for (uint8_t i = 0; i < max_num_displays; i++) {
             mp_const_obj_t bus_type = display_buses[i].bus_base.type;
             #if CIRCUITPY_FOURWIRE
             if (bus_type == &fourwire_fourwire_type && display_buses[i].fourwire_bus.bus == &spi_obj[instance]) {
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 4b467b75589d..f3e845ea973b 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -22,6 +22,10 @@
 
 #include "py/mpconfig.h"
 
+#if CIRCUITPY_OS_GETENV
+#include "shared-module/os/__init__.h"
+#endif
+
 #if CIRCUITPY_BUSDISPLAY
 #include "shared-bindings/busdisplay/BusDisplay.h"
 #endif
@@ -46,9 +50,12 @@
 
 // The default indicates no primary display
 static int primary_display_number = -1;
+static int max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
 
-primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
-primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
+primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT];
+primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT];
+primary_display_bus_t *display_buses = &display_busesx[0];
+primary_display_t *displays = &displaysx[0];
 
 displayio_buffer_transform_t null_transform = {
     .x = 0,
@@ -65,7 +72,7 @@ displayio_buffer_transform_t null_transform = {
 
 #if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI
 static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) {
             framebufferio_framebufferdisplay_obj_t *display = &displays[i].framebuffer_display;
             if (display->framebuffer == obj) {
@@ -87,7 +94,7 @@ void displayio_background(void) {
         return;
     }
 
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t display_type = displays[i].display_base.type;
         if (display_type == NULL || display_type == &mp_type_NoneType) {
             // Skip null display.
@@ -117,7 +124,7 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
     if (!keep_primary) {
         primary_display_number = -1;
     }
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         if (i == primary_display_number) {
             continue;
         }
@@ -139,7 +146,7 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
         }
         displays[i].display_base.type = &mp_type_NoneType;
     }
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t bus_type = display_buses[i].bus_base.type;
         if (bus_type == NULL || bus_type == &mp_type_NoneType) {
             continue;
@@ -190,12 +197,24 @@ void common_hal_displayio_release_displays(void) {
     common_hal_displayio_release_displays_impl(false);
 }
 
+void malloc_display_memory(void) {
+    #if CIRCUITPY_OS_GETENV
+    (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
+    if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) {
+        display_buses = (primary_display_bus_t*)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false);
+        displays = (primary_display_t*)port_malloc(sizeof(primary_display_t) * max_num_displays, false);
+        memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * max_num_displays);
+        memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays);    
+    }
+    #endif
+}
+
 void reset_displays(void) {
     // In CircuitPython 10, release secondary displays before doing anything else:
     // common_hal_displayio_release_displays_impl(true);
 
     // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline.
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             continue;
@@ -203,7 +222,7 @@ void reset_displays(void) {
         } else if (display_bus_type == &fourwire_fourwire_type) {
             fourwire_fourwire_obj_t *fourwire = &display_buses[i].fourwire_bus;
             if (((size_t)fourwire->bus) < ((size_t)&display_buses) ||
-                ((size_t)fourwire->bus) > ((size_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT * sizeof(primary_display_bus_t))) {
+                ((size_t)fourwire->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) {
                 busio_spi_obj_t *original_spi = fourwire->bus;
                 #if CIRCUITPY_BOARD_SPI
                 // We don't need to move original_spi if it is a board.SPI object because it is
@@ -221,7 +240,7 @@ void reset_displays(void) {
                 memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t));
                 fourwire->bus = &fourwire->inline_bus;
                 // Check for other display buses that use the same spi bus and swap them too.
-                for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
+                for (uint8_t j = i + 1; j < max_num_displays; j++) {
                     if (display_buses[j].fourwire_bus.base.type == &fourwire_fourwire_type &&
                         display_buses[j].fourwire_bus.bus == original_spi) {
                         display_buses[j].fourwire_bus.bus = &fourwire->inline_bus;
@@ -234,7 +253,7 @@ void reset_displays(void) {
             i2cdisplaybus_i2cdisplaybus_obj_t *i2c = &display_buses[i].i2cdisplay_bus;
             // Check to see if we need to inline the I2C bus.
             if (((size_t)i2c->bus) < ((size_t)&display_buses) ||
-                ((size_t)i2c->bus) > ((size_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT * sizeof(primary_display_bus_t))) {
+                ((size_t)i2c->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) {
                 busio_i2c_obj_t *original_i2c = i2c->bus;
                 #if CIRCUITPY_BOARD_I2C
                 // We don't need to move original_i2c if it is a board.I2C object because it is
@@ -247,7 +266,7 @@ void reset_displays(void) {
                 memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t));
                 i2c->bus = &i2c->inline_bus;
                 // Check for other displays that use the same i2c bus and swap them too.
-                for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) {
+                for (uint8_t j = i + 1; j < max_num_displays; j++) {
                     if (display_buses[j].i2cdisplay_bus.base.type == &i2cdisplaybus_i2cdisplaybus_type &&
                         display_buses[j].i2cdisplay_bus.bus == original_i2c) {
                         display_buses[j].i2cdisplay_bus.bus = &i2c->inline_bus;
@@ -271,7 +290,7 @@ void reset_displays(void) {
             is31fl3741_framebuffer_obj_t *is31fb = &display_buses[i].is31fl3741;
 
             if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) ||
-                ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT)) {
+                ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + max_num_displays)) {
                 #if CIRCUITPY_BOARD_I2C
                 // We don't need to move original_i2c if it is the board.I2C object because it is
                 // statically allocated already. (Doing so would also make it impossible to reference in
@@ -334,7 +353,7 @@ void reset_displays(void) {
         }
     }
 
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         // Reset the displayed group. Only the first will get the terminal but
         // that's ok.
         mp_const_obj_t display_type = displays[i].display_base.type;
@@ -358,7 +377,7 @@ void reset_displays(void) {
 }
 
 void displayio_gc_collect(void) {
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             continue;
@@ -385,7 +404,7 @@ void displayio_gc_collect(void) {
         #endif
     }
 
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t display_type = displays[i].display_base.type;
         if (display_type == NULL || display_type == &mp_type_NoneType) {
             continue;
@@ -413,7 +432,7 @@ static bool is_display_active(mp_obj_base_t *display_maybe) {
 }
 
 primary_display_t *allocate_display(void) {
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         if (!is_display_active(&displays[i].display_base)) {
             // Clear this memory so it is in a known state before init.
             memset(&displays[i], 0, sizeof(displays[i]));
@@ -434,7 +453,7 @@ primary_display_t *allocate_display_or_raise(void) {
 }
 
 primary_display_bus_t *allocate_display_bus(void) {
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             // Clear this memory so it is in a known state before init.
@@ -455,7 +474,7 @@ primary_display_bus_t *allocate_display_bus_or_raise(void) {
 }
 
 mp_obj_t common_hal_displayio_get_primary_display(void) {
-    if (primary_display_number == -1 || primary_display_number >= CIRCUITPY_DISPLAY_LIMIT) {
+    if (primary_display_number == -1 || primary_display_number >= max_num_displays) {
         return mp_const_none;
     }
     mp_obj_base_t *primary_display = &displays[primary_display_number].display_base;
@@ -470,7 +489,7 @@ void common_hal_displayio_set_primary_display(mp_obj_t new_primary_display) {
         primary_display_number = -1;
         return;
     }
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_obj_t display = MP_OBJ_FROM_PTR(&displays[i]);
         if (new_primary_display == display && is_display_active(display)) {
             primary_display_number = i;
@@ -485,7 +504,7 @@ void common_hal_displayio_auto_primary_display(void) {
     if (primary_display_number != -1) {
         return;
     }
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         if (is_display_active(&displays[i].display_base)) {
             primary_display_number = i;
             return;
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index 29b8c64c9724..c34d8ea6e960 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -99,13 +99,16 @@ typedef struct {
     };
 } primary_display_t;
 
-extern primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
-extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
+extern primary_display_bus_t display_busesx[];
+extern primary_display_t displaysx[];
+extern primary_display_bus_t *display_buses;
+extern primary_display_t *displays;
 
 extern displayio_group_t circuitpython_splash;
 
 void displayio_background(void);
 void reset_displays(void);
+void malloc_display_memory(void);
 void displayio_gc_collect(void);
 
 primary_display_t *allocate_display(void);
diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c
index 14fbc3341b5f..41c1695dbca6 100644
--- a/shared-module/epaperdisplay/EPaperDisplay.c
+++ b/shared-module/epaperdisplay/EPaperDisplay.c
@@ -20,6 +20,10 @@
 #include "supervisor/usb.h"
 #endif
 
+#if CIRCUITPY_OS_GETENV
+#include "shared-module/os/__init__.h"
+#endif
+
 #include <stdint.h>
 #include <string.h>
 
@@ -501,7 +505,13 @@ void epaperdisplay_epaperdisplay_collect_ptrs(epaperdisplay_epaperdisplay_obj_t
 }
 
 size_t maybe_refresh_epaperdisplay(void) {
-    for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+    mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
+
+    #if CIRCUITPY_OS_GETENV
+    (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
+    #endif
+
+    for (uint8_t i = 0; i < max_num_displays; i++) {
         if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
             displays[i].epaper_display.core.current_group != &circuitpython_splash) {
             // Skip regular displays and those not showing the splash.
diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c
index eea11bd5fb4a..584b4741e753 100644
--- a/supervisor/shared/web_workflow/web_workflow.c
+++ b/supervisor/shared/web_workflow/web_workflow.c
@@ -1554,24 +1554,29 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
 }
 
 static bool supervisor_filesystem_access_could_block(void) {
+    bool could_block = false;
     #if CIRCUITPY_FOURWIRE
     mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
     if (!vfs->next) {
         // Assume that the CIRCUITPY root is not sharing a SPI bus with the display SPI bus
         return false;
     }
-    // Check display 0 to see if it's on a fourwire (SPI) bus. If it is, blocking is possible
-    // in theory other displays could block but also in reality there's generally 0 or 1 displays
-    for (size_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+
+    mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
+    #if CIRCUITPY_OS_GETENV
+    (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
+    #endif
+    // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible
+    for (size_t i = 0; i < max_num_displays; i++) {
         if (display_buses[i].bus_base.type != &fourwire_fourwire_type) {
             continue;
         }
         if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(&display_buses[i].bus_base))) {
-            return true;
+            could_block = true;
         }
     }
     #endif
-    return false;
+    return could_block;
 }
 
 void supervisor_web_workflow_background(void *data) {

From d6a55bbec47af02630f31fb7baaaa8fdc4c9e339 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Thu, 20 Mar 2025 21:51:11 -0400
Subject: [PATCH 02/14] Document new parameter + pre-commit

---
 docs/environment.rst               | 24 ++++++++++++++++++++++++
 main.c                             |  2 +-
 shared-module/displayio/__init__.c |  6 +++---
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/docs/environment.rst b/docs/environment.rst
index 82d7e8790bcd..daa726c48f3d 100644
--- a/docs/environment.rst
+++ b/docs/environment.rst
@@ -190,3 +190,27 @@ flag has been set to 0. Currently this is primarily boards with limited flash in
 of the Atmel_samd boards based on the SAMD21/M0 microprocessor.
 
 `boards that the terminalio core module is available on <https://docs.circuitpython.org/en/latest/shared-bindings/terminalio/>`_
+
+CIRCUITPY_DISPLAY_LIMIT
+~~~~~~~~~~~~~~~~~~~~~~~
+Set the maximum supported number of displayio displays. This value overrides the
+CIRCUITPY_DISPLAY_LIMIT compile-time flag defined in mpconfigport.h.
+It specifies the maximum number of active display objects that can be supported simultaneously
+on a CircuitPython board. This setting is used to manage memory and resource allocation for
+display handling.
+
+By default, the value of CIRCUITPY_DISPLAY_LIMIT is set to 1 for most boards, meaning only
+one display can be active at a time. Users can modify this value by adding a settings.toml entry
+to support additional displays, depending on the hardware capabilities and available resources.
+
+The value of CIRCUITPY_DISPLAY_LIMIT should be set to a value that is supported by the
+hardware and does not exceed the available memory and resources on the board.
+
+*** Note: Setting CIRCUITPY_DISPLAY_LIMIT to a value greater than 1 should be considered an
+ALPHA feature and may result in unexpected behavior or crashes. ***
+
+Example: Set the maximum supported number of displayio displays to 2:
+
+.. code-block::
+
+    CIRCUITPY_DISPLAY_LIMIT=2
diff --git a/main.c b/main.c
index 60844813fa60..74654e00d550 100644
--- a/main.c
+++ b/main.c
@@ -1058,7 +1058,7 @@ int __attribute__((used)) main(void) {
     reset_board();
 
     #if CIRCUITPY_DISPLAYIO
-    // If number of displays has been overriden in settings.toml allocate memory and dynamic memory
+    // If number of displays has been overridden in settings.toml allocate memory and dynamic memory
     malloc_display_memory();
     #endif
 
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index f3e845ea973b..ebe89ee0bfbd 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -201,10 +201,10 @@ void malloc_display_memory(void) {
     #if CIRCUITPY_OS_GETENV
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) {
-        display_buses = (primary_display_bus_t*)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false);
-        displays = (primary_display_t*)port_malloc(sizeof(primary_display_t) * max_num_displays, false);
+        display_buses = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false);
+        displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false);
         memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * max_num_displays);
-        memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays);    
+        memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays);
     }
     #endif
 }

From 088cf955b83cdeb0ae7def528df39026bdae6404 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Thu, 20 Mar 2025 22:35:05 -0400
Subject: [PATCH 03/14] fix boar/__init__.c, move malloc slightly earlier

---
 docs/environment.rst           |  5 ++---
 main.c                         | 11 ++++++-----
 shared-module/board/__init__.c |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/docs/environment.rst b/docs/environment.rst
index daa726c48f3d..77eb4b5b6d18 100644
--- a/docs/environment.rst
+++ b/docs/environment.rst
@@ -196,12 +196,11 @@ CIRCUITPY_DISPLAY_LIMIT
 Set the maximum supported number of displayio displays. This value overrides the
 CIRCUITPY_DISPLAY_LIMIT compile-time flag defined in mpconfigport.h.
 It specifies the maximum number of active display objects that can be supported simultaneously
-on a CircuitPython board. This setting is used to manage memory and resource allocation for
-display handling.
+on a CircuitPython board.
 
 By default, the value of CIRCUITPY_DISPLAY_LIMIT is set to 1 for most boards, meaning only
 one display can be active at a time. Users can modify this value by adding a settings.toml entry
-to support additional displays, depending on the hardware capabilities and available resources.
+to support additional displays.
 
 The value of CIRCUITPY_DISPLAY_LIMIT should be set to a value that is supported by the
 hardware and does not exceed the available memory and resources on the board.
diff --git a/main.c b/main.c
index 74654e00d550..16a16e653a47 100644
--- a/main.c
+++ b/main.c
@@ -1051,17 +1051,18 @@ int __attribute__((used)) main(void) {
     alarm_reset();
     #endif
 
+    #if CIRCUITPY_DISPLAYIO
+    // If number of displays has been overridden in settings.toml allocate memory and
+    // move existing displays
+    malloc_display_memory();
+    #endif
+
     // Reset everything and prep MicroPython to run boot.py.
     reset_port();
     // Port-independent devices, like CIRCUITPY_BLEIO_HCI.
     reset_devices();
     reset_board();
 
-    #if CIRCUITPY_DISPLAYIO
-    // If number of displays has been overridden in settings.toml allocate memory and dynamic memory
-    malloc_display_memory();
-    #endif
-
     // displays init after filesystem, since they could share the flash SPI
     board_init();
 
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 3ccd24e36d1e..4bf1521b7f31 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -185,7 +185,7 @@ void reset_board_buses(void) {
     #endif
 
     #if CIRCUITPY_BOARD_I2C
-    for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) {
+    for (uint8_t instance = 0; instance < max_num_displays; instance++) {
         bool display_using_i2c = false;
         #if CIRCUITPY_I2CDISPLAYBUS
         for (uint8_t i = 0; i < max_num_displays; i++) {

From 9b6219fca58b30b7e2a1764c7dcff094bc483cfb Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Thu, 20 Mar 2025 22:43:39 -0400
Subject: [PATCH 04/14] board/__init__: only declare max_num_displays when
 neeeded

---
 shared-module/board/__init__.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 4bf1521b7f31..2488a492fb47 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -176,7 +176,7 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) {
 #endif
 
 void reset_board_buses(void) {
-    #if CIRCUITPY_BOARD_I2C || CIRCUITPY_BOARD_SPI
+    #if CIRCUITPY_BOARD_I2C || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER))
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
 
     #if CIRCUITPY_OS_GETENV

From ec349f631df22d5d5328fbe6a6009f7397aae8ca Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 00:08:45 -0400
Subject: [PATCH 05/14] memcpy should only copy for length of compile time
 struct

---
 shared-module/displayio/__init__.c            | 4 ++--
 shared-module/displayio/__init__.h            | 4 ++--
 supervisor/shared/web_workflow/web_workflow.c | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index ebe89ee0bfbd..41b17042834e 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -203,8 +203,8 @@ void malloc_display_memory(void) {
     if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) {
         display_buses = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false);
         displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false);
-        memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * max_num_displays);
-        memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays);
+        memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT);
+        memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT);
     }
     #endif
 }
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index c34d8ea6e960..ccdc2887eda6 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -99,8 +99,8 @@ typedef struct {
     };
 } primary_display_t;
 
-extern primary_display_bus_t display_busesx[];
-extern primary_display_t displaysx[];
+extern primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT];
+extern primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT];
 extern primary_display_bus_t *display_buses;
 extern primary_display_t *displays;
 
diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c
index 584b4741e753..ea7e005b5918 100644
--- a/supervisor/shared/web_workflow/web_workflow.c
+++ b/supervisor/shared/web_workflow/web_workflow.c
@@ -1567,7 +1567,7 @@ static bool supervisor_filesystem_access_could_block(void) {
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     #endif
     // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible
-    for (size_t i = 0; i < max_num_displays; i++) {
+    for (mp_int_t i = 0; i < max_num_displays; i++) {
         if (display_buses[i].bus_base.type != &fourwire_fourwire_type) {
             continue;
         }

From 17b1ce1619710f92935684fe8d1a9e84018e7f3a Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 01:09:52 -0400
Subject: [PATCH 06/14] initalize dynamically allocated displays

---
 shared-module/displayio/__init__.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 41b17042834e..76252d7a9ce1 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -205,6 +205,12 @@ void malloc_display_memory(void) {
         displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false);
         memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT);
         memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT);
+
+        for (uint8_t i=CIRCUITPY_DISPLAY_LIMIT; i<max_num_displays; i++) {
+            memset(&displays[i], 0, sizeof(displays[i]));
+            display_buses[i].bus_base.type = &mp_type_NoneType;
+            displays[i].display_base.type = &mp_type_NoneType;
+        }
     }
     #endif
 }

From 6ed0bcab1fcb31748a8166bf096ebd914afa4631 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 01:11:25 -0400
Subject: [PATCH 07/14] local pre-commit :(

---
 shared-module/displayio/__init__.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 76252d7a9ce1..77c497cb65c1 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -206,7 +206,7 @@ void malloc_display_memory(void) {
         memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT);
         memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT);
 
-        for (uint8_t i=CIRCUITPY_DISPLAY_LIMIT; i<max_num_displays; i++) {
+        for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) {
             memset(&displays[i], 0, sizeof(displays[i]));
             display_buses[i].bus_base.type = &mp_type_NoneType;
             displays[i].display_base.type = &mp_type_NoneType;

From a61fac69bb110dc07719123a35e05ef909ba6b65 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 01:14:04 -0400
Subject: [PATCH 08/14] Initialize display_buses as well

---
 shared-module/displayio/__init__.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 77c497cb65c1..ae675b0791ee 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -208,6 +208,7 @@ void malloc_display_memory(void) {
 
         for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) {
             memset(&displays[i], 0, sizeof(displays[i]));
+            memset(&display_buses[i], 0, sizeof(display_buses[i]));
             display_buses[i].bus_base.type = &mp_type_NoneType;
             displays[i].display_base.type = &mp_type_NoneType;
         }

From 437e36ed63462589d97ccd2d6cd906ef84666a5e Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 16:53:37 -0400
Subject: [PATCH 09/14] Use compile-time arrays AND additional dynamic memory

---
 main.c                                        |   2 +-
 shared-module/board/__init__.c                |  17 +-
 shared-module/displayio/__init__.c            | 175 +++++++++++-------
 shared-module/displayio/__init__.h            |  12 +-
 shared-module/epaperdisplay/EPaperDisplay.c   |  28 ++-
 supervisor/shared/web_workflow/web_workflow.c |   9 +-
 6 files changed, 157 insertions(+), 86 deletions(-)

diff --git a/main.c b/main.c
index 16a16e653a47..e2587a30fd44 100644
--- a/main.c
+++ b/main.c
@@ -1051,7 +1051,7 @@ int __attribute__((used)) main(void) {
     alarm_reset();
     #endif
 
-    #if CIRCUITPY_DISPLAYIO
+    #if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV
     // If number of displays has been overridden in settings.toml allocate memory and
     // move existing displays
     malloc_display_memory();
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 2488a492fb47..4e9eb5f9b849 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -178,6 +178,11 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) {
 void reset_board_buses(void) {
     #if CIRCUITPY_BOARD_I2C || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER))
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
+    #if CIRCUITPY_OS_GETENV
+    #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+    #else
+    #define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
+    #endif
 
     #if CIRCUITPY_OS_GETENV
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
@@ -185,11 +190,11 @@ void reset_board_buses(void) {
     #endif
 
     #if CIRCUITPY_BOARD_I2C
-    for (uint8_t instance = 0; instance < max_num_displays; instance++) {
+    for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) {
         bool display_using_i2c = false;
         #if CIRCUITPY_I2CDISPLAYBUS
         for (uint8_t i = 0; i < max_num_displays; i++) {
-            if (display_buses[i].bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && display_buses[i].i2cdisplay_bus.bus == &i2c_obj[instance]) {
+            if (DYN_DISPLAY_BUSES(i).bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && DYN_DISPLAY_BUSES(i).i2cdisplay_bus.bus == &i2c_obj[instance]) {
                 display_using_i2c = true;
                 break;
             }
@@ -210,21 +215,21 @@ void reset_board_buses(void) {
         bool display_using_spi = false;
         #if CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER
         for (uint8_t i = 0; i < max_num_displays; i++) {
-            mp_const_obj_t bus_type = display_buses[i].bus_base.type;
+            mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
             #if CIRCUITPY_FOURWIRE
-            if (bus_type == &fourwire_fourwire_type && display_buses[i].fourwire_bus.bus == &spi_obj[instance]) {
+            if (bus_type == &fourwire_fourwire_type && DYN_DISPLAY_BUSES(i).fourwire_bus.bus == &spi_obj[instance]) {
                 display_using_spi = true;
                 break;
             }
             #endif
             #if CIRCUITPY_SHARPDISPLAY
-            if (bus_type == &sharpdisplay_framebuffer_type && display_buses[i].sharpdisplay.bus == &spi_obj[instance]) {
+            if (bus_type == &sharpdisplay_framebuffer_type && DYN_DISPLAY_BUSES(i).sharpdisplay.bus == &spi_obj[instance]) {
                 display_using_spi = true;
                 break;
             }
             #endif
             #if CIRCUITPY_AURORA_EPAPER
-            if (bus_type == &aurora_epaper_framebuffer_type && display_buses[i].aurora_epaper.bus == &spi_obj[instance]) {
+            if (bus_type == &aurora_epaper_framebuffer_type && DYN_DISPLAY_BUSES(i).aurora_epaper.bus == &spi_obj[instance]) {
                 display_using_spi = true;
                 break;
             }
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index ae675b0791ee..a17f37e0dca2 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -52,10 +52,25 @@
 static int primary_display_number = -1;
 static int max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
 
-primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT];
-primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT];
-primary_display_bus_t *display_buses = &display_busesx[0];
-primary_display_t *displays = &displaysx[0];
+primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
+primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
+#if CIRCUITPY_OS_GETENV
+primary_display_bus_t *display_buses_dyn = &display_buses[0];
+primary_display_t *displays_dyn = &displays[0];
+#define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+#define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
+#define DYN_DISPLAY_BUSES_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx] : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+#define DYN_DISPLAYS(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? displays[indx] : displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+#define DYN_DISPLAYS_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx].membr : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
+#define DYN_DISPLAYS_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx] : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+#else
+#define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
+#define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr)
+#define DYN_DISPLAY_BUSES_ADR0(indx) (&display_buses[indx])
+#define DYN_DISPLAYS(indx) (displays[indx])
+#define DYN_DISPLAYS_ADR(indx,membr) (&displays[indx].membr)
+#define DYN_DISPLAYS_ADR0(indx) (&displays[indx])
+#endif
 
 displayio_buffer_transform_t null_transform = {
     .x = 0,
@@ -73,8 +88,8 @@ displayio_buffer_transform_t null_transform = {
 #if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI
 static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_obj_t *display = &displays[i].framebuffer_display;
+        if (DYN_DISPLAYS(i).display_base.type == &framebufferio_framebufferdisplay_type) {
+            framebufferio_framebufferdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,framebuffer_display);
             if (display->framebuffer == obj) {
                 return true;
             }
@@ -95,7 +110,7 @@ void displayio_background(void) {
     }
 
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_const_obj_t display_type = displays[i].display_base.type;
+        mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type;
         if (display_type == NULL || display_type == &mp_type_NoneType) {
             // Skip null display.
             continue;
@@ -103,15 +118,15 @@ void displayio_background(void) {
         if (false) {
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            busdisplay_busdisplay_background(&displays[i].display);
+            busdisplay_busdisplay_background(DYN_DISPLAYS_ADR(i,display));
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_background(&displays[i].framebuffer_display);
+            framebufferio_framebufferdisplay_background(DYN_DISPLAYS_ADR(i,framebuffer_display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            epaperdisplay_epaperdisplay_background(&displays[i].epaper_display);
+            epaperdisplay_epaperdisplay_background(DYN_DISPLAYS_ADR(i,epaper_display));
         #endif
         }
     }
@@ -128,66 +143,78 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
         if (i == primary_display_number) {
             continue;
         }
-        mp_const_obj_t display_type = displays[i].display_base.type;
+        mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type;
         if (display_type == NULL || display_type == &mp_type_NoneType) {
             continue;
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            release_busdisplay(&displays[i].display);
+            release_busdisplay(DYN_DISPLAYS_ADR(i,display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            release_epaperdisplay(&displays[i].epaper_display);
+            release_epaperdisplay(DYN_DISPLAYS_ADR(i,epaper_display));
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            release_framebufferdisplay(&displays[i].framebuffer_display);
+            release_framebufferdisplay(DYN_DISPLAYS_ADR(i,framebuffer_display));
+        #endif
+        }
+        if (i < CIRCUITPY_DISPLAY_LIMIT) {
+            displays[i].display_base.type = &mp_type_NoneType;
+        #if CIRCUITPY_OS_GETENV
+        } else {
+            displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType;
         #endif
         }
-        displays[i].display_base.type = &mp_type_NoneType;
     }
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_const_obj_t bus_type = display_buses[i].bus_base.type;
+        mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
         if (bus_type == NULL || bus_type == &mp_type_NoneType) {
             continue;
         #if CIRCUITPY_FOURWIRE
         } else if (bus_type == &fourwire_fourwire_type) {
-            common_hal_fourwire_fourwire_deinit(&display_buses[i].fourwire_bus);
+            common_hal_fourwire_fourwire_deinit(DYN_DISPLAY_BUSES_ADR(i,fourwire_bus));
         #endif
         #if CIRCUITPY_I2CDISPLAYBUS
         } else if (bus_type == &i2cdisplaybus_i2cdisplaybus_type) {
-            common_hal_i2cdisplaybus_i2cdisplaybus_deinit(&display_buses[i].i2cdisplay_bus);
+            common_hal_i2cdisplaybus_i2cdisplaybus_deinit(DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus));
         #endif
         #if CIRCUITPY_DOTCLOCKFRAMEBUFFER
         } else if (bus_type == &dotclockframebuffer_framebuffer_type) {
-            common_hal_dotclockframebuffer_framebuffer_deinit(&display_buses[i].dotclock);
+            common_hal_dotclockframebuffer_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,dotclock));
         #endif
         #if CIRCUITPY_PARALLELDISPLAYBUS
         } else if (bus_type == &paralleldisplaybus_parallelbus_type) {
-            common_hal_paralleldisplaybus_parallelbus_deinit(&display_buses[i].parallel_bus);
+            common_hal_paralleldisplaybus_parallelbus_deinit(DYN_DISPLAY_BUSES_ADR(i,parallel_bus));
         #endif
         #if CIRCUITPY_RGBMATRIX
         } else if (bus_type == &rgbmatrix_RGBMatrix_type) {
-            common_hal_rgbmatrix_rgbmatrix_deinit(&display_buses[i].rgbmatrix);
+            common_hal_rgbmatrix_rgbmatrix_deinit(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix));
         #endif
         #if CIRCUITPY_IS31FL3741
         } else if (bus_type == &is31fl3741_framebuffer_type) {
-            common_hal_is31fl3741_framebuffer_deinit(&display_buses[i].is31fl3741);
+            common_hal_is31fl3741_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,is31fl3741));
         #endif
         #if CIRCUITPY_SHARPDISPLAY
         } else if (bus_type == &sharpdisplay_framebuffer_type) {
-            common_hal_sharpdisplay_framebuffer_deinit(&display_buses[i].sharpdisplay);
+            common_hal_sharpdisplay_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay));
         #endif
         #if CIRCUITPY_VIDEOCORE
         } else if (bus_type == &videocore_framebuffer_type) {
-            common_hal_videocore_framebuffer_deinit(&display_buses[i].videocore);
+            common_hal_videocore_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,videocore));
         #endif
         #if CIRCUITPY_PICODVI
         } else if (bus_type == &picodvi_framebuffer_type) {
-            common_hal_picodvi_framebuffer_deinit(&display_buses[i].picodvi);
+            common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,picodvi));
+        #endif
+        }
+        if (i < CIRCUITPY_DISPLAY_LIMIT) {
+            display_buses[i].bus_base.type = &mp_type_NoneType;
+        #if CIRCUITPY_OS_GETENV
+        } else {
+            display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType;
         #endif
         }
-        display_buses[i].bus_base.type = &mp_type_NoneType;
     }
 
     supervisor_stop_terminal();
@@ -201,16 +228,14 @@ void malloc_display_memory(void) {
     #if CIRCUITPY_OS_GETENV
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) {
-        display_buses = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false);
-        displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false);
-        memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT);
-        memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT);
-
+        display_buses_dyn = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false);
+        displays_dyn = (primary_display_t *)port_malloc(sizeof(primary_display_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false);
+        
         for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) {
-            memset(&displays[i], 0, sizeof(displays[i]));
-            memset(&display_buses[i], 0, sizeof(display_buses[i]));
-            display_buses[i].bus_base.type = &mp_type_NoneType;
-            displays[i].display_base.type = &mp_type_NoneType;
+            memset(&displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT]));
+            memset(&display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT]));
+            display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType;
+            displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType;
         }
     }
     #endif
@@ -222,12 +247,12 @@ void reset_displays(void) {
 
     // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline.
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
+        mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             continue;
         #if CIRCUITPY_FOURWIRE
         } else if (display_bus_type == &fourwire_fourwire_type) {
-            fourwire_fourwire_obj_t *fourwire = &display_buses[i].fourwire_bus;
+            fourwire_fourwire_obj_t *fourwire = DYN_DISPLAY_BUSES_ADR(i,fourwire_bus);
             if (((size_t)fourwire->bus) < ((size_t)&display_buses) ||
                 ((size_t)fourwire->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) {
                 busio_spi_obj_t *original_spi = fourwire->bus;
@@ -257,7 +282,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_I2CDISPLAYBUS
         } else if (display_bus_type == &i2cdisplaybus_i2cdisplaybus_type) {
-            i2cdisplaybus_i2cdisplaybus_obj_t *i2c = &display_buses[i].i2cdisplay_bus;
+            i2cdisplaybus_i2cdisplaybus_obj_t *i2c = DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus);
             // Check to see if we need to inline the I2C bus.
             if (((size_t)i2c->bus) < ((size_t)&display_buses) ||
                 ((size_t)i2c->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) {
@@ -285,7 +310,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_RGBMATRIX
         } else if (display_bus_type == &rgbmatrix_RGBMatrix_type) {
-            rgbmatrix_rgbmatrix_obj_t *pm = &display_buses[i].rgbmatrix;
+            rgbmatrix_rgbmatrix_obj_t *pm = DYN_DISPLAY_BUSES_ADR(i,rgbmatrix);
             if (!any_display_uses_this_framebuffer(&pm->base)) {
                 common_hal_rgbmatrix_rgbmatrix_deinit(pm);
             } else {
@@ -294,7 +319,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_IS31FL3741
         } else if (display_bus_type == &is31fl3741_framebuffer_type) {
-            is31fl3741_framebuffer_obj_t *is31fb = &display_buses[i].is31fl3741;
+            is31fl3741_framebuffer_obj_t *is31fb = DYN_DISPLAY_BUSES_ADR(i,is31fl3741);
 
             if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) ||
                 ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + max_num_displays)) {
@@ -324,12 +349,12 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_SHARPDISPLAY
         } else if (display_bus_type == &sharpdisplay_framebuffer_type) {
-            sharpdisplay_framebuffer_obj_t *sharp = &display_buses[i].sharpdisplay;
+            sharpdisplay_framebuffer_obj_t *sharp = DYN_DISPLAY_BUSES_ADR(i,sharpdisplay);
             common_hal_sharpdisplay_framebuffer_reset(sharp);
         #endif
         #if CIRCUITPY_VIDEOCORE
         } else if (display_bus_type == &videocore_framebuffer_type) {
-            videocore_framebuffer_obj_t *vc = &display_buses[i].videocore;
+            videocore_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,videocore);
             if (!any_display_uses_this_framebuffer(&vc->base)) {
                 common_hal_videocore_framebuffer_deinit(vc);
             }
@@ -338,7 +363,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_PICODVI
         } else if (display_bus_type == &picodvi_framebuffer_type) {
-            picodvi_framebuffer_obj_t *vc = &display_buses[i].picodvi;
+            picodvi_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,picodvi);
             if (!any_display_uses_this_framebuffer(&vc->base)) {
                 common_hal_picodvi_framebuffer_deinit(vc);
             }
@@ -346,13 +371,13 @@ void reset_displays(void) {
         #if CIRCUITPY_AURORA_EPAPER
         } else if (display_bus_type == &aurora_framebuffer_type) {
             #if CIRCUITPY_BOARD_SPI
-            aurora_epaper_framebuffer_obj_t *aurora = &display_buses[i].aurora_epaper;
+            aurora_epaper_framebuffer_obj_t *aurora = DYN_DISPLAY_BUSES_ADR(i,aurora_epaper);
             if (common_hal_board_is_spi(aurora->bus)) {
                 common_hal_aurora_epaper_framebuffer_set_free_bus(false);
             }
             #endif
             // Set to None, gets deinit'd up by display_base
-            display_buses[i].bus_base.type = &mp_type_NoneType;
+            DYN_DISPLAY_BUSES(i).bus_base.type = &mp_type_NoneType;
         #endif
         } else {
             // Not an active display bus.
@@ -363,21 +388,21 @@ void reset_displays(void) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
         // Reset the displayed group. Only the first will get the terminal but
         // that's ok.
-        mp_const_obj_t display_type = displays[i].display_base.type;
+        mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type;
         if (display_type == NULL || display_type == &mp_type_NoneType) {
             continue;
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            reset_busdisplay(&displays[i].display);
+            reset_busdisplay(DYN_DISPLAYS_ADR(i,display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            epaperdisplay_epaperdisplay_obj_t *display = &displays[i].epaper_display;
+            epaperdisplay_epaperdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,epaper_display);
             epaperdisplay_epaperdisplay_reset(display);
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_reset(&displays[i].framebuffer_display);
+            framebufferio_framebufferdisplay_reset(DYN_DISPLAYS_ADR(i,framebuffer_display));
         #endif
         }
     }
@@ -385,34 +410,34 @@ void reset_displays(void) {
 
 void displayio_gc_collect(void) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
+        mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             continue;
         }
         #if CIRCUITPY_RGBMATRIX
         if (display_bus_type == &rgbmatrix_RGBMatrix_type) {
-            rgbmatrix_rgbmatrix_collect_ptrs(&display_buses[i].rgbmatrix);
+            rgbmatrix_rgbmatrix_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix));
         }
         #endif
         #if CIRCUITPY_IS31FL3741
         if (display_bus_type == &is31fl3741_framebuffer_type) {
-            is31fl3741_framebuffer_collect_ptrs(&display_buses[i].is31fl3741);
+            is31fl3741_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,is31fl3741));
         }
         #endif
         #if CIRCUITPY_SHARPDISPLAY
         if (display_bus_type == &sharpdisplay_framebuffer_type) {
-            common_hal_sharpdisplay_framebuffer_collect_ptrs(&display_buses[i].sharpdisplay);
+            common_hal_sharpdisplay_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay));
         }
         #endif
         #if CIRCUITPY_AURORA_EPAPER
         if (display_bus_type == &aurora_framebuffer_type) {
-            common_hal_aurora_epaper_framebuffer_collect_ptrs(&display_buses[i].aurora_epaper);
+            common_hal_aurora_epaper_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,aurora_epaper));
         }
         #endif
     }
 
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_const_obj_t display_type = displays[i].display_base.type;
+        mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type;
         if (display_type == NULL || display_type == &mp_type_NoneType) {
             continue;
 
@@ -420,15 +445,15 @@ void displayio_gc_collect(void) {
             // but this is more precise, and is the only field that needs marking.
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            busdisplay_busdisplay_collect_ptrs(&displays[i].display);
+            busdisplay_busdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,display));
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_collect_ptrs(&displays[i].framebuffer_display);
+            framebufferio_framebufferdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,framebuffer_display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            epaperdisplay_epaperdisplay_collect_ptrs(&displays[i].epaper_display);
+            epaperdisplay_epaperdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,epaper_display));
         #endif
         }
     }
@@ -440,12 +465,19 @@ static bool is_display_active(mp_obj_base_t *display_maybe) {
 
 primary_display_t *allocate_display(void) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        if (!is_display_active(&displays[i].display_base)) {
+        if (!is_display_active(DYN_DISPLAYS_ADR(i,display_base))) {
             // Clear this memory so it is in a known state before init.
-            memset(&displays[i], 0, sizeof(displays[i]));
+//            memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i)));
+            memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0]));
             // Default to None so that it works as board.DISPLAY.
-            displays[i].display_base.type = &mp_type_NoneType;
-            return &displays[i];
+            if (i < CIRCUITPY_DISPLAY_LIMIT) {
+                displays[i].display_base.type = &mp_type_NoneType;
+            #if CIRCUITPY_OS_GETENV
+            } else {
+                displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType;
+            #endif
+            }
+            return DYN_DISPLAYS_ADR0(i);
         }
     }
     return NULL;
@@ -461,12 +493,19 @@ primary_display_t *allocate_display_or_raise(void) {
 
 primary_display_bus_t *allocate_display_bus(void) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_const_obj_t display_bus_type = display_buses[i].bus_base.type;
+        mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             // Clear this memory so it is in a known state before init.
-            memset(&display_buses[i], 0, sizeof(display_buses[i]));
-            display_buses[i].bus_base.type = &mp_type_NoneType;
-            return &display_buses[i];
+//            memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(DYN_DISPLAY_BUSES(i)));
+            memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(display_buses[0]));
+            if (i < CIRCUITPY_DISPLAY_LIMIT) {
+                display_buses[i].bus_base.type = &mp_type_NoneType;
+            #if CIRCUITPY_OS_GETENV
+            } else {
+                display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType;
+            #endif
+            }
+            return DYN_DISPLAY_BUSES_ADR0(i);
         }
     }
     return NULL;
@@ -497,7 +536,7 @@ void common_hal_displayio_set_primary_display(mp_obj_t new_primary_display) {
         return;
     }
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        mp_obj_t display = MP_OBJ_FROM_PTR(&displays[i]);
+        mp_obj_t display = MP_OBJ_FROM_PTR(DYN_DISPLAYS_ADR0(i));
         if (new_primary_display == display && is_display_active(display)) {
             primary_display_number = i;
             return;
@@ -512,7 +551,7 @@ void common_hal_displayio_auto_primary_display(void) {
         return;
     }
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        if (is_display_active(&displays[i].display_base)) {
+        if (is_display_active(DYN_DISPLAYS_ADR(i,display_base))) {
             primary_display_number = i;
             return;
         }
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index ccdc2887eda6..9ddcbcef9eb7 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -99,16 +99,20 @@ typedef struct {
     };
 } primary_display_t;
 
-extern primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT];
-extern primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT];
-extern primary_display_bus_t *display_buses;
-extern primary_display_t *displays;
+extern primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
+extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
+#if CIRCUITPY_OS_GETENV
+extern primary_display_bus_t *display_buses_dyn;
+extern primary_display_t *displays_dyn;
+#endif
 
 extern displayio_group_t circuitpython_splash;
 
 void displayio_background(void);
 void reset_displays(void);
+#if CIRCUITPY_OS_GETENV
 void malloc_display_memory(void);
+#endif
 void displayio_gc_collect(void);
 
 primary_display_t *allocate_display(void);
diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c
index 41c1695dbca6..f7d6135b3ecb 100644
--- a/shared-module/epaperdisplay/EPaperDisplay.c
+++ b/shared-module/epaperdisplay/EPaperDisplay.c
@@ -512,12 +512,30 @@ size_t maybe_refresh_epaperdisplay(void) {
     #endif
 
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
-            displays[i].epaper_display.core.current_group != &circuitpython_splash) {
-            // Skip regular displays and those not showing the splash.
-            continue;
+        if (i < CIRCUITPY_DISPLAY_LIMIT) {
+            if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
+                displays[i].epaper_display.core.current_group != &circuitpython_splash) {
+                // Skip regular displays and those not showing the splash.
+                continue;
+            }
+        #if CIRCUITPY_OS_GETENV
+        } else {
+            if (displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
+                displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.core.current_group != &circuitpython_splash) {
+                // Skip regular displays and those not showing the splash.
+                continue;
+            }
+        #endif            
+        }
+
+        epaperdisplay_epaperdisplay_obj_t *display;
+        if (i < CIRCUITPY_DISPLAY_LIMIT) {
+            display = &displays[i].epaper_display;
+        #if CIRCUITPY_OS_GETENV
+        } else {
+            display = &displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display;
+        #endif
         }
-        epaperdisplay_epaperdisplay_obj_t *display = &displays[i].epaper_display;
         size_t time_to_refresh = common_hal_epaperdisplay_epaperdisplay_get_time_to_refresh(display);
         if (time_to_refresh > 0) {
             return time_to_refresh;
diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c
index ea7e005b5918..22957293219a 100644
--- a/supervisor/shared/web_workflow/web_workflow.c
+++ b/supervisor/shared/web_workflow/web_workflow.c
@@ -1565,13 +1565,18 @@ static bool supervisor_filesystem_access_could_block(void) {
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
     #if CIRCUITPY_OS_GETENV
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
+    #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+    #define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
+    #else
+    #define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
+    #define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr)
     #endif
     // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible
     for (mp_int_t i = 0; i < max_num_displays; i++) {
-        if (display_buses[i].bus_base.type != &fourwire_fourwire_type) {
+        if (DYN_DISPLAY_BUSES(i).bus_base.type != &fourwire_fourwire_type) {
             continue;
         }
-        if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(&display_buses[i].bus_base))) {
+        if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(DYN_DISPLAY_BUSES_ADR(i,bus_base)))) {
             could_block = true;
         }
     }

From a82ddf4745eb421d24f9b74ac4fbdf0e79a7aab7 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 16:54:34 -0400
Subject: [PATCH 10/14] Local pre-commit....

---
 shared-module/displayio/__init__.c            | 82 +++++++++----------
 shared-module/epaperdisplay/EPaperDisplay.c   |  2 +-
 supervisor/shared/web_workflow/web_workflow.c |  6 +-
 3 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index a17f37e0dca2..f03e7c426e0c 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -58,17 +58,17 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
 primary_display_bus_t *display_buses_dyn = &display_buses[0];
 primary_display_t *displays_dyn = &displays[0];
 #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
-#define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
+#define DYN_DISPLAY_BUSES_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
 #define DYN_DISPLAY_BUSES_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx] : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
 #define DYN_DISPLAYS(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? displays[indx] : displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
-#define DYN_DISPLAYS_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx].membr : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
+#define DYN_DISPLAYS_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx].membr : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
 #define DYN_DISPLAYS_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx] : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
 #else
 #define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
-#define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr)
+#define DYN_DISPLAY_BUSES_ADR(indx, membr) (&display_buses[indx].membr)
 #define DYN_DISPLAY_BUSES_ADR0(indx) (&display_buses[indx])
 #define DYN_DISPLAYS(indx) (displays[indx])
-#define DYN_DISPLAYS_ADR(indx,membr) (&displays[indx].membr)
+#define DYN_DISPLAYS_ADR(indx, membr) (&displays[indx].membr)
 #define DYN_DISPLAYS_ADR0(indx) (&displays[indx])
 #endif
 
@@ -89,7 +89,7 @@ displayio_buffer_transform_t null_transform = {
 static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
         if (DYN_DISPLAYS(i).display_base.type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,framebuffer_display);
+            framebufferio_framebufferdisplay_obj_t *display = DYN_DISPLAYS_ADR(i, framebuffer_display);
             if (display->framebuffer == obj) {
                 return true;
             }
@@ -118,15 +118,15 @@ void displayio_background(void) {
         if (false) {
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            busdisplay_busdisplay_background(DYN_DISPLAYS_ADR(i,display));
+            busdisplay_busdisplay_background(DYN_DISPLAYS_ADR(i, display));
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_background(DYN_DISPLAYS_ADR(i,framebuffer_display));
+            framebufferio_framebufferdisplay_background(DYN_DISPLAYS_ADR(i, framebuffer_display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            epaperdisplay_epaperdisplay_background(DYN_DISPLAYS_ADR(i,epaper_display));
+            epaperdisplay_epaperdisplay_background(DYN_DISPLAYS_ADR(i, epaper_display));
         #endif
         }
     }
@@ -148,15 +148,15 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
             continue;
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            release_busdisplay(DYN_DISPLAYS_ADR(i,display));
+            release_busdisplay(DYN_DISPLAYS_ADR(i, display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            release_epaperdisplay(DYN_DISPLAYS_ADR(i,epaper_display));
+            release_epaperdisplay(DYN_DISPLAYS_ADR(i, epaper_display));
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            release_framebufferdisplay(DYN_DISPLAYS_ADR(i,framebuffer_display));
+            release_framebufferdisplay(DYN_DISPLAYS_ADR(i, framebuffer_display));
         #endif
         }
         if (i < CIRCUITPY_DISPLAY_LIMIT) {
@@ -173,39 +173,39 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
             continue;
         #if CIRCUITPY_FOURWIRE
         } else if (bus_type == &fourwire_fourwire_type) {
-            common_hal_fourwire_fourwire_deinit(DYN_DISPLAY_BUSES_ADR(i,fourwire_bus));
+            common_hal_fourwire_fourwire_deinit(DYN_DISPLAY_BUSES_ADR(i, fourwire_bus));
         #endif
         #if CIRCUITPY_I2CDISPLAYBUS
         } else if (bus_type == &i2cdisplaybus_i2cdisplaybus_type) {
-            common_hal_i2cdisplaybus_i2cdisplaybus_deinit(DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus));
+            common_hal_i2cdisplaybus_i2cdisplaybus_deinit(DYN_DISPLAY_BUSES_ADR(i, i2cdisplay_bus));
         #endif
         #if CIRCUITPY_DOTCLOCKFRAMEBUFFER
         } else if (bus_type == &dotclockframebuffer_framebuffer_type) {
-            common_hal_dotclockframebuffer_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,dotclock));
+            common_hal_dotclockframebuffer_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, dotclock));
         #endif
         #if CIRCUITPY_PARALLELDISPLAYBUS
         } else if (bus_type == &paralleldisplaybus_parallelbus_type) {
-            common_hal_paralleldisplaybus_parallelbus_deinit(DYN_DISPLAY_BUSES_ADR(i,parallel_bus));
+            common_hal_paralleldisplaybus_parallelbus_deinit(DYN_DISPLAY_BUSES_ADR(i, parallel_bus));
         #endif
         #if CIRCUITPY_RGBMATRIX
         } else if (bus_type == &rgbmatrix_RGBMatrix_type) {
-            common_hal_rgbmatrix_rgbmatrix_deinit(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix));
+            common_hal_rgbmatrix_rgbmatrix_deinit(DYN_DISPLAY_BUSES_ADR(i, rgbmatrix));
         #endif
         #if CIRCUITPY_IS31FL3741
         } else if (bus_type == &is31fl3741_framebuffer_type) {
-            common_hal_is31fl3741_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,is31fl3741));
+            common_hal_is31fl3741_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, is31fl3741));
         #endif
         #if CIRCUITPY_SHARPDISPLAY
         } else if (bus_type == &sharpdisplay_framebuffer_type) {
-            common_hal_sharpdisplay_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay));
+            common_hal_sharpdisplay_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, sharpdisplay));
         #endif
         #if CIRCUITPY_VIDEOCORE
         } else if (bus_type == &videocore_framebuffer_type) {
-            common_hal_videocore_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,videocore));
+            common_hal_videocore_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, videocore));
         #endif
         #if CIRCUITPY_PICODVI
         } else if (bus_type == &picodvi_framebuffer_type) {
-            common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,picodvi));
+            common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, picodvi));
         #endif
         }
         if (i < CIRCUITPY_DISPLAY_LIMIT) {
@@ -230,7 +230,7 @@ void malloc_display_memory(void) {
     if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) {
         display_buses_dyn = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false);
         displays_dyn = (primary_display_t *)port_malloc(sizeof(primary_display_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false);
-        
+
         for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) {
             memset(&displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT]));
             memset(&display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT]));
@@ -252,7 +252,7 @@ void reset_displays(void) {
             continue;
         #if CIRCUITPY_FOURWIRE
         } else if (display_bus_type == &fourwire_fourwire_type) {
-            fourwire_fourwire_obj_t *fourwire = DYN_DISPLAY_BUSES_ADR(i,fourwire_bus);
+            fourwire_fourwire_obj_t *fourwire = DYN_DISPLAY_BUSES_ADR(i, fourwire_bus);
             if (((size_t)fourwire->bus) < ((size_t)&display_buses) ||
                 ((size_t)fourwire->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) {
                 busio_spi_obj_t *original_spi = fourwire->bus;
@@ -282,7 +282,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_I2CDISPLAYBUS
         } else if (display_bus_type == &i2cdisplaybus_i2cdisplaybus_type) {
-            i2cdisplaybus_i2cdisplaybus_obj_t *i2c = DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus);
+            i2cdisplaybus_i2cdisplaybus_obj_t *i2c = DYN_DISPLAY_BUSES_ADR(i, i2cdisplay_bus);
             // Check to see if we need to inline the I2C bus.
             if (((size_t)i2c->bus) < ((size_t)&display_buses) ||
                 ((size_t)i2c->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) {
@@ -310,7 +310,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_RGBMATRIX
         } else if (display_bus_type == &rgbmatrix_RGBMatrix_type) {
-            rgbmatrix_rgbmatrix_obj_t *pm = DYN_DISPLAY_BUSES_ADR(i,rgbmatrix);
+            rgbmatrix_rgbmatrix_obj_t *pm = DYN_DISPLAY_BUSES_ADR(i, rgbmatrix);
             if (!any_display_uses_this_framebuffer(&pm->base)) {
                 common_hal_rgbmatrix_rgbmatrix_deinit(pm);
             } else {
@@ -319,7 +319,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_IS31FL3741
         } else if (display_bus_type == &is31fl3741_framebuffer_type) {
-            is31fl3741_framebuffer_obj_t *is31fb = DYN_DISPLAY_BUSES_ADR(i,is31fl3741);
+            is31fl3741_framebuffer_obj_t *is31fb = DYN_DISPLAY_BUSES_ADR(i, is31fl3741);
 
             if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) ||
                 ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + max_num_displays)) {
@@ -349,12 +349,12 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_SHARPDISPLAY
         } else if (display_bus_type == &sharpdisplay_framebuffer_type) {
-            sharpdisplay_framebuffer_obj_t *sharp = DYN_DISPLAY_BUSES_ADR(i,sharpdisplay);
+            sharpdisplay_framebuffer_obj_t *sharp = DYN_DISPLAY_BUSES_ADR(i, sharpdisplay);
             common_hal_sharpdisplay_framebuffer_reset(sharp);
         #endif
         #if CIRCUITPY_VIDEOCORE
         } else if (display_bus_type == &videocore_framebuffer_type) {
-            videocore_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,videocore);
+            videocore_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i, videocore);
             if (!any_display_uses_this_framebuffer(&vc->base)) {
                 common_hal_videocore_framebuffer_deinit(vc);
             }
@@ -363,7 +363,7 @@ void reset_displays(void) {
         #endif
         #if CIRCUITPY_PICODVI
         } else if (display_bus_type == &picodvi_framebuffer_type) {
-            picodvi_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,picodvi);
+            picodvi_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i, picodvi);
             if (!any_display_uses_this_framebuffer(&vc->base)) {
                 common_hal_picodvi_framebuffer_deinit(vc);
             }
@@ -371,7 +371,7 @@ void reset_displays(void) {
         #if CIRCUITPY_AURORA_EPAPER
         } else if (display_bus_type == &aurora_framebuffer_type) {
             #if CIRCUITPY_BOARD_SPI
-            aurora_epaper_framebuffer_obj_t *aurora = DYN_DISPLAY_BUSES_ADR(i,aurora_epaper);
+            aurora_epaper_framebuffer_obj_t *aurora = DYN_DISPLAY_BUSES_ADR(i, aurora_epaper);
             if (common_hal_board_is_spi(aurora->bus)) {
                 common_hal_aurora_epaper_framebuffer_set_free_bus(false);
             }
@@ -393,16 +393,16 @@ void reset_displays(void) {
             continue;
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            reset_busdisplay(DYN_DISPLAYS_ADR(i,display));
+            reset_busdisplay(DYN_DISPLAYS_ADR(i, display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            epaperdisplay_epaperdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,epaper_display);
+            epaperdisplay_epaperdisplay_obj_t *display = DYN_DISPLAYS_ADR(i, epaper_display);
             epaperdisplay_epaperdisplay_reset(display);
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_reset(DYN_DISPLAYS_ADR(i,framebuffer_display));
+            framebufferio_framebufferdisplay_reset(DYN_DISPLAYS_ADR(i, framebuffer_display));
         #endif
         }
     }
@@ -416,22 +416,22 @@ void displayio_gc_collect(void) {
         }
         #if CIRCUITPY_RGBMATRIX
         if (display_bus_type == &rgbmatrix_RGBMatrix_type) {
-            rgbmatrix_rgbmatrix_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix));
+            rgbmatrix_rgbmatrix_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, rgbmatrix));
         }
         #endif
         #if CIRCUITPY_IS31FL3741
         if (display_bus_type == &is31fl3741_framebuffer_type) {
-            is31fl3741_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,is31fl3741));
+            is31fl3741_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, is31fl3741));
         }
         #endif
         #if CIRCUITPY_SHARPDISPLAY
         if (display_bus_type == &sharpdisplay_framebuffer_type) {
-            common_hal_sharpdisplay_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay));
+            common_hal_sharpdisplay_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, sharpdisplay));
         }
         #endif
         #if CIRCUITPY_AURORA_EPAPER
         if (display_bus_type == &aurora_framebuffer_type) {
-            common_hal_aurora_epaper_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,aurora_epaper));
+            common_hal_aurora_epaper_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, aurora_epaper));
         }
         #endif
     }
@@ -445,15 +445,15 @@ void displayio_gc_collect(void) {
             // but this is more precise, and is the only field that needs marking.
         #if CIRCUITPY_BUSDISPLAY
         } else if (display_type == &busdisplay_busdisplay_type) {
-            busdisplay_busdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,display));
+            busdisplay_busdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i, display));
         #endif
         #if CIRCUITPY_FRAMEBUFFERIO
         } else if (display_type == &framebufferio_framebufferdisplay_type) {
-            framebufferio_framebufferdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,framebuffer_display));
+            framebufferio_framebufferdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i, framebuffer_display));
         #endif
         #if CIRCUITPY_EPAPERDISPLAY
         } else if (display_type == &epaperdisplay_epaperdisplay_type) {
-            epaperdisplay_epaperdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,epaper_display));
+            epaperdisplay_epaperdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i, epaper_display));
         #endif
         }
     }
@@ -465,7 +465,7 @@ static bool is_display_active(mp_obj_base_t *display_maybe) {
 
 primary_display_t *allocate_display(void) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        if (!is_display_active(DYN_DISPLAYS_ADR(i,display_base))) {
+        if (!is_display_active(DYN_DISPLAYS_ADR(i, display_base))) {
             // Clear this memory so it is in a known state before init.
 //            memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i)));
             memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0]));
@@ -551,7 +551,7 @@ void common_hal_displayio_auto_primary_display(void) {
         return;
     }
     for (uint8_t i = 0; i < max_num_displays; i++) {
-        if (is_display_active(DYN_DISPLAYS_ADR(i,display_base))) {
+        if (is_display_active(DYN_DISPLAYS_ADR(i, display_base))) {
             primary_display_number = i;
             return;
         }
diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c
index f7d6135b3ecb..da9b965f1524 100644
--- a/shared-module/epaperdisplay/EPaperDisplay.c
+++ b/shared-module/epaperdisplay/EPaperDisplay.c
@@ -525,7 +525,7 @@ size_t maybe_refresh_epaperdisplay(void) {
                 // Skip regular displays and those not showing the splash.
                 continue;
             }
-        #endif            
+        #endif
         }
 
         epaperdisplay_epaperdisplay_obj_t *display;
diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c
index 22957293219a..29f23e1cfe8f 100644
--- a/supervisor/shared/web_workflow/web_workflow.c
+++ b/supervisor/shared/web_workflow/web_workflow.c
@@ -1566,17 +1566,17 @@ static bool supervisor_filesystem_access_could_block(void) {
     #if CIRCUITPY_OS_GETENV
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
-    #define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
+    #define DYN_DISPLAY_BUSES_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)
     #else
     #define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
-    #define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr)
+    #define DYN_DISPLAY_BUSES_ADR(indx, membr) (&display_buses[indx].membr)
     #endif
     // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible
     for (mp_int_t i = 0; i < max_num_displays; i++) {
         if (DYN_DISPLAY_BUSES(i).bus_base.type != &fourwire_fourwire_type) {
             continue;
         }
-        if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(DYN_DISPLAY_BUSES_ADR(i,bus_base)))) {
+        if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(DYN_DISPLAY_BUSES_ADR(i, bus_base)))) {
             could_block = true;
         }
     }

From 424ea8861e1a124c42e475c4545492c264c6e131 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 17:19:03 -0400
Subject: [PATCH 11/14] don't define max_num_displays when not needed

---
 shared-module/board/__init__.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 4e9eb5f9b849..34df0053e0a9 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -176,7 +176,7 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) {
 #endif
 
 void reset_board_buses(void) {
-    #if CIRCUITPY_BOARD_I2C || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER))
+    #if (CIRCUITPY_BOARD_I2C && CIRCUITPY_I2CDISPLAYBUS) || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER))
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
     #if CIRCUITPY_OS_GETENV
     #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])

From 4c11d11647112c8ab3ab3f1aa90edf50c3328242 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 17:40:10 -0400
Subject: [PATCH 12/14] compile error fixes

---
 shared-module/displayio/__init__.c | 2 +-
 shared-module/displayio/__init__.h | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index f03e7c426e0c..a2c04c946ca3 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -50,7 +50,7 @@
 
 // The default indicates no primary display
 static int primary_display_number = -1;
-static int max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
+static mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
 
 primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
 primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index 9ddcbcef9eb7..d6eaaf597cb3 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -110,9 +110,7 @@ extern displayio_group_t circuitpython_splash;
 
 void displayio_background(void);
 void reset_displays(void);
-#if CIRCUITPY_OS_GETENV
 void malloc_display_memory(void);
-#endif
 void displayio_gc_collect(void);
 
 primary_display_t *allocate_display(void);

From 0c27bd87ff5af06767b221ce995310fc86ce6ce9 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Fri, 21 Mar 2025 19:17:47 -0400
Subject: [PATCH 13/14] Add compile flag to remove code from smaller boards

---
 main.c                                        |  2 +-
 ports/atmel-samd/mpconfigport.mk              |  1 +
 .../stm32f411ve_discovery/mpconfigboard.mk    |  1 +
 py/circuitpy_mpconfig.mk                      |  3 ++
 shared-module/board/__init__.c                |  9 ++----
 shared-module/displayio/__init__.c            | 30 ++++++++++++-------
 shared-module/displayio/__init__.h            |  2 +-
 shared-module/epaperdisplay/EPaperDisplay.c   | 20 +++++++++----
 supervisor/shared/web_workflow/web_workflow.c |  2 +-
 9 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/main.c b/main.c
index e2587a30fd44..5f00371a2be5 100644
--- a/main.c
+++ b/main.c
@@ -1051,7 +1051,7 @@ int __attribute__((used)) main(void) {
     alarm_reset();
     #endif
 
-    #if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV
+    #if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
     // If number of displays has been overridden in settings.toml allocate memory and
     // move existing displays
     malloc_display_memory();
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index 15013b2d831c..d0831f70651c 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -12,6 +12,7 @@ CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 1
 CIRCUITPY_LTO = 1
 
 CIRCUITPY_KEYPAD_DEMUX ?= 0
+CIRCUITPY_SET_DISPLAY_LIMIT ?= 0
 
 ######################################################################
 # Put samd21-only choices here.
diff --git a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk
index f34fac4047a7..6d33abb05fa7 100644
--- a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk
+++ b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk
@@ -22,3 +22,4 @@ CIRCUITPY_BLEIO_HCI = 0
 CIRCUITPY_CODEOP = 0
 CIRCUITPY_MSGPACK = 0
 CIRCUITPY_VECTORIO = 0
+CIRCUITPY_SET_DISPLAY_LIMIT = 0
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index 831c1ec245fc..0c2b40bc70d9 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -227,6 +227,9 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
 CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
 CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
 
+CIRCUITPY_SET_DISPLAY_LIMIT ?= $(CIRCUITPY_DISPLAYIO)
+CFLAGS += -DCIRCUITPY_SET_DISPLAY_LIMIT=$(CIRCUITPY_SET_DISPLAY_LIMIT)
+
 CIRCUITPY_BUSDISPLAY ?= $(CIRCUITPY_DISPLAYIO)
 CFLAGS += -DCIRCUITPY_BUSDISPLAY=$(CIRCUITPY_BUSDISPLAY)
 
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 34df0053e0a9..78e25488006d 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -10,7 +10,7 @@
 #include "mpconfigboard.h"
 #include "py/runtime.h"
 
-#if CIRCUITPY_OS_GETENV
+#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
 #include "shared-module/os/__init__.h"
 #endif
 
@@ -178,15 +178,12 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) {
 void reset_board_buses(void) {
     #if (CIRCUITPY_BOARD_I2C && CIRCUITPY_I2CDISPLAYBUS) || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER))
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
-    #if CIRCUITPY_OS_GETENV
+    #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
     #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
+    (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     #else
     #define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
     #endif
-
-    #if CIRCUITPY_OS_GETENV
-    (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
-    #endif
     #endif
 
     #if CIRCUITPY_BOARD_I2C
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index a2c04c946ca3..da6bb3799d99 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -22,7 +22,7 @@
 
 #include "py/mpconfig.h"
 
-#if CIRCUITPY_OS_GETENV
+#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
 #include "shared-module/os/__init__.h"
 #endif
 
@@ -54,7 +54,7 @@ static mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
 
 primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
 primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
-#if CIRCUITPY_OS_GETENV
+#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
 primary_display_bus_t *display_buses_dyn = &display_buses[0];
 primary_display_t *displays_dyn = &displays[0];
 #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
@@ -159,13 +159,15 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
             release_framebufferdisplay(DYN_DISPLAYS_ADR(i, framebuffer_display));
         #endif
         }
+        #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
         if (i < CIRCUITPY_DISPLAY_LIMIT) {
             displays[i].display_base.type = &mp_type_NoneType;
-        #if CIRCUITPY_OS_GETENV
         } else {
             displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType;
-        #endif
         }
+        #else
+        displays[i].display_base.type = &mp_type_NoneType;
+        #endif
     }
     for (uint8_t i = 0; i < max_num_displays; i++) {
         mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
@@ -208,13 +210,15 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
             common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, picodvi));
         #endif
         }
+        #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
         if (i < CIRCUITPY_DISPLAY_LIMIT) {
             display_buses[i].bus_base.type = &mp_type_NoneType;
-        #if CIRCUITPY_OS_GETENV
         } else {
             display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType;
-        #endif
         }
+        #else
+        display_buses[i].bus_base.type = &mp_type_NoneType;
+        #endif
     }
 
     supervisor_stop_terminal();
@@ -225,7 +229,7 @@ void common_hal_displayio_release_displays(void) {
 }
 
 void malloc_display_memory(void) {
-    #if CIRCUITPY_OS_GETENV
+    #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) {
         display_buses_dyn = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false);
@@ -470,13 +474,15 @@ primary_display_t *allocate_display(void) {
 //            memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i)));
             memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0]));
             // Default to None so that it works as board.DISPLAY.
+            #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
             if (i < CIRCUITPY_DISPLAY_LIMIT) {
                 displays[i].display_base.type = &mp_type_NoneType;
-            #if CIRCUITPY_OS_GETENV
             } else {
                 displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType;
-            #endif
             }
+            #else
+            displays[i].display_base.type = &mp_type_NoneType;
+            #endif
             return DYN_DISPLAYS_ADR0(i);
         }
     }
@@ -498,13 +504,15 @@ primary_display_bus_t *allocate_display_bus(void) {
             // Clear this memory so it is in a known state before init.
 //            memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(DYN_DISPLAY_BUSES(i)));
             memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(display_buses[0]));
+            #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
             if (i < CIRCUITPY_DISPLAY_LIMIT) {
                 display_buses[i].bus_base.type = &mp_type_NoneType;
-            #if CIRCUITPY_OS_GETENV
             } else {
                 display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType;
-            #endif
             }
+            #else
+            display_buses[i].bus_base.type = &mp_type_NoneType;
+            #endif
             return DYN_DISPLAY_BUSES_ADR0(i);
         }
     }
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index d6eaaf597cb3..9d67fa32fd6a 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -101,7 +101,7 @@ typedef struct {
 
 extern primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT];
 extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT];
-#if CIRCUITPY_OS_GETENV
+#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
 extern primary_display_bus_t *display_buses_dyn;
 extern primary_display_t *displays_dyn;
 #endif
diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c
index da9b965f1524..dfb074cab8e7 100644
--- a/shared-module/epaperdisplay/EPaperDisplay.c
+++ b/shared-module/epaperdisplay/EPaperDisplay.c
@@ -20,7 +20,7 @@
 #include "supervisor/usb.h"
 #endif
 
-#if CIRCUITPY_OS_GETENV
+#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
 #include "shared-module/os/__init__.h"
 #endif
 
@@ -507,35 +507,43 @@ void epaperdisplay_epaperdisplay_collect_ptrs(epaperdisplay_epaperdisplay_obj_t
 size_t maybe_refresh_epaperdisplay(void) {
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
 
-    #if CIRCUITPY_OS_GETENV
+    #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     #endif
 
     for (uint8_t i = 0; i < max_num_displays; i++) {
+        #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
         if (i < CIRCUITPY_DISPLAY_LIMIT) {
             if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
                 displays[i].epaper_display.core.current_group != &circuitpython_splash) {
                 // Skip regular displays and those not showing the splash.
                 continue;
             }
-        #if CIRCUITPY_OS_GETENV
         } else {
             if (displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
                 displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.core.current_group != &circuitpython_splash) {
                 // Skip regular displays and those not showing the splash.
                 continue;
             }
-        #endif
         }
+        #else
+        if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type ||
+            displays[i].epaper_display.core.current_group != &circuitpython_splash) {
+            // Skip regular displays and those not showing the splash.
+            continue;
+        }
+        #endif
 
         epaperdisplay_epaperdisplay_obj_t *display;
+        #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
         if (i < CIRCUITPY_DISPLAY_LIMIT) {
             display = &displays[i].epaper_display;
-        #if CIRCUITPY_OS_GETENV
         } else {
             display = &displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display;
-        #endif
         }
+        #else
+        display = &displays[i].epaper_display;
+        #endif
         size_t time_to_refresh = common_hal_epaperdisplay_epaperdisplay_get_time_to_refresh(display);
         if (time_to_refresh > 0) {
             return time_to_refresh;
diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c
index 29f23e1cfe8f..31a6282c2802 100644
--- a/supervisor/shared/web_workflow/web_workflow.c
+++ b/supervisor/shared/web_workflow/web_workflow.c
@@ -1563,7 +1563,7 @@ static bool supervisor_filesystem_access_could_block(void) {
     }
 
     mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
-    #if CIRCUITPY_OS_GETENV
+    #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
     (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
     #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
     #define DYN_DISPLAY_BUSES_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr)

From 68e3532291946f98b972d5436156aec0b16bacf2 Mon Sep 17 00:00:00 2001
From: RetiredWizard <github@retiredwizard.com>
Date: Sun, 23 Mar 2025 14:15:59 -0400
Subject: [PATCH 14/14] Cleanup commented code

---
 shared-module/displayio/__init__.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index da6bb3799d99..ed324e6c7f42 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -471,7 +471,6 @@ primary_display_t *allocate_display(void) {
     for (uint8_t i = 0; i < max_num_displays; i++) {
         if (!is_display_active(DYN_DISPLAYS_ADR(i, display_base))) {
             // Clear this memory so it is in a known state before init.
-//            memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i)));
             memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0]));
             // Default to None so that it works as board.DISPLAY.
             #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
@@ -502,7 +501,6 @@ primary_display_bus_t *allocate_display_bus(void) {
         mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
         if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) {
             // Clear this memory so it is in a known state before init.
-//            memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(DYN_DISPLAY_BUSES(i)));
             memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(display_buses[0]));
             #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
             if (i < CIRCUITPY_DISPLAY_LIMIT) {