diff --git a/src/conio/bitmap_con.c b/src/conio/bitmap_con.c
index 4866fc05ccf0051f789e14a565581b68cf80c684..3ce2c75b31906b01d1824d509021581a4283a7f3 100644
--- a/src/conio/bitmap_con.c
+++ b/src/conio/bitmap_con.c
@@ -1120,6 +1120,40 @@ int bitmap_loadfont(const char *filename)
 	return ret;
 }
 
+static void
+bitmap_movetext_screen(struct bitmap_screen *screen, int x, int y, int tox, int toy, int direction, int height, int width)
+{
+	int32_t sdestoffset;
+	size_t ssourcepos;
+	int step;
+	int32_t screeny;
+
+	if (direction == -1) {
+		ssourcepos=((y + height - 1)     * vstat.charheight - 1) * vstat.scrnwidth + (x - 1)  * vstat.charwidth;
+		sdestoffset=((((toy + height - 1) * vstat.charheight - 1) * vstat.scrnwidth + (tox - 1) * vstat.charwidth) - ssourcepos);
+	}
+	else {
+		ssourcepos=(y - 1)     * vstat.scrnwidth * vstat.charheight + (x - 1)  * vstat.charwidth;
+		sdestoffset=(((toy - 1) * vstat.scrnwidth * vstat.charheight + (tox - 1) * vstat.charwidth) - ssourcepos);
+	}
+
+	pthread_mutex_lock(&screen->screenlock);
+	if (width == cio_textinfo.screenwidth) {
+		memmove(&(screen->screen[ssourcepos+sdestoffset]), &(screen->screen[ssourcepos]), sizeof(screen->screen[0])*width*vstat.charwidth*height*vstat.charheight);
+		memmove(&(screen->rect->data[ssourcepos+sdestoffset]), &(screen->rect->data[ssourcepos]), sizeof(screen->screen[0])*width*vstat.charwidth*height*vstat.charheight);
+	}
+	else {
+		step = direction * vstat.scrnwidth;
+		for(screeny=0; screeny < height*vstat.charheight; screeny++) {
+			memmove(&(screen->screen[ssourcepos+sdestoffset]), &(screen->screen[ssourcepos]), sizeof(screen->screen[0])*width*vstat.charwidth);
+			memmove(&(screen->rect->data[ssourcepos+sdestoffset]), &(screen->rect->data[ssourcepos]), sizeof(screen->screen[0])*width*vstat.charwidth);
+			ssourcepos += step;
+		}
+	}
+	screen->update_pixels = 1;
+	pthread_mutex_unlock(&screen->screenlock);
+}
+
 int bitmap_movetext(int x, int y, int ex, int ey, int tox, int toy)
 {
 	int	direction=1;
@@ -1129,9 +1163,7 @@ int bitmap_movetext(int x, int y, int ex, int ey, int tox, int toy)
 	int width=ex-x+1;
 	int height=ey-y+1;
 	struct vstat_vmem *vmem_ptr;
-	int32_t sdestoffset;
-	size_t ssourcepos;
-	int32_t screeny;
+	int step;
 
 	if(		   x<1
 			|| y<1
@@ -1163,46 +1195,23 @@ int bitmap_movetext(int x, int y, int ex, int ey, int tox, int toy)
 
 	pthread_mutex_lock(&vstatlock);
 	vmem_ptr = get_vmem(&vstat);
-	for(cy=0; cy<height; cy++) {
-		memmove(&(vmem_ptr->vmem[sourcepos+destoffset]), &(vmem_ptr->vmem[sourcepos]), sizeof(vmem_ptr->vmem[0])*width);
-		sourcepos += direction * cio_textinfo.screenwidth;
-	}
-
-	if (direction == -1) {
-		ssourcepos=((y + height - 1)     * vstat.charheight - 1) * vstat.scrnwidth + (x - 1)  * vstat.charwidth;
-		sdestoffset=((((toy + height - 1) * vstat.charheight - 1) * vstat.scrnwidth + (tox - 1) * vstat.charwidth) - ssourcepos);
-	}
-	else {
-		ssourcepos=(y - 1)     * vstat.scrnwidth * vstat.charheight + (x - 1)  * vstat.charwidth;
-		sdestoffset=(((toy - 1) * vstat.scrnwidth * vstat.charheight + (tox - 1) * vstat.charwidth) - ssourcepos);
-	}
-
-	pthread_mutex_lock(&screena.screenlock);
-	for(screeny=0; screeny < height*vstat.charheight; screeny++) {
-		memmove(&(screena.screen[ssourcepos+sdestoffset]), &(screena.screen[ssourcepos]), sizeof(screena.screen[0])*width*vstat.charwidth);
-		memmove(&(screena.rect->data[ssourcepos+sdestoffset]), &(screena.rect->data[ssourcepos]), sizeof(screena.screen[0])*width*vstat.charwidth);
-		ssourcepos += direction * vstat.scrnwidth;
-	}
-	screena.update_pixels = 1;
-	pthread_mutex_unlock(&screena.screenlock);
-
-	if (direction == -1) {
-		ssourcepos=((y+height-1)     *vstat.charheight-1)*vstat.scrnwidth + (x-1)  *vstat.charwidth;
-		sdestoffset=((((toy+height-1)*vstat.charheight-1)*vstat.scrnwidth + (tox-1)*vstat.charwidth)-ssourcepos);
+	/*
+	 * TODO: Optimization... make the buffers twice the height of the actual screen and just move the pointer
+	 * when scrolling until you hit the end... maybe not worth it for vmem, but likely a big win for the screen
+	 */
+	if (width == cio_textinfo.screenwidth) {
+		memmove(&(vmem_ptr->vmem[sourcepos+destoffset]), &(vmem_ptr->vmem[sourcepos]), sizeof(vmem_ptr->vmem[0])*width*height);
 	}
 	else {
-		ssourcepos=(y-1)     *vstat.scrnwidth*vstat.charheight + (x-1)  *vstat.charwidth;
-		sdestoffset=(((toy-1)*vstat.scrnwidth*vstat.charheight + (tox-1)*vstat.charwidth)-ssourcepos);
+		step = direction * cio_textinfo.screenwidth;
+		for(cy=0; cy<height; cy++) {
+			memmove(&(vmem_ptr->vmem[sourcepos+destoffset]), &(vmem_ptr->vmem[sourcepos]), sizeof(vmem_ptr->vmem[0])*width);
+			sourcepos += step;
+		}
 	}
 
-	pthread_mutex_lock(&screenb.screenlock);
-	for(screeny=0; screeny < height*vstat.charheight; screeny++) {
-		memmove(&(screenb.screen[ssourcepos+sdestoffset]), &(screenb.screen[ssourcepos]), sizeof(screenb.screen[0])*width*vstat.charwidth);
-		memmove(&(screenb.rect->data[ssourcepos+sdestoffset]), &(screenb.rect->data[ssourcepos]), sizeof(screenb.screen[0])*width*vstat.charwidth);
-		ssourcepos += direction * vstat.scrnwidth;
-	}
-	screenb.update_pixels = 1;
-	pthread_mutex_unlock(&screenb.screenlock);
+	bitmap_movetext_screen(&screena, x, y, tox, toy, direction, height, width);
+	bitmap_movetext_screen(&screenb, x, y, tox, toy, direction, height, width);
 
 	release_vmem(vmem_ptr);
 	pthread_mutex_unlock(&vstatlock);
@@ -1624,7 +1633,7 @@ int bitmap_setpalette(uint32_t index, uint16_t r, uint16_t g, uint16_t b)
 // Called with vstatlock
 static int init_screen(struct bitmap_screen *screen, int *width, int *height)
 {
-	uint32_t *newscreen;
+	uint32_t *newbuf;
 
 	pthread_mutex_lock(&screen->screenlock);
 	screen->screenwidth = vstat.scrnwidth;
@@ -1633,14 +1642,14 @@ static int init_screen(struct bitmap_screen *screen, int *width, int *height)
 	screen->screenheight = vstat.scrnheight;
 	if (height)
 		*height = screen->screenheight;
-	newscreen = realloc(screen->screen, screen->screenwidth * screen->screenheight * sizeof(screen->screen[0]));
+	newbuf = realloc(screen->screen, screen->screenwidth * screen->screenheight * 2 * sizeof(screen->screen[0]));
 
-	if (!newscreen) {
+	if (!newbuf) {
 		pthread_mutex_unlock(&screen->screenlock);
 		return(-1);
 	}
-	screen->screen = newscreen;
-	memset_u32(screen->screen, vstat.palette[0], screen->screenwidth * screen->screenheight);
+	memset_u32(newbuf, vstat.palette[0], screen->screenwidth * 2 * screen->screenheight);
+	screen->screen = newbuf;
 	screen->update_pixels = 1;
 	bitmap_drv_free_rect(screen->rect);
 	screen->rect = alloc_full_rect(screen);
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index e2a32aefaa365c255254187ce973ef35c8488d83..927be7e4ea904d79c7ba121a15eeecefe4edcd72 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -1063,6 +1063,7 @@ void sdl_video_event_thread(void *data)
 					case SDL_USEREVENT_FLUSH:
 						pthread_mutex_lock(&win_mutex);
 						if (win != NULL) {
+							pthread_mutex_unlock(&win_mutex);
 							pthread_mutex_lock(&sdl_headlock);
 							pthread_mutex_lock(&sdl_mode_mutex);
 							list = update_list;
@@ -1160,8 +1161,9 @@ void sdl_video_event_thread(void *data)
 								bitmap_drv_free_rect(list);
 							}
 						}
+						else
+							pthread_mutex_unlock(&win_mutex);
 
-						pthread_mutex_unlock(&win_mutex);
 						break;
 					case SDL_USEREVENT_SETNAME:
 						pthread_mutex_lock(&win_mutex);