diff --git a/src/conio/scale.c b/src/conio/scale.c
index 880822e38cbbdb387631ce314054354c2e03165b..fa92ebdabdb4127320a7d540a7507747759610de 100644
--- a/src/conio/scale.c
+++ b/src/conio/scale.c
@@ -8,6 +8,7 @@ static int r2y_inited;
 static void pointy_scale3(uint32_t* src, uint32_t* dest, int width, int height);
 static void pointy_scale5(uint32_t* src, uint32_t* dest, int width, int height);
 static void interpolate_height(uint32_t* src, uint32_t* dst, int width, int height, int newheight);
+static void interpolate_width(uint32_t* src, uint32_t* dst, int width, int height, int newwidth);
 static void multiply_scale(uint32_t* src, uint32_t* dst, int width, int height, int xmult, int ymult);
 
 static struct graphics_buffer *free_list;
@@ -104,6 +105,7 @@ do_scale(struct rectlist* rect, int* xscale, int* yscale, double ratio)
 	struct graphics_buffer *csrc;
 	uint32_t* nt;
 	int fheight;
+	int fwidth;
 
 	switch (*xscale) {
 		case 1:
@@ -172,10 +174,18 @@ do_scale(struct rectlist* rect, int* xscale, int* yscale, double ratio)
 	}
 
 	// Calculate the scaled height from ratio...
-	fheight = lround((double)(rect->rect.height * (*yscale)) / ratio);
+	if (ratio < 1)
+		fheight = lround((double)(rect->rect.height * (*yscale)) / ratio);
+	else
+		fheight = rect->rect.height * *yscale;
+
+	if (ratio > 1)
+		fwidth = lround((double)(rect->rect.width * (*xscale)) / ratio);
+	else
+		fwidth = rect->rect.width * *xscale;
 
 	// Now make sure target is big enough...
-	size_t needsz = rect->rect.width * (*xscale) * fheight * sizeof(uint32_t);
+	size_t needsz = fwidth * fheight * sizeof(uint32_t);
 	if (needsz > ret1->sz) {
 		nt = realloc(ret1->data, needsz);
 		if (nt == NULL)
@@ -259,7 +269,7 @@ do_scale(struct rectlist* rect, int* xscale, int* yscale, double ratio)
 	}
 
 	// And finally, interpolate if needed
-	if (ratio != 1) {
+	if (ratio < 1) {
 		interpolate_height(csrc->data, ctarget->data, csrc->w, csrc->h, fheight);
 		ctarget->h = fheight;
 		ctarget->w = csrc->w;
@@ -270,6 +280,17 @@ do_scale(struct rectlist* rect, int* xscale, int* yscale, double ratio)
 			ctarget = ret1;
 	}
 
+	if (ratio > 1) {
+		interpolate_width(csrc->data, ctarget->data, csrc->w, csrc->h, fwidth);
+		ctarget->h = csrc->h;
+		ctarget->w = fwidth;
+		csrc = ctarget;
+		if (ctarget == ret1)
+			ctarget = ret2;
+		else
+			ctarget = ret1;
+	}
+
 	*xscale = newscale;
 	*yscale = newscale;
 	release_buffer(ctarget);
@@ -495,6 +516,46 @@ uint32_t blend(const uint32_t c1, const uint32_t c2, const double weight)
 	return y2r[(y<<16)|(u<<8)|v];
 }
 
+/*
+ * This does non-integer *width* scaling.  It does not scale in the other
+ * direction.  This does the interpolation using Y'UV to prevent dimming of
+ * pixels.
+ */
+static void
+interpolate_width(uint32_t* src, uint32_t* dst, int width, int height, int newwidth)
+{
+	int x, y;
+	const double mult = (double)width / newwidth;
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < newwidth; x++) {
+			// First, calculate which two pixels this is between.
+			const double xpos = mult * x;
+			const int xposi = xpos;
+			if (x == xpos) {
+				// Exact match!
+				*dst = src[width * y + x];
+			}
+			else {
+				const double weight = xpos - xposi;
+				// Now pick the two pixels
+				const uint32_t pix1 = src[y * width + xposi] & 0xffffff;
+				uint32_t pix2;
+				if (xposi < width - 1)
+					pix2 = src[y * width + xposi + 1] & 0xffffff;
+				else
+					pix2 = src[y * width + xposi] & 0xffffff;
+				if (pix1 == pix2)
+					*dst = pix1;
+				else {
+					*dst = blend(pix1, pix2, weight);
+				}
+			}
+			dst++;
+		}
+	}
+}
+
 /*
  * This does non-integer *height* scaling.  It does not scale in the other
  * direction.  This does the interpolation using Y'UV to prevent dimming of
diff --git a/src/conio/vidmodes.c b/src/conio/vidmodes.c
index f804377efd66aa056685a866b9425216ebfb938e..463fd00711a144746e6f49ce2ac85b0c4481c5ed 100644
--- a/src/conio/vidmodes.c
+++ b/src/conio/vidmodes.c
@@ -67,7 +67,7 @@ struct video_params vparams[] = {
 	/* BW 80x28 */
 	{BW80X28, GREYSCALE_PALETTE,          80, 28, 12, 13, 14, 8, 1, 7, 0,   1,    1, 640,  392},
 	/* BW 80x43 */
-	{BW80X43, GREYSCALE_PALETTE,          80, 43,  7,  7, 14, 8, 1, 7, 0,   1,    1, 640,  350},
+	{BW80X43, GREYSCALE_PALETTE,          80, 43,  7,  7, 14, 8, 1, 7, 0, 729, 1000, 640,  350},
 	/* BW 80x50 */
 	{BW80X50, GREYSCALE_PALETTE,          80, 50,  7,  7,  8, 8, 1, 7, 0, 833, 1000, 640,  400},
 	/* BW 80x60 */
@@ -87,11 +87,11 @@ struct video_params vparams[] = {
 	/* Magical C4350 Mode */
 	{C4350, COLOUR_PALETTE,               80, 50,  7,  7,  8, 8, 1, 7, 0, 833, 1000, 640,  400},
 	/* Commodore 64 40x25 mode */
-	{C64_40X25, C64_PALETTE,              40, 25,  0,  7,  8, 8, 1, 0x6e, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 1, 1, 320, 200},
+	{C64_40X25, C64_PALETTE,              40, 25,  0,  7,  8, 8, 1, 0x6e, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 240, 312, 320, 200},
 	/* Commodore 128 40x25 mode */
-	{C128_40X25, C64_PALETTE,             40, 25,  0,  7,  8, 8, 1, 0xbd, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 1, 1, 320, 200},
+	{C128_40X25, C64_PALETTE,             40, 25,  0,  7,  8, 8, 1, 0xbd, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 240, 312, 320, 200},
 	/* Commodore 128 80x25 mode */
-	{C128_80X25, COLOUR_PALETTE,          80, 25,  0,  7,  8, 8, 2, 7,    CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 1, 1, 640, 200},
+	{C128_80X25, COLOUR_PALETTE,          80, 25,  0,  7,  8, 8, 2, 7,    CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 240, 312, 640, 200},
 	/* Atari 800 40x24 mode */
 	{ATARI_40X24, ATARI_PALETTE,          40, 24,  0,  7,  8, 8, 1, 7, 0,   1,    1, 320,  192},
 	/* Atari 800 XEP80 80x25 mode */