diff -u --recursive --new-file v1.3.0/linux/Makefile linux/Makefile
--- v1.3.0/linux/Makefile	Wed Jun  7 13:44:44 1995
+++ linux/Makefile	Tue Jun 13 10:48:24 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 0
+SUBLEVEL = 1
 
 ARCH = i386
 
@@ -236,6 +236,7 @@
 mrproper: clean
 	rm -f include/linux/autoconf.h include/linux/version.h
 	rm -f drivers/sound/local.h
+	rm -f drivers/char/uni_hash_tbl.h drivers/char/conmakehash
 	rm -f .version .config* config.in config.old
 	rm -f include/asm
 	rm -f .depend `find . -name .depend -print`
diff -u --recursive --new-file v1.3.0/linux/README linux/README
--- v1.3.0/linux/README	Wed Apr 12 08:12:14 1995
+++ linux/README	Tue Jun 13 10:47:46 1995
@@ -1,10 +1,24 @@
 
-	Linux kernel release 1.2.xx
+	Linux kernel release 1.3.xx
 
-These are the release notes for linux version 1.2.  Read them carefully,
+These are the release notes for linux version 1.3.  Read them carefully,
 as they tell you what this is all about, explain how to install the
 kernel, and what to do if something goes wrong. 
 
+Linux version 1.3 is a DEVELOPMENT kernel, and not intended for general 
+public use.  Different releases may have various and sometimes severe 
+bugs.  It is *strongly* recommended that you back up the previous kernel 
+before installing any new 1.3.xx release.
+
+If you need to use a proven and stable Linux kernel, please use either 
+1.0.9 or 1.2.xx.  All features which will be in the 1.3.xx releases will 
+be contained in 1.4.xx when the code base has stabilized again.
+
+If you decide to use 1.3, it is recommended that you join the kernel mailing 
+list.  To do this, e-mail majordomo@vger.rutgers.edu, and put in the body 
+of the message "subscribe linux-kernel" or "subscribe linux-kernel-digest" 
+for a daily digest of the mailing list (it is a high-traffic list.)
+
 WHAT IS LINUX?
 
   Linux is a Unix clone for 386/486-based PCs written from scratch by
@@ -33,12 +47,13 @@
  - If you install the full sources, do a
 
 		cd /usr/src
-		gzip -cd linux-1.2.XX.tar.gz | tar xfv -
+		gzip -cd linux-1.3.XX.tar.gz | tar xfv -
 
    to get it all put in place. Replace "XX" with the version number of the
    latest kernel.
 
- - Installing by patching is not worth the effort because the full set of
+ - You can also upgrade between 1.3.xx releases by patching.  For a large
+   set of revisions, it is not worth the effort since the full set of 
    patches is bigger than a new kernel distribution. Instead, get the
    latest full source archive and install as above. Then, get all newer
    patch files, and do
@@ -105,7 +120,8 @@
    versions can have problems compiling newer versions of linux.  If you
    upgrade your compiler, remember to get the new binutils package too
    (for as/ld/nm and company). Do not use gcc-2.6.0; it has a few serious
-   bugs.
+   bugs.  Some problems have been reported occasionally with 2.6.3 as well,
+   so use that version at your own risk.
 
  - do a "make zImage" to create a compressed kernel image.  If you want
    to make a bootdisk (without root filesystem or lilo), insert a floppy
@@ -113,7 +129,9 @@
    "make zlilo" if you have lilo installed to suit the kernel makefiles,
    but you may want to check your particular lilo setup first. 
 
- - keep a backup kernel handy in case something goes wrong. 
+ - keep a backup kernel handy in case something goes wrong.  This is 
+   especially true for the development releases, since each new release
+   contains new code which has not been debugged. 
 
  - In order to boot your new kernel, you'll need to copy the kernel
    image (found in /usr/src/linux/arch/i386/boot/zImage after compilation)
diff -u --recursive --new-file v1.3.0/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v1.3.0/linux/arch/i386/boot/setup.S	Thu Jan  5 13:55:40 1995
+++ linux/arch/i386/boot/setup.S	Tue Jun 13 10:47:46 1995
@@ -175,6 +175,11 @@
 	int	0x10
 	mov	[4],bx		! bh = display page
 	mov	[6],ax		! al = video mode, ah = window width
+	xor	ax,ax
+	mov	es,ax		! Access low memory
+	seg es
+	mov	ax,[0x485]	! POINTS - Height of character matrix
+	mov	[16],ax
 
 ! Get hd0 data
 
diff -u --recursive --new-file v1.3.0/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v1.3.0/linux/drivers/char/Makefile	Tue Jun  6 11:22:05 1995
+++ linux/drivers/char/Makefile	Tue Jun 13 10:47:46 1995
@@ -16,6 +16,11 @@
 .c.o:
 	$(CC) $(CFLAGS) -c $<
 
+#
+# This file contains the font map for the default (hardware) font
+#
+FONTMAPFILE = cp437.uni
+
 OBJS  = tty_io.o n_tty.o console.o keyboard.o serial.o \
 	tty_ioctl.o pty.o vt.o mem.o vc_screen.o \
 	defkeymap.o consolemap.o vesa_blank.o selection.o
@@ -24,7 +29,6 @@
 	tty_ioctl.c pty.c vt.c mem.c vc_screen.c \
 	defkeymap.c consolemap.c vesa_blank.c selection.c
 
-
 ifdef CONFIG_CYCLADES
 OBJS := $(OBJS) cyclades.o
 SRCS := $(SRCS) cyclades.c
@@ -98,13 +102,19 @@
 
 endif
 
-dep:
+dep: uni_hash_tbl.h
 	$(CPP) -M $(SRCS) > .depend
 ifdef MODULES
 	$(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend
 endif
 
 dummy:
+
+conhakehash: conmakehash.c
+	$(HOSTCC) -o conmakehash conmakehash.c
+
+uni_hash_tbl.h: $(FONTMAPFILE) conmakehash
+	./conmakehash $(FONTMAPFILE) 641 283 6 > uni_hash_tbl.h
 
 #
 # include a dependency file if one exists
diff -u --recursive --new-file v1.3.0/linux/drivers/char/README.unicode linux/drivers/char/README.unicode
--- v1.3.0/linux/drivers/char/README.unicode	Thu Jan  1 02:00:00 1970
+++ linux/drivers/char/README.unicode	Tue Jun 13 10:47:47 1995
@@ -0,0 +1,49 @@
+The Linux kernel code has been rewritten to use Unicode to map
+characters to fonts.  By downloading a single Unicode-to-font table,
+both the eight-bit character sets and UTF-8 mode are changed to use
+the font as indicated.
+
+This changes the semantics of the eight-bit character tables subtly.
+The four character tables are now:
+
+Map symbol	Map name			Escape code (G0)
+
+LAT1_MAP	Latin-1 (ISO 8859-1)		ESC ( B
+GRAF_MAP	DEC VT100 pseudographics	ESC ( 0
+IBMPC_MAP	IBM code page 437		ESC ( U
+USER_MAP	User defined			ESC ( K
+
+In particular, ESC ( U is no longer "straight to font", since the font
+might be completely different than the IBM character set.  This
+permits for example the use of block graphics even with a Latin-1 font
+loaded.
+
+In accordance with the Unicode standard/ISO 10646 the range U+F000 to
+U+F8FF has been reserved for OS-wide allocation (the Unicode Standard
+refers to this as a "Corporate Zone").  U+F000 was picked as the
+starting point since it lets the direct-mapping area start on a large
+power of two (in case 1024- or 2048-character fonts ever become
+necessary).  This leaves U+E000 to U+EFFF as End User Zone.
+
+The Unicodes in the range U+F000 to U+F1FF have been hard-coded to map
+directly to the loaded font, bypassing the translation table.  The
+user-defined map now defaults to U+F000 to U+F1FF, emulating the
+previous behaviour.
+
+In addition, the following characters not present in Unicode 1.1.4 (at
+least, I have not found them!) have been defined; these are used by
+the DEC VT graphics map:
+
+U+F800 DEC VT GRAPHICS HORIZONTAL LINE SCAN 1
+U+F801 DEC VT GRAPHICS HORIZONTAL LINE SCAN 3
+U+F803 DEC VT GRAPHICS HORIZONTAL LINE SCAN 7
+U+F804 DEC VT GRAPHICS HORIZONTAL LINE SCAN 9
+
+The DEC VT220 uses a 6x10 character matrix, and these characters form
+a smooth progression in the DEC VT graphics character set.  I have
+omitted the scan 5 line, since it is also used as a block-graphics
+character, and hence has been coded as U+2500 FORMS LIGHT HORIZONTAL.
+However, I left U+F802 blank should the need arise.  
+
+	H. Peter Anvin <Peter.Anvin@linux.org>
+	Yggdrasil Computing, Inc.
diff -u --recursive --new-file v1.3.0/linux/drivers/char/conmakehash.c linux/drivers/char/conmakehash.c
--- v1.3.0/linux/drivers/char/conmakehash.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/char/conmakehash.c	Tue Jun 13 10:51:47 1995
@@ -0,0 +1,361 @@
+/*
+ * conmakehash.c
+ *
+ * Create a pre-initialized kernel Unicode hash table
+ *
+ * Copyright (C) 1995 H. Peter Anvin
+ *
+ * This program may be freely copied under the terms of the GNU
+ * General Public License (GPL), version 2, or at your option
+ * any later version.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef unsigned short unicode;
+
+struct unipair
+{
+  unsigned short glyph;		/* Glyph code */
+  unicode uc;			/* Unicode listed */
+};
+
+void usage(char *argv0)
+{
+  fprintf(stderr, "Usage: \n"
+         "        %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
+  exit(EX_USAGE);
+}
+
+int getunicode(char **p0)
+{
+  char *p = *p0;
+
+  while (*p == ' ' || *p == '\t')
+    p++;
+  if (*p != 'U' || p[1] != '+' ||
+      !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
+      !isxdigit(p[5]) || isxdigit(p[6]))
+    return -1;
+  *p0 = p+6;
+  return strtol(p+2,0,16);
+}
+
+struct unipair *hashtable;
+int hashsize = 641;		/* Size of hash table */
+int hashstep = 189;		/* Hash stepping */
+int maxhashlevel = 6;		/* Maximum hash depth */
+int hashlevel = 0;		/* Actual hash depth */
+
+void addpair(int fp, int un)
+{
+  int i, lct;
+  unicode hu;
+
+  if ( un <= 0xFFFE )
+    {
+      /* Add to hash table */
+
+      i = un % hashsize;
+      lct = 1;
+      
+      while ( (hu = hashtable[i].uc) != 0xffff && hu != un )
+	{
+	  if (lct++ >= maxhashlevel)
+	    {
+	      fprintf(stderr, "ERROR: Hash table overflow\n");
+	      exit(EX_DATAERR);
+	    }
+	  i += hashstep;
+	  if ( i >= hashsize )
+	    i -= hashsize;
+	}
+      if ( lct > hashlevel )
+	hashlevel = lct;
+
+      hashtable[i].uc = un;
+      hashtable[i].glyph = fp;
+    }
+
+  /* otherwise: ignore */
+}
+
+int main(int argc, char *argv[])
+{
+  FILE *ctbl;
+  char *tblname;
+  char buffer[65536];
+  int fontlen;
+  int i;
+  int fp0, fp1, un0, un1;
+  char *p, *p1;
+
+  if ( argc < 2 || argc > 5 )
+    usage(argv[0]);
+
+  if ( !strcmp(argv[1],"-") )
+    {
+      ctbl = stdin;
+      tblname = "stdin";
+    }
+  else
+    {
+      ctbl = fopen(tblname = argv[1], "r");
+      if ( !ctbl )
+	{
+	  perror(tblname);
+	  exit(EX_NOINPUT);
+	}
+    }
+
+  if ( argc > 2 )
+    {
+      hashsize = atoi(argv[2]);
+      if ( hashsize < 256 || hashsize > 2048 )
+	{
+	  fprintf(stderr, "Illegal hash size\n");
+	  exit(EX_USAGE);
+	}
+    }
+  
+  if ( argc > 3 )
+    {
+      hashstep = atoi(argv[3]) % hashsize;
+      if ( hashstep < 0 ) hashstep += hashsize;
+      if ( hashstep < 16 || hashstep >= hashsize-16 )
+	{
+	  fprintf(stderr, "Bad hash step\n");
+	  exit(EX_USAGE);
+	}
+    }
+
+  /* Warn the user in case the hashstep and hashsize are not relatively
+     prime -- this algorithm could be massively improved */
+
+  for ( i = hashstep ; i > 1 ; i-- )
+    {
+      if ( hashstep % i == 0 && hashsize % i == 0 )
+	break;			/* Found GCD */
+    }
+
+  if ( i > 1 )
+    {
+      fprintf(stderr,
+      "WARNING: hashsize and hashstep have common factors (gcd = %d)\n", i);
+    }
+
+  if ( argc > 4 )
+    {
+      maxhashlevel = atoi(argv[4]);
+      if ( maxhashlevel < 1 || maxhashlevel > hashsize )
+	{
+	  fprintf(stderr, "Illegal max hash level\n");
+	  exit(EX_USAGE);
+	}
+    }
+
+  /* For now we assume the default font is always 256 characters */
+  fontlen = 256;
+
+  /* Initialize hash table */
+
+  hashtable = malloc(hashsize * sizeof(struct unipair));
+  if ( !hashtable )
+    {
+      fprintf(stderr, "Could not allocate memory for hash table\n");
+      exit(EX_OSERR);
+    }
+
+  for ( i = 0 ; i < hashsize ; i++ )
+    {
+      hashtable[i].uc = 0xffff;
+      hashtable[i].glyph = 0;
+    }
+
+  /* Now we come to the tricky part.  Parse the input table. */
+
+  while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
+    {
+      if ( (p = strchr(buffer, '\n')) != NULL )
+	*p = '\0';
+      else
+	fprintf(stderr, "%s: Warning: line too long\n", tblname);
+
+      p = buffer;
+
+/*
+ * Syntax accepted:
+ *	<fontpos>	<unicode> <unicode> ...
+ *	<range>		idem
+ *	<range>		<unicode range>
+ *
+ * where <range> ::= <fontpos>-<fontpos>
+ * and <unicode> ::= U+<h><h><h><h>
+ * and <h> ::= <hexadecimal digit>
+ */
+
+      while (*p == ' ' || *p == '\t')
+	p++;
+      if (!*p || *p == '#')
+	continue;	/* skip comment or blank line */
+
+      fp0 = strtol(p, &p1, 0);
+      if (p1 == p)
+	{
+	  fprintf(stderr, "Bad input line: %s\n", buffer);
+	  exit(EX_DATAERR);
+        }
+      p = p1;
+
+      while (*p == ' ' || *p == '\t')
+	p++;
+      if (*p == '-')
+	{
+	  p++;
+	  fp1 = strtol(p, &p1, 0);
+	  if (p1 == p)
+	    {
+	      fprintf(stderr, "Bad input line: %s\n", buffer);
+	      exit(EX_DATAERR);
+	    }
+	  p = p1;
+        }
+      else
+	fp1 = 0;
+
+      if ( fp0 < 0 || fp0 >= fontlen )
+	{
+	    fprintf(stderr,
+		    "%s: Glyph number (0x%x) larger than font length\n",
+		    tblname, fp0);
+	    exit(EX_DATAERR);
+	}
+      if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
+	{
+	    fprintf(stderr,
+		    "%s: Bad end of range (0x%x)\n",
+		    tblname, fp1);
+	    exit(EX_DATAERR);
+	}
+
+      if (fp1)
+	{
+	  /* we have a range; expect the word "idem" or a Unicode range of the
+	     same length */
+	  while (*p == ' ' || *p == '\t')
+	    p++;
+	  if (!strncmp(p, "idem", 4))
+	    {
+	      for (i=fp0; i<=fp1; i++)
+		addpair(i,i);
+	      p += 4;
+	    }
+	  else
+	    {
+	      un0 = getunicode(&p);
+	      while (*p == ' ' || *p == '\t')
+		p++;
+	      if (*p != '-')
+		{
+		  fprintf(stderr,
+"%s: Corresponding to a range of font positions, there should be a Unicode range\n",
+			  tblname);
+		  exit(EX_DATAERR);
+	        }
+	      p++;
+	      un1 = getunicode(&p);
+	      if (un0 < 0 || un1 < 0)
+		{
+		  fprintf(stderr,
+"%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
+			  tblname, fp0, fp1);
+		  exit(EX_DATAERR);
+	        }
+	      if (un1 - un0 != fp1 - fp0)
+		{
+		  fprintf(stderr,
+"%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
+			  tblname, un0, un1, fp0, fp1);
+		  exit(EX_DATAERR);
+	        }
+	      for(i=fp0; i<=fp1; i++)
+		addpair(i,un0-fp0+i);
+	    }
+        }
+      else
+	{
+	    /* no range; expect a list of unicode values for a single font position */
+
+	    while ( (un0 = getunicode(&p)) >= 0 )
+	      addpair(fp0, un0);
+	}
+      while (*p == ' ' || *p == '\t')
+	p++;
+      if (*p && *p != '#')
+	fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
+    }
+
+  /* Okay, we hit EOF, now output hash table */
+  
+  fclose(ctbl);
+  
+  printf("\
+/*\n\
+ * uni_hash_tbl.h\n\
+ *\n\
+ * Do not edit this file; it was automatically generated by\n\
+ *\n\
+ * conmakehash %s %d %d %d > uni_hash_tbl.h\n\
+ *\n\
+ */\n\
+\n\
+#include <linux/kd.h>\n\
+\n\
+#define HASHSIZE      %d\n\
+#define HASHSTEP      %d\n\
+#define MAXHASHLEVEL  %d\n\
+#define DEF_HASHLEVEL %d\n\
+\n\
+static unsigned int hashsize     = HASHSIZE;\n\
+static unsigned int hashstep     = HASHSTEP;\n\
+static unsigned int maxhashlevel = MAXHASHLEVEL;\n\
+static unsigned int hashlevel    = DEF_HASHLEVEL;\n\
+\n\
+static struct unipair hashtable[HASHSIZE] =\n\
+{\n\t", argv[1], hashsize, hashstep, maxhashlevel,
+	 hashsize, hashstep, maxhashlevel, hashlevel);
+  
+  for ( i = 0 ; i < hashsize ; i++ )
+    {
+      printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
+      if ( i == hashsize-1 )
+	printf("\n};\n");
+      else if ( i % 4 == 3 )
+	printf(",\n\t");
+      else
+	printf(", ");
+    }
+
+  printf("\n\
+#ifdef NEED_BACKUP_HASHTABLE\n\
+\n\
+static const struct unipair backup_hashtable[HASHSIZE] = \n{\n\t");
+ 
+  for ( i = 0 ; i < hashsize ; i++ )
+    {
+      printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
+      if ( i == hashsize-1 )
+	printf("\n};\n#endif\n");
+      else if ( i % 4 == 3 )
+	printf(",\n\t");
+      else
+	printf(", ");
+    }
+
+  exit(EX_OK);
+}
diff -u --recursive --new-file v1.3.0/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.3.0/linux/drivers/char/console.c	Sat Jun 10 19:13:12 1995
+++ linux/drivers/char/console.c	Tue Jun 13 10:47:47 1995
@@ -33,8 +33,9 @@
  *     'void scrollback(int lines)'
  *     'void scrollfront(int lines)'
  *
- *     'int con_get_font(char *)' 
- *     'int con_set_font(char *)'
+ *     'int con_get_font(char *data)' 
+ *     'int con_set_font(char *data, int ch512)'
+ *     'int con_adjust_height(int fontheight)'
  *
  *     'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
  *     'int mouse_reporting(void)'
@@ -64,6 +65,8 @@
  * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
  * <poe@daimi.aau.dk>
  *
+ * Improved loadable font/UTF-8 support by H. Peter Anvin, Feb 1995
+ *
  */
 
 #define BLANK 0x0020
@@ -74,7 +77,8 @@
  * (such as cursor movement) and should not be displayed as a
  * glyph unless the disp_ctrl mode is explicitly enabled.
  */
-#define CTRL_ACTION 0xd00ff80
+#define CTRL_ACTION 0x0d00ff81
+#define CTRL_ALWAYS 0x0800f501	/* Cannot be overridden by disp_ctrl */
 
 /*
  *  NOTE!!! We sometimes disable and enable interrupts for a short while
@@ -122,8 +126,8 @@
 #define NPAR 16
 
 static void con_setsize(unsigned long rows, unsigned long cols);
-static void vc_init(unsigned int console, unsigned long rows, unsigned long cols,
-		    int do_clear);
+static void vc_init(unsigned int console, unsigned long rows,
+		    unsigned long cols, int do_clear);
 static void get_scrmem(int currcons);
 static void set_scrmem(int currcons, long offset);
 static void set_origin(int currcons);
@@ -140,7 +144,7 @@
 extern void vesa_blank(void);
 extern void vesa_unblank(void);
 extern void compute_shiftstate(void);
-extern int conv_uni_to_pc(unsigned long ucs);
+extern int conv_uni_to_pc(long ucs);
 
 /* Description of the hardware situation */
 static unsigned char	video_type;		/* Type of display being used	*/
@@ -157,6 +161,11 @@
 static unsigned long	video_screen_size;
 static int can_do_color = 0;
 static int printable = 0;			/* Is console ready for printing? */
+	/* these two also used in in vt.c */
+       int		video_mode_512ch = 0;	/* 512-character mode */
+       unsigned long	video_font_height;	/* Height of current screen font */
+static unsigned long	video_scan_lines;	/* Number of scan lines on screen */
+static unsigned short console_charmask = 0x0ff;
 
 static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
 
@@ -164,6 +173,7 @@
 static int blankinterval = 10*60*HZ;
 static long blank_origin, blank__origin, unblank_origin;
 
+
 struct vc_data {
 	unsigned long	vc_screenbuf_size;
 	unsigned short	vc_video_erase_char;	/* Background erase character */
@@ -212,9 +222,9 @@
 	unsigned long	vc_report_mouse : 2;
 	unsigned char	vc_utf		: 1;	/* Unicode UTF-8 encoding */
 	unsigned char	vc_utf_count;
-	unsigned long	vc_utf_char;
+	         long	vc_utf_char;
 	unsigned long	vc_tab_stop[5];		/* Tab stops. 160 columns. */
-	unsigned char * vc_translate;
+	unsigned short * vc_translate;
 	unsigned char 	vc_G0_charset;
 	unsigned char 	vc_G1_charset;
 	unsigned char 	vc_saved_G0;
@@ -879,7 +889,7 @@
 				  * Select first alternate font, let's
 				  * chars < 32 be displayed as ROM chars.
 				  */
-				translate = set_translate(NULL_MAP);
+				translate = set_translate(IBMPC_MAP);
 				disp_ctrl = 1;
 				toggle_meta = 0;
 				break;
@@ -887,7 +897,7 @@
 				  * Select second alternate font, toggle
 				  * high bit before displaying as ROM char.
 				  */
-				translate = set_translate(NULL_MAP);
+				translate = set_translate(IBMPC_MAP);
 				disp_ctrl = 1;
 				toggle_meta = 1;
 				break;
@@ -1264,8 +1274,8 @@
 	bottom		= video_num_lines;
 	vc_state	= ESnormal;
 	ques		= 0;
-	translate	= set_translate(NORM_MAP);
-	G0_charset	= NORM_MAP;
+	translate	= set_translate(LAT1_MAP);
+	G0_charset	= LAT1_MAP;
 	G1_charset	= GRAF_MAP;
 	charset		= 0;
 	need_wrap	= 0;
@@ -1370,7 +1380,7 @@
 				utf_char = (utf_char << 6) | (c & 0x3f);
 				utf_count--;
 				if (utf_count == 0)
-				    c = utf_char;
+				    tc = c = utf_char;
 				else continue;
 			} else {
 				if ((c & 0xe0) == 0xc0) {
@@ -1379,26 +1389,25 @@
 				} else if ((c & 0xf0) == 0xe0) {
 				    utf_count = 2;
 				    utf_char = (c & 0x0f);
+				} else if ((c & 0xf8) == 0xf0) {
+				    utf_count = 3;
+				    utf_char = (c & 0x07);
+				} else if ((c & 0xfc) == 0xf8) {
+				    utf_count = 4;
+				    utf_char = (c & 0x03);
+				} else if ((c & 0xfe) == 0xfc) {
+				    utf_count = 5;
+				    utf_char = (c & 0x01);
 				} else
 				    utf_count = 0;
 				continue;
-			}
-		    } else
-			utf_count = 0;
-
-		    /* Now try to find out how to display it */
-		    tc = conv_uni_to_pc(c);
-		    if (tc == -1 || tc == -2)
-		      continue;
-		    if (tc == -3 || tc == -4) {	/* hashtable not valid */
-						/* or symbol not found */
-			tc = (c <= 0xff) ? translate[c] : 040;
-			ok = 0;
-		    } else
-		        ok = 1;
+			      }
+		    } else {
+		      tc = c;
+		      utf_count = 0;
+		    }
 		} else {	/* no utf */
-		    tc = translate[toggle_meta ? (c|0x80) : c];
-		    ok = 0;
+		  tc = translate[toggle_meta ? (c|0x80) : c];
 		}
 
 		/* If the original code was < 32 we only allow a
@@ -1407,19 +1416,39 @@
 		 * disp_ctrl mode has been explicitly enabled.
 		 * Note: ESC is *never* allowed to be displayed as
 		 * that would disable all escape sequences!
+		 * To display font position 0x1B, go into UTF mode
+		 * and display character U+F01B, or change the mapping.
 		 */
-		if (!ok && tc && (c >= 32 || (disp_ctrl && c != 0x1b)
-		|| !((CTRL_ACTION >> c) & 1)))
-		    ok = 1;
-
+		ok = (tc && (c >= 32 || (!utf && !(((disp_ctrl ? CTRL_ALWAYS
+					    : CTRL_ACTION) >> c) & 1))));
+		
 		if (vc_state == ESnormal && ok) {
+		        /* Now try to find out how to display it */
+		        tc = conv_uni_to_pc(tc);
+			if ( tc == -4 )
+			  {
+			    /* If we got -4 (not found) then see if we have
+			       defined a replacement character (U+FFFD) */
+			    tc = conv_uni_to_pc(0xfffd);
+			  }
+			else if ( tc == -3 )
+			  {
+			    /* Bad hash table -- hope for the best */
+			    tc = c;
+			  }
+			if (tc & ~console_charmask)
+			  continue; /* Conversion failed */
+
 			if (need_wrap) {
 				cr(currcons);
 				lf(currcons);
 			}
 			if (decim)
 				insert_char(currcons);
-			scr_writew((attr << 8) + tc, (unsigned short *) pos);
+			scr_writew( video_mode_512ch ?
+			   ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
+			   (tc & 0x0ff) : (attr << 8) + tc,
+			   (unsigned short *) pos);
 			if (x == video_num_columns - 1)
 				need_wrap = decawm;
 			else {
@@ -1710,9 +1739,9 @@
 				if (c == '0')
 					G0_charset = GRAF_MAP;
 				else if (c == 'B')
-					G0_charset = NORM_MAP;
+					G0_charset = LAT1_MAP;
 				else if (c == 'U')
-					G0_charset = NULL_MAP;
+					G0_charset = IBMPC_MAP;
 				else if (c == 'K')
 					G0_charset = USER_MAP;
 				if (charset == 0)
@@ -1723,9 +1752,9 @@
 				if (c == '0')
 					G1_charset = GRAF_MAP;
 				else if (c == 'B')
-					G1_charset = NORM_MAP;
+					G1_charset = LAT1_MAP;
 				else if (c == 'U')
-					G1_charset = NULL_MAP;
+					G1_charset = IBMPC_MAP;
 				else if (c == 'K')
 					G1_charset = USER_MAP;
 				if (charset == 1)
@@ -1973,6 +2002,21 @@
 	gotoxy(currcons,orig_x,orig_y);
 	set_origin(currcons);
 	csi_J(currcons, 0);
+
+
+	/* Figure out the size of the screen and screen font so we
+	   can figure out the appropriate screen size should we load
+	   a different font */
+
+	if ( video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM )
+	{
+		video_font_height = ORIG_VIDEO_POINTS;
+		/* This may be suboptimal but is a safe bet - go with it */
+		video_scan_lines = video_font_height * video_num_lines;
+		printk("Console: %ld point font, %ld scans\n",
+		       video_font_height, video_scan_lines);
+	}
+
 	printable = 1;
 	printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
 		can_do_color ? "colour" : "mono",
@@ -2187,17 +2231,19 @@
    should use 0xA0000 for the bwmap as well.. */
 #define blackwmap ((char *)0xa0000)
 #define cmapsz 8192
+#define attrib_port (0x3c0)
 #define seq_port_reg (0x3c4)
 #define seq_port_val (0x3c5)
 #define gr_port_reg (0x3ce)
 #define gr_port_val (0x3cf)
 
-static int set_get_font(char * arg, int set)
+static int set_get_font(char * arg, int set, int ch512)
 {
 #ifdef CAN_LOAD_EGA_FONTS
 	int i;
 	char *charmap;
 	int beg;
+	unsigned short video_port_status = video_port_reg + 6;
 
 	/* no use to "load" CGA... */
 
@@ -2210,7 +2256,8 @@
 	} else
 		return -EINVAL;
 
-	i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
+	i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg,
+			ch512 ? 2*cmapsz : cmapsz);
 	if (i)
 		return i;
 
@@ -2239,6 +2286,23 @@
 		for (i=0; i<cmapsz ; i++)
 			put_user(scr_readb(charmap + i), arg + i);
 
+	/*
+	 * In 512-character mode, the character map is not contiguous if
+	 * we want to remain EGA compatible -- which we do
+	 */
+
+	if (ch512)
+	  {
+	    charmap += 2*cmapsz;
+	    arg += cmapsz;
+	    if (set)
+	      for (i=0; i<cmapsz ; i++)
+		*(charmap+i) = get_fs_byte(arg+i);
+	    else
+	      for (i=0; i<cmapsz ; i++)
+		put_fs_byte(*(charmap+i), arg+i);
+	  };
+
 	cli();
 	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
 	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
@@ -2246,6 +2310,11 @@
 	outb_p( 0x03, seq_port_val );   /* CPU writes to maps 0 and 1 */
 	outb_p( 0x04, seq_port_reg );
 	outb_p( 0x03, seq_port_val );   /* odd-even addressing */
+	if (set)
+	  {
+	    outb_p( 0x03, seq_port_reg ); /* Character Map Select */
+	    outb_p( ch512 ? 0x04 : 0x00, seq_port_val );
+	  }
 	outb_p( 0x00, seq_port_reg );
 	outb_p( 0x03, seq_port_val );   /* clear synchronous reset */
 
@@ -2255,6 +2324,18 @@
 	outb_p( 0x10, gr_port_val );    /* enable even-odd addressing */
 	outb_p( 0x06, gr_port_reg );
 	outb_p( beg, gr_port_val );     /* map starts at b800:0 or b000:0 */
+	if (set)			/* attribute controller */
+	  {
+	    /* 256-char: enable intensity bit
+	       512-char: disable intensity bit */
+	    inb_p( video_port_status );	/* clear address flip-flop */
+	    outb_p ( 0x12, attrib_port ); /* color plane enable register */
+	    outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );
+	    /* Wilton (1987) mentions the following; I don't know what
+	       it means, but it works, and it appears necessary */
+	    inb_p( video_port_status );
+	    outb_p ( 0x20, attrib_port );
+	  }
 	sti();
 
 	return 0;
@@ -2269,13 +2350,96 @@
  * 8xH fonts (0 < H <= 32).
  */
 
-int con_set_font (char *arg)
+int con_set_font (char *arg, int ch512)
 {
-	hashtable_contents_valid = 0;
-	return set_get_font (arg,1);
+	int i;
+
+	i = set_get_font (arg,1,ch512);
+  	if ( !i ) {
+		hashtable_contents_valid = 0;
+      		video_mode_512ch = ch512;
+      		console_charmask = ch512 ? 0x1ff : 0x0ff;
+	}
+	return i;
 }
 
 int con_get_font (char *arg)
 {
-	return set_get_font (arg,0);
+	return set_get_font (arg,0,video_mode_512ch);
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ *
+ * Returns < 0 for error, 0 if nothing changed, and the number
+ * of lines on the adjusted console if changed.
+ */
+int con_adjust_height(unsigned long fontheight)
+{
+	int rows, maxscan;
+	unsigned char ovr, vde, fsr, curs, cure;
+
+	if (fontheight > 32 ||
+	     (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM))
+		return -EINVAL;
+
+	if ( fontheight == video_font_height || fontheight == 0 )
+		return 0;
+	
+	video_font_height = fontheight;
+
+	rows = video_scan_lines/fontheight;	/* Number of video rows we end up with */
+	maxscan = rows*fontheight - 1;		/* Scan lines to actually display-1 */
+
+	/* Reprogram the CRTC for the new font size
+           Note: the attempt to read the overflow register will fail
+	   on an EGA, but using 0xff for the previous value appears to
+	   be OK for EGA text modes in the range 257-512 scan lines, so I
+	   guess we don't need to worry about it.
+
+	   The same applies for the spill bits in the font size and cursor
+	   registers; they are write-only on EGA, but it appears that they
+	   are all don't care bits on EGA, so I guess it doesn't matter. */
+
+	cli();
+	outb_p( 0x07, video_port_reg );		/* CRTC overflow register */
+	ovr = inb_p(video_port_val);
+	outb_p( 0x09, video_port_reg );	        /* Font size register */
+	fsr = inb_p(video_port_val);
+	outb_p( 0x0a, video_port_reg );	        /* Cursor start */
+	curs = inb_p(video_port_val);
+	outb_p( 0x0b, video_port_reg );	        /* Cursor end */
+	cure = inb_p(video_port_val);
+	sti();
+
+	vde = maxscan & 0xff;			/* Vertical display end reg */
+	ovr = (ovr & 0xbd) +			/* Overflow register */
+	      ((maxscan & 0x100) >> 7) +
+	      ((maxscan & 0x200) >> 3);
+	fsr = (fsr & 0xe0) + (fontheight-1);    /*  Font size register */
+	curs = (curs & 0xc0) + fontheight - (fontheight < 10 ? 2 : 3);
+	cure = (cure & 0xe0) + fontheight - (fontheight < 10 ? 1 : 2);
+
+	cli();
+	outb_p( 0x07, video_port_reg );		/* CRTC overflow register */
+	outb_p( ovr, video_port_val );
+	outb_p( 0x09, video_port_reg );	        /* Font size */
+	outb_p( fsr, video_port_val );
+	outb_p( 0x0a, video_port_reg );	        /* Cursor start */
+	outb_p( curs, video_port_val );
+	outb_p( 0x0b, video_port_reg );	        /* Cursor end */
+	outb_p( cure, video_port_val );
+	outb_p( 0x12, video_port_reg );	        /* Vertical display limit */
+	outb_p( vde, video_port_val );
+	sti();
+
+	if ( rows == video_num_lines ) {
+	  /* Change didn't affect number of lines -- no need to scare
+	     the rest of the world */
+	  return 0;
+	}
+
+	vc_resize(rows, 0);	                /* Adjust console size */
+
+	return rows;
 }
diff -u --recursive --new-file v1.3.0/linux/drivers/char/consolemap.c linux/drivers/char/consolemap.c
--- v1.3.0/linux/drivers/char/consolemap.c	Wed Feb 15 10:50:55 1995
+++ linux/drivers/char/consolemap.c	Tue Jun 13 10:47:47 1995
@@ -14,74 +14,147 @@
 #include <asm/segment.h>
 #include "consolemap.h"
 
-static unsigned char * translations[] = {
-/* 8-bit Latin-1 mapped to the PC character set: '\0' means non-printable */
-(unsigned char *)
-	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-	"\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
-	" !\"#$%&'()*+,-./0123456789:;<=>?"
-	"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
-	"`abcdefghijklmnopqrstuvwxyz{|}~\0"
-	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-	"\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
-	"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
-	"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
-	"\376\245\376\376\376\376\231\376\350\376\376\376\232\376\376\341"
-	"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
-	"\376\244\225\242\223\376\224\366\355\227\243\226\201\376\376\230",
-/* vt100 graphics */
-(unsigned char *)
-	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-	"\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
-	" !\"#$%&'()*+,-./0123456789:;<=>?"
-	"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
-	"\004\261\007\007\007\007\370\361\007\007\331\277\332\300\305\304"
-	"\304\304\137\137\303\264\301\302\263\363\362\343\330\234\007\0"
-	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-	"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-	"\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
-	"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
-	"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
-	"\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
-	"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
-	"\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
-/* IBM graphics: minimal translations (BS, CR, LF, LL, SO, SI and ESC) */
-(unsigned char *)
-	"\000\001\002\003\004\005\006\007\000\011\000\013\000\000\000\000"
-	"\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
-	"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
-	"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
-	"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
-	"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
-	"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
-	"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
-	"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
-	"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
-	"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
-	"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
-	"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
-	"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
-	"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
-	"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",
- /* USER: customizable mappings, initialized as the previous one (IBM) */
-(unsigned char *)
-	"\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017"
-	"\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
-	"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
-	"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
-	"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
-	"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
-	"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
-	"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
-	"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
-	"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
-	"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
-	"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
-	"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
-	"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
-	"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
-	"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
+static unsigned short translations[][256] = {
+  /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
+  {
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+  }, 
+  /* VT100 graphics mapped to Unicode */
+  {
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+    0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+    0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
+    0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
+    0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800,
+    0xf801, 0x2500, 0xf803, 0xf804, 0x251c, 0x2524, 0x2534, 0x252c,
+    0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+    0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+    0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+    0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+    0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+    0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+    0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+    0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+    0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+  },
+  /* IBM Codepage 437 mapped to Unicode */
+  {
+    0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 
+    0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
+    0x25ba, 0x25c4, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
+    0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+    0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+    0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+    0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
+    0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
+    0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
+    0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+    0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
+    0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
+    0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+    0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
+    0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
+    0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
+    0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
+    0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
+    0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
+    0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
+    0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
+  }, 
+  /* User mapping -- default to codes for direct font mapping */
+  {
+    0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
+    0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
+    0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
+    0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
+    0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
+    0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
+    0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
+    0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
+    0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
+    0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
+    0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
+    0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
+    0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
+    0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
+    0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
+    0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
+    0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
+    0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
+    0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
+    0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
+    0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
+    0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
+    0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
+    0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
+    0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
+    0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
+    0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
+    0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
+    0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
+    0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
+    0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
+    0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
+  }
 };
 
 /* the above mappings are not invertible - this is just a best effort */
@@ -91,13 +164,13 @@
 
 static void set_inverse_transl(int i)
 {
-	int j;
-	unsigned char *p = translations[i];
+	int j, glyph;
+	unsigned short *p = translations[i];
 	unsigned char *q = inverse_translations[i];
 
 	if (!q) {
 		/* slightly messy to avoid calling kmalloc too early */
-		q = inverse_translations[i] = ((i == NORM_MAP)
+		q = inverse_translations[i] = ((i == LAT1_MAP)
 			? inv_norm_transl
 			: (unsigned char *) kmalloc(E_TABSZ, GFP_KERNEL));
 		if (!q)
@@ -106,11 +179,12 @@
 	for (j=0; j<E_TABSZ; j++)
 		q[j] = 0;
 	for (j=0; j<E_TABSZ; j++)
-		if (q[p[j]] < 32)	/* prefer '-' above SHY etc. */
-			q[p[j]] = j;
+		if (q[glyph = conv_uni_to_pc(p[j])] < 32) 
+		  /* prefer '-' above SHY etc. */
+		  q[glyph] = j;
 }
 
-unsigned char *set_translate(int m)
+unsigned short *set_translate(int m)
 {
 	if (!inverse_translations[m])
 		set_inverse_transl(m);
@@ -132,33 +206,73 @@
 /*
  * Load customizable translation table
  * arg points to a 256 byte translation table.
+ *
+ * The "old" variants are for translation directly to font (using the
+ * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
+ * unicodes explictly.
  */
-int con_set_trans(char * arg)
+int con_set_trans_old(char * arg)
 {
 	int i;
-	unsigned char *p = translations[USER_MAP];
+	unsigned short *p = translations[USER_MAP];
 
 	i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ);
 	if (i)
 		return i;
 
 	for (i=0; i<E_TABSZ ; i++)
-		p[i] = get_fs_byte(arg+i);
-	p[012] = p[014] = p[015] = p[033] = 0;
+		p[i] = UNI_DIRECT_BASE | get_fs_byte(arg+i);
+
 	set_inverse_transl(USER_MAP);
 	return 0;
 }
 
-int con_get_trans(char * arg)
+int con_get_trans_old(char * arg)
 {
-	int i;
-	unsigned char *p = translations[USER_MAP];
+	int i, ch;
+	unsigned short *p = translations[USER_MAP];
 
 	i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ);
 	if (i)
 		return i;
 
-	for (i=0; i<E_TABSZ ; i++) put_fs_byte(p[i],arg+i);
+	for (i=0; i<E_TABSZ ; i++)
+	  {
+	    ch = conv_uni_to_pc(p[i]);
+	    put_fs_byte((ch & ~0xff) ? 0 : ch, arg+i);
+	  }
+	return 0;
+}
+int con_set_trans_new(ushort * arg)
+{
+	int i;
+	unsigned short *p = translations[USER_MAP];
+
+	i = verify_area(VERIFY_READ, (void *)arg,
+			E_TABSZ*sizeof(unsigned short));
+	if (i)
+		return i;
+
+	for (i=0; i<E_TABSZ ; i++)
+	  p[i] = get_fs_word(arg+i);
+
+	set_inverse_transl(USER_MAP);
+	return 0;
+}
+
+int con_get_trans_new(ushort * arg)
+{
+	int i;
+	unsigned short *p = translations[USER_MAP];
+
+	i = verify_area(VERIFY_WRITE, (void *)arg,
+			E_TABSZ*sizeof(unsigned short));
+	if (i)
+		return i;
+
+	for (i=0; i<E_TABSZ ; i++)
+	  put_fs_word(p[i], arg+i);
+	
 	return 0;
 }
 
@@ -180,17 +294,9 @@
  * Usually, the mapping will be loaded simultaneously with the font.
  */
 
-#define HASHSIZE   641
-#define HASHSTEP   189		/* yields hashlevel = 3 initially */
-#define MAXHASHLEVEL 6
-static struct unipair hashtable[HASHSIZE];
-
-int hashtable_contents_valid = 0; 	/* cleared by setfont */
-
-static unsigned int hashsize;
-static unsigned int hashstep;
-static unsigned int hashlevel;
-static unsigned int maxhashlevel;
+#include "uni_hash_tbl.h"	/* Include hash tables & parameters */
+
+int hashtable_contents_valid = 1;
 
 void
 con_clear_unimap(struct unimapinit *ui) {
@@ -242,6 +348,10 @@
 	    list++;
 	    ct--;
 	}
+
+	for ( i = 0 ; i <= 3 ; i++ )
+	  set_inverse_transl(i); /* Update all inverse translations */
+
 	return 0;
 }
 
@@ -264,15 +374,26 @@
 }
 
 int
-conv_uni_to_pc(unsigned long ucs) {
+conv_uni_to_pc(long ucs) {
       int i, h;
+      
+      /* Only 16-bit codes supported at this time */
+      if (ucs > 0xffff)
+	ucs = 0xfffd;		/* U+FFFD: REPLACEMENT CHARACTER */
+      else if (ucs < 0x20 || ucs >= 0xfffe)
+	return -1;		/* Not a printable character */
+      else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
+	return -2;		/* Zero-width space */
+      /*
+       * UNI_DIRECT_BASE indicates the start of the region in the User Zone
+       * which always has a 1:1 mapping to the currently loaded font.  The
+       * UNI_DIRECT_MASK indicates the bit span of the region.
+       */
+      else if ( (ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE )
+	return ucs & UNI_DIRECT_MASK;
 
-      if (!hashtable_contents_valid || ucs < 0x20)
+      if (!hashtable_contents_valid)
 	return -3;
-      if (ucs == 0xffff || ucs == 0xfffe)
-	return -1;
-      if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
-	return -2;
       
       h = ucs % hashsize;
       for (i = 0; i < hashlevel; i++) {
diff -u --recursive --new-file v1.3.0/linux/drivers/char/consolemap.h linux/drivers/char/consolemap.h
--- v1.3.0/linux/drivers/char/consolemap.h	Wed Feb 15 10:50:55 1995
+++ linux/drivers/char/consolemap.h	Tue Jun 13 10:47:47 1995
@@ -3,11 +3,12 @@
  *
  * Interface between console.c, selection.c  and consolemap.c
  */
-#define NORM_MAP 0
+#define LAT1_MAP 0
 #define GRAF_MAP 1
-#define NULL_MAP 2
+#define IBMPC_MAP 2
 #define USER_MAP 3
 
 extern int hashtable_contents_valid;
 extern unsigned char inverse_translate(unsigned char c);
-extern unsigned char *set_translate(int m);
+extern unsigned short *set_translate(int m);
+extern int conv_uni_to_pc(long ucs);
diff -u --recursive --new-file v1.3.0/linux/drivers/char/cp437.uni linux/drivers/char/cp437.uni
--- v1.3.0/linux/drivers/char/cp437.uni	Thu Jan  1 02:00:00 1970
+++ linux/drivers/char/cp437.uni	Tue Jun 13 10:47:47 1995
@@ -0,0 +1,291 @@
+#
+# Unicode table for IBM Codepage 437.  Note that there are many more
+# substitutions that could be conceived (for example, thick-line
+# graphs probably should be replaced with double-line ones, accented
+# Latin characters should replaced with their nonaccented versions,
+# and some upper case Greek characters could be replaced by Latin), however,
+# I have limited myself to the Unicodes used by the kernel ISO 8859-1,
+# DEC VT, and IBM CP 437 tables.
+#
+# --------------------------------
+#
+# Basic IBM dingbats, some of which will never have a purpose clear
+# to mankind
+#
+0x00	U+0000
+0x01	U+263a
+0x02	U+263b
+0x03	U+2665
+0x04	U+2666 U+25c6
+0x05	U+2663
+0x06	U+2660
+0x07	U+2022
+0x08	U+25d8
+0x09	U+25cb
+0x0a	U+25d9
+0x0b	U+2642
+0x0c	U+2640
+0x0d	U+266a
+0x0e	U+266b
+0x0f	U+263c
+0x10	U+25ba
+0x11	U+25c4
+0x12	U+2195
+0x13	U+203c
+0x14	U+00b6
+0x15	U+00a7
+0x16	U+25ac
+0x17	U+21a8
+0x18	U+2191
+0x19	U+2193
+0x1a	U+2192
+0x1b	U+2190
+0x1c	U+221f
+0x1d	U+2194
+0x1e	U+25b2
+0x1f	U+25bc
+#
+# The ASCII range is identity-mapped, but some of the characters also
+# have to act as substitutes, especially the upper-case characters.
+#
+0x20	U+0020
+0x21	U+0021
+0x22	U+0022 U+00a8
+0x23	U+0023
+0x24	U+0024
+0x25	U+0025
+0x26	U+0026
+0x27	U+0027
+0x28	U+0028
+0x29	U+0029
+0x2a	U+002a
+0x2b	U+002b
+0x2c	U+002c U+00b8
+0x2d	U+002d U+00ad
+0x2e	U+002e
+0x2f	U+002f
+0x30	U+0030
+0x31	U+0031
+0x32	U+0032
+0x33	U+0033
+0x34	U+0034
+0x35	U+0035
+0x36	U+0036
+0x37	U+0037
+0x38	U+0038
+0x39	U+0039
+0x3a	U+003a
+0x3b	U+003b
+0x3c	U+003c
+0x3d	U+003d
+0x3e	U+003e
+0x3f	U+003f
+0x40	U+0040
+0x41	U+0041 U+00c0 U+00c1 U+00c2 U+00c3
+0x42	U+0042
+0x43	U+0043 U+00a9
+0x44	U+0044
+0x45	U+0045 U+00c8 U+00ca U+00cb
+0x46	U+0046
+0x47	U+0047
+0x48	U+0048
+0x49	U+0049 U+00cc U+00cd U+00ce U+00cf
+0x4a	U+004a
+0x4b	U+004b U+212a
+0x4c	U+004c
+0x4d	U+004d
+0x4e	U+004e
+0x4f	U+004f U+00d2 U+00d3 U+00d4 U+00d5
+0x50	U+0050
+0x51	U+0051
+0x52	U+0052 U+00ae
+0x53	U+0053
+0x54	U+0054
+0x55	U+0055 U+00d9 U+00da U+00db
+0x56	U+0056
+0x57	U+0057
+0x58	U+0058
+0x59	U+0059 U+00dd
+0x5a	U+005a
+0x5b	U+005b
+0x5c	U+005c
+0x5d	U+005d
+0x5e	U+005e
+0x5f	U+005f U+f804
+0x60	U+0060
+0x61	U+0061 U+00e3
+0x62	U+0062
+0x63	U+0063
+0x64	U+0064
+0x65	U+0065
+0x66	U+0066
+0x67	U+0067
+0x68	U+0068
+0x69	U+0069
+0x6a	U+006a
+0x6b	U+006b
+0x6c	U+006c
+0x6d	U+006d
+0x6e	U+006e
+0x6f	U+006f U+00f5
+0x70	U+0070
+0x71	U+0071
+0x72	U+0072
+0x73	U+0073
+0x74	U+0074
+0x75	U+0075
+0x76	U+0076
+0x77	U+0077
+0x78	U+0078 U+00d7
+0x79	U+0079 U+00fd
+0x7a	U+007a
+0x7b	U+007b
+0x7c	U+007c U+00a5
+0x7d	U+007d
+0x7e	U+007e
+#
+# Okay, what on Earth is this one supposed to be used for?
+#
+0x7f	U+2302
+#
+# Non-English characters, mostly lower case letters...
+#
+0x80	U+00c7
+0x81	U+00fc
+0x82	U+00e9
+0x83	U+00e2
+0x84	U+00e4
+0x85	U+00e0
+0x86	U+00e5
+0x87	U+00e7
+0x88	U+00ea
+0x89	U+00eb
+0x8a	U+00e8
+0x8b	U+00ef
+0x8c	U+00ee
+0x8d	U+00ec
+0x8e	U+00c4
+0x8f	U+00c5 U+212b
+0x90	U+00c9
+0x91	U+00e6
+0x92	U+00c6
+0x93	U+00f4
+0x94	U+00f6
+0x95	U+00f2
+0x96	U+00fb
+0x97	U+00f9
+0x98	U+00ff
+0x99	U+00d6
+0x9a	U+00dc
+0x9b	U+00a2
+0x9c	U+00a3
+0x9d	U+00a5
+0x9e	U+20a7
+0x9f	U+0192
+0xa0	U+00e1
+0xa1	U+00ed
+0xa2	U+00f3
+0xa3	U+00fa
+0xa4	U+00f1
+0xa5	U+00d1
+0xa6	U+00aa
+0xa7	U+00ba
+0xa8	U+00bf
+0xa9	U+2310
+0xaa	U+00ac
+0xab	U+00bd
+0xac	U+00bc
+0xad	U+00a1
+0xae	U+00ab
+0xaf	U+00bb
+#
+# Block graphics
+#
+0xb0	U+2591
+0xb1	U+2592
+0xb2	U+2593
+0xb3	U+2502
+0xb4	U+2524
+0xb5	U+2561
+0xb6	U+2562
+0xb7	U+2556
+0xb8	U+2555
+0xb9	U+2563
+0xba	U+2551
+0xbb	U+2557
+0xbc	U+255d
+0xbd	U+255c
+0xbe	U+255b
+0xbf	U+2510
+0xc0	U+2514
+0xc1	U+2534
+0xc2	U+252c
+0xc3	U+251c
+0xc4	U+2500
+0xc5	U+253c
+0xc6	U+255e
+0xc7	U+255f
+0xc8	U+255a
+0xc9	U+2554
+0xca	U+2569
+0xcb	U+2566
+0xcc	U+2560
+0xcd	U+2550
+0xce	U+256c
+0xcf	U+2567
+0xd0	U+2568
+0xd1	U+2564
+0xd2	U+2565
+0xd3	U+2559
+0xd4	U+2558
+0xd5	U+2552
+0xd6	U+2553
+0xd7	U+256b
+0xd8	U+256a
+0xd9	U+2518
+0xda	U+250c
+0xdb	U+2588
+0xdc	U+2584
+0xdd	U+258c
+0xde	U+2590
+0xdf	U+2580
+#
+# Greek letters and mathematical symbols
+#
+0xe0	U+03b1
+0xe1	U+03b2 U+00df
+0xe2	U+0393
+0xe3	U+03c0
+0xe4	U+03a3
+0xe5	U+03c3
+0xe6	U+00b5 U+03bc
+0xe7	U+03c4
+0xe8	U+03a6 U+00d8
+0xe9	U+0398
+0xea	U+03a9 U+2126
+0xeb	U+03b4
+0xec	U+221e
+0xed	U+03c6 U+00f8
+0xee	U+03b5
+0xef	U+2229
+0xf0	U+2261
+0xf1	U+00b1
+0xf2	U+2265
+0xf3	U+2264
+0xf4	U+2320
+0xf5	U+2321
+0xf6	U+00f7
+0xf7	U+2248
+0xf8	U+00b0
+0xf9	U+2219
+0xfa	U+00b7
+0xfb	U+221a
+0xfc	U+207f
+0xfd	U+00b2
+#
+# Square bullet, non-spacing blank
+# Mapping U+fffd to the square bullet means it is the substitution
+# character
+# 
+0xfe	U+25a0 U+fffd
+0xff	U+00a0
diff -u --recursive --new-file v1.3.0/linux/drivers/char/vt.c linux/drivers/char/vt.c
--- v1.3.0/linux/drivers/char/vt.c	Wed Feb 15 10:50:55 1995
+++ linux/drivers/char/vt.c	Tue Jun 13 10:47:47 1995
@@ -17,6 +17,8 @@
 #include <linux/vt.h>
 #include <linux/string.h>
 #include <linux/malloc.h>
+#include <linux/major.h>
+#include <linux/fs.h>
 
 #include <asm/io.h>
 #include <asm/segment.h>
@@ -63,13 +65,19 @@
 /*
  * routines to load custom translation table and EGA/VGA font from console.c
  */
-extern int con_set_trans(char * table);
-extern int con_get_trans(char * table);
+extern int con_set_trans_old(char * table);
+extern int con_get_trans_old(char * table);
+extern int con_set_trans_new(unsigned short * table);
+extern int con_get_trans_new(unsigned short * table);
 extern void con_clear_unimap(struct unimapinit *ui);
 extern int con_set_unimap(ushort ct, struct unipair *list);
 extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
-extern int con_set_font(char * fontmap);
+extern int con_set_font(char * fontmap, int ch512);
 extern int con_get_font(char * fontmap);
+extern int con_adjust_height(unsigned long fontheight);
+
+extern int video_mode_512ch;
+extern unsigned long video_font_height;
 
 /*
  * these are the valid i/o ports we're allowed to change. they map all the
@@ -80,6 +88,41 @@
 #define GPNUM (GPLAST - GPFIRST + 1)
 
 /*
+ * This function is called when the size of the physical screen has been
+ * changed.  If either the row or col argument is nonzero, set the appropriate
+ * entry in each winsize structure for all the virtual consoles, then
+ * send SIGWINCH to all processes with a virtual console as controlling
+ * tty.
+ */
+
+static void
+kd_size_changed(int row, int col)
+{
+  struct task_struct *p;
+  int i;
+
+  if ( !row && !col ) return;
+
+  for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
+    {
+      if ( console_driver.table[i] )
+	{
+	  if ( row ) console_driver.table[i]->winsize.ws_row = row;
+	  if ( col ) console_driver.table[i]->winsize.ws_col = col;
+	}
+    }
+
+  for_each_task(p)
+    {
+      if ( p->tty && MAJOR(p->tty->device) == TTY_MAJOR &&
+	   MINOR(p->tty->device) <= MAX_NR_CONSOLES && MINOR(p->tty->device) )
+	{
+	  send_sig(SIGWINCH, p, 1);
+	}
+    }
+}
+
+/*
  * Generates sound of some count for some number of clock ticks
  * [count = 1193180 / frequency]
  *
@@ -829,22 +872,85 @@
 			return -EPERM;
 		if (vt_cons[fg_console]->vc_mode != KD_TEXT)
 			return -EINVAL;
-		return con_set_font((char *)arg);
+		return con_set_font((char *)arg, 0);
 		/* con_set_font() defined in console.c */
 
 	case GIO_FONT:
-		if (vt_cons[fg_console]->vc_mode != KD_TEXT)
+		if (vt_cons[fg_console]->vc_mode != KD_TEXT ||
+		    video_mode_512ch)
 			return -EINVAL;
 		return con_get_font((char *)arg);
 		/* con_get_font() defined in console.c */
 
+	case PIO_FONTX:
+	{
+	        struct consolefontdesc cfdarg;
+
+		if (!perm)
+			return -EPERM;
+		if (vt_cons[fg_console]->vc_mode != KD_TEXT)
+			return -EINVAL;
+		i = verify_area(VERIFY_READ, (void *)arg,
+				sizeof(struct consolefontdesc));
+		if (i) return i;
+		memcpy_fromfs(&cfdarg, (void *)arg,
+			      sizeof(struct consolefontdesc)); 
+		
+		if ( cfdarg.charcount == 256 ||
+		     cfdarg.charcount == 512 ) {
+			i = con_set_font(cfdarg.chardata,
+				cfdarg.charcount == 512);
+			if (i)
+				return i;
+			i = con_adjust_height(cfdarg.charheight);
+			if (i <= 0) return i;
+			kd_size_changed(i, 0);
+			return 0;
+		} else
+			return -EINVAL;
+	}
+
+	case GIO_FONTX:
+	{
+	        struct consolefontdesc cfdarg;
+		int nchar;
+
+		if (vt_cons[fg_console]->vc_mode != KD_TEXT)
+			return -EINVAL;
+		i = verify_area(VERIFY_WRITE, (void *)arg,
+			sizeof(struct consolefontdesc));
+		if (i) return i;	
+		memcpy_fromfs(&cfdarg, (void *) arg,
+			      sizeof(struct consolefontdesc)); 
+		i = cfdarg.charcount;
+		cfdarg.charcount = nchar = video_mode_512ch ? 512 : 256;
+		cfdarg.charheight = video_font_height;
+		memcpy_tofs((void *) arg, &cfdarg,
+			    sizeof(struct consolefontdesc)); 
+		if ( cfdarg.chardata )
+		{
+			if ( i < nchar )
+				return -ENOMEM;
+			return con_get_font(cfdarg.chardata);
+		} else
+			return 0;
+	}
+
 	case PIO_SCRNMAP:
 		if (!perm)
 			return -EPERM;
-		return con_set_trans((char *)arg);
+		return con_set_trans_old((char *)arg);
 
 	case GIO_SCRNMAP:
-		return con_get_trans((char *)arg);
+		return con_get_trans_old((char *)arg);
+
+	case PIO_UNISCRNMAP:
+		if (!perm)
+			return -EPERM;
+		return con_set_trans_new((unsigned short *)arg);
+
+	case GIO_UNISCRNMAP:
+		return con_get_trans_new((unsigned short *)arg);
 
 	case PIO_UNIMAPCLR:
 	      { struct unimapinit ui;
diff -u --recursive --new-file v1.3.0/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v1.3.0/linux/drivers/scsi/u14-34f.c	Mon Mar 20 09:13:46 1995
+++ linux/drivers/scsi/u14-34f.c	Tue Jun 13 14:40:59 1995
@@ -1,6 +1,10 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      13 Jun 1995 rev. 2.01 for linux 1.2.10
+ *         HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when
+ *         the firmware prom is not the lastest one (28008-006).
+ *
  *      11 Mar 1995 rev. 2.00 for linux 1.2.0
  *          Fixed a bug which prevented media change detection for removable
  *          disk drives.
@@ -53,11 +57,11 @@
  *
  *      Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com)
  *
- *      WARNING: if your 14F board has an old firmware revision (see below)
+ *      WARNING: if your 14/34F board has an old firmware revision (see below)
  *               you must change "#undef" into "#define" in the following
  *               statement.
  */
-#undef HAVE_OLD_U14F_FIRMWARE
+#undef HAVE_OLD_UX4F_FIRMWARE
 /*
  *  The UltraStor 14F, 24F, and 34F are a family of intelligent, high
  *  performance SCSI-2 host adapters.
@@ -124,6 +128,10 @@
  *
  *    The new firmware has fixed all the above problems.
  *
+ *  For U34F boards the latest bios prom is 38008-002 (BIOS rev. 2.01),
+ *  the latest firmware prom is 28008-006. Older firmware 28008-005 has
+ *  problems when using more then 16 scatter/gather lists.
+ *
  *  In order to support multiple ISA boards in a reliable way,
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
@@ -449,6 +457,11 @@
    irqlist[irq] = j;
 
    if (HD(j)->subversion == ESA) {
+
+#if defined (HAVE_OLD_UX4F_FIRMWARE)
+      sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
+#endif
+
       sh[j]->dma_channel = NO_DMA;
       sh[j]->unchecked_isa_dma = FALSE;
       sprintf(BN(j), "U34F%d", j);
@@ -456,7 +469,7 @@
    else {
       sh[j]->wish_block = TRUE;
 
-#if defined (HAVE_OLD_U14F_FIRMWARE)
+#if defined (HAVE_OLD_UX4F_FIRMWARE)
       sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
       sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
 #endif
@@ -475,7 +488,7 @@
 
       if (strcmp(&HD(j)->board_id[32], "06000600")) {
          printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]);
-         printk("%s: firmware %s is outdated, BIOS rev. should be 2.01.\n", 
+         printk("%s: firmware %s is outdated, FW PROM should be 28004-006.\n",
                 BN(j), &HD(j)->board_id[32]);
          sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
          sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
diff -u --recursive --new-file v1.3.0/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h
--- v1.3.0/linux/drivers/scsi/u14-34f.h	Mon Mar 20 09:13:46 1995
+++ linux/drivers/scsi/u14-34f.h	Tue Jun 13 14:40:59 1995
@@ -10,7 +10,7 @@
 int u14_34f_reset(Scsi_Cmnd *);
 int u14_34f_biosparam(Disk *, int, int *);
 
-#define U14_34F_VERSION "2.00.00"
+#define U14_34F_VERSION "2.01.00"
 
 #define ULTRASTOR_14_34F {                                            \
                 NULL, /* Ptr for modules */                           \
diff -u --recursive --new-file v1.3.0/linux/fs/buffer.c linux/fs/buffer.c
--- v1.3.0/linux/fs/buffer.c	Mon Jun 12 12:48:33 1995
+++ linux/fs/buffer.c	Tue Jun 13 13:51:18 1995
@@ -1160,6 +1160,31 @@
 }
 
 /*
+ * bwrite_page writes a page out to the buffer cache and/or the physical device.
+ * It's used for mmap writes (the same way bread_page() is used for mmap reads).
+ */
+void bwrite_page(unsigned long address, dev_t dev, int b[], int size)
+{
+	struct buffer_head * bh[MAX_BUF_PER_PAGE];
+	int i, j;
+
+ 	for (i=0, j=0; j<PAGE_SIZE ; i++, j+= size) {
+		bh[i] = NULL;
+		if (b[i])
+			bh[i] = getblk(dev, b[i], size);
+	}
+ 	for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, address += size) {
+		if (bh[i]) {
+			memcpy(bh[i]->b_data, (void *) address, size);
+			bh[i]->b_uptodate = 1;
+			mark_buffer_dirty(bh[i], 0);
+			brelse(bh[i]);
+		} else
+			memset((void *) address, 0, size);
+	}	
+}
+
+/*
  * Try to increase the number of buffers available: the size argument
  * is used to determine what kind of buffers we want.
  */
diff -u --recursive --new-file v1.3.0/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v1.3.0/linux/fs/minix/inode.c	Mon Jun 12 16:49:40 1995
+++ linux/fs/minix/inode.c	Tue Jun 13 08:13:53 1995
@@ -232,7 +232,7 @@
 	tmp.f_bsize = 1024;
 	tmp.f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
 	tmp.f_bfree = minix_count_free_blocks(sb);
-	tmp.f_bavail = tmp.f_bavail;
+	tmp.f_bavail = tmp.f_bfree;
 	tmp.f_files = sb->u.minix_sb.s_ninodes;
 	tmp.f_ffree = minix_count_free_inodes(sb);
 	tmp.f_namelen = sb->u.minix_sb.s_namelen;
diff -u --recursive --new-file v1.3.0/linux/include/asm-i386/segment.h linux/include/asm-i386/segment.h
--- v1.3.0/linux/include/asm-i386/segment.h	Mon Jun 12 13:06:46 1995
+++ linux/include/asm-i386/segment.h	Tue Jun 13 10:16:25 1995
@@ -151,17 +151,32 @@
 		case 0:
 			return;
 		case 1:
-			put_user_byte(*(const char *) from, (char *) to);
+			__put_user(*(const char *) from, (char *) to, 1);
 			return;
 		case 2:
-			put_user_word(*(const short *) from, (short *) to);
+			__put_user(*(const short *) from, (short *) to, 2);
 			return;
 		case 3:
-			put_user_word(*(const short *) from, (short *) to);
-			put_user_byte(*(2+(const char *) from), 2+(char *) to);
+			__put_user(*(const short *) from, (short *) to, 2);
+			__put_user(*(2+(const char *) from), 2+(char *) to, 1);
 			return;
 		case 4:
-			put_user_long(*(const int *) from, (int *) to);
+			__put_user(*(const int *) from, (int *) to, 4);
+			return;
+		case 8:
+			__put_user(*(const int *) from, (int *) to, 4);
+			__put_user(*(1+(const int *) from), 1+(int *) to, 4);
+			return;
+		case 12:
+			__put_user(*(const int *) from, (int *) to, 4);
+			__put_user(*(1+(const int *) from), 1+(int *) to, 4);
+			__put_user(*(2+(const int *) from), 2+(int *) to, 4);
+			return;
+		case 16:
+			__put_user(*(const int *) from, (int *) to, 4);
+			__put_user(*(1+(const int *) from), 1+(int *) to, 4);
+			__put_user(*(2+(const int *) from), 2+(int *) to, 4);
+			__put_user(*(3+(const int *) from), 3+(int *) to, 4);
 			return;
 	}
 #define COMMON(x) \
@@ -215,17 +230,32 @@
 		case 0:
 			return;
 		case 1:
-			*(char *)to = get_user_byte((const char *) from);
+			*(char *)to = __get_user((const char *) from, 1);
 			return;
 		case 2:
-			*(short *)to = get_user_word((const short *) from);
+			*(short *)to = __get_user((const short *) from, 2);
 			return;
 		case 3:
-			*(short *) to = get_user_word((const short *) from);
-			*((char *) to + 2) = get_user_byte(2+(const char *) from);
+			*(short *) to = __get_user((const short *) from, 2);
+			*((char *) to + 2) = __get_user(2+(const char *) from, 1);
 			return;
 		case 4:
-			*(int *) to = get_user_long((const int *) from);
+			*(int *) to = __get_user((const int *) from, 4);
+			return;
+		case 8:
+			*(int *) to = __get_user((const int *) from, 4);
+			*(1+(int *) to) = __get_user(1+(const int *) from, 4);
+			return;
+		case 12:
+			*(int *) to = __get_user((const int *) from, 4);
+			*(1+(int *) to) = __get_user(1+(const int *) from, 4);
+			*(1+(int *) to) = __get_user(2+(const int *) from, 4);
+			return;
+		case 16:
+			*(int *) to = __get_user((const int *) from, 4);
+			*(1+(int *) to) = __get_user(1+(const int *) from, 4);
+			*(2+(int *) to) = __get_user(2+(const int *) from, 4);
+			*(3+(int *) to) = __get_user(3+(const int *) from, 4);
 			return;
 	}
 #define COMMON(x) \
diff -u --recursive --new-file v1.3.0/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.3.0/linux/include/linux/fs.h	Mon Jun 12 16:49:41 1995
+++ linux/include/linux/fs.h	Tue Jun 13 11:33:59 1995
@@ -501,6 +501,7 @@
 extern void set_blocksize(dev_t dev, int size);
 extern struct buffer_head * bread(dev_t dev, int block, int size);
 extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share);
+extern void bwrite_page(unsigned long addr,dev_t dev,int b[],int size);
 extern struct buffer_head * breada(dev_t dev,int block, int size, 
 				   unsigned int pos, unsigned int filesize);
 extern void put_super(dev_t dev);
diff -u --recursive --new-file v1.3.0/linux/include/linux/kd.h linux/include/linux/kd.h
--- v1.3.0/linux/include/linux/kd.h	Sun Jan  1 19:49:19 1995
+++ linux/include/linux/kd.h	Tue Jun 13 10:47:47 1995
@@ -7,6 +7,14 @@
 #define GIO_FONT	0x4B60	/* gets font in expanded form */
 #define PIO_FONT	0x4B61	/* use font in expanded form */
 
+#define GIO_FONTX	0x4B6B	/* get font using struct consolefontdesc */
+#define PIO_FONTX	0x4B6C	/* set font using struct consolefontdesc */
+struct consolefontdesc {
+	u_short charcount;	/* characters in font (256 or 512) */
+	u_short charheight;	/* scan lines per character (1-32) */
+	char *chardata;		/* font data in expanded form */
+};
+
 #define KIOCSOUND	0x4B2F	/* start sound generation (0 for off) */
 #define KDMKTONE	0x4B30	/* generate tone */
 
@@ -40,6 +48,8 @@
 #define		E_TABSZ		256
 #define GIO_SCRNMAP	0x4B40	/* get screen mapping from kernel */
 #define PIO_SCRNMAP	0x4B41	/* put screen mapping table in kernel */
+#define GIO_UNISCRNMAP  0x4B69	/* get full Unicode screen mapping */
+#define PIO_UNISCRNMAP  0x4B6A  /* set full Unicode screen mapping */
 
 #define GIO_UNIMAP	0x4B66	/* get unicode-to-font mapping from kernel */
 struct unipair {
@@ -58,6 +68,9 @@
 	u_short advised_hashlevel; /* 0 if no opinion */
 };
 
+#define UNI_DIRECT_BASE 0xF000	/* start of Direct Font Region */
+#define UNI_DIRECT_MASK 0x01FF	/* Direct Font Region bitmask */
+
 #define		K_RAW		0x00
 #define		K_XLATE		0x01
 #define		K_MEDIUMRAW	0x02
@@ -116,6 +129,6 @@
 
 /* note: 0x4B00-0x4B4E all have had a value at some time;
    don't reuse for the time being */
-/* note: 0x4B60-0x4B68 used above */
+/* note: 0x4B60-0x4B6C used above */
 
 #endif /* _LINUX_KD_H */
diff -u --recursive --new-file v1.3.0/linux/include/linux/mm.h linux/include/linux/mm.h
--- v1.3.0/linux/include/linux/mm.h	Sat Jun 10 12:55:57 1995
+++ linux/include/linux/mm.h	Tue Jun 13 13:00:29 1995
@@ -239,7 +239,8 @@
  *
  * Will go away eventually..
  */
-#define SHM_SWP_TYPE 0x41
+#define SHM_SWP_TYPE 0x40
+
 extern void shm_no_page (ulong *);
 
 /*
diff -u --recursive --new-file v1.3.0/linux/include/linux/tty.h linux/include/linux/tty.h
--- v1.3.0/linux/include/linux/tty.h	Sat Jun 10 19:13:13 1995
+++ linux/include/linux/tty.h	Tue Jun 13 10:47:47 1995
@@ -44,6 +44,7 @@
 	unsigned short orig_video_ega_bx;
 	unsigned short orig_video_ega_cx;
 	unsigned char  orig_video_lines;
+	unsigned short orig_video_points;
 };
 
 extern struct screen_info screen_info;
@@ -57,6 +58,7 @@
 #define ORIG_VIDEO_EGA_BX	(screen_info.orig_video_ega_bx)
 #define ORIG_VIDEO_EGA_CX	(screen_info.orig_video_ega_cx)
 #define ORIG_VIDEO_LINES	(screen_info.orig_video_lines)
+#define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
 
 #define VIDEO_TYPE_MDA		0x10	/* Monochrome Text Display	*/
 #define VIDEO_TYPE_CGA		0x11	/* CGA Display 			*/
diff -u --recursive --new-file v1.3.0/linux/ipc/shm.c linux/ipc/shm.c
--- v1.3.0/linux/ipc/shm.c	Sat Jun 10 12:55:57 1995
+++ linux/ipc/shm.c	Tue Jun 13 13:03:11 1995
@@ -502,7 +502,7 @@
 		return -EIDRM;
 	}
 
-	shmd->vm_pte = (SHM_SWP_TYPE << 1) | (id << SHM_ID_SHIFT);
+	shmd->vm_pte = SWP_ENTRY(SHM_SWP_TYPE, id);
 	shmd->vm_start = addr;
 	shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
 	shmd->vm_task = current;
diff -u --recursive --new-file v1.3.0/linux/mm/filemap.c linux/mm/filemap.c
--- v1.3.0/linux/mm/filemap.c	Tue May 30 12:17:18 1995
+++ linux/mm/filemap.c	Tue Jun 13 14:34:04 1995
@@ -28,25 +28,26 @@
  * though.
  */
 
-static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address,
-	unsigned long page, int no_share)
+static inline void multi_bmap(struct inode * inode, unsigned int block, unsigned int * nr, int shift)
 {
-	struct inode * inode = area->vm_inode;
-	unsigned int block;
-	int nr[8];
-	int i, *p;
-
-	address &= PAGE_MASK;
-	block = address - area->vm_start + area->vm_offset;
-	block >>= inode->i_sb->s_blocksize_bits;
-	i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
-	p = nr;
+	int i = PAGE_SIZE >> shift;
+	block >>= shift;
 	do {
-		*p = bmap(inode,block);
+		*nr = bmap(inode, block);
 		i--;
 		block++;
-		p++;
+		nr++;
 	} while (i > 0);
+}
+
+static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address,
+	unsigned long page, int no_share)
+{
+	struct inode * inode = area->vm_inode;
+	int nr[PAGE_SIZE/512];
+
+	multi_bmap(inode, (address & PAGE_MASK) - area->vm_start + area->vm_offset, nr,
+		inode->i_sb->s_blocksize_bits);
 	return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, no_share);
 }
 
@@ -65,9 +66,10 @@
 	unsigned long offset,
 	unsigned long page)
 {
+	struct inode * inode;
+	int nr[PAGE_SIZE/512];
 	struct buffer_head * bh;
 
-	printk("msync: %ld: [%08lx]\n", offset, page);
 	bh = buffer_pages[MAP_NR(page)];
 	if (bh) {
 		/* whee.. just mark the buffer heads dirty */
@@ -78,9 +80,49 @@
 		} while (tmp != bh);
 		return;
 	}
-	/* we'll need to go fetch the buffer heads etc.. RSN */
-	printk("Can't handle non-shared page yet\n");
-	return;
+	inode = vma->vm_inode;
+	multi_bmap(inode, offset, nr, inode->i_sb->s_blocksize_bits);
+	bwrite_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize);
+}
+
+/*
+ * Swapping to a shared file: while we're busy writing out the page
+ * (and the page still exists in memory), we save the page information
+ * in the page table, so that "filemap_swapin()" can re-use the page
+ * immediately if it is called while we're busy swapping it out..
+ *
+ * Once we've written it all out, we mark the page entry "empty", which
+ * will result in a normal page-in (instead of a swap-in) from the now
+ * up-to-date shared file mapping.
+ */
+void filemap_swapout(struct vm_area_struct * vma,
+	unsigned long offset,
+	pte_t *page_table)
+{
+	unsigned long page = pte_page(*page_table);
+	unsigned long entry = SWP_ENTRY(SHM_SWP_TYPE, MAP_NR(page));
+
+	pte_val(*page_table) = entry;
+	filemap_sync_page(vma, offset, page);
+	if (pte_val(*page_table) == entry)
+		pte_clear(page_table);
+}
+
+/*
+ * filemap_swapin() is called only if we have something in the page
+ * tables that is non-zero (but not present), which we know to be the
+ * page index of a page that is busy being swapped out (see above).
+ * So we just use it directly..
+ */
+static pte_t filemap_swapin(struct vm_area_struct * vma,
+	unsigned long offset,
+	unsigned long entry)
+{
+	unsigned long page = SWP_OFFSET(entry);
+
+	mem_map[page]++;
+	page = (page << PAGE_SHIFT) + PAGE_OFFSET;
+	return pte_mkdirty(mk_pte(page,vma->vm_page_prot));
 }
 
 static inline void filemap_sync_pte(pte_t * pte, struct vm_area_struct *vma,
@@ -189,21 +231,6 @@
 }
 
 /*
- * This isn't implemented yet: you'll get a warning and incorrect behaviour.
- *
- * Note that the page is free'd by the higher-level after return,
- * so we have to either write it out or just forget it. We currently
- * forget it..
- */
-void filemap_swapout(struct vm_area_struct * vma,
-	unsigned long offset,
-	pte_t *page_table)
-{
-	printk("swapout not implemented on shared files..\n");
-	pte_clear(page_table);
-}
-
-/*
  * Shared mappings need to be able to do the right thing at
  * close/unmap/sync. They will also use the private file as
  * backing-store for swapping..
@@ -218,7 +245,7 @@
 	filemap_nopage,		/* nopage */
 	NULL,			/* wppage */
 	filemap_swapout,	/* swapout */
-	NULL,			/* swapin */
+	filemap_swapin,		/* swapin */
 };
 
 /*
@@ -253,15 +280,8 @@
 		return -ENOEXEC;
 	ops = &file_private_mmap;
 	if (vma->vm_flags & VM_SHARED) {
-		if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) {
-			static int nr = 0;
+		if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
 			ops = &file_shared_mmap;
-#ifndef SHARED_MMAP_REALLY_WORKS /* it doesn't, yet */
-			if (nr++ < 5)
-				printk("%s tried to do a shared writeable mapping\n", current->comm);
-			return -EINVAL;
-#endif
-		}
 	}
 	if (!IS_RDONLY(inode)) {
 		inode->i_atime = CURRENT_TIME;
diff -u --recursive --new-file v1.3.0/linux/mm/swap.c linux/mm/swap.c
--- v1.3.0/linux/mm/swap.c	Sat Jun 10 12:55:57 1995
+++ linux/mm/swap.c	Tue Jun 13 12:59:40 1995
@@ -211,7 +211,7 @@
 		return;
 	offset = SWP_OFFSET(entry);
 	type = SWP_TYPE(entry);
-	if (type == SHM_SWP_TYPE)
+	if (type & SHM_SWP_TYPE)
 		return;
 	if (type >= nr_swapfiles) {
 		printk("Trying to duplicate nonexistent swap-page\n");
@@ -238,7 +238,7 @@
 	if (!entry)
 		return;
 	type = SWP_TYPE(entry);
-	if (type == SHM_SWP_TYPE)
+	if (type & SHM_SWP_TYPE)
 		return;
 	if (type >= nr_swapfiles) {
 		printk("Trying to free nonexistent swap-page\n");
