--- SDL_fbvideo.c.org	2003-08-29 18:52:32.000000000 +0900
+++ SDL_fbvideo.c	2003-09-01 21:23:59.000000000 +0900
@@ -51,7 +51,7 @@
 #include "SDL_fbmatrox.h"
 #include "SDL_fbriva.h"
 
-
+/* #define FBCON_DEBUG 1 */
 #if defined(i386) && defined(FB_TYPE_VGA_PLANES)
 #define VGA16_FBCON_SUPPORT
 #ifndef FB_AUX_VGA_PLANES_VGA4
@@ -76,9 +76,11 @@
 	{  0, 0,  720,  576 },		/* PAL */
 	{  0, 0,  720,  480 },		/* NTSC */
 	{  0, 0,  640,  480 },		/* 16 bpp: 0x111, or 273 */
+	{  0, 0,  480,  640 },
 	{  0, 0,  640,  400 },		/*  8 bpp: 0x100, or 256 */
 	{  0, 0,  512,  384 },
 	{  0, 0,  320,  240 },
+	{  0, 0,  240,  320 },
 	{  0, 0,  320,  200 }
 };
 static const struct {
@@ -112,9 +114,11 @@
 	*/
 	{  320,  200, 79440,  16, 16, 20,  4,  48, 1, 0, 2 },	/* 70 Hz */
 	{  320,  240, 63492,  16, 16, 16,  4,  48, 2, 0, 2 },	/* 72 Hz */
+        {  240,  320, 63492,  16, 16, 16,  4,  48, 3, 0, 2 },   /* 72 Hz */
 	{  512,  384, 49603,  48, 16, 16,  1,  64, 3, 0, 0 },	/* 78 Hz */
 	{  640,  400, 31746,  96, 32, 41,  1,  64, 3, 2, 0 },	/* 85 Hz */
 	{  640,  480, 31746, 120, 16, 16,  1,  64, 3, 0, 0 },	/* 75 Hz */
+        {  480,  640, 31746, 120, 16, 16,  1,  64, 4, 0, 0 },   /* 75 Hz */
 	{  768,  576, 26101, 144, 16, 28,  6, 112, 4, 0, 0 },	/* 60 Hz */
 	{  800,  600, 20000,  64, 56, 23, 37, 120, 6, 3, 0 },	/* 72 Hz */
 	{  960,  720, 17686, 144, 24, 28,  8, 112, 4, 0, 0 },	/* 60 Hz */
@@ -152,6 +156,10 @@
                                   struct fb_var_screeninfo *vinfo);
 static void FB_RestorePalette(_THIS);
 
+static char *console_fd_buf;
+static char *mapped_mem_fb;
+static int rotation_flag;
+
 /* FB driver bootstrap functions */
 
 static int FB_Available(void)
@@ -241,18 +249,30 @@
 
 	mode_okay = 0;
 	vinfo->bits_per_pixel = (index+1)*8;
-	vinfo->xres = *w;
-	vinfo->xres_virtual = *w;
-	vinfo->yres = *h;
-	vinfo->yres_virtual = *h;
+	if (rotation_flag == 0) {
+		vinfo->xres = *w;
+		vinfo->xres_virtual = *w;
+		vinfo->yres = *h;
+		vinfo->yres_virtual = *h;
+	} else {
+		vinfo->xres = *h;
+		vinfo->xres_virtual = *h;
+		vinfo->yres = *w;
+		vinfo->yres_virtual = *w;
+	}
 	vinfo->activate = FB_ACTIVATE_TEST;
 	if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, vinfo) == 0 ) {
 #ifdef FBCON_DEBUG
 		fprintf(stderr, "Checked mode %dx%d at %d bpp, got mode %dx%d at %d bpp\n", *w, *h, (index+1)*8, vinfo->xres, vinfo->yres, vinfo->bits_per_pixel);
 #endif
 		if ( (((vinfo->bits_per_pixel+7)/8)-1) == index ) {
-			*w = vinfo->xres;
-			*h = vinfo->yres;
+			if (rotation_flag == 0) {
+				*w = vinfo->xres;
+				*h = vinfo->yres;
+			} else {
+				*h = vinfo->xres;
+				*w = vinfo->yres;
+			}
 			mode_okay = 1;
 		}
 	}
@@ -332,6 +352,7 @@
 	unsigned int current_w;
 	unsigned int current_h;
 	const char *SDL_fbdev;
+	const char *SDL_rot_flag;
 
 	/* Initialize the library */
 	SDL_fbdev = getenv("SDL_FBDEV");
@@ -344,6 +365,14 @@
 		return(-1);
 	}
 
+	SDL_rot_flag = getenv("SDL_FBROT");
+	if ( SDL_rot_flag == NULL ) {
+		rotation_flag = 0;
+	} else {
+		rotation_flag = atoi(SDL_rot_flag);
+	}
+
+
 #ifndef DISABLE_THREADS
 	/* Create the hardware surface lock mutex */
 	hw_lock = SDL_CreateMutex();
@@ -407,13 +436,33 @@
 	mapped_offset = (((long)finfo.smem_start) -
 	                (((long)finfo.smem_start)&~(PAGE_SIZE-1)));
 	mapped_memlen = finfo.smem_len+mapped_offset;
-	mapped_mem = mmap(NULL, mapped_memlen,
-	                  PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
-	if ( mapped_mem == (char *)-1 ) {
-		SDL_SetError("Unable to memory map the video hardware");
-		mapped_mem = NULL;
-		FB_VideoQuit(this);
-		return(-1);
+	if (rotation_flag == 0) { 
+		mapped_mem = mmap(NULL, mapped_memlen,
+		                  PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
+		if ( mapped_mem == (char *)-1 ) {
+			SDL_SetError("Unable to memory map the video hardware");
+			mapped_mem = NULL;
+			FB_VideoQuit(this);
+			return(-1);
+		}
+	} else {
+ 
+		console_fd_buf = (char *)malloc(640*480*2);
+
+		if (console_fd_buf == NULL){
+			SDL_SetError("Unable to memory for buffer");
+			return(-1);
+		}
+	
+		mapped_mem_fb = mmap(NULL, mapped_memlen,
+		                  PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
+		if ( mapped_mem_fb == (char *)-1 ) {
+			SDL_SetError("Unable to memory map the video hardware");
+			mapped_mem_fb = NULL;
+			FB_VideoQuit(this);
+			return(-1);
+		}
+		mapped_mem = console_fd_buf;
 	}
 
 	/* Determine the current screen depth */
@@ -555,6 +604,7 @@
 
 /* Various screen update functions available */
 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
+static void FB_RotationUpdate(_THIS, int numrects, SDL_Rect *rects);
 #ifdef VGA16_FBCON_SUPPORT
 static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects);
 #endif
@@ -725,7 +775,7 @@
 	Uint32 Bmask;
 	char *surfaces_mem;
 	int surfaces_len;
-
+	
 	/* Set the terminal into graphics mode */
 	if ( FB_EnterGraphicsMode(this) < 0 ) {
 		return(NULL);
@@ -748,13 +798,24 @@
 		vinfo.activate = FB_ACTIVATE_NOW;
 		vinfo.accel_flags = 0;
 		vinfo.bits_per_pixel = bpp;
-		vinfo.xres = width;
-		vinfo.xres_virtual = width;
-		vinfo.yres = height;
-		if ( flags & SDL_DOUBLEBUF ) {
-			vinfo.yres_virtual = height*2;
+		if (rotation_flag == 0) {
+			vinfo.xres = width;
+			vinfo.xres_virtual = width;
+			vinfo.yres = height;
+			if ( flags & SDL_DOUBLEBUF ) {
+				vinfo.yres_virtual = height*2;
+			} else {
+				vinfo.yres_virtual = height;
+			}
 		} else {
-			vinfo.yres_virtual = height;
+			vinfo.xres = height;
+			vinfo.xres_virtual = height;
+			vinfo.yres = width;
+			if ( flags & SDL_DOUBLEBUF ) {
+				vinfo.yres_virtual = width*2;
+			} else {
+				vinfo.yres_virtual = width;
+			}
 		}
 		vinfo.xoffset = 0;
 		vinfo.yoffset = 0;
@@ -776,6 +837,15 @@
 				return(NULL);
 			}
 		}
+		vinfo.xres = width;
+		vinfo.xres_virtual = width;
+		vinfo.yres = height;
+		if ( flags & SDL_DOUBLEBUF ) {
+			vinfo.yres_virtual = height*2;
+		} else {
+			vinfo.yres_virtual = height;
+		}
+
 	} else {
 		int maxheight;
 
@@ -821,7 +891,9 @@
 		SDL_SetError("Couldn't get console hardware info");
 		return(NULL);
 	}
-
+#ifdef FBCON_DEBUG
+	print_finfo(&finfo);
+#endif
 	/* Save hardware palette, if needed */
 	FB_SavePalette(this, &finfo, &vinfo);
 
@@ -829,7 +901,11 @@
 	current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);
 	current->w = vinfo.xres;
 	current->h = vinfo.yres;
-	current->pitch = finfo.line_length;
+	if (rotation_flag == 0 ) {
+		current->pitch = finfo.line_length;
+	} else { 
+	current->pitch = vinfo.xres*2;
+	}
 	current->pixels = mapped_mem+mapped_offset;
 
 	/* Set up the information for hardware surfaces */
@@ -863,7 +939,7 @@
 	}
 
 	/* Set the update rectangle function */
-	this->UpdateRects = FB_DirectUpdate;
+	this->UpdateRects = FB_RotationUpdate;
 
 	/* We're done */
 	return(current);
@@ -1123,6 +1199,85 @@
 	return;
 }
 
+static void FB_RotationUpdate(_THIS, int numrects, SDL_Rect *rects)
+{
+	unsigned short *pDst;
+	unsigned short *pSrc;
+	unsigned int width;
+	unsigned int height;
+	unsigned int srcYAdd;
+	unsigned int dstXAdd;
+	unsigned int dstYSub;
+	unsigned int i;
+	unsigned int dstH;
+	unsigned int dstW;
+	
+
+	switch (rotation_flag) {
+	case 0:
+		break;
+	case 1:
+		memcpy(mapped_mem_fb,mapped_mem,640*480*2);
+		break;
+	case 2:
+		break;
+	case 3:
+		dstW=cache_vinfo.xres;
+		dstH=cache_vinfo.yres;
+#ifdef FBCON_DEBUG
+		printf("dstH = %d : dstW = %d : rects->x = %d : rects->y = %d\n",dstH,dstW,rects->x,rects->y);
+#endif
+		while (numrects) {
+			if (rects->w != dstW || rects->h != dstH) {
+				pSrc = mapped_mem + (rects->x + rects->y * dstW)*2;
+				pDst = mapped_mem_fb + (dstH-1+rects->x * dstH - rects->y)*2;
+
+				width = rects->w;
+				height = rects->h;
+
+				srcYAdd = dstW - rects->w;
+				dstXAdd = dstH;
+				dstYSub = (dstH * rects->w) + 1;
+
+				while (height--) {
+					i = width;
+					while (i--) {
+						*pDst = *pSrc ++;
+						pDst += dstXAdd;
+					}
+					pSrc += srcYAdd;
+					pDst -= dstYSub;
+				}
+
+			} else {
+				pDst=mapped_mem_fb+dstH*2-2;
+				pSrc=mapped_mem;
+				height=dstH;
+				width=dstW;
+				dstXAdd=height;
+				dstYSub=dstW*dstH+1;
+
+				while (height--) {
+					i = width;
+					while (i--) {
+						*pDst = *pSrc ++;
+						pDst += dstXAdd;
+					}
+					pDst -= dstYSub;
+				}
+			}
+			numrects--;
+			rects++;
+		}
+		break;
+	default:
+		break;
+	}
+
+
+
+}
+
 #ifdef VGA16_FBCON_SUPPORT
 /* Code adapted with thanks from the XFree86 VGA16 driver! :) */
 #define writeGr(index, value) \
