Index: fb/ega.c
===================================================================
--- fb/ega.c	(revision 26f48570da29985456d52782f8cbb838002ab4dc)
+++ fb/ega.c	(revision 1160f8dedddd04b402223af10ebc3b40509cbc14)
@@ -26,5 +26,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
+#include <stdlib.h>
+#include <unistd.h>
 #include <align.h>
 #include <async.h>
@@ -44,4 +45,11 @@
 #include "main.h"
 
+#define MAX_SAVED_SCREENS 256
+typedef struct saved_screen {
+	short *data;
+} saved_screen;
+
+saved_screen saved_screens[MAX_SAVED_SCREENS];
+
 
 #define EGA_IO_ADDRESS 0x3d4
@@ -60,5 +68,5 @@
 static char *scr_addr;
 
-static unsigned int style = 0x0f;
+static unsigned int style = 0x1e;
 
 static inline void outb(u16 port, u8 b)
@@ -114,5 +122,5 @@
 }
 
-void cursor_goto(unsigned int row, unsigned int col)
+static void cursor_goto(unsigned int row, unsigned int col)
 {
 	int ega_cursor;
@@ -126,5 +134,5 @@
 }
 
-void cursor_disable(void)
+static void cursor_disable(void)
 {
 	u8 stat;
@@ -135,5 +143,5 @@
 }
 
-void cursor_enable(void)
+static void cursor_enable(void)
 {
 	u8 stat;
@@ -144,4 +152,19 @@
 }
 
+static void scroll(int rows)
+{
+	int i;
+	if (rows > 0) {
+		memcpy(scr_addr,((char *)scr_addr)+rows*scr_width*2,scr_width*scr_height*2-rows*scr_width*2);
+		for(i=0;i<rows*scr_width;i++)
+			(((short *)scr_addr)+scr_width*scr_height-rows*scr_width)[i]=((style<<8)+' ');
+	} else if (rows < 0) {
+
+		memcpy(((char *)scr_addr)-rows*scr_width*2,scr_addr,scr_width*scr_height*2+rows*scr_width*2);
+		for(i=0;i<-rows*scr_width;i++)
+			((short *)scr_addr)[i]=((style<<8)+' ');
+	}
+}
+
 static void printchar(char c, unsigned int row, unsigned int col)
 {
@@ -159,9 +182,29 @@
 		scr_addr[i*2] = data[i].character;
 		if (data[i].style.fg_color > data[i].style.bg_color)
-			scr_addr[i*2+1] = 0x0f;
+			scr_addr[i*2+1] = 0x1e;
 		else
-			scr_addr[i*2+1] = 0xf0;
-	}
-}
+			scr_addr[i*2+1] = 0xe1;
+	}
+}
+
+static int save_screen(void)
+{
+	int i;
+	short *mem;
+	for(i=0;(i<MAX_SAVED_SCREENS)&&(saved_screens[i].data);i++);
+	if(i==MAX_SAVED_SCREENS) return EINVAL;
+	if(!(saved_screens[i].data=malloc(2*scr_width*scr_height))) return ENOMEM;
+	memcpy(saved_screens[i].data,scr_addr,2*scr_width*scr_height);
+	return i;
+}
+
+static int print_screen(int i)
+{
+	if(saved_screens[i].data)
+			memcpy(scr_addr,saved_screens[i].data,2*scr_width*scr_height);
+	else return EINVAL;
+	return i;
+}
+
 
 static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall)
@@ -175,4 +218,5 @@
 	keyfield_t *interbuf = NULL;
 	size_t intersize = 0;
+	int i;
 
 	if (client_connected) {
@@ -235,4 +279,13 @@
  			retval = 0;
  			break;
+		case FB_SCROLL:
+			i = IPC_GET_ARG1(call);
+			if (i > scr_height || i < (- (int)scr_height)) {
+				retval = EINVAL;
+				break;
+			}
+			scroll(i);
+			retval = 0;
+			break;
 		case FB_CURSOR_VISIBILITY:
 			if(IPC_GET_ARG1(call))
@@ -246,7 +299,27 @@
 			bgcolor = IPC_GET_ARG2(call);
 			if (fgcolor > bgcolor)
-				style = 0x0f;
+				style = 0x1e;
 			else
-				style = 0xf0;
+				style = 0xe1;
+
+		case FB_VP_DRAW_PIXMAP:
+			i = IPC_GET_ARG2(call);
+			retval = print_screen(i);
+			break;
+		case FB_VP2PIXMAP:
+			retval = save_screen();
+			break;
+		case FB_DROP_PIXMAP:
+			i = IPC_GET_ARG1(call);
+			if (i >= MAX_SAVED_SCREENS) {
+				retval = EINVAL;
+				break;
+			}
+			if (saved_screens[i].data) {
+				free(saved_screens[i].data);
+				saved_screens[i].data = NULL;
+			}
+			break;
+
 		default:
 			retval = ENOENT;
@@ -275,6 +348,4 @@
 	async_set_client_connection(ega_client_connection);
 
-	clrscr();
-
 	return 0;
 }
Index: fb/fb.c
===================================================================
--- fb/fb.c	(revision 26f48570da29985456d52782f8cbb838002ab4dc)
+++ fb/fb.c	(revision 1160f8dedddd04b402223af10ebc3b40509cbc14)
@@ -700,4 +700,5 @@
 		memcpy(screen.fbaddress + tmp, pmap->data + y * srcrowsize, realrowsize);
 	}
+	return pm;
 }
 
