diff --git a/apps/plugin.c b/apps/plugin.c
index b9c2e7c..abc03c0 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 = { /* FIXME! */
 
     /* 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,
     lcd_update_rect,
     lcd_set_drawmode,
     lcd_get_drawmode,
@@ -863,6 +863,7 @@ int plugin_load(const char* plugin, const void* parameter)
     plugin_size = 0;
 #endif
 
+    rockbox_api.lcd_framebuffer = lcd_framebuffer;
     *(p_hdr->api) = &rockbox_api;
 
     lcd_clear_display();
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 28c3285..60d8b57 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -46,9 +46,9 @@ enum fill_opt {
 };
 
 /*** globals ***/
-fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
-    IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
-
+fb_data _lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
+IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16);
+fb_data *lcd_framebuffer = _lcd_framebuffer;
 
 static fb_data* lcd_backdrop = NULL;
 static long lcd_backdrop_offset IDATA_ATTR = 0;
@@ -203,7 +203,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 +247,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/export/lcd.h b/firmware/export/lcd.h
index 76b8b09..8d50eb6 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -408,7 +408,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..df8f6b0 100644
--- a/firmware/export/scroll_engine.h
+++ b/firmware/export/scroll_engine.h
@@ -68,9 +68,12 @@ 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 */
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+    int line_size; /* max chars storable on each scroll line */
+#endif
     long ticks; /* # of ticks between updates*/
     long delay; /* ticks delay before start */
     int bidir_limit;  /* percent */
diff --git a/firmware/screendump.c b/firmware/screendump.c
index 30b9539..c886459 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,8 +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
             {
 #if (LCD_PIXELFORMAT == RGB565SWAPPED)
diff --git a/firmware/target/arm/ipod/video/lcd-video.c b/firmware/target/arm/ipod/video/lcd-video.c
index c499e9f..db7f35e 100644
--- a/firmware/target/arm/ipod/video/lcd-video.c
+++ b/firmware/target/arm/ipod/video/lcd-video.c
@@ -410,7 +410,7 @@ void lcd_update_rect(int x, int y, int width, int height)
     /* Prevent the tick from triggering BCM updates while we're writing. */
     lcd_block_tick();
 
-    addr = &lcd_framebuffer[y][x];
+    addr = (lcd_framebuffer + y * LCD_WIDTH + x);
     bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1);
 
     if (width == LCD_WIDTH)
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c
index abde721..64597ce 100644
--- a/firmware/target/hosted/android/lcd-android.c
+++ b/firmware/target/hosted/android/lcd-android.c
@@ -87,6 +87,19 @@ void connect_with_java(JNIEnv* env, jobject fb_instance)
  */
 void lcd_init_device(void)
 {
+#ifdef HAVE_DYNAMIC_LCD_SIZE
+    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];
+    (*env_ptr)->ReleaseIntArrayElements(env_ptr, resolution, resolutionElements, 0);
+#else
+    lcd_height = LCD_HEIGHT;
+    lcd_width = LCD_WIDTH;
+#endif
+    lcd_framebuffer = malloc(sizeof(fb_data) * lcd_width * lcd_height);
 }
 
 void lcd_update(void)
@@ -190,6 +203,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 +220,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 +265,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 +284,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 +295,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 +328,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 +347,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 +358,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..06d6522 100644
--- a/firmware/target/hosted/sdl/lcd-bitmap.c
+++ b/firmware/target/hosted/sdl/lcd-bitmap.c
@@ -88,6 +88,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 +115,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
@@ -176,6 +178,8 @@ void sim_backlight(int value)
 /* initialise simulator lcd driver */
 void lcd_init_device(void)
 {
+    lcd_framebuffer = malloc(LCD_HEIGHT * LCD_WIDTH * sizeof(fb_data));
+
 #if LCD_DEPTH == 16
     lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
                                        SIM_LCD_WIDTH * display_zoom,
@@ -269,13 +273,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 +321,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 +340,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 +351,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 +387,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 +406,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 +417,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 */
