* Patch by Marc Singer, 29 May 2003:
  Fixed rarp boot method for IA32 and other little-endian CPUs.

* Patch by Marc Singer, 28 May 2003:
  Added port I/O commands.

* Patch by Matthew McClintock, 28 May 2003
  - cpu/mpc824x/start.S: fix relocation code when booting from RAM
  - minor patches for utx8245

* Patch by Daniel Engström, 28 May 2003:
  x86 update

* Patch by Dave Ellis, 9 May 2003 + 27 May 2003:
  add nand flash support to SXNI855T configuration
  fix/extend nand flash support:
  - fix 'nand erase' command so does not erase bad blocks
  - fix 'nand write' command so does not write to bad blocks
  - fix nand_probe() so handles no flash detected properly
  - add doc/README.nand
  - add .jffs2 and .oob options to nand read/write
  - add 'nand bad' command to list bad blocks
  - add 'clean' option to 'nand erase' to write JFFS2 clean markers
  - make NAND read/write faster

* Patch by Rune Torgersen, 23 May 2003:
  Update for MPC8266ADS board
diff --git a/lib_i386/video.c b/lib_i386/video.c
new file mode 100644
index 0000000..776022e
--- /dev/null
+++ b/lib_i386/video.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h> 
+#include <pci.h> 
+#include <devices.h>
+#include <i8042.h>
+#include <asm/ptrace.h> 
+#include <asm/realmode.h> 
+#include <asm/io.h> 
+#include <asm/pci.h> 
+
+
+/* basic textmode I/O from linux kernel */
+static char *vidmem = (char *)0xb8000;
+static int vidport;
+static int lines, cols;
+static int orig_x, orig_y;
+
+static void beep(int dur)
+{
+	int i;
+	
+	outb_p(3, 0x61);
+	for (i=0;i<10*dur;i++) {
+		udelay(1000);
+	}
+	outb_p(0, 0x61);
+}
+
+static void scroll(void)
+{
+	int i;
+
+	memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+	for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+		vidmem[i] = ' ';
+}
+
+static void __video_putc(const char c, int *x, int *y)
+{
+	if (c == '\n') {
+ 		(*x) = 0;
+		if ( ++(*y) >= lines ) {
+			scroll();
+			(*y)--;
+		}
+	} else if (c == '\b') { 
+		if ((*x) != 0) {
+			--(*x);
+			vidmem [ ( (*x) + cols * (*y) ) * 2 ] = ' '; 
+		}
+ 	} else if (c == '\r') { 
+		(*x) = 0;
+		
+	} else if (c == '\a') { 
+		beep(3);
+		
+	} else if (c == '\t') { 
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+		__video_putc(' ', x, y);
+	} else if (c == '\v') { 
+		switch ((*x) % 8) {
+		case 0:
+			__video_putc(' ', x, y);
+		case 7:
+			__video_putc(' ', x, y);
+		case 6:
+			__video_putc(' ', x, y);
+		case 5:
+			__video_putc(' ', x, y);
+		case 4:
+			__video_putc(' ', x, y);
+		case 3:
+			__video_putc(' ', x, y);
+		case 2:
+			__video_putc(' ', x, y);
+		case 1:
+			__video_putc(' ', x, y);
+		}
+	} else if (c == '\f') { 
+		int i;
+		for (i=0;i<lines*cols*2;i+=2) {
+			vidmem[i] = 0;
+		}
+		(*x) = 0;
+		(*y) = 0;
+	} else {
+		vidmem [ ( (*x) + cols * (*y) ) * 2 ] = c; 
+		if ( ++(*x) >= cols ) {
+			(*x) = 0;
+			if ( ++(*y) >= lines ) {
+				scroll();
+				(*y)--;
+			}
+		}
+	}
+}
+
+static void video_putc(const char c)
+{
+	int x,y,pos;
+	
+	x = orig_x;
+	y = orig_y;
+	
+	__video_putc(c, &x, &y);
+
+	orig_x = x;
+	orig_y = y;
+	
+	pos = (x + cols * y) * 2;	/* Update cursor position */
+	outb_p(14, vidport);
+	outb_p(0xff & (pos >> 9), vidport+1);
+	outb_p(15, vidport);
+	outb_p(0xff & (pos >> 1), vidport+1);
+}
+
+static void video_puts(const char *s)
+{
+	int x,y,pos;
+	char c;
+
+	x = orig_x;
+	y = orig_y;
+
+	while ( ( c = *s++ ) != '\0' ) {
+		__video_putc(c, &x, &y);
+	}
+
+	orig_x = x;
+	orig_y = y;
+
+	pos = (x + cols * y) * 2;	/* Update cursor position */
+	outb_p(14, vidport);
+	outb_p(0xff & (pos >> 9), vidport+1);
+	outb_p(15, vidport);
+	outb_p(0xff & (pos >> 1), vidport+1);
+}
+
+int video_init(void)
+{
+	u16 pos;
+	
+	static device_t vga_dev;
+	static device_t kbd_dev;
+	
+	vidmem = (char *) 0xb8000;
+	vidport = 0x3d4;
+
+	lines = 25;
+	cols = 80;
+	
+	outb_p(14, vidport);
+	pos = inb_p(vidport+1);
+	pos <<= 8;
+	outb_p(15, vidport);
+	pos |= inb_p(vidport+1);
+	
+	orig_x = pos%cols;
+	orig_y = pos/cols;
+
+#if 0	
+	printf("pos %x %d %d\n", pos, orig_x, orig_y);
+#endif	
+	if (orig_y > lines) {
+		orig_x = orig_y =0;
+	}
+	
+	
+	memset(&vga_dev, 0, sizeof(vga_dev));
+        strcpy(vga_dev.name, "vga");
+        vga_dev.ext   = 0; 
+        vga_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+        vga_dev.putc  = video_putc;        /* 'putc' function */
+        vga_dev.puts  = video_puts;        /* 'puts' function */
+        vga_dev.tstc  = NULL;              /* 'tstc' function */
+        vga_dev.getc  = NULL;              /* 'getc' function */
+
+        if (device_register(&vga_dev) == 0) {
+            return 1;
+	}
+	
+	if (i8042_kbd_init()) {
+		return 1;
+	}
+	
+	memset(&kbd_dev, 0, sizeof(kbd_dev));
+        strcpy(kbd_dev.name, "kbd");
+        kbd_dev.ext   = 0; 
+        kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+        kbd_dev.putc  = NULL;        /* 'putc' function */
+        kbd_dev.puts  = NULL;        /* 'puts' function */
+        kbd_dev.tstc  = i8042_tstc;  /* 'tstc' function */
+        kbd_dev.getc  = i8042_getc;  /* 'getc' function */
+
+        if (device_register(&kbd_dev) == 0) {
+            return 1;
+	}
+	return 0;
+}
+
+
+int drv_video_init(void) 
+{
+	if (video_bios_init()) {
+		return 1;
+	}
+	
+	return video_init();	
+}
+