From 259cf1b0b2794f119a2a776be577567982d4e398 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Wed, 18 Oct 2017 23:16:14 -0500
Subject: [PATCH 1/3] BQ enables this in the config. Remove here

---
 Marlin/Conditionals_LCD.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Marlin/Conditionals_LCD.h b/Marlin/Conditionals_LCD.h
index b5b476a60d0..8dd2ed1b776 100644
--- a/Marlin/Conditionals_LCD.h
+++ b/Marlin/Conditionals_LCD.h
@@ -62,7 +62,6 @@
   #elif ENABLED(BQ_LCD_SMART_CONTROLLER)
 
     #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
-    #define LONG_FILENAME_HOST_SUPPORT
 
   #elif ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
 

From 91c5c2538a6cdbed437297cc59ef49455bdf2154 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Wed, 18 Oct 2017 20:26:19 -0500
Subject: [PATCH 2/3] Add SCROLL_LONG_FILENAMES advanced option

Based on #7637 by @marcio-ao
---
 .travis.yml                                   |   4 +-
 Marlin/Configuration_adv.h                    |   3 +
 Marlin/SdBaseFile.cpp                         |   2 +-
 Marlin/SdFatConfig.h                          | 210 +++++++++---------
 .../AlephObjects/TAZ4/Configuration_adv.h     |   3 +
 .../Anet/A6/Configuration_adv.h               |   3 +
 .../Anet/A8/Configuration_adv.h               |   3 +
 .../BQ/Hephestos/Configuration_adv.h          |   3 +
 .../BQ/Hephestos_2/Configuration_adv.h        |   3 +
 .../BQ/WITBOX/Configuration_adv.h             |   3 +
 .../Cartesio/Configuration_adv.h              |   3 +
 .../Creality/CR-10/Configuration_adv.h        |   3 +
 .../Felix/Configuration_adv.h                 |   3 +
 .../Folger Tech/i3-2020/Configuration_adv.h   |   3 +
 .../Infitary/i3-M508/Configuration_adv.h      |   3 +
 .../Malyan/M150/Configuration_adv.h           |   3 +
 .../RigidBot/Configuration_adv.h              |   3 +
 .../SCARA/Configuration_adv.h                 |   3 +
 .../Sanguinololu/Configuration_adv.h          |   3 +
 .../TinyBoy2/Configuration_adv.h              |   3 +
 .../Velleman/K8200/Configuration_adv.h        |   3 +
 .../Velleman/K8400/Configuration_adv.h        |   3 +
 .../FLSUN/auto_calibrate/Configuration_adv.h  |   3 +
 .../FLSUN/kossel_mini/Configuration_adv.h     |   3 +
 .../delta/generic/Configuration_adv.h         |   3 +
 .../delta/kossel_mini/Configuration_adv.h     |   3 +
 .../delta/kossel_pro/Configuration_adv.h      |   3 +
 .../delta/kossel_xl/Configuration_adv.h       |   3 +
 .../gCreate/gMax1.5+/Configuration_adv.h      |   3 +
 .../makibox/Configuration_adv.h               |   3 +
 .../tvrrug/Round2/Configuration_adv.h         |   3 +
 .../wt150/Configuration_adv.h                 |   3 +
 Marlin/ultralcd.cpp                           |  21 +-
 Marlin/ultralcd_impl_DOGM.h                   |  29 ++-
 Marlin/ultralcd_impl_HD44780.h                |  31 ++-
 35 files changed, 267 insertions(+), 117 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 93a365a7210..5b5eab496ca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -252,7 +252,7 @@ script:
   #
   - restore_configs
   - opt_enable G3D_PANEL SDSUPPORT
-  - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING
+  - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES
   - opt_set_adv SDSORT_GCODE true
   - opt_set_adv SDSORT_USES_RAM true
   - opt_set_adv SDSORT_USES_STACK true
@@ -263,7 +263,7 @@ script:
   #
   - restore_configs
   - opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT
-  - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING
+  - opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES
   - build_marlin
   #
   # REPRAPWORLD_KEYPAD
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index ead3cf298d9..9215e30085f 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/SdBaseFile.cpp b/Marlin/SdBaseFile.cpp
index 95fc2b62b6a..0511994e241 100644
--- a/Marlin/SdBaseFile.cpp
+++ b/Marlin/SdBaseFile.cpp
@@ -1142,7 +1142,7 @@ int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
       vfat_t* VFAT = (vfat_t*)dir;
       // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
       if (VFAT->firstClusterLow == 0 && (VFAT->sequenceNumber & 0x1F) > 0 && (VFAT->sequenceNumber & 0x1F) <= MAX_VFAT_ENTRIES) {
-        // TODO: Store the filename checksum to verify if a none-long filename aware system modified the file table.
+        // TODO: Store the filename checksum to verify if a long-filename-unaware system modified the file table.
         n = ((VFAT->sequenceNumber & 0x1F) - 1) * (FILENAME_LENGTH);
         for (uint8_t i = 0; i < FILENAME_LENGTH; i++)
           longFilename[n + i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i - 5] : VFAT->name3[i - 11];
diff --git a/Marlin/SdFatConfig.h b/Marlin/SdFatConfig.h
index d3406a0282d..9305a0f110d 100644
--- a/Marlin/SdFatConfig.h
+++ b/Marlin/SdFatConfig.h
@@ -21,114 +21,126 @@
  */
 
 /**
+ * SdFatConfig.h
  * Arduino SdFat Library
  * Copyright (C) 2009 by William Greiman
  *
  * This file is part of the Arduino Sd2Card Library
  */
+
+#ifndef _SDFATCONFIG_H_
+#define _SDFATCONFIG_H_
+
+#include "MarlinConfig.h"
+
+//------------------------------------------------------------------------------
+
 /**
- * \file
- * \brief configuration definitions
+ * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
+ *
+ * Using multiple cards costs 400 - 500  bytes of flash.
+ *
+ * Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
  */
-#include "Marlin.h"
-#if ENABLED(SDSUPPORT)
+#define USE_MULTIPLE_CARDS 0
 
-#ifndef SdFatConfig_h
-  #define SdFatConfig_h
-  #include <stdint.h>
-  //------------------------------------------------------------------------------
-  /**
-  * To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
-  *
-  * Using multiple cards costs 400 - 500  bytes of flash.
-  *
-  * Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
-  */
-  #define USE_MULTIPLE_CARDS 0
-  //------------------------------------------------------------------------------
-  /**
-  * Call flush for endl if ENDL_CALLS_FLUSH is nonzero
-  *
-  * The standard for iostreams is to call flush.  This is very costly for
-  * SdFat.  Each call to flush causes 2048 bytes of I/O to the SD.
-  *
-  * SdFat has a single 512 byte buffer for SD I/O so it must write the current
-  * data block to the SD, read the directory block from the SD, update the
-  * directory entry, write the directory block to the SD and read the data
-  * block back into the buffer.
-  *
-  * The SD flash memory controller is not designed for this many rewrites
-  * so performance may be reduced by more than a factor of 100.
-  *
-  * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
-  * all data to be written to the SD.
-  */
-  #define ENDL_CALLS_FLUSH 0
-  //------------------------------------------------------------------------------
-  /**
-  * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero
-  */
-  #define ALLOW_DEPRECATED_FUNCTIONS 1
-  //------------------------------------------------------------------------------
-  /**
-  * Allow FAT12 volumes if FAT12_SUPPORT is nonzero.
-  * FAT12 has not been well tested.
-  */
-  #define FAT12_SUPPORT 0
-  //------------------------------------------------------------------------------
-  /**
-  * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64)
-  * or 6 (F_CPU/128).
-  */
-  #define SPI_SD_INIT_RATE 5
-  //------------------------------------------------------------------------------
-  /**
-  * Set the SS pin high for hardware SPI.  If SS is chip select for another SPI
-  * device this will disable that device during the SD init phase.
-  */
-  #define SET_SPI_SS_HIGH 1
-  //------------------------------------------------------------------------------
-  /**
-  * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos.
-  * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
-  *
-  * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
-  * on Mega Arduinos.  Software SPI works well with GPS Shield V1.1
-  * but many SD cards will fail with GPS Shield V1.0.
-  */
-  #define MEGA_SOFT_SPI 0
-  //------------------------------------------------------------------------------
-  /**
-  * Set USE_SOFTWARE_SPI nonzero to always use software SPI.
-  */
-  #define USE_SOFTWARE_SPI 0
-  // define software SPI pins so Mega can use unmodified 168/328 shields
-  /** Software SPI chip select pin for the SD */
-  #define SOFT_SPI_CS_PIN 10
-  /** Software SPI Master Out Slave In pin */
-  #define SOFT_SPI_MOSI_PIN 11
-  /** Software SPI Master In Slave Out pin */
-  #define SOFT_SPI_MISO_PIN 12
-  /** Software SPI Clock pin */
-  #define SOFT_SPI_SCK_PIN 13
-  //------------------------------------------------------------------------------
-  /**
-  * The __cxa_pure_virtual function is an error handler that is invoked when
-  * a pure virtual function is called.
-  */
-  #define USE_CXA_PURE_VIRTUAL 1
+//------------------------------------------------------------------------------
 
-  /** Number of UTF-16 characters per entry */
-  #define FILENAME_LENGTH 13
+/**
+ * Call flush for endl if ENDL_CALLS_FLUSH is nonzero
+ *
+ * The standard for iostreams is to call flush.  This is very costly for
+ * SdFat.  Each call to flush causes 2048 bytes of I/O to the SD.
+ *
+ * SdFat has a single 512 byte buffer for SD I/O so it must write the current
+ * data block to the SD, read the directory block from the SD, update the
+ * directory entry, write the directory block to the SD and read the data
+ * block back into the buffer.
+ *
+ * The SD flash memory controller is not designed for this many rewrites
+ * so performance may be reduced by more than a factor of 100.
+ *
+ * If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
+ * all data to be written to the SD.
+ */
+#define ENDL_CALLS_FLUSH 0
 
-  /**
-  * Defines for long (vfat) filenames
-  */
-  /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
+//------------------------------------------------------------------------------
+
+/**
+ * Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero
+ */
+#define ALLOW_DEPRECATED_FUNCTIONS 1
+
+//------------------------------------------------------------------------------
+
+/**
+ * Allow FAT12 volumes if FAT12_SUPPORT is nonzero.
+ * FAT12 has not been well tested.
+ */
+#define FAT12_SUPPORT 0
+
+//------------------------------------------------------------------------------
+
+/**
+ * SPI init rate for SD initialization commands. Must be 5 (F_CPU/64)
+ * or 6 (F_CPU/128).
+ */
+#define SPI_SD_INIT_RATE 5
+
+//------------------------------------------------------------------------------
+
+/**
+ * Set the SS pin high for hardware SPI.  If SS is chip select for another SPI
+ * device this will disable that device during the SD init phase.
+ */
+#define SET_SPI_SS_HIGH 1
+
+//------------------------------------------------------------------------------
+
+/**
+ * Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos.
+ * Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
+ *
+ * MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
+ * on Mega Arduinos.  Software SPI works well with GPS Shield V1.1
+ * but many SD cards will fail with GPS Shield V1.0.
+ */
+#define MEGA_SOFT_SPI 0
+
+//------------------------------------------------------------------------------
+
+// Set USE_SOFTWARE_SPI nonzero to ALWAYS use Software SPI.
+#define USE_SOFTWARE_SPI 0
+
+// Define software SPI pins so Mega can use unmodified 168/328 shields
+#define SOFT_SPI_CS_PIN   10 // Software SPI chip select pin for the SD
+#define SOFT_SPI_MOSI_PIN 11 // Software SPI Master Out Slave In pin
+#define SOFT_SPI_MISO_PIN 12 // Software SPI Master In Slave Out pin
+#define SOFT_SPI_SCK_PIN  13 // Software SPI Clock pin
+
+//------------------------------------------------------------------------------
+
+/**
+ * The __cxa_pure_virtual function is an error handler that is invoked when
+ * a pure virtual function is called.
+ */
+#define USE_CXA_PURE_VIRTUAL 1
+
+/**
+ * Defines for 8.3 and long (vfat) filenames
+ */
+
+#define FILENAME_LENGTH 13 // Number of UTF-16 characters per entry
+
+// Number of VFAT entries used. Each entry has 13 UTF-16 characters
+#if ENABLED(SCROLL_LONG_FILENAMES)
+  #define MAX_VFAT_ENTRIES (5)
+#else
   #define MAX_VFAT_ENTRIES (2)
-  /** Total size of the buffer used to store the long filenames */
-  #define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1)
-#endif  // SdFatConfig_h
-
-
 #endif
+
+// Total bytes needed to store a single long filename
+#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * MAX_VFAT_ENTRIES + 1)
+
+#endif // _SDFATCONFIG_H_
diff --git a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
index 7c2ca4db241..b49679344c2 100644
--- a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
+++ b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Anet/A6/Configuration_adv.h b/Marlin/example_configurations/Anet/A6/Configuration_adv.h
index 3ccb25fca2d..57cb8229e0f 100644
--- a/Marlin/example_configurations/Anet/A6/Configuration_adv.h
+++ b/Marlin/example_configurations/Anet/A6/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Anet/A8/Configuration_adv.h b/Marlin/example_configurations/Anet/A8/Configuration_adv.h
index e29c3d1ada7..0e886af7acb 100644
--- a/Marlin/example_configurations/Anet/A8/Configuration_adv.h
+++ b/Marlin/example_configurations/Anet/A8/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h b/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
index fcb13988a87..e2364def06d 100644
--- a/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
+++ b/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h b/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
index a08dde0640e..92b099c05da 100644
--- a/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
+++ b/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
@@ -538,6 +538,9 @@
   // This allows hosts to request long names for files and folders with M33
   #define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h b/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
index fcb13988a87..e2364def06d 100644
--- a/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
+++ b/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Cartesio/Configuration_adv.h b/Marlin/example_configurations/Cartesio/Configuration_adv.h
index 2cff3ea7c03..df40a384b67 100644
--- a/Marlin/example_configurations/Cartesio/Configuration_adv.h
+++ b/Marlin/example_configurations/Cartesio/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h b/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
index 0d5d71f732a..062cae71325 100755
--- a/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
+++ b/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Felix/Configuration_adv.h b/Marlin/example_configurations/Felix/Configuration_adv.h
index 9fe995f1659..28bb1d013ca 100644
--- a/Marlin/example_configurations/Felix/Configuration_adv.h
+++ b/Marlin/example_configurations/Felix/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h b/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h
index c12dd203de7..36bbe8cea4f 100644
--- a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h	
+++ b/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h	
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h b/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
index d802e208e54..29dc1689e06 100644
--- a/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
+++ b/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Malyan/M150/Configuration_adv.h b/Marlin/example_configurations/Malyan/M150/Configuration_adv.h
index 337b4ab739b..097990bde86 100644
--- a/Marlin/example_configurations/Malyan/M150/Configuration_adv.h
+++ b/Marlin/example_configurations/Malyan/M150/Configuration_adv.h
@@ -538,6 +538,9 @@
   // This allows hosts to request long names for files and folders with M33
   #define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/RigidBot/Configuration_adv.h b/Marlin/example_configurations/RigidBot/Configuration_adv.h
index 73bfa6634b8..8a48e518410 100644
--- a/Marlin/example_configurations/RigidBot/Configuration_adv.h
+++ b/Marlin/example_configurations/RigidBot/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/SCARA/Configuration_adv.h b/Marlin/example_configurations/SCARA/Configuration_adv.h
index 66a9e5bf9e8..16c2a776a0e 100644
--- a/Marlin/example_configurations/SCARA/Configuration_adv.h
+++ b/Marlin/example_configurations/SCARA/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Sanguinololu/Configuration_adv.h b/Marlin/example_configurations/Sanguinololu/Configuration_adv.h
index 4f6d2eac585..9e03756a637 100644
--- a/Marlin/example_configurations/Sanguinololu/Configuration_adv.h
+++ b/Marlin/example_configurations/Sanguinololu/Configuration_adv.h
@@ -530,6 +530,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
index b2cf69d8468..249e3a5c7d4 100644
--- a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
+++ b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h b/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
index 10526d4e318..7596d3858d4 100644
--- a/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
+++ b/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
@@ -551,6 +551,9 @@
   // This allows hosts to request long names for files and folders with M33
   #define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h b/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
index 0f1ec54f8fa..d9879b8375e 100644
--- a/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
+++ b/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
index 52df91af97d..2844945fc4b 100644
--- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
@@ -543,6 +543,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
index 5df21188115..d89c6e4562d 100644
--- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
@@ -543,6 +543,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/delta/generic/Configuration_adv.h b/Marlin/example_configurations/delta/generic/Configuration_adv.h
index 5df21188115..d89c6e4562d 100644
--- a/Marlin/example_configurations/delta/generic/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/generic/Configuration_adv.h
@@ -543,6 +543,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
index 5df21188115..d89c6e4562d 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
@@ -543,6 +543,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
index 4efd3365117..d537652e89a 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
@@ -548,6 +548,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
index 613b37119e8..82956af2580 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
@@ -543,6 +543,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
index ab577d65ee3..0aad89a4c4e 100644
--- a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
+++ b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h
index b126f465b8e..91bf58d557d 100644
--- a/Marlin/example_configurations/makibox/Configuration_adv.h
+++ b/Marlin/example_configurations/makibox/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
index d64db53ad0b..61d057cc75c 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/example_configurations/wt150/Configuration_adv.h b/Marlin/example_configurations/wt150/Configuration_adv.h
index 17a51b0bb10..0daac93ff78 100644
--- a/Marlin/example_configurations/wt150/Configuration_adv.h
+++ b/Marlin/example_configurations/wt150/Configuration_adv.h
@@ -541,6 +541,9 @@
   // This allows hosts to request long names for files and folders with M33
   //#define LONG_FILENAME_HOST_SUPPORT
 
+  // Enable this option to scroll long filenames in the SD card menu
+  //#define SCROLL_LONG_FILENAMES
+
   // This option allows you to abort SD printing when any endstop is triggered.
   // This feature must be enabled with "M540 S1" or from the LCD menu.
   // To have any effect, endstops must be enabled during SD printing.
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index a13055b7247..b4e9eae0199 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -77,13 +77,18 @@ int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_spe
   #endif
 #endif
 
-uint8_t lcd_status_message_level;
+uint8_t lcd_status_update_delay = 1, // First update one loop delayed
+        lcd_status_message_level;    // Higher level blocks lower level
 char lcd_status_message[3 * (LCD_WIDTH) + 1] = WELCOME_MSG; // worst case is kana with up to 3*LCD_WIDTH+1
 
 #if ENABLED(STATUS_MESSAGE_SCROLLING)
   uint8_t status_scroll_pos = 0;
 #endif
 
+#if ENABLED(SCROLL_LONG_FILENAMES)
+  uint8_t filename_scroll_pos, filename_scroll_max, filename_scroll_hash;
+#endif
+
 #if ENABLED(DOGLCD)
   #include "ultralcd_impl_DOGM.h"
   #include <U8glib.h>
@@ -4675,7 +4680,6 @@ void lcd_update() {
 
     // We arrive here every ~100ms when idling often enough.
     // Instead of tracking the changes simply redraw the Info Screen ~1 time a second.
-    static int8_t lcd_status_update_delay = 1; // first update one loop delayed
     if (
       #if ENABLED(ULTIPANEL)
         currentScreen == lcd_status_screen &&
@@ -4691,6 +4695,17 @@ void lcd_update() {
       lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
     }
 
+    #if ENABLED(SCROLL_LONG_FILENAMES)
+      // If scrolling of long file names is enabled and we are in the sd card menu,
+      // cause a refresh to occur until all the text has scrolled into view.
+      if (currentScreen == lcd_sdcard_menu && filename_scroll_pos < filename_scroll_max && !lcd_status_update_delay--) {
+        lcd_status_update_delay = 6;
+        lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
+        filename_scroll_pos++;
+        return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS;
+      }
+    #endif
+
     // then we want to use 1/2 of the time only.
     uint16_t bbr2 = planner.block_buffer_runtime() >> 1;
 
@@ -4775,7 +4790,7 @@ void lcd_update() {
   } // ELAPSED(ms, next_lcd_update_ms)
 }
 
-void pad_message_string() {
+inline void pad_message_string() {
   uint8_t i = 0, j = 0;
   char c;
   while ((c = lcd_status_message[i]) && j < LCD_WIDTH) {
diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h
index 886156ee1c2..6bf2c524aa4 100644
--- a/Marlin/ultralcd_impl_DOGM.h
+++ b/Marlin/ultralcd_impl_DOGM.h
@@ -934,19 +934,36 @@ static void lcd_implementation_status_screen() {
 
       if (!PAGE_CONTAINS(row_y1, row_y2)) return;
 
-      uint8_t n = LCD_WIDTH - (START_COL) - 1;
+      constexpr uint8_t maxlen = LCD_WIDTH - (START_COL) - 1;
+      const char *outstr = longFilename[0] ? longFilename : filename;
       if (longFilename[0]) {
-        filename = longFilename;
-        longFilename[n] = '\0'; // cutoff at screen edge
+        #if ENABLED(SCROLL_LONG_FILENAMES)
+          if (isSelected) {
+            uint8_t name_hash = row;
+            for (uint8_t l = FILENAME_LENGTH; l--;)
+              name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ filename[l];  // rotate, xor
+            if (filename_scroll_hash != name_hash) {                            // If the hash changed...
+              filename_scroll_hash = name_hash;                                 // Save the new hash
+              filename_scroll_max = max(0, lcd_strlen(longFilename) - maxlen);  // Update the scroll limit
+              filename_scroll_pos = 0;                                          // Reset scroll to the start
+              lcd_status_update_delay = 8;                                      // Don't scroll right away
+            }
+            outstr += filename_scroll_pos;
+          }
+        #else
+          longFilename[maxlen] = '\0'; // cutoff at screen edge
+        #endif
       }
 
       if (isDir) lcd_print(LCD_STR_FOLDER[0]);
 
-      while (char c = *filename) {
+      char c;
+      uint8_t n = maxlen;
+      while (n && (c = *outstr)) {
         n -= lcd_print_and_count(c);
-        filename++;
+        ++outstr;
       }
-      while (n--) u8g.print(' ');
+      while (n) { --n; u8g.print(' '); }
     }
 
     #define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false)
diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h
index f1009697de1..057675226d1 100644
--- a/Marlin/ultralcd_impl_HD44780.h
+++ b/Marlin/ultralcd_impl_HD44780.h
@@ -988,18 +988,37 @@ static void lcd_implementation_status_screen() {
 
     static void lcd_implementation_drawmenu_sd(const bool sel, const uint8_t row, const char* const pstr, const char* filename, char* const longFilename, const uint8_t concat, const char post_char) {
       UNUSED(pstr);
-      uint8_t n = LCD_WIDTH - concat;
       lcd.setCursor(0, row);
       lcd.print(sel ? '>' : ' ');
+
+      uint8_t n = LCD_WIDTH - concat;
+      const char *outstr = longFilename[0] ? longFilename : filename;
       if (longFilename[0]) {
-        filename = longFilename;
-        longFilename[n] = '\0';
+        #if ENABLED(SCROLL_LONG_FILENAMES)
+          if (sel) {
+            uint8_t name_hash = row;
+            for (uint8_t l = FILENAME_LENGTH; l--;)
+              name_hash = ((name_hash << 1) | (name_hash >> 7)) ^ filename[l];  // rotate, xor
+            if (filename_scroll_hash != name_hash) {                            // If the hash changed...
+              filename_scroll_hash = name_hash;                                 // Save the new hash
+              filename_scroll_max = max(0, lcd_strlen(longFilename) - n);  // Update the scroll limit
+              filename_scroll_pos = 0;                                          // Reset scroll to the start
+              lcd_status_update_delay = 8;                                      // Don't scroll right away
+            }
+            outstr += filename_scroll_pos;
+          }
+        #else
+          longFilename[n] = '\0'; // cutoff at screen edge
+        #endif
       }
-      while (char c = *filename) {
+
+      char c;
+      while (n && (c = *outstr)) {
         n -= charset_mapper(c);
-        filename++;
+        ++outstr;
       }
-      while (n--) lcd.write(' ');
+      while (n) { --n; lcd.write(' '); }
+
       lcd.print(post_char);
     }
 

From a7398a0459973abd0056f0c2051d1fae8375e67c Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Wed, 18 Oct 2017 20:38:18 -0500
Subject: [PATCH 3/3] Prevent SDCARD_SORT_ALPHA from exploding

---
 Marlin/Configuration_adv.h                             |  2 ++
 Marlin/SanityCheck.h                                   | 10 ++++++++++
 Marlin/cardreader.h                                    |  2 +-
 .../AlephObjects/TAZ4/Configuration_adv.h              |  2 ++
 .../example_configurations/Anet/A6/Configuration_adv.h |  4 +++-
 .../example_configurations/Anet/A8/Configuration_adv.h |  2 ++
 .../BQ/Hephestos/Configuration_adv.h                   |  2 ++
 .../BQ/Hephestos_2/Configuration_adv.h                 |  2 ++
 .../BQ/WITBOX/Configuration_adv.h                      |  2 ++
 .../Cartesio/Configuration_adv.h                       |  2 ++
 .../Creality/CR-10/Configuration_adv.h                 | 10 ++++++----
 .../example_configurations/Felix/Configuration_adv.h   |  2 ++
 .../Folger Tech/i3-2020/Configuration_adv.h            | 10 ++++++----
 .../Infitary/i3-M508/Configuration_adv.h               |  2 ++
 .../Malyan/M150/Configuration_adv.h                    |  2 ++
 .../RigidBot/Configuration_adv.h                       |  2 ++
 .../example_configurations/SCARA/Configuration_adv.h   |  2 ++
 .../Sanguinololu/Configuration_adv.h                   |  2 ++
 .../TinyBoy2/Configuration_adv.h                       |  2 ++
 .../Velleman/K8200/Configuration_adv.h                 |  2 ++
 .../Velleman/K8400/Configuration_adv.h                 |  2 ++
 .../delta/FLSUN/auto_calibrate/Configuration_adv.h     | 10 ++++++----
 .../delta/FLSUN/kossel_mini/Configuration_adv.h        |  2 ++
 .../delta/generic/Configuration_adv.h                  |  2 ++
 .../delta/kossel_mini/Configuration_adv.h              |  2 ++
 .../delta/kossel_pro/Configuration_adv.h               |  2 ++
 .../delta/kossel_xl/Configuration_adv.h                |  2 ++
 .../gCreate/gMax1.5+/Configuration_adv.h               | 10 ++++++----
 .../example_configurations/makibox/Configuration_adv.h |  2 ++
 .../tvrrug/Round2/Configuration_adv.h                  |  2 ++
 .../example_configurations/wt150/Configuration_adv.h   |  2 ++
 31 files changed, 86 insertions(+), 18 deletions(-)

diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 9215e30085f..4101e2b3d41 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 22b7340cf79..0c1b6780302 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -301,6 +301,16 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE,
       #error "SDSORT_CACHE_NAMES requires SDSORT_USES_RAM (which reads the directory into RAM)."
     #endif
   #endif
+
+  #if ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM)
+    #if SDSORT_CACHE_VFATS < 2
+      #error "SDSORT_CACHE_VFATS must be 2 or greater!"
+    #elif SDSORT_CACHE_VFATS > MAX_VFAT_ENTRIES
+      #undef SDSORT_CACHE_VFATS
+      #define SDSORT_CACHE_VFATS MAX_VFAT_ENTRIES
+      #warning "SDSORT_CACHE_VFATS was reduced to MAX_VFAT_ENTRIES!"
+    #endif
+  #endif
 #endif
 
 /**
diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h
index 75674a8e599..60930c4428e 100644
--- a/Marlin/cardreader.h
+++ b/Marlin/cardreader.h
@@ -120,7 +120,7 @@ private:
           char **sortshort, **sortnames;
         #else
           char sortshort[SDSORT_LIMIT][FILENAME_LENGTH];
-          char sortnames[SDSORT_LIMIT][LONG_FILENAME_LENGTH];
+          char sortnames[SDSORT_LIMIT][SDSORT_CACHE_VFATS * FILENAME_LENGTH + 1];
         #endif
       #elif DISABLED(SDSORT_USES_STACK)
         char sortnames[SDSORT_LIMIT][LONG_FILENAME_LENGTH];
diff --git a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
index b49679344c2..6908790505b 100644
--- a/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
+++ b/Marlin/example_configurations/AlephObjects/TAZ4/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Anet/A6/Configuration_adv.h b/Marlin/example_configurations/Anet/A6/Configuration_adv.h
index 57cb8229e0f..7214db0231f 100644
--- a/Marlin/example_configurations/Anet/A6/Configuration_adv.h
+++ b/Marlin/example_configurations/Anet/A6/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
@@ -607,7 +609,7 @@
  */
 //#define BABYSTEPPING
 #if ENABLED(BABYSTEPPING)
-  //#define BABYSTEP_XY            // Also enable X/Y Babystepping. Not supported on DELTA!
+  //#define BABYSTEP_XY              // Also enable X/Y Babystepping. Not supported on DELTA!
   #define BABYSTEP_INVERT_Z false    // Change if Z babysteps should go the other way
   #define BABYSTEP_MULTIPLICATOR 100 // Babysteps are very small. Increase for faster motion.
   //#define BABYSTEP_ZPROBE_OFFSET   // Enable to combine M851 and Babystepping
diff --git a/Marlin/example_configurations/Anet/A8/Configuration_adv.h b/Marlin/example_configurations/Anet/A8/Configuration_adv.h
index 0e886af7acb..7b1388d4248 100644
--- a/Marlin/example_configurations/Anet/A8/Configuration_adv.h
+++ b/Marlin/example_configurations/Anet/A8/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h b/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
index e2364def06d..110f447d898 100644
--- a/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
+++ b/Marlin/example_configurations/BQ/Hephestos/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h b/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
index 92b099c05da..e3d0a9cfc51 100644
--- a/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
+++ b/Marlin/example_configurations/BQ/Hephestos_2/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h b/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
index e2364def06d..110f447d898 100644
--- a/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
+++ b/Marlin/example_configurations/BQ/WITBOX/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Cartesio/Configuration_adv.h b/Marlin/example_configurations/Cartesio/Configuration_adv.h
index df40a384b67..806508974be 100644
--- a/Marlin/example_configurations/Cartesio/Configuration_adv.h
+++ b/Marlin/example_configurations/Cartesio/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h b/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
index 062cae71325..e13ff4de2db 100755
--- a/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
+++ b/Marlin/example_configurations/Creality/CR-10/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES true   // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
@@ -607,10 +609,10 @@
  */
 #define BABYSTEPPING
 #if ENABLED(BABYSTEPPING)
-  //#define BABYSTEP_XY            // Also enable X/Y Babystepping. Not supported on DELTA!
-  #define BABYSTEP_INVERT_Z false  // Change if Z babysteps should go the other way
-  #define BABYSTEP_MULTIPLICATOR 10 // Babysteps are very small. Increase for faster motion.
-  //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping
+  //#define BABYSTEP_XY              // Also enable X/Y Babystepping. Not supported on DELTA!
+  #define BABYSTEP_INVERT_Z false    // Change if Z babysteps should go the other way
+  #define BABYSTEP_MULTIPLICATOR  10 // Babysteps are very small. Increase for faster motion.
+  //#define BABYSTEP_ZPROBE_OFFSET   // Enable to combine M851 and Babystepping
   #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
   #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
                                         // Note: Extra time may be added to mitigate controller latency.
diff --git a/Marlin/example_configurations/Felix/Configuration_adv.h b/Marlin/example_configurations/Felix/Configuration_adv.h
index 28bb1d013ca..650039ae1eb 100644
--- a/Marlin/example_configurations/Felix/Configuration_adv.h
+++ b/Marlin/example_configurations/Felix/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h b/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h
index 36bbe8cea4f..ae58b4d4b4c 100644
--- a/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h	
+++ b/Marlin/example_configurations/Folger Tech/i3-2020/Configuration_adv.h	
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
@@ -607,10 +609,10 @@
  */
 #define BABYSTEPPING
 #if ENABLED(BABYSTEPPING)
-  //#define BABYSTEP_XY            // Also enable X/Y Babystepping. Not supported on DELTA!
-  #define BABYSTEP_INVERT_Z false  // Change if Z babysteps should go the other way
-  #define BABYSTEP_MULTIPLICATOR 2 // Babysteps are very small. Increase for faster motion.
-  //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping
+  //#define BABYSTEP_XY              // Also enable X/Y Babystepping. Not supported on DELTA!
+  #define BABYSTEP_INVERT_Z false    // Change if Z babysteps should go the other way
+  #define BABYSTEP_MULTIPLICATOR   2 // Babysteps are very small. Increase for faster motion.
+  //#define BABYSTEP_ZPROBE_OFFSET   // Enable to combine M851 and Babystepping
   #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
   #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
                                         // Note: Extra time may be added to mitigate controller latency.
diff --git a/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h b/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
index 29dc1689e06..07f67fd6c2f 100644
--- a/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
+++ b/Marlin/example_configurations/Infitary/i3-M508/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Malyan/M150/Configuration_adv.h b/Marlin/example_configurations/Malyan/M150/Configuration_adv.h
index 097990bde86..1402ee599ba 100644
--- a/Marlin/example_configurations/Malyan/M150/Configuration_adv.h
+++ b/Marlin/example_configurations/Malyan/M150/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/RigidBot/Configuration_adv.h b/Marlin/example_configurations/RigidBot/Configuration_adv.h
index 8a48e518410..112c0bec960 100644
--- a/Marlin/example_configurations/RigidBot/Configuration_adv.h
+++ b/Marlin/example_configurations/RigidBot/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/SCARA/Configuration_adv.h b/Marlin/example_configurations/SCARA/Configuration_adv.h
index 16c2a776a0e..63bee9e1240 100644
--- a/Marlin/example_configurations/SCARA/Configuration_adv.h
+++ b/Marlin/example_configurations/SCARA/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Sanguinololu/Configuration_adv.h b/Marlin/example_configurations/Sanguinololu/Configuration_adv.h
index 9e03756a637..526984b2567 100644
--- a/Marlin/example_configurations/Sanguinololu/Configuration_adv.h
+++ b/Marlin/example_configurations/Sanguinololu/Configuration_adv.h
@@ -506,6 +506,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
index 249e3a5c7d4..b2f921e5ccd 100644
--- a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
+++ b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h b/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
index 7596d3858d4..5956adfbee9 100644
--- a/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
+++ b/Marlin/example_configurations/Velleman/K8200/Configuration_adv.h
@@ -530,6 +530,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h b/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
index d9879b8375e..db81334d49a 100644
--- a/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
+++ b/Marlin/example_configurations/Velleman/K8400/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
index 2844945fc4b..2356a54afc1 100644
--- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
@@ -519,6 +519,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
@@ -609,10 +611,10 @@
  */
 //#define BABYSTEPPING
 #if ENABLED(BABYSTEPPING)
-  //#define BABYSTEP_XY            // Also enable X/Y Babystepping. Not supported on DELTA!
-  #define BABYSTEP_INVERT_Z false  // Change if Z babysteps should go the other way
-  #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion.
-  //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping
+  //#define BABYSTEP_XY              // Also enable X/Y Babystepping. Not supported on DELTA!
+  #define BABYSTEP_INVERT_Z false    // Change if Z babysteps should go the other way
+  #define BABYSTEP_MULTIPLICATOR   1 // Babysteps are very small. Increase for faster motion.
+  //#define BABYSTEP_ZPROBE_OFFSET   // Enable to combine M851 and Babystepping
   //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
   #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
                                         // Note: Extra time may be added to mitigate controller latency.
diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
index d89c6e4562d..c26f6f35ccc 100644
--- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
@@ -519,6 +519,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/delta/generic/Configuration_adv.h b/Marlin/example_configurations/delta/generic/Configuration_adv.h
index d89c6e4562d..c26f6f35ccc 100644
--- a/Marlin/example_configurations/delta/generic/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/generic/Configuration_adv.h
@@ -519,6 +519,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
index d89c6e4562d..c26f6f35ccc 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
@@ -519,6 +519,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
index d537652e89a..254d3b049f6 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
@@ -524,6 +524,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
index 82956af2580..1c79fb6f25e 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
@@ -519,6 +519,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
index 0aad89a4c4e..277edd6598c 100644
--- a/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
+++ b/Marlin/example_configurations/gCreate/gMax1.5+/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
@@ -607,10 +609,10 @@
  */
 #define BABYSTEPPING
 #if ENABLED(BABYSTEPPING)
-  //#define BABYSTEP_XY            // Also enable X/Y Babystepping. Not supported on DELTA!
-  #define BABYSTEP_INVERT_Z false  // Change if Z babysteps should go the other way
-  #define BABYSTEP_MULTIPLICATOR 1 // Babysteps are very small. Increase for faster motion.
-  //#define BABYSTEP_ZPROBE_OFFSET // Enable to combine M851 and Babystepping
+  //#define BABYSTEP_XY              // Also enable X/Y Babystepping. Not supported on DELTA!
+  #define BABYSTEP_INVERT_Z false    // Change if Z babysteps should go the other way
+  #define BABYSTEP_MULTIPLICATOR   1 // Babysteps are very small. Increase for faster motion.
+  //#define BABYSTEP_ZPROBE_OFFSET   // Enable to combine M851 and Babystepping
   #define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
   #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
                                         // Note: Extra time may be added to mitigate controller latency.
diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h
index 91bf58d557d..560164eb93c 100644
--- a/Marlin/example_configurations/makibox/Configuration_adv.h
+++ b/Marlin/example_configurations/makibox/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
index 61d057cc75c..dd293430c22 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing
diff --git a/Marlin/example_configurations/wt150/Configuration_adv.h b/Marlin/example_configurations/wt150/Configuration_adv.h
index 0daac93ff78..d8cedff8dc0 100644
--- a/Marlin/example_configurations/wt150/Configuration_adv.h
+++ b/Marlin/example_configurations/wt150/Configuration_adv.h
@@ -517,6 +517,8 @@
     #define SDSORT_USES_STACK  false  // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
     #define SDSORT_CACHE_NAMES false  // Keep sorted items in RAM longer for speedy performance. Most expensive option.
     #define SDSORT_DYNAMIC_RAM false  // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
+    #define SDSORT_CACHE_VFATS 2      // Maximum number of 13-byte VFAT entries to use for sorting.
+                                      // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
   #endif
 
   // Show a progress bar on HD44780 LCDs for SD printing