diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java
index d078fe8..ab7d65f 100644
--- a/android/src/org/rockbox/RockboxService.java
+++ b/android/src/org/rockbox/RockboxService.java
@@ -45,6 +45,7 @@ import android.os.Bundle;
 import android.os.Environment;
 import android.os.IBinder;
 import android.os.ResultReceiver;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.KeyEvent;
 
@@ -91,7 +92,13 @@ public class RockboxService extends Service
          * android, so we can't just create a new one */
     	return instance;
     }
-    
+
+    public int[] getResolution()
+    {
+        DisplayMetrics metrics = getResources().getDisplayMetrics();
+        return new int[] {metrics.widthPixels, metrics.heightPixels};
+    }
+
     public boolean isRockboxRunning()
     {
         return rockbox_running;
diff --git a/apps/bitmaps/native/SOURCES b/apps/bitmaps/native/SOURCES
index 9ce7d89..ca3647b 100644
--- a/apps/bitmaps/native/SOURCES
+++ b/apps/bitmaps/native/SOURCES
@@ -1,5 +1,13 @@
 #ifdef HAVE_LCD_BITMAP
 
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+/* This is a hack to prevent buildtime errors popping up */
+#undef LCD_WIDTH
+#undef LCD_HEIGHT
+#define LCD_WIDTH 0
+#define LCD_HEIGHT 0
+#endif
+
 /* Rockbox logo */
 #if (LCD_DEPTH == 1)
 #if (LCD_WIDTH == 160)
@@ -9,6 +17,12 @@ rockboxlogo.128x42x1.bmp
 #else
 rockboxlogo.112x30x1.bmp
 #endif
+#elif defined(HAVE_DYNAMIC_LCD_SIZE)
+/* Currently only one screen size is supported.
+ * Ideally, we should compile in multiple logos and choose the correct one
+ * at runtime (and optionally discard the others using INIT_ATTR).
+ */
+rockboxlogo.320x98x16.bmp
 #elif (LCD_WIDTH == 128) && (LCD_DEPTH == 2)
 rockboxlogo.128x42x2.bmp
 #elif (LCD_WIDTH == 128) && (LCD_DEPTH == 16)
@@ -41,7 +55,9 @@ rockboxlogo.640x198x16.bmp
 
 /* USB logo */
 #ifdef HAVE_LCD_COLOR
-#if LCD_WIDTH > 176
+#if defined(HAVE_DYNAMIC_LCD_SIZE)
+usblogo.176x48x16.bmp
+#elif LCD_WIDTH > 176
 usblogo.176x48x16.bmp
 #elif LCD_WIDTH >= 128
 usblogo.128x37x16.bmp
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 828b881..ea068f3 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -345,8 +345,13 @@ static bool dbg_buffering_thread(void)
             screens[i].putsf(0, line++, "alloc: %6ld/%ld", audio_filebufused(),
                             (long) filebuflen);
 
-#if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
-            if (screens[i].lcdheight > 80)
+            if ((LCD_HEIGHT > 80 ||
+#ifdef HAVE_REMOTE_LCD
+                LCD_REMOTE_HEIGHT > 80
+#else
+                0
+#endif
+                ) && screens[i].lcdheight > 80)
             {
                 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
                                    filebuflen, 0, audio_filebufused(), HORIZONTAL);
@@ -359,19 +364,22 @@ static bool dbg_buffering_thread(void)
                                    filebuflen, 0, (long)d.buffered_data, HORIZONTAL);
                 line++;
             }
-#endif
 
             screens[i].putsf(0, line++, "usefl: %6ld/%ld", (long)(d.useful_data),
                                                        (long)filebuflen);
 
-#if LCD_HEIGHT > 80 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_HEIGHT > 80)
-            if (screens[i].lcdheight > 80)
+            if ((LCD_HEIGHT > 80 ||
+#ifdef HAVE_REMOTE_LCD
+                LCD_REMOTE_HEIGHT > 80
+#else
+                0
+#endif
+                ) && screens[i].lcdheight > 80)
             {
                 gui_scrollbar_draw(&screens[i],0, line*8, screens[i].lcdwidth, 6,
                                    filebuflen, 0, d.useful_data, HORIZONTAL);
                 line++;
             }
-#endif
 
             screens[i].putsf(0, line++, "data_rem: %ld", (long)d.data_rem);
 
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 3e04bea..fdaa160 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -116,6 +116,14 @@ bool skin_backdrops_preload(void)
                 char* temp = filename+2; /* slightly hacky to get a buffer */
                 size_t size = sizeof(backdrops[i].name) - 2;
                 snprintf(temp, size, BACKDROP_DIR "/%s.bmp", global_settings.backdrop_file);
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+                if (!file_exists(temp))
+                {
+                    snprintf(temp, size, BACKDROP_DIR"/%s.%dx%dx%d.bmp",
+                         global_settings.backdrop_file, screens[screen].lcdwidth, 
+                         screens[screen].lcdheight, screens[screen].depth);
+                }
+#endif
                 filename = temp;
             }
             if (*filename && *filename != '-')
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index fbedbb9..780c42d 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -30,6 +30,7 @@
 #include "settings.h"
 #include "wps.h"
 #include "file.h"
+#include "filefuncs.h"
 #include "buffer.h"
 #if CONFIG_TUNER
 #include "radio.h"
@@ -227,6 +228,14 @@ struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type scre
         if (strcmp(setting, "rockbox_failsafe"))
         {
             snprintf(buf, sizeof buf, WPS_DIR "/%s.%s", setting, ext);
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+            if (!file_exists(buf))
+            {
+                snprintf(buf, sizeof buf, WPS_DIR "/%s.%dx%dx%d.%s",
+                     setting, screens[screen].lcdwidth, 
+                     screens[screen].lcdheight, screens[screen].depth, ext);
+            }
+#endif
         }
         cpu_boost(true);
         skin_load(skin, screen, buf, true);
diff --git a/apps/gui/skin_engine/skin_fonts.h b/apps/gui/skin_engine/skin_fonts.h
index 698ed4f..48bef2c 100644
--- a/apps/gui/skin_engine/skin_fonts.h
+++ b/apps/gui/skin_engine/skin_fonts.h
@@ -31,11 +31,7 @@
 #ifndef _SKINFONTS_H_
 #define _SKINFONTS_H_
 
-#if LCD_HEIGHT > 160
-#define SKIN_FONT_SIZE (1024*10)
-#else
-#define SKIN_FONT_SIZE (1024*3)
-#endif
+#define SKIN_FONT_SIZE  (LCD_HEIGHT > 160 ? 1024*10 : 1024*3)
 #define GLYPHS_TO_CACHE 256
 
 void skin_font_init(void);
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 236c6fe..bbb113c 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1787,7 +1787,8 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
     if (isfile)
     {
         /* get the bitmap dir */
-        char *dot = strrchr(buf, '.');
+        char *slash = strrchr(buf, '/');
+        char *dot = strchr(slash, '.');
         strlcpy(bmpdir, buf, dot - buf + 1);
     }
     else
diff --git a/apps/main.c b/apps/main.c
index 0b566b5..ab75e95 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -348,6 +348,7 @@ static void init(void)
     lcd_remote_init();
 #endif
     font_init();
+    screen_init();
     show_logo();
     button_init();
     powermgmt_init();
diff --git a/apps/plugin.c b/apps/plugin.c
index ea290c8..c76eb08 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -145,7 +145,7 @@ static int close_wrapper(int fd);
 static int creat_wrapper(const char *pathname, mode_t mode);
 #endif
 
-static const struct plugin_api rockbox_api = {
+static struct plugin_api rockbox_api = {
 
     /* lcd */
 #ifdef HAVE_LCD_CONTRAST
@@ -170,7 +170,7 @@ static const struct plugin_api rockbox_api = {
     lcd_icon,
     lcd_double_height,
 #else
-    &lcd_framebuffer[0][0],
+    NULL, /* will get filled in later */
     lcd_update_rect,
     lcd_set_drawmode,
     lcd_get_drawmode,
@@ -841,7 +841,8 @@ int plugin_load(const char* plugin, const void* parameter)
 #else
     plugin_size = 0;
 #endif
-
+    rockbox_api.lcd_framebuffer = lcd_framebuffer;
+    
     *(p_hdr->api) = &rockbox_api;
 
 #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1
diff --git a/apps/plugins/SOURCES.app_build b/apps/plugins/SOURCES.app_build
index ddac2b9..93231ba 100644
--- a/apps/plugins/SOURCES.app_build
+++ b/apps/plugins/SOURCES.app_build
@@ -1,5 +1,7 @@
 /* plugins common to all models */
+#ifndef HAVE_DYNAMIC_LCD_SIZE
 credits.c
+#endif
 properties.c
 random_folder_advance_config.c
 search.c
diff --git a/apps/plugins/SUBDIRS.app_build b/apps/plugins/SUBDIRS.app_build
index dbf4382..8fc61be 100644
--- a/apps/plugins/SUBDIRS.app_build
+++ b/apps/plugins/SUBDIRS.app_build
@@ -1,7 +1,7 @@
 /* For all targets with a bitmap display */
 #ifdef HAVE_LCD_BITMAP
 
-#ifdef HAVE_TAGCACHE
+#if defined(HAVE_TAGCACHE) && !defined(HAVE_DYNAMIC_LCD_SIZE)
 pictureflow
 #endif
 
@@ -11,7 +11,9 @@ pictureflow
 #if CONFIG_CODEC == SWCODEC
 
 #if MEMORYSIZE > 2 /* we need a lot of RAM for instruments */
+#ifndef HAVE_DYNAMIC_LCD_SIZE
 mikmod
 #endif
+#endif
 
 #endif /* CONFIG_CODEC == SWCODEC */
diff --git a/apps/plugins/bitmaps/mono/SOURCES b/apps/plugins/bitmaps/mono/SOURCES
index c12c7c7..3c53515 100644
--- a/apps/plugins/bitmaps/mono/SOURCES
+++ b/apps/plugins/bitmaps/mono/SOURCES
@@ -1,5 +1,13 @@
 #ifdef HAVE_LCD_BITMAP
 
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+/* This is a hack to prevent buildtime errors popping up */
+#undef LCD_WIDTH
+#undef LCD_HEIGHT
+#define LCD_WIDTH 0
+#define LCD_HEIGHT 0
+#endif
+
 /* Bubbles */
 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
 bubbles_bubble.112x64x1.bmp
diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES
index 65b1a38..9f7bee6 100644
--- a/apps/plugins/bitmaps/native/SOURCES
+++ b/apps/plugins/bitmaps/native/SOURCES
@@ -1,5 +1,13 @@
 #ifdef HAVE_LCD_BITMAP
 
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+/* This is a hack to prevent buildtime errors popping up */
+#undef LCD_WIDTH
+#undef LCD_HEIGHT
+#define LCD_WIDTH 0
+#define LCD_HEIGHT 0
+#endif
+
 /* Brickmania */
 #ifdef HAVE_LCD_COLOR
 brickmania_gameover.112x54x16.bmp
diff --git a/apps/plugins/lib/simple_viewer.c b/apps/plugins/lib/simple_viewer.c
index 16cbcb3..5d633fd 100644
--- a/apps/plugins/lib/simple_viewer.c
+++ b/apps/plugins/lib/simple_viewer.c
@@ -182,7 +182,11 @@ static int init_view(struct view_info *info,
 static void draw_text(struct view_info *info)
 {
 #ifdef HAVE_LCD_BITMAP
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+#define OUTPUT_SIZE MAX_LCD_WIDTH+1
+#else
 #define OUTPUT_SIZE LCD_WIDTH+1
+#endif
 #else
 #define OUTPUT_SIZE LCD_WIDTH*3+1
 #endif
diff --git a/apps/recorder/bmp.h b/apps/recorder/bmp.h
index 31bd073..88a6297 100644
--- a/apps/recorder/bmp.h
+++ b/apps/recorder/bmp.h
@@ -33,7 +33,7 @@
 
 #define IMG_NORESIZE           0
 #define IMG_RESIZE             1
-#define BM_MAX_WIDTH (((LCD_WIDTH) + 7) & ~7)
+#define BM_MAX_WIDTH (((MAX_LCD_WIDTH) + 7) & ~7)
 
 struct uint8_rgb {
     uint8_t blue;
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c
index 1b2d76e..c748add 100644
--- a/apps/recorder/keyboard.c
+++ b/apps/recorder/keyboard.c
@@ -371,10 +371,8 @@ int kbd_input(char* text, int buflen)
             const unsigned char *p;
             int len = 0;
 
-#if LCD_WIDTH >= 160 && LCD_HEIGHT >= 96
-            struct screen *sc = &screens[l];
-
-            if (sc->getwidth() >= 160 && sc->getheight() >= 96)
+            if (LCD_WIDTH >= 160 && LCD_HEIGHT >= 96 &&
+                screens[l].getwidth() >= 160 && screens[l].getheight() >= 96)
             {
                 p = "ABCDEFG abcdefg !?\" @#$%+'\n"
                     "HIJKLMN hijklmn 789 &_()-`\n"
@@ -389,7 +387,6 @@ int kbd_input(char* text, int buflen)
                 pm->max_line_len = 26;
             }
             else
-#endif /* LCD_WIDTH >= 160 && LCD_HEIGHT >= 96 */
             {
                 p = "ABCDEFG !?\" @#$%+'\n"
                     "HIJKLMN 789 &_()-`\n"
diff --git a/apps/screen_access.c b/apps/screen_access.c
index b83e842..00794d1 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -105,8 +105,6 @@ struct screen screens[NB_SCREENS] =
 {
     {
         .screen_type=SCREEN_MAIN,
-        .lcdwidth=LCD_WIDTH,
-        .lcdheight=LCD_HEIGHT,
         .depth=LCD_DEPTH,
         .getnblines=&screen_helper_getnblines,
 #if defined(HAVE_LCD_COLOR)
@@ -316,3 +314,9 @@ void screen_clear_area(struct screen * display, int xstart, int ystart,
     display->set_drawmode(DRMODE_SOLID);
 }
 #endif
+
+void screen_init(void)
+{
+    screens[SCREEN_MAIN].lcdwidth = LCD_WIDTH;
+    screens[SCREEN_MAIN].lcdheight = LCD_HEIGHT;
+}
diff --git a/apps/screen_access.h b/apps/screen_access.h
index efe232b..599ca76 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -177,4 +177,6 @@ void screen_clear_area(struct screen * display, int xstart, int ystart,
  */
 extern struct screen screens[NB_SCREENS];
 
+void screen_init(void) INIT_ATTR;
+
 #endif /*_SCREEN_ACCESS_H_*/
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 7f2cf38..1919444 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -205,7 +205,7 @@ static const char graphic_numeric[] = "graphic,numeric";
 #define DEFAULT_SBSNAME  "-"
 #define DEFAULT_FMS_NAME DEFAULT_WPSNAME
 
-#ifdef HAVE_LCD_BITMAP
+#if defined(HAVE_LCD_BITMAP) && !defined(HAVE_DYNAMIC_LCD_SIZE)
 
 #if LCD_HEIGHT <= 64
   #define DEFAULT_FONTNAME "08-Rockfont"
@@ -224,7 +224,7 @@ static const char graphic_numeric[] = "graphic,numeric";
 #endif
 
 #else
-  #define DEFAULT_FONTNAME ""
+  #define DEFAULT_FONTNAME "27-Adobe-Helvetica"
 #endif
 
 #ifdef HAVE_REMOTE_LCD
@@ -732,7 +732,7 @@ const struct settings_list settings[] = {
                   LANG_SCROLL_BAR, SCROLLBAR_LEFT, "scrollbar","off,left,right",
                   NULL, 3, ID2P(LANG_OFF), ID2P(LANG_LEFT), ID2P(LANG_RIGHT)),
     INT_SETTING(F_THEMESETTING, scrollbar_width, LANG_SCROLLBAR_WIDTH, 6,
-                "scrollbar width",UNIT_INT, 3, MAX(LCD_WIDTH/10,25), 1,
+                "scrollbar width",UNIT_INT, 3, 25, 1,
                 NULL, NULL, NULL),
 #if CONFIG_KEYPAD == RECORDER_PAD
     OFFON_SETTING(F_THEMESETTING,buttonbar, LANG_BUTTON_BAR ,true,"buttonbar", NULL),
@@ -919,9 +919,9 @@ const struct settings_list settings[] = {
                   false, "Screen Scrolls Out Of View",
                   gui_list_screen_scroll_out_of_view),
     INT_SETTING(F_PADTITLE, scroll_step, LANG_SCROLL_STEP, 6, "scroll step",
-                UNIT_PIXEL, 1, LCD_WIDTH, 1, NULL, NULL, lcd_scroll_step),
+                UNIT_PIXEL, 1, 400/*LCD_WIDTH*/, 1, NULL, NULL, lcd_scroll_step),
     INT_SETTING(F_PADTITLE, screen_scroll_step, LANG_SCREEN_SCROLL_STEP, 16,
-                "screen scroll step", UNIT_PIXEL, 1, LCD_WIDTH, 1, NULL, NULL,
+                "screen scroll step", UNIT_PIXEL, 1, 400/*LCD_WIDTH*/, 1, NULL, NULL,
                 gui_list_screen_scroll_step),
 #endif /* HAVE_LCD_BITMAP */
     OFFON_SETTING(0,scroll_paginated,LANG_SCROLL_PAGINATED,
diff --git a/firmware/bidi.c b/firmware/bidi.c
index 2f4e137..ffd18c6 100644
--- a/firmware/bidi.c
+++ b/firmware/bidi.c
@@ -137,10 +137,10 @@ static void arabjoin(unsigned short * stringprt, int length)
 
 unsigned short *bidi_l2v(const unsigned char *str, int orientation)
 {
-    static unsigned short  utf16_buf[SCROLL_LINE_SIZE];
+    unsigned short  utf16_buf[SCROLL_LINE_SIZE];
     unsigned short *target, *tmp;
 #ifndef BOOTLOADER
-    static unsigned short  bidi_buf[SCROLL_LINE_SIZE];
+    unsigned short  bidi_buf[SCROLL_LINE_SIZE];
     unsigned short *heb_str; /* *broken_str */
     int block_start, block_end, block_type, block_length, i;
     int length = utf8length(str);
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 28c3285..1598a0b 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -46,9 +46,12 @@ enum fill_opt {
 };
 
 /*** globals ***/
-fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
-    IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
+fb_data *lcd_framebuffer;
 
+#ifndef HAVE_DYNAMIC_LCD_SIZE
+fb_data _lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
+    IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
+#endif
 
 static fb_data* lcd_backdrop = NULL;
 static long lcd_backdrop_offset IDATA_ATTR = 0;
@@ -57,8 +60,6 @@ static struct viewport default_vp =
 {
     .x        = 0,
     .y        = 0,
-    .width    = LCD_WIDTH,
-    .height   = LCD_HEIGHT,
     .font     = FONT_SYSFIXED,
     .drawmode = DRMODE_SOLID,
     .fg_pattern = LCD_DEFAULT_FG,
@@ -78,6 +79,12 @@ void lcd_init(void)
     /* Call device specific init */
     lcd_init_device();
     scroll_init();
+
+    default_vp.width = LCD_WIDTH;
+    default_vp.height = LCD_HEIGHT;
+#ifndef HAVE_DYNAMIC_LCD_SIZE
+    lcd_framebuffer = &_lcd_framebuffer[0][0];
+#endif
 }
 /*** Viewports ***/
 
@@ -203,7 +210,7 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
 
 /*** low-level drawing functions ***/
 
-#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
+#define LCDADDR(x, y) (lcd_framebuffer + y * LCD_WIDTH + x)
 
 static void ICODE_ATTR setpixel(fb_data *address)
 {
@@ -247,7 +254,7 @@ void lcd_set_backdrop(fb_data* backdrop)
     lcd_backdrop = backdrop;
     if (backdrop)
     {
-        lcd_backdrop_offset = (long)backdrop - (long)&lcd_framebuffer[0][0];
+        lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer;
         lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop;
     }
     else
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index fc84fdd..9c77c8c 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -383,7 +383,7 @@ void LCDFN(puts_scroll_style_xyoffset)(int x, int y, const unsigned char *string
     s->start_tick = current_tick + LCDFN(scroll_info).delay;
     s->style = style;
 
-    strlcpy(s->line, string, sizeof s->line);
+    strlcpy(s->line, string, LCDFN(scroll_info).max_line);
 
     /* get width */
     s->width = LCDFN(getstringsize)(s->line, &w, &h);
diff --git a/firmware/export/config.h b/firmware/export/config.h
index cd4896f..e84affd 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -592,6 +592,24 @@ Lyre prototype 1 */
 #define LCD_SPLIT_LINES 0
 #endif
 
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+#define LCD_WIDTH ({extern int lcd_width; lcd_width;})
+#define LCD_HEIGHT ({extern int lcd_height; lcd_height;})
+#ifdef HAVE_REMOTE_LCD
+#error unsupported config (HAVE_REMOTE_LCD && HAVE_DYNAMIC_LCD_SIZE)
+#endif
+#else
+#ifdef DEFAULT_LCD_HEIGHT
+#define LCD_HEIGHT DEFAULT_LCD_HEIGHT
+#endif
+#ifdef DEFAULT_LCD_WIDTH
+#define LCD_WIDTH DEFAULT_LCD_WIDTH
+#endif
+#ifndef MAX_LCD_WIDTH
+#define MAX_LCD_WIDTH LCD_WIDTH
+#endif
+#endif /* HAVE_DYNAMIC_LCD_SIZE */
+
 /* Simulator LCD dimensions. Set to standard dimensions if undefined */
 #ifndef SIM_LCD_WIDTH
 #define SIM_LCD_WIDTH LCD_WIDTH
diff --git a/firmware/export/config/android.h b/firmware/export/config/android.h
index 69a758d..dfc9652 100644
--- a/firmware/export/config/android.h
+++ b/firmware/export/config/android.h
@@ -36,22 +36,14 @@
 /* define this if you would like tagcache to build on this target */
 #define HAVE_TAGCACHE
 
-/* LCD dimensions
- *
- * overriden by configure for application builds */
-#ifndef LCD_WIDTH
-#define LCD_WIDTH  320
-#endif
-
-#ifndef LCD_HEIGHT
-#define LCD_HEIGHT 480
-#endif
-
 #define LCD_DEPTH  16
 #define LCD_PIXELFORMAT 565
 
 #define HAVE_LCD_ENABLE
 
+#define HAVE_DYNAMIC_LCD_SIZE
+#define MAX_LCD_WIDTH 1024
+
 /* define this to indicate your device's keypad */
 #define HAVE_TOUCHSCREEN
 #define HAVE_BUTTON_DATA
diff --git a/firmware/export/config/sdlapp.h b/firmware/export/config/sdlapp.h
index a55b7e3..43f4c6e 100644
--- a/firmware/export/config/sdlapp.h
+++ b/firmware/export/config/sdlapp.h
@@ -39,13 +39,9 @@
 /* LCD dimensions
  *
  * overriden by configure for application builds */
-#ifndef LCD_WIDTH
-#define LCD_WIDTH  320
-#endif
 
-#ifndef LCD_HEIGHT
-#define LCD_HEIGHT 480
-#endif
+#define HAVE_DYNAMIC_LCD_SIZE
+#define MAX_LCD_WIDTH 1024
 
 #define LCD_DEPTH  16
 #define LCD_PIXELFORMAT 565
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index e6e19b1..ea66358 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -407,7 +407,7 @@ static inline unsigned lcd_color_to_native(unsigned color)
 #define LCD_FBHEIGHT LCD_HEIGHT
 #endif
 /* The actual framebuffer */
-extern fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH];
+extern fb_data *lcd_framebuffer;
 
 /** Port-specific functions. Enable in port config file. **/
 #ifdef HAVE_REMOTE_LCD_AS_MAIN
diff --git a/firmware/export/scroll_engine.h b/firmware/export/scroll_engine.h
index 0fe6fe4..e731e70 100644
--- a/firmware/export/scroll_engine.h
+++ b/firmware/export/scroll_engine.h
@@ -49,7 +49,7 @@ void lcd_remote_scroll_stop_line(const struct viewport* vp, int y);
 struct scrollinfo
 {
     struct viewport* vp;
-    char line[SCROLL_LINE_SIZE];
+    char *line;
 #ifdef HAVE_LCD_CHARCELLS
     int len;    /* length of line in chars */
 #endif
@@ -68,9 +68,10 @@ struct scrollinfo
 
 struct scroll_screen_info
 {
-    struct scrollinfo * const scroll;
+    struct scrollinfo * scroll;
     const int num_scroll; /* number of scrollable lines (also number of scroll structs) */
     int lines;  /* Number of currently scrolling lines */
+    int max_line; /* max chars storable on each scroll line */
     long ticks; /* # of ticks between updates*/
     long delay; /* ticks delay before start */
     int bidir_limit;  /* percent */
diff --git a/firmware/font.c b/firmware/font.c
index 0f9f453..f10d62e 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include "inttypes.h"
 #include "lcd.h"
+#include "buffer.h"
 #include "system.h"
 #include "font.h"
 #include "file.h"
@@ -44,15 +45,7 @@
 
 /* max static loadable font buffer size */
 #ifndef MAX_FONT_SIZE
-#if LCD_HEIGHT > 64
-#if MEMORYSIZE > 2
-#define MAX_FONT_SIZE   60000
-#else
-#define MAX_FONT_SIZE   10000
-#endif
-#else
-#define MAX_FONT_SIZE   4000
-#endif
+#define MAX_FONT_SIZE (LCD_HEIGHT > 64 ? (MEMORYSIZE > 2 ? 60000 : 10000) : 4000) > 2
 #endif
 
 #ifndef FONT_HEADER_SIZE
@@ -77,11 +70,11 @@ extern struct font sysfont;
 /* structure filled in by font_load */
 static struct font font_ui;
 /* static buffer allocation structures */
-static unsigned char main_buf[MAX_FONT_SIZE] CACHEALIGN_ATTR;
+static unsigned char *main_buf CACHEALIGN_ATTR;
 #ifdef HAVE_REMOTE_LCD
 #define REMOTE_FONT_SIZE 10000
 static struct font remote_font_ui;
-static unsigned char remote_buf[REMOTE_FONT_SIZE] CACHEALIGN_ATTR;
+static unsigned char *remote_buf CACHEALIGN_ATTR;
 #endif
 
 /* system font table, in order of FONT_xxx definition */
@@ -98,8 +91,10 @@ void font_init(void)
     int i = SYSTEMFONTCOUNT;
     while (i<MAXFONTS)
         sysfonts[i++] = NULL;
+    main_buf = buffer_alloc(MAX_FONT_SIZE);
     font_reset(NULL);
 #ifdef HAVE_REMOTE_LCD
+    remote_buf = buffer_alloc(REMOTE_FONT_SIZE);
     font_reset(&remote_font_ui);
 #endif
 }
diff --git a/firmware/screendump.c b/firmware/screendump.c
index 30b9539..b0a3c19 100644
--- a/firmware/screendump.c
+++ b/firmware/screendump.c
@@ -53,25 +53,44 @@
 #define BMP_DATASIZE   (DUMP_BMP_LINESIZE * (LCD_HEIGHT+LCD_SPLIT_LINES))
 #define BMP_TOTALSIZE  (BMP_HEADERSIZE + BMP_DATASIZE)
 
-static const unsigned char bmpheader[] =
-{
-    0x42, 0x4d,                 /* 'BM' */
-    LE32_CONST(BMP_TOTALSIZE),  /* Total file size */
-    0x00, 0x00, 0x00, 0x00,     /* Reserved */
-    LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */
-
-    0x28, 0x00, 0x00, 0x00,     /* Size of (2nd) header */
-    LE32_CONST(LCD_WIDTH),      /* Width in pixels */
-    LE32_CONST(LCD_HEIGHT+LCD_SPLIT_LINES),  /* Height in pixels */
-    0x01, 0x00,                 /* Number of planes (always 1) */
-    LE16_CONST(DUMP_BMP_BPP),   /* Bits per pixel 1/4/8/16/24 */
-    LE32_CONST(BMP_COMPRESSION),/* Compression mode */
-    LE32_CONST(BMP_DATASIZE),   /* Size of bitmap data */
-    0xc4, 0x0e, 0x00, 0x00,     /* Horizontal resolution (pixels/meter) */
-    0xc4, 0x0e, 0x00, 0x00,     /* Vertical resolution (pixels/meter) */
-    LE32_CONST(BMP_NUMCOLORS),  /* Number of used colours */
-    LE32_CONST(BMP_NUMCOLORS),  /* Number of important colours */
-
+#define ASSIGN_LE32(dst, x) memcpy((dst), (unsigned char[4]){LE32_CONST(x)}, 4);
+
+static struct {
+    const unsigned char header[2];
+    unsigned char       file_size[4];
+    const unsigned char reserved[4];
+    unsigned char       header_size[4];
+    const unsigned char second_header_size[4];
+    unsigned char       lcd_width[4];
+    unsigned char       lcd_height[4];
+    const unsigned char nr_planes[2];
+    const unsigned char bpp[2];
+    const unsigned char compression[4];
+    unsigned char       data_size[4];
+    const unsigned char horizontal_resolution[4];
+    const unsigned char vertical_resolution[4];
+    const unsigned char nr_used_colors[4];
+    const unsigned char nr_important_colors[4];
+    const unsigned char colors[BMP_NUMCOLORS*4];
+} __attribute__((__packed__)) bmpheader = {
+    {0x42, 0x4d},                 /* 'BM' */
+    {},                           /* Total file size */
+    {0x00, 0x00, 0x00, 0x00},     /* Reserved */
+    {},                           /* Offset to start of pixel data */
+
+    {0x28, 0x00, 0x00, 0x00},     /* Size of (2nd) header */
+    {},                           /* Width in pixels */
+    {},                           /* Height in pixels */
+    {0x01, 0x00},                 /* Number of planes (always 1) */
+    {LE16_CONST(DUMP_BMP_BPP)},   /* Bits per pixel 1/4/8/16/24 */
+    {LE32_CONST(BMP_COMPRESSION)},/* Compression mode */
+    {},                           /* Size of bitmap data */
+    {0xc4, 0x0e, 0x00, 0x00},     /* Horizontal resolution (pixels/meter) */
+    {0xc4, 0x0e, 0x00, 0x00},     /* Vertical resolution (pixels/meter) */
+    {LE32_CONST(BMP_NUMCOLORS)},  /* Number of used colours */
+    {LE32_CONST(BMP_NUMCOLORS)},  /* Number of important colours */
+ 
+    {
 #if LCD_DEPTH == 1
 #ifdef HAVE_NEGATIVE_LCD
     BMP_COLOR(LCD_BL_DARKCOLOR),
@@ -94,6 +113,7 @@ static const unsigned char bmpheader[] =
     0xe0, 0x07, 0x00, 0x00,     /* green bitfield mask */
     0x1f, 0x00, 0x00, 0x00,     /* blue bitfield mask */
 #endif
+    }
 };
 
 static void (*screen_dump_hook)(int fh) = NULL;
@@ -136,7 +156,12 @@ void screen_dump(void)
     }
     else
     {
-        write(fd, bmpheader, sizeof(bmpheader));
+        ASSIGN_LE32(bmpheader.file_size, BMP_TOTALSIZE);
+        ASSIGN_LE32(bmpheader.header_size, BMP_HEADERSIZE);
+        ASSIGN_LE32(bmpheader.lcd_width, LCD_WIDTH);
+        ASSIGN_LE32(bmpheader.lcd_height, LCD_HEIGHT+LCD_SPLIT_LINES);
+        ASSIGN_LE32(bmpheader.data_size, BMP_DATASIZE);
+        write(fd, &bmpheader, sizeof(bmpheader));
 
         /* BMP image goes bottom up */
         for (y = LCD_HEIGHT - 1; y >= 0; y--)
@@ -214,7 +239,7 @@ void screen_dump(void)
 #endif
 #elif LCD_DEPTH == 16
             dst_end = dst + LCD_WIDTH;
-            src = lcd_framebuffer[y];
+            src = &lcd_framebuffer[y];
             
             do
             {
diff --git a/firmware/scroll_engine.c b/firmware/scroll_engine.c
index 5dd80f1..5bc71e6 100644
--- a/firmware/scroll_engine.c
+++ b/firmware/scroll_engine.c
@@ -33,6 +33,7 @@
 #ifdef HAVE_REMOTE_LCD
 #include "lcd-remote.h"
 #endif
+#include "buffer.h"
 #include "scroll_engine.h"
 
 static const char scroll_tick_table[16] = {
@@ -45,16 +46,13 @@ static void scroll_thread(void);
 static char scroll_stack[DEFAULT_STACK_SIZE*3];
 static const char scroll_name[] = "scroll";
 
-static struct scrollinfo lcd_scroll[LCD_SCROLLABLE_LINES];
 
 #ifdef HAVE_REMOTE_LCD
-static struct scrollinfo lcd_remote_scroll[LCD_REMOTE_SCROLLABLE_LINES];
 static struct event_queue scroll_queue SHAREDBSS_ATTR;
 #endif
 
 struct scroll_screen_info lcd_scroll_info =
 {
-    .scroll       = lcd_scroll,
     .lines        = 0,
     .ticks        = 12,
     .delay        = HZ/2,
@@ -71,7 +69,6 @@ struct scroll_screen_info lcd_scroll_info =
 #ifdef HAVE_REMOTE_LCD
 struct scroll_screen_info lcd_remote_scroll_info =
 {
-    .scroll       = lcd_remote_scroll,
     .lines        = 0,
     .ticks        = 12,
     .delay        = HZ/2,
@@ -341,6 +338,8 @@ static void scroll_thread(void)
 
 void scroll_init(void)
 {
+    int i;
+    const int max_line = SCROLL_LINE_SIZE;
 #ifdef HAVE_REMOTE_LCD
     queue_init(&scroll_queue, true);
 #endif
@@ -348,5 +347,23 @@ void scroll_init(void)
                   sizeof(scroll_stack), 0, scroll_name
                   IF_PRIO(, PRIORITY_USER_INTERFACE)
                   IF_COP(, CPU));
+
+    struct scrollinfo *lcd_scroll = buffer_alloc(sizeof(struct scrollinfo) *
+                                                 LCD_SCROLLABLE_LINES);
+    lcd_scroll_info.scroll = lcd_scroll;
+    lcd_scroll_info.max_line = max_line;
+
+    for (i = 0; i < LCD_SCROLLABLE_LINES; i++)
+        lcd_scroll[i].line = buffer_alloc(max_line);
+#ifdef HAVE_REMOTE_LCD
+    struct scrollinfo *lcd_remote_scroll;
+    lcd_remote_scroll = buffer_alloc(sizeof(struct scrollinfo) *
+                                     LCD_REMOTE_SCROLLABLE_LINES);
+    lcd_remote_scroll_info.scroll = lcd_remote_scroll;
+    lcd_remote_scroll_info.max_line = max_line;
+
+    for (int i = 0; i < LCD_REMOTE_SCROLLABLE_LINES; i++)
+        lcd_remote_scroll[i].line = buffer_alloc(max_line);
+#endif
 }
 
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c
index abde721..aab6c23 100644
--- a/firmware/target/hosted/android/lcd-android.c
+++ b/firmware/target/hosted/android/lcd-android.c
@@ -30,6 +30,7 @@
 
 extern JNIEnv *env_ptr;
 extern jobject RockboxService_instance;
+extern jclass  RockboxService_class;
 
 static jobject RockboxFramebuffer_instance;
 static jmethodID java_lcd_update;
@@ -40,6 +41,8 @@ static int dpi;
 static int scroll_threshold;
 static bool display_on;
 
+int lcd_width, lcd_height;
+
 /* this might actually be called before lcd_init_device() or even main(), so
  * be sure to only access static storage initalized at library loading,
  * and not more */
@@ -75,11 +78,10 @@ void connect_with_java(JNIEnv* env, jobject fb_instance)
 
     /* Create native_buffer */
     jobject buffer = (*env)->NewDirectByteBuffer(env, lcd_framebuffer,
-                                               (jlong) sizeof(lcd_framebuffer));
-
+                            (jlong) (lcd_width * lcd_height * sizeof(fb_data)));
     /* we need to setup parts for the java object every time */
-    (*env)->CallVoidMethod(env, fb_instance, java_lcd_init,
-                          (jint)LCD_WIDTH, (jint)LCD_HEIGHT, buffer);
+    (*env)->CallVoidMethod(env, fb_instance, java_lcd_init, lcd_width,
+                           lcd_height, buffer);
 }
 
 /*
@@ -87,6 +89,15 @@ void connect_with_java(JNIEnv* env, jobject fb_instance)
  */
 void lcd_init_device(void)
 {
+    jmethodID getResolution = (*env_ptr)->GetMethodID(env_ptr, RockboxService_class, "getResolution", "()[I");
+    jintArray resolution = (jintArray) (*env_ptr)->CallObjectMethod(env_ptr, RockboxService_instance, getResolution);
+    jint *resolutionElements = (*env_ptr)->GetIntArrayElements(env_ptr, resolution, NULL);
+
+    lcd_width = resolutionElements[0];
+    lcd_height = resolutionElements[1];
+    lcd_framebuffer = malloc(sizeof(fb_data) * lcd_width * lcd_height);
+
+    (*env_ptr)->ReleaseIntArrayElements(env_ptr, resolution, resolutionElements, 0);
 }
 
 void lcd_update(void)
@@ -190,6 +201,8 @@ void lcd_yuv_set_options(unsigned options)
     (void)options;
 }
 
+#define LCDADDR(x, y) (lcd_framebuffer + y * LCD_WIDTH + x)
+
 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
    in the core */
 void lcd_blit_yuv(unsigned char * const src[3],
@@ -205,13 +218,13 @@ void lcd_blit_yuv(unsigned char * const src[3],
     width &= ~1;
     linecounter = height >> 1;
 
-#if LCD_WIDTH >= LCD_HEIGHT
-    dst     = &lcd_framebuffer[y][x];
-    row_end = dst + width;
-#else
-    dst     = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
+    if (LCD_WIDTH >= LCD_HEIGHT) {
+        dst     = LCDADDR(y, x);
+        row_end = dst + width;
+    } else {
+    dst     = LCDADDR(x, LCD_WIDTH - y - 1);
     row_end = dst + LCD_WIDTH * width;
-#endif
+    }
 
     z    = stride * src_y;
     ysrc = src[0] + z + src_x;
@@ -250,11 +263,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
 
             y = YFAC*(*ysrc++ - 16);
             r = y + rv;
@@ -270,11 +282,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
         }
         while (dst < row_end);
 
@@ -282,13 +293,13 @@ void lcd_blit_yuv(unsigned char * const src[3],
         usrc    -= width >> 1;
         vsrc    -= width >> 1;
 
-#if LCD_WIDTH >= LCD_HEIGHT
-        row_end += LCD_WIDTH;
-        dst     += LCD_WIDTH - width;
-#else
-        row_end -= 1;
-        dst     -= LCD_WIDTH*width + 1;
-#endif
+        if (LCD_WIDTH >= LCD_HEIGHT) {
+            row_end += LCD_WIDTH;
+            dst     += LCD_WIDTH - width;
+        } else {
+            row_end -= 1;
+            dst     -= LCD_WIDTH*width + 1;
+        }
 
         do
         {
@@ -315,11 +326,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
 
             y = YFAC*(*ysrc++ - 16);
             r = y + rv;
@@ -335,11 +345,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
         }
         while (dst < row_end);
 
@@ -347,19 +356,18 @@ void lcd_blit_yuv(unsigned char * const src[3],
         usrc    += stride >> 1;
         vsrc    += stride >> 1;
 
-#if LCD_WIDTH >= LCD_HEIGHT
-        row_end += LCD_WIDTH;
-        dst     += LCD_WIDTH - width;
-#else
-        row_end -= 1;
-        dst     -= LCD_WIDTH*width + 1;
-#endif
+        if (LCD_WIDTH >= LCD_HEIGHT) {
+            row_end += LCD_WIDTH;
+            dst     += LCD_WIDTH - width;
+        } else {
+            row_end -= 1;
+            dst     -= LCD_WIDTH*width + 1;
+        }
     }
     while (--linecounter > 0);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-    lcd_update_rect(x, y, width, height);
-#else
-    lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
-#endif
+    if (LCD_WIDTH >= LCD_HEIGHT)
+        lcd_update_rect(x, y, width, height);
+    else
+        lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
 }
diff --git a/firmware/target/hosted/sdl/lcd-bitmap.c b/firmware/target/hosted/sdl/lcd-bitmap.c
index 4c29692..239d5a0 100644
--- a/firmware/target/hosted/sdl/lcd-bitmap.c
+++ b/firmware/target/hosted/sdl/lcd-bitmap.c
@@ -30,6 +30,9 @@
 #endif
 
 SDL_Surface* lcd_surface;
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+extern int lcd_width, lcd_height;
+#endif
 
 #if LCD_DEPTH <= 8
 #ifdef HAVE_BACKLIGHT
@@ -88,6 +91,8 @@ unsigned long (*lcd_ex_getpixel)(int, int) = NULL;
 static const unsigned char colorindex[4] = {128, 85, 43, 0};
 #endif
 
+#define LCD_PIXEL(x, y) (lcd_framebuffer + y * LCD_WIDTH + x)
+
 static unsigned long get_lcd_pixel(int x, int y)
 {
 #if LCD_DEPTH == 1
@@ -113,7 +118,7 @@ static unsigned long get_lcd_pixel(int x, int y)
 #if   defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
     return *(&lcd_framebuffer[0][0]+LCD_HEIGHT*x+y);
 #else
-    return lcd_framebuffer[y][x];
+    return *LCD_PIXEL(x, y);
 #endif
 #endif
 #endif
@@ -140,7 +145,7 @@ void lcd_update_rect(int x_start, int y_start, int width, int height)
     sdl_update_rect(lcd_surface, x_start, y_start, width, height,
                     LCD_WIDTH, LCD_HEIGHT, get_lcd_pixel);
     sdl_gui_update(lcd_surface, x_start, y_start, width,
-                   height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
+                   height + LCD_SPLIT_LINES, LCD_WIDTH, LCD_HEIGHT,
                    background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
 }
 
@@ -168,7 +173,7 @@ void sim_backlight(int value)
 #endif /* LCD_DEPTH */
 
     sdl_gui_update(lcd_surface, 0, 0, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
-                   SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
+                   LCD_WIDTH, LCD_HEIGHT,
                    background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
 }
 #endif /* HAVE_BACKLIGHT */
@@ -176,10 +181,14 @@ void sim_backlight(int value)
 /* initialise simulator lcd driver */
 void lcd_init_device(void)
 {
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+    lcd_framebuffer = malloc(lcd_width * lcd_height * sizeof(fb_data));
+#endif
+
 #if LCD_DEPTH == 16
     lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
-                                       SIM_LCD_WIDTH * display_zoom,
-                                       SIM_LCD_HEIGHT * display_zoom,
+                                       LCD_WIDTH * display_zoom,
+                                       LCD_HEIGHT * display_zoom,
                                        LCD_DEPTH, 0, 0, 0, 0);
 #elif LCD_DEPTH <= 8
     lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
@@ -217,7 +226,7 @@ void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height)
         sdl_update_rect(lcd_surface, x_start, y_start, width, height,
                         LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel);
         sdl_gui_update(lcd_surface, x_start, y_start, width, 
-                       height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
+                       height + LCD_SPLIT_LINES, LCD_WIDTH, LCD_HEIGHT,
                        background ? UI_LCD_POSX : 0,
                        background ? UI_LCD_POSY : 0);
     }
@@ -269,13 +278,16 @@ void lcd_blit_yuv(unsigned char * const src[3],
     width &= ~1;
     linecounter = height >> 1;
 
-#if LCD_WIDTH >= LCD_HEIGHT
-    dst     = &lcd_framebuffer[y][x];
-    row_end = dst + width;
-#else
-    dst     = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
-    row_end = dst + LCD_WIDTH * width;
-#endif
+    if (LCD_WIDTH >= LCD_HEIGHT)
+    {
+        dst     = LCD_PIXEL(x, y);
+        row_end = dst + width;
+    }
+    else
+    {
+        dst     = LCD_PIXEL(x, LCD_WIDTH - y - 1);
+        row_end = dst + LCD_WIDTH * width;
+    }
 
     z    = stride * src_y;
     ysrc = src[0] + z + src_x;
@@ -314,11 +326,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
 
             y = YFAC*(*ysrc++ - 16);
             r = y + rv;
@@ -334,11 +345,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
         }
         while (dst < row_end);
 
@@ -346,13 +356,16 @@ void lcd_blit_yuv(unsigned char * const src[3],
         usrc    -= width >> 1;
         vsrc    -= width >> 1;
 
-#if LCD_WIDTH >= LCD_HEIGHT
-        row_end += LCD_WIDTH;
-        dst     += LCD_WIDTH - width;
-#else
-        row_end -= 1;
-        dst     -= LCD_WIDTH*width + 1;
-#endif
+        if (LCD_WIDTH >= LCD_HEIGHT)
+        {
+            row_end += LCD_WIDTH;
+            dst     += LCD_WIDTH - width;
+        }
+        else
+        {
+            row_end -= 1;
+            dst     -= LCD_WIDTH*width + 1;
+        }
 
         do
         {
@@ -379,11 +392,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
 
             y = YFAC*(*ysrc++ - 16);
             r = y + rv;
@@ -399,11 +411,10 @@ void lcd_blit_yuv(unsigned char * const src[3],
 
             *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-            dst++;
-#else
-            dst += LCD_WIDTH;
-#endif
+            if (LCD_WIDTH >= LCD_HEIGHT)
+                dst++;
+            else
+                dst += LCD_WIDTH;
         }
         while (dst < row_end);
 
@@ -411,20 +422,22 @@ void lcd_blit_yuv(unsigned char * const src[3],
         usrc    += stride >> 1;
         vsrc    += stride >> 1;
 
-#if LCD_WIDTH >= LCD_HEIGHT
-        row_end += LCD_WIDTH;
-        dst     += LCD_WIDTH - width;
-#else
-        row_end -= 1;
-        dst     -= LCD_WIDTH*width + 1;
-#endif
+        if (LCD_WIDTH >= LCD_HEIGHT)
+        {
+            row_end += LCD_WIDTH;
+            dst     += LCD_WIDTH - width;
+        }
+        else
+        {
+            row_end -= 1;
+            dst     -= LCD_WIDTH*width + 1;
+        }
     }
     while (--linecounter > 0);
 
-#if LCD_WIDTH >= LCD_HEIGHT
-    lcd_update_rect(x, y, width, height);
-#else
-    lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
-#endif
+    if (LCD_WIDTH >= LCD_HEIGHT)
+        lcd_update_rect(x, y, width, height);
+    else
+        lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
 }
 #endif /* HAVE_LCD_COLOR */
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index 750a014..bae1e45 100644
--- a/firmware/target/hosted/sdl/system-sdl.c
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -61,6 +61,10 @@ char            having_new_lcd = true;      /* Used for player simulator */
 bool            sim_alarm_wakeup = false;
 const char     *sim_root_dir = NULL;
 extern int      display_zoom;
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+int             lcd_width = DEFAULT_LCD_WIDTH;
+int             lcd_height = DEFAULT_LCD_HEIGHT;
+#endif
 
 static SDL_Thread *evt_thread = NULL;
 
@@ -287,6 +291,19 @@ void sys_handle_argv(int argc, char *argv[])
                 background = false;
                 printf("Disabling background image.\n");
             } 
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+            else if (!strcmp("--display", argv[x]))
+            {
+                x++;
+                if(x < argc)
+                {
+                    /* <width>x<height> */
+                    char *xchar = strchr(argv[x], 'x');
+                    lcd_width = atoi(argv[x]);
+                    lcd_height = atoi(xchar+1);
+                }
+            }
+#endif
 #ifdef HAVE_REMOTE_LCD
             else if (!strcmp("--noremote", argv[x]))
             {
@@ -342,6 +359,9 @@ void sys_handle_argv(int argc, char *argv[])
 #endif
                 printf("  --debugwps \t Print advanced WPS debug info\n");
                 printf("  --nobackground \t Disable the background image\n");
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+                printf("  --display WIDTHxHEIGHT\t Set the window size\n");
+#endif
 #ifdef HAVE_REMOTE_LCD
                 printf("  --noremote \t Disable the remote image (will disable backgrounds)\n");
 #endif
diff --git a/tools/configure b/tools/configure
index 9f95fec..90ee0f0 100755
--- a/tools/configure
+++ b/tools/configure
@@ -104,8 +104,8 @@ app_set_lcd_size () {
     ARG_LCDWIDTH=$app_lcd_width
     ARG_LCDHEIGHT=$app_lcd_height
 
-    app_lcd_width="#define LCD_WIDTH $app_lcd_width"
-    app_lcd_height="#define LCD_HEIGHT $app_lcd_height"
+    app_lcd_width="#define DEFAULT_LCD_WIDTH $app_lcd_width"
+    app_lcd_height="#define DEFAULT_LCD_HEIGHT $app_lcd_height"
 }
 
 findarmgcc() {
