Index: firmware/font.c
===================================================================
--- firmware/font.c	(revision 27742)
+++ firmware/font.c	(working copy)
@@ -28,6 +28,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include "inttypes.h"
 #include "lcd.h"
 #include "font.h"
@@ -57,7 +58,6 @@
 #define FONT_HEADER_SIZE 36
 #endif
 
-
 #ifndef BOOTLOADER
 /* Font cache includes */
 #include "font_cache.h"
@@ -586,9 +586,12 @@
     unsigned short ch;
     unsigned char tmp[2];
 
+    if ( p->_char_code == 0xffff )
+        return;
+    
     ch = p->_char_code + pf->firstchar;
 
-    if (ch != 0xffff && cache_fd >= 0) {
+    if ( cache_fd >= 0) {
         tmp[0] = ch >> 8;
         tmp[1] = ch & 0xff;
         if (write(cache_fd, tmp, 2) != 2) {
@@ -625,28 +628,73 @@
     return;
 }
 
+static int ushortcmp(const void *a, const void *b)
+{
+    return ((int)(*(unsigned short*)a - *(unsigned short*)b));
+}
 static void glyph_cache_load(struct font* pf)
 {
+
+#define MAX_SORT 256
     if (pf->fd >= 0) {
         int fd;
+        int i, size;
         unsigned char tmp[2];
         unsigned short ch;
         char path[MAX_PATH];
+        unsigned short glyphs[MAX_SORT];
+        unsigned short glyphs_lru_order[MAX_SORT];
+        int glyph_file_skip=0, glyph_file_size=0;
+        
+        int sort_size = pf->cache._capacity;        
+        if ( sort_size > MAX_SORT )
+             sort_size = MAX_SORT;
 
         fd = open(get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE,
                                      path, sizeof(path)), O_RDONLY|O_BINARY);
         if (fd >= 0) {
+            
+            /* only read what fits */
+            glyph_file_size = filesize( fd );
+            if ( glyph_file_size > 2*pf->cache._capacity ) {
+                glyph_file_skip = glyph_file_size - 2*pf->cache._capacity;
+                lseek( fd, glyph_file_skip, SEEK_SET );
+            }
 
-            while (read(fd, tmp, 2) == 2) {
-                ch = (tmp[0] << 8) | tmp[1];
-                font_get_bits(pf, ch);
+            while(1) {
+
+                for ( size = 0;
+                      read( fd, tmp, 2 ) == 2 && size < sort_size;
+                      size++ ) 
+                {
+                    glyphs[size] = (tmp[0] << 8) | tmp[1];
+                    glyphs_lru_order[size] = glyphs[size];
+                }
+                
+                /* sort glyphs array to make sector cache happy */
+                qsort((void *)glyphs, size, sizeof(unsigned short), 
+                      ushortcmp );
+
+                /* load font bitmaps */
+                i = 0;
+                font_get_bits(pf, glyphs[i]);
+                for ( i = 1; i < size ; i++) {
+                     if ( glyphs[i] != glyphs[i-1] )
+                         font_get_bits(pf, glyphs[i]);
+                }
+                
+                /* redo to fix lru order */
+                for ( i = 0; i < size ; i++)
+                    font_get_bits(pf, glyphs_lru_order[i]);
+
+                if ( size < sort_size )
+                    break;
             }
 
             close(fd);
         } else {
             /* load latin1 chars into cache */
-            ch = 256;
-            while (ch-- > 32)
+            for ( ch = 32 ; ch < 256 ; ch++ );
                 font_get_bits(pf, ch);
         }
     }
