Date: Tue, 17 Jun 1997 00:05:04 +0200 (MET DST)
From: Geert Uytterhoeven <Geert.Uytterhoeven@thomas.kotnet.org>
To: Linux/m68k <linux-m68k@phil.uni-sb.de>
Subject: L68K: Loadable frame buffer devices
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>


This patch cleans up the video drivers:

  - Fix function name typo in the vfb initialization

  - drivers/video/fbcmap.c: I removed all common colormap code from each frame
    buffer device and put it in a separate file

  - drivers/video/Makefile:

      o CONFIG_FB dependencies

      o addition of compile definitions for gspcon.c

  - Moved txtcon.c skeleton to drivers/video/

  - drivers/char/mem.c: replaced __mc68000__ by CONFIG_FB

--- linux-2.1.42/drivers/char/fbmem.c.orig	Mon Jun 16 21:44:05 1997
+++ linux-2.1.42/drivers/char/fbmem.c	Mon Jun 16 21:44:26 1997
@@ -59,7 +59,7 @@
 extern void clgen_video_setup(char *options, int *ints);
 #endif
 #ifdef CONFIG_FB_VIRTUAL
-extern int vfb_fb_init(u_long *mem_start);
+extern int virtual_fb_init(u_long *mem_start);
 extern void vfb_video_setup(char *options, int *ints);
 #endif
 #ifdef CONFIG_GSP_RESOLVER
--- linux-2.1.42/drivers/video/fbcmap.c.orig	Mon Jun 16 21:43:37 1997
+++ linux-2.1.42/drivers/video/fbcmap.c	Mon Jun 16 21:44:26 1997
@@ -0,0 +1,323 @@
+/*
+ *  linux/drivers/video/fbcmap.c -- Colormap handling for frame buffer devices
+ *
+ *	Created 15 Jun 1997 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+
+
+static void memcpy_fs(int fsfromto, void *to, void *from, int len)
+{
+    switch (fsfromto) {
+    	case 0:
+    	    memcpy(to, from, len);
+    	    return;
+    	case 1:
+    	    copy_from_user(to, from, len);
+    	    return;
+    	case 2:
+    	    copy_to_user(to, from, len);
+    	    return;
+    }
+}
+
+#define CNVT_TOHW(val,width)	((((val)<<(width))+0x7fff-(val))>>16)
+#define CNVT_FROMHW(val,width)	(((width) ? ((((val)<<16)-(val)) / \
+					((1<<(width))-1)) : 0))
+
+static u_short red2[] = {
+    0x0000, 0xc000
+};
+static u_short green2[] = {
+    0x0000, 0xc000
+};
+static u_short blue2[] = {
+    0x0000, 0xc000
+};                                                  
+ 
+static u_short red4[] = {
+    0x0000, 0xc000, 0x8000, 0xffff
+};
+static u_short green4[] = {
+    0x0000, 0xc000, 0x8000, 0xffff
+};
+static u_short blue4[] = {
+    0x0000, 0xc000, 0x8000, 0xffff
+};
+ 
+static u_short red8[] = {
+    0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000
+};
+static u_short green8[] = {
+    0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000
+};
+static u_short blue8[] = {
+    0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000
+};
+ 
+static u_short red16[] = {
+    0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000,
+    0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff
+};
+static u_short green16[] = {
+    0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000,
+    0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff
+};
+static u_short blue16[] = {
+    0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,
+    0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff
+};
+
+static struct fb_cmap default_2_colors = {
+    0, 2, red2, green2, blue2, NULL
+};
+static struct fb_cmap default_8_colors = {
+    0, 8, red8, green8, blue8, NULL
+};                                  
+static struct fb_cmap default_4_colors = {
+    0, 4, red4, green4, blue4, NULL
+};             
+static struct fb_cmap default_16_colors = {
+    0, 16, red16, green16, blue16, NULL
+};
+
+
+    /*
+     *  Allocate a colormap
+     */
+
+int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+    int size = len*sizeof(u_short);
+		    
+    if (cmap->len != len) {
+	if (cmap->red)                                         
+	    kfree(cmap->red);
+	if (cmap->green)
+	    kfree(cmap->green);
+	if (cmap->blue)
+	    kfree(cmap->blue);
+	if (cmap->transp)
+	    kfree(cmap->transp);            
+	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;    
+	cmap->len = 0;                          
+	if (!len) 
+	    return 0;                                      
+	if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
+	    return -1;
+	if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))                 
+	    return -1;
+	if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
+	    return -1;                  
+	if (transp) {                            
+	    if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+		return -1;                                      
+	} else                  
+	    cmap->transp = NULL;                                    
+    }
+    cmap->start = 0;
+    cmap->len = len;
+    fb_copy_cmap(fb_default_cmap(len), cmap, 0);
+    return 0;
+}
+
+
+    /*
+     *  Copy a colormap
+     */
+
+void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
+{
+    int size;
+    int tooff = 0, fromoff = 0;
+
+    if (to->start > from->start)
+	fromoff = to->start-from->start;
+    else
+	tooff = from->start-to->start;
+    size = to->len-tooff;
+    if (size > from->len-fromoff)
+	size = from->len-fromoff;
+    if (size < 0)
+	return;
+    size *= sizeof(u_short);                         
+    memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
+    memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
+    memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
+    if (from->transp && to->transp)
+	memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);                              
+}
+
+
+    /*
+     *  Get the colormap for a screen
+     */
+
+int fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc,
+    	    	int (*getcolreg)(u_int, u_int *, u_int *, u_int *, u_int *))
+{
+    int i, start;
+    u_short *red, *green, *blue, *transp;
+    u_int hred, hgreen, hblue, htransp;
+
+    red = cmap->red;
+    green = cmap->green;
+    blue = cmap->blue;
+    transp = cmap->transp;
+    start = cmap->start;
+    if (start < 0)
+	return -EINVAL;
+    for (i = 0; i < cmap->len; i++) {
+	if (getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
+	    return 0;
+	hred = CNVT_FROMHW(hred, var->red.length);
+	hgreen = CNVT_FROMHW(hgreen, var->green.length);
+	hblue = CNVT_FROMHW(hblue, var->blue.length);
+	htransp = CNVT_FROMHW(htransp, var->transp.length);
+	if (kspc) {
+	    *red = hred;
+	    *green = hgreen;
+	    *blue = hblue;
+	    if (transp)
+		*transp = htransp;
+	} else {
+	    put_user(hred, red);
+	    put_user(hgreen, green);
+	    put_user(hblue, blue);
+	    if (transp)
+		put_user(htransp, transp);
+	}
+	red++;
+	green++;
+	blue++;
+	if (transp)
+	    transp++;
+    }
+    return 0;
+}
+
+
+    /*
+     *  Set the colormap for a screen
+     */
+
+int fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc,
+    	    	int (*setcolreg)(u_int, u_int, u_int, u_int, u_int))
+{
+    int i, start;
+    u_short *red, *green, *blue, *transp;
+    u_int hred, hgreen, hblue, htransp;
+
+    red = cmap->red;
+    green = cmap->green;
+    blue = cmap->blue;
+    transp = cmap->transp;
+    start = cmap->start;
+
+    if (start < 0)
+	return -EINVAL;
+    for (i = 0; i < cmap->len; i++) {
+	if (kspc) {
+	    hred = *red;
+	    hgreen = *green;
+	    hblue = *blue;
+	    htransp = transp ? *transp : 0;
+	} else {
+	    get_user(hred, red);
+	    get_user(hgreen, green);
+	    get_user(hblue, blue);
+	    if (transp)
+		get_user(htransp, transp);
+	    else
+		htransp = 0;
+	}
+	hred = CNVT_TOHW(hred, var->red.length);
+	hgreen = CNVT_TOHW(hgreen, var->green.length);
+	hblue = CNVT_TOHW(hblue, var->blue.length);
+	htransp = CNVT_TOHW(htransp, var->transp.length);
+	red++;
+	green++;
+	blue++;
+	if (transp)
+	    transp++;
+	if (setcolreg(start++, hred, hgreen, hblue, htransp))
+	    return 0;
+    }
+    return 0;
+}
+
+
+    /*
+     *  Get the default colormap for a specific screen depth
+     */
+
+struct fb_cmap *fb_default_cmap(int bpp)
+{
+    switch (bpp) {                                                          
+	case 1:                                                       
+	    return &default_2_colors;
+	    break;
+	case 2:                                            
+	    return &default_4_colors;                             
+	    break;                                   
+	case 3:
+	    return &default_8_colors;                              
+	    break;
+	default:
+	    return &default_16_colors;
+	    break;                                                  
+    }
+}
+
+
+    /*
+     *  Invert all default colormaps
+     */
+
+void fb_invert_cmaps(void)
+{
+    u_int i;
+
+    for (i = 0; i < 2; i++) {
+	red2[i] = ~red2[i];
+	green2[i] = ~green2[i];
+	blue2[i] = ~blue2[i];
+    }
+    for (i = 0; i < 4; i++) {
+	red4[i] = ~red4[i];
+	green4[i] = ~green4[i];
+	blue4[i] = ~blue4[i];
+    }
+    for (i = 0; i < 8; i++) {
+	red8[i] = ~red8[i];
+	green8[i] = ~green8[i];
+	blue8[i] = ~blue8[i];
+    }
+    for (i = 0; i < 16; i++) {
+	red16[i] = ~red16[i];
+	green16[i] = ~green16[i];
+	blue16[i] = ~blue16[i];
+    }
+}
+
+
+    /*
+     *  Visible symbols for modules
+     */
+
+EXPORT_SYMBOL(fb_alloc_cmap);
+EXPORT_SYMBOL(fb_copy_cmap);
+EXPORT_SYMBOL(fb_get_cmap);
+EXPORT_SYMBOL(fb_set_cmap);
+EXPORT_SYMBOL(fb_default_cmap);
+EXPORT_SYMBOL(fb_invert_cmaps);
--- linux-2.1.42/drivers/video/Makefile.orig	Mon Jun 16 21:43:37 1997
+++ linux-2.1.42/drivers/video/Makefile	Mon Jun 16 21:47:14 1997
@@ -9,15 +9,23 @@
 # parent makes..
 #
 
+GSPA = gspa
+GSPH2C = gspahextoc
+
 L_TARGET := video.a
-L_OBJS   := fonts.o font_8x8.o font_8x16.o pearl_8x8.o
+L_OBJS   :=
 M_OBJS   :=
-MOD_LIST_NAME := VIDEO_MODULES
-LX_OBJS  := fbcon.o
+LX_OBJS  :=
 MX_OBJS  :=
+MOD_LIST_NAME := VIDEO_MODULES
 
 # Frame buffer devices
 
+ifeq ($(CONFIG_FB),y)
+  L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o
+  LX_OBJS += fbcon.o fbcmap.o
+endif
+
 ifeq ($(CONFIG_FB_AMIGA),y)
 L_OBJS += amifb.o
 else
@@ -140,5 +148,12 @@
   endif
 endif
 
+ifdef CONFIG_AMIGA_GSP
+L_OBJS := $(L_OBJS) gspcon.o gspcore.o
+endif
+
 include $(TOPDIR)/Rules.make
 
+gspcore.c: gspcore.gsp
+	$(GSPA) $< > $*.hex
+	$(GSPH2C) $*.hex > gspcore.c
--- linux-2.1.42/drivers/video/txtcon.c.orig	Mon Jun 16 21:46:01 1997
+++ linux-2.1.42/drivers/video/txtcon.c	Mon Jun 16 21:48:13 1997
@@ -0,0 +1,145 @@
+/*
+ * linux/drivers/video/txtcon.c -- Low level text mode based console driver
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * This file is currently only a skeleton, since all Amigas and Ataris have
+ * bitmapped graphics.
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+
+#include <linux/types.h>
+#include <linux/console.h>
+
+
+   /*
+    *    Interface used by the world
+    */
+
+static int txtcon_startup(u_long *kmem_start, const char **display_desc);
+static void txtcon_init(struct vc_data *conp);
+static int txtcon_deinit(struct vc_data *conp);
+static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                        int width);
+static int txtcon_putc(struct vc_data *conp, int c, int y, int x);
+static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                        int x);
+static int txtcon_cursor(struct vc_data *conp, int mode);
+static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
+static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                        int height, int width);
+static int txtcon_switch(struct vc_data *conp);
+static int txtcon_blank(int blank);
+static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
+static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int txtcon_set_palette(struct vc_data *conp, unsigned char *table);
+
+
+static int txtcon_startup(u_long *kmem_start, const char **display_desc)
+{
+   return -ENODEV;
+}
+
+
+static void txtcon_init(struct vc_data *conp)
+{
+}
+
+
+static int txtcon_deinit(struct vc_data *conp)
+{
+   return(0);
+}
+
+
+/* ====================================================================== */
+
+/* txtcon_XXX routines - interface used by the world */
+
+
+static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
+                        int width)
+{
+   return(0);
+}
+
+
+static int txtcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+   return(0);
+}
+
+
+static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
+                        int x)
+{
+   return(0);
+}
+
+
+static int txtcon_cursor(struct vc_data *conp, int mode)
+{
+   return(0);
+}
+
+
+static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+   return(0);
+}
+
+
+static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+                        int height, int width)
+{
+   return(0);
+}
+
+
+static int txtcon_switch(struct vc_data *conp)
+{
+   return(0);
+}
+
+
+static int txtcon_blank(int blank)
+{
+   return(0);
+}
+
+
+static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+   return(0);
+}
+
+
+static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+   return(0);
+}
+
+
+static int txtcon_set_palette(struct vc_data *conp, unsigned char *table)
+{
+   return(0);
+}
+
+
+/* ====================================================================== */
+
+   /*
+    *    The console `switch' structure for the text mode based console
+    */
+
+struct consw txt_con = {
+   txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc,
+   txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch,
+   txtcon_blank, txtcon_get_font, txtcon_set_font, txtcon_set_palette
+};
--- linux-2.1.42/drivers/video/amifb.c.orig	Mon Jun 16 21:43:37 1997
+++ linux-2.1.42/drivers/video/amifb.c	Mon Jun 16 21:44:27 1997
@@ -1170,50 +1170,6 @@
 	FMODE_SPAGEM | FMODE_SPR32	/* 4x */
 };
 
-	/*
-	 * Default Colormaps
-	 */
-
-static u_short red2[] =
-	{ 0x0000, 0xc000 };
-static u_short green2[] =
-	{ 0x0000, 0xc000 };
-static u_short blue2[] =
-	{ 0x0000, 0xc000 };
-
-static u_short red4[] =
-	{ 0x0000, 0xc000, 0x8000, 0xffff };
-static u_short green4[] =
-	{ 0x0000, 0xc000, 0x8000, 0xffff };
-static u_short blue4[] =
-	{ 0x0000, 0xc000, 0x8000, 0xffff };
-
-static u_short red8[] =
-	{ 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000 };
-static u_short green8[] =
-	{ 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000 };
-static u_short blue8[] =
-	{ 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000 };
-
-static u_short red16[] =
-	{ 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000,
-	  0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff };
-static u_short green16[] =
-	{ 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000,
-	  0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff };
-static u_short blue16[] =
-	{ 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,
-	  0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff };
-
-
-static struct fb_cmap default_2_colors =
-	{ 0, 2, red2, green2, blue2, NULL };
-static struct fb_cmap default_8_colors =
-	{ 0, 8, red8, green8, blue8, NULL };
-static struct fb_cmap default_4_colors =
-	{ 0, 4, red4, green4, blue4, NULL };
-static struct fb_cmap default_16_colors =
-	{ 0, 16, red16, green16, blue16, NULL };
 
 	/*
 	 * Interface used by the world
@@ -1252,15 +1208,7 @@
 	 * Internal routines
 	 */
 
-static struct fb_cmap *get_default_colormap(int bpp);
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
 static void do_install_cmap(int con);
-static void memcpy_fs(int fsfromto, void *to, void *from, int len);
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 static int flash_cursor(void);
 static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
 static void get_video_mode(const char *name);
@@ -1320,7 +1268,6 @@
 __initfunc(void amiga_video_setup(char *options, int *ints))
 {
 	char *this_opt;
-	int i;
 	char mcap_spec[80];
 
 	mcap_spec[0] = '\0';
@@ -1334,26 +1281,7 @@
 
 		if (!strcmp(this_opt, "inverse")) {
 			amifb_inverse = 1;
-			for (i = 0; i < 16; i++) {
-				red16[i] = ~red16[i];
-				green16[i] = ~green16[i];
-				blue16[i] = ~blue16[i];
-			}
-			for (i = 0; i < 8; i++) {
-				red8[i] = ~red8[i];
-				green8[i] = ~green8[i];
-				blue8[i] = ~blue8[i];
-			}
-			for (i = 0; i < 4; i++) {
-				red4[i] = ~red4[i];
-				green4[i] = ~green4[i];
-				blue4[i] = ~blue4[i];
-			}
-			for (i = 0; i < 2; i++) {
-				red2[i] = ~red2[i];
-				green2[i] = ~green2[i];
-				blue2[i] = ~blue2[i];
-			}
+			fb_invert_cmaps();
 		} else if (!strcmp(this_opt, "ilbm"))
 			amifb_ilbm = 1;
 		else if (!strncmp(this_opt, "monitorcap:", 11))
@@ -1579,7 +1507,7 @@
 				(*fb_info.changevar)(con);
 		}
 		if (oldbpp != var->bits_per_pixel) {
-			if ((err = alloc_cmap(&display->cmap, 0, 0)))
+			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 				return err;
 			do_install_cmap(con);
 		}
@@ -1627,12 +1555,13 @@
 static int amiga_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
 {
 	if (con == currcon) /* current console? */
-		return do_fb_get_cmap(cmap, &fb_display[con].var, kspc);
+		return fb_get_cmap(cmap, &fb_display[con].var, kspc,
+				   ami_getcolreg);
 	else if (fb_display[con].cmap.len) /* non default colormap? */
-		copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		copy_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-		          cmap, kspc ? 0 : 2);
+		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+			     cmap, kspc ? 0 : 2);
 	return 0;
 }
 
@@ -1644,15 +1573,17 @@
 {
 	int err;
 
-	if (!fb_display[con].cmap.len) {		/* no colormap allocated? */
-		if ((err = alloc_cmap(&fb_display[con].cmap,
-		                      1<<fb_display[con].var.bits_per_pixel, 0)))
+	if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+		if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+					 1<<fb_display[con].var.bits_per_pixel,
+					 0)))
 			return err;
 	}
 	if (con == currcon)			/* current console? */
-		return do_fb_set_cmap(cmap, &fb_display[con].var, kspc);
+		return fb_set_cmap(cmap, &fb_display[con].var, kspc,
+				   ami_setcolreg);
 	else
-		copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
 }
 
@@ -1958,7 +1889,8 @@
 {
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
-		do_fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1);
+		fb_get_cmap(&fb_display[currcon].cmap,
+			    &fb_display[currcon].var, 1, ami_getcolreg);
 
 	currcon = con;
 	ami_set_var(&fb_display[con].var);
@@ -1995,199 +1927,18 @@
 	return(amiga_fb_set_cmap(cmap, 1, con));
 }
 
-/* ---------------------------- Generic routines ---------------------------- */
-
-static struct fb_cmap *get_default_colormap(int bpp)
-{
-	switch (bpp) {
-		case 1:
-			return &default_2_colors;
-			break;
-		case 2:
-			return &default_4_colors;
-			break;
-		case 3:
-			return &default_8_colors;
-			break;
-		default:
-			return &default_16_colors;
-			break;
-	}
-}
-
-#define CNVT_TOHW(val,width)	((((val)<<(width))+0x7fff-(val))>>16)
-#define CNVT_FROMHW(val,width)	(((width) ? ((((val)<<16)-(val)) / \
-                                            ((1<<(width))-1)) : 0))
-
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-	int i, start;
-	u_short *red, *green, *blue, *transp;
-	u_int hred, hgreen, hblue, htransp;
-
-	red = cmap->red;
-	green = cmap->green;
-	blue = cmap->blue;
-	transp = cmap->transp;
-	start = cmap->start;
-	if (start < 0)
-		return -EINVAL;
-	for (i = 0; i < cmap->len; i++) {
-		if (ami_getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
-			return 0;
-		hred = CNVT_FROMHW(hred, var->red.length);
-		hgreen = CNVT_FROMHW(hgreen, var->green.length);
-		hblue = CNVT_FROMHW(hblue, var->blue.length);
-		htransp = CNVT_FROMHW(htransp, var->transp.length);
-		if (kspc) {
-			*red = hred;
-			*green = hgreen;
-			*blue = hblue;
-			if (transp)
-				*transp = htransp;
-		} else {
-			put_user(hred, red);
-			put_user(hgreen, green);
-			put_user(hblue, blue);
-			if (transp)
-				put_user(htransp, transp);
-		}
-		red++;
-		green++;
-		blue++;
-		if (transp)
-			transp++;
-	}
-	return 0;
-}
-
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-	int i, start;
-	u_short *red, *green, *blue, *transp;
-	u_int hred, hgreen, hblue, htransp;
-
-	red = cmap->red;
-	green = cmap->green;
-	blue = cmap->blue;
-	transp = cmap->transp;
-	start = cmap->start;
-
-	if (start < 0)
-		return -EINVAL;
-	for (i = 0; i < cmap->len; i++) {
-		if (kspc) {
-			hred = *red;
-			hgreen = *green;
-			hblue = *blue;
-			htransp = transp ? *transp : 0;
-		} else {
-			get_user(hred, red);
-			get_user(hgreen, green);
-			get_user(hblue, blue);
-			if (transp)
-				get_user(htransp, transp);
-			else
-				htransp = 0;
-		}
-		hred = CNVT_TOHW(hred, var->red.length);
-		hgreen = CNVT_TOHW(hgreen, var->green.length);
-		hblue = CNVT_TOHW(hblue, var->blue.length);
-		htransp = CNVT_TOHW(htransp, var->transp.length);
-		red++;
-		green++;
-		blue++;
-		if (transp)
-			transp++;
-		if (ami_setcolreg(start++, hred, hgreen, hblue, htransp))
-			return 0;
-	}
-	return 0;
-}
 
 static void do_install_cmap(int con)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
-		do_fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1);
+		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+			    ami_setcolreg);
 	else
-		do_fb_set_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-		                                    &fb_display[con].var, 1);
-}
-
-static void memcpy_fs(int fsfromto, void *to, void *from, int len)
-{
-	switch (fsfromto) {
-		case 0:
-			memcpy(to, from, len);
-			return;
-		case 1:
-			copy_from_user(to, from, len);
-			return;
-		case 2:
-			copy_to_user(to, from, len);
-			return;
-	}
-}
-
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
-{
-	int size;
-	int tooff = 0, fromoff = 0;
-
-	if (to->start > from->start)
-		fromoff = to->start-from->start;
-	else
-		tooff = from->start-to->start;
-	size = to->len-tooff;
-	if (size > from->len-fromoff)
-		size = from->len-fromoff;
-	if (size < 0)
-		return;
-	size *= sizeof(u_short);
-	memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
-	memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
-	memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
-	if (from->transp && to->transp)
-		memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
-}
-
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
-{
-	int size = len*sizeof(u_short);
-
-	if (cmap->len != len) {
-		if (cmap->red)
-			kfree(cmap->red);
-		if (cmap->green)
-			kfree(cmap->green);
-		if (cmap->blue)
-			kfree(cmap->blue);
-		if (cmap->transp)
-			kfree(cmap->transp);
-		cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
-		cmap->len = 0;
-		if (!len)
-			return 0;
-		if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (transp) {
-			if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-				return -1;
-		} else
-			cmap->transp = NULL;
-	}
-	cmap->start = 0;
-	cmap->len = len;
-	copy_cmap(get_default_colormap(len), cmap, 0);
-	return 0;
+		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+					    &fb_display[con].var, 1,
+					    ami_setcolreg);
 }
 
 static int flash_cursor(void)
--- linux-2.1.42/drivers/video/atafb.c.orig	Mon Jun 16 21:44:06 1997
+++ linux-2.1.42/drivers/video/atafb.c	Mon Jun 16 21:44:28 1997
@@ -2436,230 +2436,20 @@
 
 /* Functions for handling colormap */
 
-/* there seems to be a bug in gcc 2.5.8 which inhibits using an other solution */
-/* I always get a sigsegv */
-
-static short red16[]=
-	{ 0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,
-	  0x8000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff};
-static short green16[]=
-	{ 0x0000,0x0000,0xc000,0xc000,0x0000,0x0000,0xc000,0xc000,
-	  0x8000,0x0000,0xffff,0xffff,0x0000,0x0000,0xffff,0xffff};
-static short blue16[]=
-	{ 0x0000,0xc000,0x0000,0xc000,0x0000,0xc000,0x0000,0xc000,
-	  0x8000,0xffff,0x0000,0xffff,0x0000,0xffff,0x0000,0xffff};
-
-static short red4[]=
-	{ 0x0000,0xc000,0x8000,0xffff};
-static short green4[]=
-	{ 0x0000,0xc000,0x8000,0xffff};
-static short blue4[]=
-	{ 0x0000,0xc000,0x8000,0xffff};
-
-static short red2[]=
-	{ 0x0000,0xffff};
-static short green2[]=
-	{ 0x0000,0xffff};
-static short blue2[]=
-	{ 0x0000,0xffff};
-
-static struct fb_cmap default_16_colors = {
-    0, 16, red16, green16, blue16, NULL
-};
-static struct fb_cmap default_4_colors = {
-    0, 4, red4, green4, blue4, NULL
-};
-static struct fb_cmap default_2_colors = {
-    0, 2, red2, green2, blue2, NULL
-};
-
-static struct fb_cmap *
-get_default_colormap(int bpp)
-{
-	if (bpp == 1)
-		return &default_2_colors;
-	if (bpp == 2)
-		return &default_4_colors;
-	return &default_16_colors;
-}
-
-#define CNVT_TOHW(val,width)	(((val) << (width)) + 0x7fff - (val)) >> 16
-#define CNVT_FROMHW(val,width) ((width)?((((val) << 16) - (val)) / ((1<<(width))-1)):0)
-
-
-static int
-do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc)
-{
-	int i,start;
-	unsigned short *red,*green,*blue,*transp;
-	unsigned int hred,hgreen,hblue,htransp;
-
-	red=cmap->red;
-	green=cmap->green;
-	blue=cmap->blue;
-	transp=cmap->transp;
-	start=cmap->start;
-	if (start < 0)
-		return EINVAL;
-	for (i=0 ; i < cmap->len ; i++) {
-		if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
-			return 0;
-		hred=CNVT_FROMHW(hred,var->red.length);
-		hgreen=CNVT_FROMHW(hgreen,var->green.length);
-		hblue=CNVT_FROMHW(hblue,var->blue.length);
-		htransp=CNVT_FROMHW(htransp,var->transp.length);
-		if (kspc) {
-			*red=hred;
-			*green=hgreen;
-			*blue=hblue;
-			if (transp) *transp=htransp;
-		}
-		else {
-			put_user(hred, red);
-			put_user(hgreen, green);
-			put_user(hblue, blue);
-			if (transp) put_user(htransp, transp);
-		}
-		red++;
-		green++;
-		blue++;
-		if (transp) transp++;
-	}
-	return 0;
-}
-
-static int
-do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc)
-{
-	int i,start;
-	unsigned short *red,*green,*blue,*transp;
-	unsigned int hred,hgreen,hblue,htransp;
-
-	red=cmap->red;
-	green=cmap->green;
-	blue=cmap->blue;
-	transp=cmap->transp;
-	start=cmap->start;
-
-	if (start < 0)
-		return -EINVAL;
-	for (i=0 ; i < cmap->len ; i++) {
-		if (kspc) {
-			hred=*red;
-			hgreen=*green;
-			hblue=*blue;
-			htransp=(transp) ? *transp : 0;
-		}
-		else {
-			get_user(hred, red);
-			get_user(hgreen, green);
-			get_user(hblue, blue);
-			if (transp)
-				get_user(htransp, transp);
-			else
-				htransp = 0;
-		}
-		hred=CNVT_TOHW(hred,var->red.length);
-		hgreen=CNVT_TOHW(hgreen,var->green.length);
-		hblue=CNVT_TOHW(hblue,var->blue.length);
-		htransp=CNVT_TOHW(htransp,var->transp.length);
-		red++;
-		green++;
-		blue++;
-		if (transp) transp++;
-		if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
-			return 0;
-	}
-	return 0;
-}
-
 static void
 do_install_cmap(int con)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
-		do_fb_set_cmap(&fb_display[con].cmap, &(fb_display[con].var), 1);
+		fb_set_cmap(&fb_display[con].cmap, &(fb_display[con].var), 1,
+			    fbhw->setcolreg);
 	else
-		do_fb_set_cmap(get_default_colormap(
-				fb_display[con].var.bits_per_pixel), &(fb_display[con].var), 1);		
+		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+					    &(fb_display[con].var), 1,
+					    fbhw->setcolreg);		
 }
 
-static void
-memcpy_fs(int fsfromto, void *to, void *from, int len)
-{
-	switch (fsfromto) {
-	case 0:
-		memcpy(to,from,len);
-		return;
-	case 1:
-		copy_from_user(to,from,len);
-		return;
-	case 2:
-		copy_to_user(to,from,len);
-		return;
-	}
-}
-
-static void
-copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
-{
-	int size;
-	int tooff=0, fromoff=0;
-
-	if (to->start > from->start)
-		fromoff=to->start-from->start;
-	else
-		tooff=from->start-to->start;			
-	size=to->len-tooff;
-	if (size > from->len-fromoff)
-		size=from->len-fromoff;
-	if (size < 0)
-		return;
-	size*=sizeof(unsigned short);
-	memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
-	memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
-	memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
-	if (from->transp && to->transp)
-		memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
-}
- 
-static int
-alloc_cmap(struct fb_cmap *cmap,int len,int transp)
-{
-	int size=len*sizeof(unsigned short);
-	if (cmap->len != len) {
-		if (cmap->red)
-			kfree(cmap->red);
-		if (cmap->green)
-			kfree(cmap->green);
-		if (cmap->blue)
-			kfree(cmap->blue);
-		if (cmap->transp)
-			kfree(cmap->transp);
-		cmap->red=cmap->green=cmap->blue=cmap->transp=NULL;
-		cmap->len=0;
-		if (! len)
-			return 0;
-		if (! (cmap->red=kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (! (cmap->green=kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (! (cmap->blue=kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (transp) {
-			if (! (cmap->transp=kmalloc(size, GFP_ATOMIC)))
-				return -1;
-		}
-		else
-			cmap->transp=NULL;
-	}
-	cmap->start=0;
-	cmap->len=len;
-	copy_cmap(get_default_colormap(len), cmap, 0);
-	return 0;
-}	
-
 
 	/*
 	 * Open/Release the frame buffer device
@@ -2758,7 +2548,7 @@
 		    || oldyoffset != var->yoffset) {
 			atari_fb_set_disp(con);
 			(*fb_info.changevar)(con);
-			alloc_cmap(&fb_display[con].cmap, 0, 0);
+			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
 			do_install_cmap(con);
 		}
 	}
@@ -2772,13 +2562,14 @@
 atari_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
 {
 	if (con == currcon) /* current console ? */
-		return do_fb_get_cmap(cmap, &(fb_display[con].var), kspc);
+		return fb_get_cmap(cmap, &(fb_display[con].var), kspc,
+				   fbhw->getcolreg);
 	else
 		if (fb_display[con].cmap.len) /* non default colormap ? */
-			copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+			fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 		else
-			copy_cmap(get_default_colormap(
-			    fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2);
+			fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+				     cmap, kspc ? 0 : 2);
 	return 0;
 }
 
@@ -2787,14 +2578,16 @@
 {
 	int err;
 	if (! fb_display[con].cmap.len) { /* no colormap allocated ? */
-		if ((err = alloc_cmap(&fb_display[con].cmap, 
-					1 << fb_display[con].var.bits_per_pixel, 0)))
+		if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+					 1 << fb_display[con].var.bits_per_pixel,
+					 0)))
 		return err;
 	}
 	if (con == currcon) /* current console ? */
-		return do_fb_set_cmap(cmap, &(fb_display[con].var), kspc);
+		return fb_set_cmap(cmap, &(fb_display[con].var), kspc,
+				   fbhw->setcolreg);
 	else
-		copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
 }
 
@@ -2898,7 +2691,8 @@
 {
 	/* Do we have to save the colormap ? */
 	if (fb_display[currcon].cmap.len)
-		do_fb_get_cmap(&fb_display[currcon].cmap, &(fb_display[currcon].var), 1);
+		fb_get_cmap(&fb_display[currcon].cmap,
+			    &(fb_display[currcon].var), 1, fbhw->getcolreg);
 	do_fb_set_var(&fb_display[con].var,1);
 	currcon=con;
 	/* Install new colormap */
@@ -2928,7 +2722,8 @@
 		cmap.transp=NULL;
 		cmap.start=0;
 		cmap.len=16;
-		do_fb_set_cmap(&cmap, &(fb_display[currcon].var), 1);
+		fb_set_cmap(&cmap, &(fb_display[currcon].var), 1,
+			    fbhw->setcolreg);
 	}
 	else
 		do_install_cmap(currcon);
--- linux-2.1.42/drivers/video/cyberfb.c.orig	Mon Jun 16 21:43:38 1997
+++ linux-2.1.42/drivers/video/cyberfb.c	Mon Jun 16 21:44:28 1997
@@ -276,15 +276,7 @@
 static void Cyber_fb_get_par(struct Cyber_fb_par *par);
 static void Cyber_fb_set_par(struct Cyber_fb_par *par);
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static struct fb_cmap *get_default_colormap(int bpp);
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
 static void do_install_cmap(int con);
-static void memcpy_fs(int fsfromto, void *to, void *from, int len);
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 static void Cyber_fb_set_disp(int con);
 static int get_video_mode(const char *name);
 
@@ -761,209 +753,16 @@
 }
 
 
-   /*
-    *    Default Colormaps
-    */
-
-static u_short red16[] =
-   { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000,
-     0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff};
-static u_short green16[] =
-   { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000,
-     0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff};
-static u_short blue16[] =
-   { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000,
-     0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff};
-
-
-static struct fb_cmap default_16_colors =
-   { 0, 16, red16, green16, blue16, NULL };
-
-
-static struct fb_cmap *get_default_colormap(int bpp)
-{
-   return(&default_16_colors);
-}
-
-
-#define CNVT_TOHW(val,width)     ((((val)<<(width))+0x7fff-(val))>>16)
-#define CNVT_FROMHW(val,width)   (((width) ? ((((val)<<16)-(val)) / \
-                                              ((1<<(width))-1)) : 0))
-
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-   int i, start;
-   u_short *red, *green, *blue, *transp;
-   u_int hred, hgreen, hblue, htransp;
-
-   red = cmap->red;
-   green = cmap->green;
-   blue = cmap->blue;
-   transp = cmap->transp;
-   start = cmap->start;
-   if (start < 0)
-      return(-EINVAL);
-   for (i = 0; i < cmap->len; i++) {
-      if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
-         return(0);
-      hred = CNVT_FROMHW(hred, var->red.length);
-      hgreen = CNVT_FROMHW(hgreen, var->green.length);
-      hblue = CNVT_FROMHW(hblue, var->blue.length);
-      htransp = CNVT_FROMHW(htransp, var->transp.length);
-      if (kspc) {
-         *red = hred;
-         *green = hgreen;
-         *blue = hblue;
-         if (transp)
-            *transp = htransp;
-      } else {
-         put_user(hred, red);
-         put_user(hgreen, green);
-         put_user(hblue, blue);
-         if (transp)
-            put_user(htransp, transp);
-      }
-      red++;
-      green++;
-      blue++;
-      if (transp)
-         transp++;
-   }
-   return(0);
-}
-
-
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-   int i, start;
-   u_short *red, *green, *blue, *transp;
-   u_int hred, hgreen, hblue, htransp;
-
-   red = cmap->red;
-   green = cmap->green;
-   blue = cmap->blue;
-   transp = cmap->transp;
-   start = cmap->start;
-
-   if (start < 0)
-      return(-EINVAL);
-   for (i = 0; i < cmap->len; i++) {
-      if (kspc) {
-         hred = *red;
-         hgreen = *green;
-         hblue = *blue;
-         htransp = transp ? *transp : 0;
-      } else {
-         get_user(hred, red);
-         get_user(hgreen, green);
-         get_user(hblue, blue);
-	 if (transp)
-		 get_user(htransp, transp);
-	 else
-		 htransp = 0;
-      }
-      hred = CNVT_TOHW(hred, var->red.length);
-      hgreen = CNVT_TOHW(hgreen, var->green.length);
-      hblue = CNVT_TOHW(hblue, var->blue.length);
-      htransp = CNVT_TOHW(htransp, var->transp.length);
-      red++;
-      green++;
-      blue++;
-      if (transp)
-         transp++;
-      if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
-         return(0);
-   }
-   return(0);
-}
-
-
 static void do_install_cmap(int con)
 {
    if (con != currcon)
       return;
    if (fb_display[con].cmap.len)
-      do_fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1);
+      fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+      		  fbhw->setcolreg);
    else
-      do_fb_set_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-                                          &fb_display[con].var, 1);
-}
-
-
-static void memcpy_fs(int fsfromto, void *to, void *from, int len)
-{
-   switch (fsfromto) {
-      case 0:
-         memcpy(to, from, len);
-         return;
-      case 1:
-         copy_from_user(to, from, len);
-         return;
-      case 2:
-         copy_to_user(to, from, len);
-         return;
-   }
-}
-
-
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
-{
-   int size;
-   int tooff = 0, fromoff = 0;
-
-   if (to->start > from->start)
-      fromoff = to->start-from->start;
-   else
-      tooff = from->start-to->start;
-   size = to->len-tooff;
-   if (size > from->len-fromoff)
-      size = from->len-fromoff;
-   if (size < 0)
-      return;
-   size *= sizeof(u_short);
-   memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
-   memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
-   memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
-   if (from->transp && to->transp)
-      memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
-}
-
-
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
-{
-   int size = len*sizeof(u_short);
-
-   if (cmap->len != len) {
-      if (cmap->red)
-         kfree(cmap->red);
-      if (cmap->green)
-         kfree(cmap->green);
-      if (cmap->blue)
-         kfree(cmap->blue);
-      if (cmap->transp)
-         kfree(cmap->transp);
-      cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
-      cmap->len = 0;
-      if (!len)
-         return(0);
-      if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-         return(-1);
-      if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-         return(-1);
-      if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-         return(-1);
-      if (transp) {
-         if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-            return(-1);
-      } else
-         cmap->transp = NULL;
-   }
-   cmap->start = 0;
-   cmap->len = len;
-   copy_cmap(get_default_colormap(len), cmap, 0);
-   return(0);
+      fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+				  &fb_display[con].var, 1, fbhw->setcolreg);
 }
 
 
@@ -1069,7 +868,7 @@
           oldbpp != var->bits_per_pixel) {
          Cyber_fb_set_disp(con);
          (*fb_info.changevar)(con);
-         alloc_cmap(&fb_display[con].cmap, 0, 0);
+         fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
          do_install_cmap(con);
       }
    }
@@ -1085,12 +884,12 @@
 static int Cyber_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
 {
    if (con == currcon) /* current console? */
-      return(do_fb_get_cmap(cmap, &fb_display[con].var, kspc));
+      return(fb_get_cmap(cmap, &fb_display[con].var, kspc, fbhw->getcolreg));
    else if (fb_display[con].cmap.len) /* non default colormap? */
-      copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+      fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
    else
-      copy_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel), cmap,
-                kspc ? 0 : 2);
+      fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+      		   cmap, kspc ? 0 : 2);
    return(0);
 }
 
@@ -1104,14 +903,14 @@
    int err;
 
    if (!fb_display[con].cmap.len) {       /* no colormap allocated? */
-      if ((err = alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel,
-                            0)))
+      if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+      			       1<<fb_display[con].var.bits_per_pixel, 0)))
          return(err);
    }
    if (con == currcon)              /* current console? */
-      return(do_fb_set_cmap(cmap, &fb_display[con].var, kspc));
+      return(fb_set_cmap(cmap, &fb_display[con].var, kspc, fbhw->setcolreg));
    else
-      copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+      fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
    return(0);
 }
 
@@ -1149,7 +948,6 @@
 __initfunc(void Cyber_video_setup(char *options, int *ints))
 {
    char *this_opt;
-   int i;
 
    fb_info.fontname[0] = '\0';
 
@@ -1159,11 +957,7 @@
    for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
       if (!strcmp(this_opt, "inverse")) {
          Cyberfb_inverse = 1;
-         for (i = 0; i < 16; i++) {
-            red16[i] = ~red16[i];
-            green16[i] = ~green16[i];
-            blue16[i] = ~blue16[i];
-         }
+         fb_invert_cmaps();
       } else if (!strncmp(this_opt, "font:", 5))
          strcpy(fb_info.fontname, this_opt+5);
       else if (!strcmp (this_opt, "cyber8"))
@@ -1226,7 +1020,8 @@
 {
    /* Do we have to save the colormap? */
    if (fb_display[currcon].cmap.len)
-      do_fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1);
+      fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+      		  fbhw->getcolreg);
 
    do_fb_set_var(&fb_display[con].var, 1);
    currcon = con;
--- linux-2.1.42/drivers/video/retz3fb.c.orig	Mon Jun 16 21:43:39 1997
+++ linux-2.1.42/drivers/video/retz3fb.c	Mon Jun 16 21:44:29 1997
@@ -373,15 +373,7 @@
 static void retz3_fb_get_par(struct retz3_fb_par *par);
 static void retz3_fb_set_par(struct retz3_fb_par *par);
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static struct fb_cmap *get_default_colormap(int bpp);
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
 static void do_install_cmap(int con);
-static void memcpy_fs(int fsfromto, void *to, void *from, int len);
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 static void retz3_fb_set_disp(int con);
 static int get_video_mode(const char *name);
 
@@ -1254,215 +1246,21 @@
 }
 
 
-/*
- *    Default Colormaps
- */
-
-static unsigned short red16[] =
-	{ 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000,
-	  0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff };
-static unsigned short green16[] =
-	{ 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000,
-	  0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff };
-static unsigned short blue16[] =
-	{ 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,
-	  0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff };
-
-
-static struct fb_cmap default_16_colors =
-   { 0, 16, red16, green16, blue16, NULL };
-
-
-static struct fb_cmap *get_default_colormap(int bpp)
-{
-	return &default_16_colors;
-}
-
-
-#define CNVT_TOHW(val,width)     ((((val)<<(width))+0x7fff-(val))>>16)
-#define CNVT_FROMHW(val,width)   (((width) ? ((((val)<<16)-(val)) / \
-                                              ((1<<(width))-1)) : 0))
-
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-	int i, start;
-	unsigned short *red, *green, *blue, *transp;
-	unsigned int hred, hgreen, hblue, htransp;
-
-	red = cmap->red;
-	green = cmap->green;
-	blue = cmap->blue;
-	transp = cmap->transp;
-	start = cmap->start;
-
-	if (start < 0)
-		return -EINVAL;
-	for (i = 0; i < cmap->len; i++) {
-		if (fbhw->getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
-			return 0;
-		hred = CNVT_FROMHW(hred, var->red.length);
-		hgreen = CNVT_FROMHW(hgreen, var->green.length);
-		hblue = CNVT_FROMHW(hblue, var->blue.length);
-		htransp = CNVT_FROMHW(htransp, var->transp.length);
-		if (kspc) {
-			*red = hred;
-			*green = hgreen;
-			*blue = hblue;
-			if (transp)
-				*transp = htransp;
-		} else {
-			put_user(hred, red);
-			put_user(hgreen, green);
-			put_user(hblue, blue);
-			if (transp)
-				put_user(htransp, transp);
-		}
-		red++;
-		green++;
-		blue++;
-		if (transp)
-			transp++;
-	}
-	return 0;
-}
-
-
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-	int i, start;
-	unsigned short *red, *green, *blue, *transp;
-	unsigned int hred, hgreen, hblue, htransp;
-
-	red = cmap->red;
-	green = cmap->green;
-	blue = cmap->blue;
-	transp = cmap->transp;
-	start = cmap->start;
-
-	if (start < 0)
-		return -EINVAL;
-	for (i = 0; i < cmap->len; i++) {
-		if (kspc) {
-			hred = *red;
-			hgreen = *green;
-			hblue = *blue;
-			htransp = transp ? *transp : 0;
-		} else {
-			get_user(hred, red);
-			get_user(hgreen, green);
-			get_user(hblue, blue);
-			if (transp)
-				get_user(htransp, transp);
-			else
-				htransp = 0;
-		}
-		hred = CNVT_TOHW(hred, var->red.length);
-		hgreen = CNVT_TOHW(hgreen, var->green.length);
-		hblue = CNVT_TOHW(hblue, var->blue.length);
-		htransp = CNVT_TOHW(htransp, var->transp.length);
-		red++;
-		green++;
-		blue++;
-		if (transp)
-			transp++;
-		if (fbhw->setcolreg(start++, hred, hgreen, hblue, htransp))
-			return 0;
-	}
-	return 0;
-}
-
-
 static void do_install_cmap(int con)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
-		do_fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1);
+		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+			    fbhw->setcolreg);
 	else
-		do_fb_set_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-                                          &fb_display[con].var, 1);
+		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+					    &fb_display[con].var, 1,
+					    fbhw->setcolreg);
 }
 
 
-static void memcpy_fs(int fsfromto, void *to, void *from, int len)
-{
-	switch (fsfromto) {
-	case 0:
-		memcpy(to, from, len);
-		return;
-	case 1:
-		copy_from_user(to, from, len);
-		return;
-	case 2:
-		copy_to_user(to, from, len);
-		return;
-	}
-}
-
-
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
-{
-	int size;
-	int tooff = 0, fromoff = 0;
-
-	if (to->start > from->start)
-		fromoff = to->start-from->start;
-	else
-		tooff = from->start-to->start;
-	size = to->len-tooff;
-	if (size > from->len-fromoff)
-		size = from->len-fromoff;
-	if (size < 0)
-		return;
-	size *= sizeof(unsigned short);
-	memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
-	memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
-	memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
-	if (from->transp && to->transp)
-		memcpy_fs(fsfromto, to->transp+tooff,
-			  from->transp+fromoff, size);
-}
-
-
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
-{
-	int size = len*sizeof(unsigned short);
-
-	if (cmap->len != len) {
-		if (cmap->red)
-			kfree(cmap->red);
-		if (cmap->green)
-			kfree(cmap->green);
-		if (cmap->blue)
-			kfree(cmap->blue);
-		if (cmap->transp)
-			kfree(cmap->transp);
-		cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
-		cmap->len = 0;
-		if (!len)
-			return 0;
-		if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-			return -1;
-		if (transp) {
-			if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-				return -1;
-		} else
-			cmap->transp = NULL;
-	}
-	cmap->start = 0;
-	cmap->len = len;
-	copy_cmap(get_default_colormap(len), cmap, 0);
-	return 0;
-}
-
-
- /*
+/*
  *    Open/Release the frame buffer device
  */
 
@@ -1565,7 +1363,7 @@
 		    oldbpp != var->bits_per_pixel) {
 			retz3_fb_set_disp(con);
 			(*fb_info.changevar)(con);
-			alloc_cmap(&fb_display[con].cmap, 0, 0);
+			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
 			do_install_cmap(con);
 		}
 	}
@@ -1581,12 +1379,13 @@
 static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
 {
 	if (con == currcon) /* current console? */
-		return(do_fb_get_cmap(cmap, &fb_display[con].var, kspc));
+		return(fb_get_cmap(cmap, &fb_display[con].var, kspc,
+				   fbhw->getcolreg));
 	else if (fb_display[con].cmap.len) /* non default colormap? */
-		copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		copy_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-			  cmap, kspc ? 0 : 2);
+		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+			     cmap, kspc ? 0 : 2);
 	return 0;
 }
 
@@ -1600,14 +1399,16 @@
 	int err;
 
 	if (!fb_display[con].cmap.len) {       /* no colormap allocated? */
-		if ((err = alloc_cmap(&fb_display[con].cmap,
-				      1<<fb_display[con].var.bits_per_pixel, 0)))
+		if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+					 1<<fb_display[con].var.bits_per_pixel,
+					 0)))
 			return err;
 	}
 	if (con == currcon)              /* current console? */
-		return(do_fb_set_cmap(cmap, &fb_display[con].var, kspc));
+		return(fb_set_cmap(cmap, &fb_display[con].var, kspc,
+				   fbhw->setcolreg));
 	else
-		copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
 }
 
@@ -1645,7 +1446,6 @@
 __initfunc(void retz3_video_setup(char *options, int *ints))
 {
 	char *this_opt;
-	int i;
 
 	fb_info.fontname[0] = '\0';
 
@@ -1656,11 +1456,7 @@
 	     this_opt = strtok(NULL, ",")){
 		if (!strcmp(this_opt, "inverse")) {
 			z3fb_inverse = 1;
-			for (i = 0; i < 16; i++) {
-				red16[i] = ~red16[i];
-				green16[i] = ~green16[i];
-				blue16[i] = ~blue16[i];
-			}
+			fb_invert_cmaps();
 		} else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
 		else
@@ -1725,7 +1521,8 @@
 {
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
-		do_fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1);
+		fb_get_cmap(&fb_display[currcon].cmap,
+			    &fb_display[currcon].var, 1, fbhw->getcolreg);
 
 	do_fb_set_var(&fb_display[con].var, 1);
 	currcon = con;
--- linux-2.1.42/drivers/video/vfb.c.orig	Mon Jun 16 21:43:39 1997
+++ linux-2.1.42/drivers/video/vfb.c	Mon Jun 16 21:44:29 1997
@@ -69,34 +69,6 @@
 
 
     /*
-     *  Default Colormaps
-     */
-
-static u_short red2[] =
-    { 0x0000, 0xc000 };
-static u_short green2[] =
-    { 0x0000, 0xc000 };
-static u_short blue2[] =
-    { 0x0000, 0xc000 };
-
-static u_short red16[] =
-    { 0x0000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0xc000,
-      0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff };
-static u_short green16[] =
-    { 0x0000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0xc000,
-      0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff };
-static u_short blue16[] =
-    { 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,
-      0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff };
-
-
-static struct fb_cmap default_2_colors =
-    { 0, 2, red2, green2, blue2, NULL };
-static struct fb_cmap default_16_colors =
-    { 0, 16, red16, green16, blue16, NULL };
-
-
-    /*
      *  Interface used by the world
      */
 
@@ -118,7 +90,7 @@
      *  Interface to the low level console driver
      */
 
-int vfb_fb_init(u_long *mem_start);
+int virtual_fb_init(u_long *mem_start);
 static int vfbcon_switch(int con);
 static int vfbcon_updatevar(int con);
 static void vfbcon_blank(int blank);
@@ -133,15 +105,11 @@
 static void vfb_encode_fix(struct fb_fix_screeninfo *fix,
 			   struct fb_var_screeninfo *var);
 static void set_color_bitfields(struct fb_var_screeninfo *var);
-static struct fb_cmap *get_default_colormap(int bpp);
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc);
+static int vfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp);
+static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp);
 static void do_install_cmap(int con);
-static void memcpy_fs(int fsfromto, void *to, void *from, int len);
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp);
 
 
 static struct fb_ops virtual_fb_ops = {
@@ -293,7 +261,7 @@
 		(*fb_info.changevar)(con);
 	}
 	if (oldbpp != var->bits_per_pixel) {
-	    if ((err = alloc_cmap(&display->cmap, 0, 0)))
+	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 		return err;
 	    do_install_cmap(con);
 	}
@@ -338,12 +306,12 @@
 static int virtual_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
 {
     if (con == currcon) /* current console? */
-	return do_fb_get_cmap(cmap, &fb_display[con].var, kspc);
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, vfb_getcolreg);
     else if (fb_display[con].cmap.len) /* non default colormap? */
-	copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
     else
-	copy_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-		  cmap, kspc ? 0 : 2);
+	fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
     return 0;
 }
 
@@ -356,14 +324,14 @@
     int err;
 
     if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
-	if ((err = alloc_cmap(&fb_display[con].cmap,
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
 			      1<<fb_display[con].var.bits_per_pixel, 0)))
 	    return err;
     }
     if (con == currcon)			/* current console? */
-	return do_fb_set_cmap(cmap, &fb_display[con].var, kspc);
+	return fb_set_cmap(cmap, &fb_display[con].var, kspc, vfb_setcolreg);
     else
-	copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
     return 0;
 }
 
@@ -400,7 +368,7 @@
      *  Initialisation
      */
 
-int vfb_fb_init(u_long *mem_start)
+int virtual_fb_init(u_long *mem_start)
 {
     int err;
 
@@ -441,7 +409,8 @@
 {
     /* Do we have to save the colormap? */
     if (fb_display[currcon].cmap.len)
-	    do_fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1);
+	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+		    vfb_getcolreg);
 
     currcon = con;
     /* Install new colormap */
@@ -568,22 +537,6 @@
 }
 
 
-static struct fb_cmap *get_default_colormap(int bpp)
-{
-    switch (bpp) {
-	case 1:
-	    return &default_2_colors;
-	    break;
-	default:
-	    return &default_16_colors;
-	    break;
-    }
-}
-
-#define CNVT_TOHW(val,width)	((((val)<<(width))+0x7fff-(val))>>16)
-#define CNVT_FROMHW(val,width)	(((width) ? ((((val)<<16)-(val)) / \
-                                            ((1<<(width))-1)) : 0))
-
     /*
      *  Read a single color register and split it into
      *  colors/transparent. Return != 0 for invalid regno.
@@ -619,182 +572,23 @@
 }
 
 
-static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-    int i, start;
-    u_short *red, *green, *blue, *transp;
-    u_int hred, hgreen, hblue, htransp;
-
-    red = cmap->red;
-    green = cmap->green;
-    blue = cmap->blue;
-    transp = cmap->transp;
-    start = cmap->start;
-    if (start < 0)
-	    return -EINVAL;
-    for (i = 0; i < cmap->len; i++) {
-	if (vfb_getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
-	    return 0;
-	hred = CNVT_FROMHW(hred, var->red.length);
-	hgreen = CNVT_FROMHW(hgreen, var->green.length);
-	hblue = CNVT_FROMHW(hblue, var->blue.length);
-	htransp = CNVT_FROMHW(htransp, var->transp.length);
-	if (kspc) {
-	    *red = hred;
-	    *green = hgreen;
-	    *blue = hblue;
-	    if (transp)
-		*transp = htransp;
-	} else {
-	    put_user(hred, red);
-	    put_user(hgreen, green);
-	    put_user(hblue, blue);
-	    if (transp)
-		put_user(htransp, transp);
-	}
-	red++;
-	green++;
-	blue++;
-	if (transp)
-	    transp++;
-    }
-    return 0;
-}
-
-static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
-                          int kspc)
-{
-    int i, start;
-    u_short *red, *green, *blue, *transp;
-    u_int hred, hgreen, hblue, htransp;
-
-    red = cmap->red;
-    green = cmap->green;
-    blue = cmap->blue;
-    transp = cmap->transp;
-    start = cmap->start;
-
-    if (start < 0)
-	return -EINVAL;
-    for (i = 0; i < cmap->len; i++) {
-	if (kspc) {
-	    hred = *red;
-	    hgreen = *green;
-	    hblue = *blue;
-	    htransp = transp ? *transp : 0;
-	} else {
-	    get_user(hred, red);
-	    get_user(hgreen, green);
-	    get_user(hblue, blue);
-	    if (transp)
-		get_user(htransp, transp);
-	    else
-		htransp = 0;
-	}
-	hred = CNVT_TOHW(hred, var->red.length);
-	hgreen = CNVT_TOHW(hgreen, var->green.length);
-	hblue = CNVT_TOHW(hblue, var->blue.length);
-	htransp = CNVT_TOHW(htransp, var->transp.length);
-	red++;
-	green++;
-	blue++;
-	if (transp)
-	    transp++;
-	if (vfb_setcolreg(start++, hred, hgreen, hblue, htransp))
-	    return 0;
-    }
-    return 0;
-}
-
 static void do_install_cmap(int con)
 {
     if (con != currcon)
 	return;
     if (fb_display[con].cmap.len)
-	do_fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1);
+	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+		    vfb_setcolreg);
     else
-	do_fb_set_cmap(get_default_colormap(fb_display[con].var.bits_per_pixel),
-					    &fb_display[con].var, 1);
-}
-
-static void memcpy_fs(int fsfromto, void *to, void *from, int len)
-{
-    switch (fsfromto) {
-	case 0:
-	    memcpy(to, from, len);
-	    return;
-	case 1:
-	    copy_from_user(to, from, len);
-	    return;
-	case 2:
-	    copy_to_user(to, from, len);
-	    return;
-    }
-}
-
-static void copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
-{
-    int size;
-    int tooff = 0, fromoff = 0;
-
-    if (to->start > from->start)
-	fromoff = to->start-from->start;
-    else
-	tooff = from->start-to->start;
-    size = to->len-tooff;
-    if (size > from->len-fromoff)
-	size = from->len-fromoff;
-    if (size < 0)
-	return;
-    size *= sizeof(u_short);
-    memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
-    memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
-    memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
-    if (from->transp && to->transp)
-	memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
-}
-
-static int alloc_cmap(struct fb_cmap *cmap, int len, int transp)
-{
-    int size = len*sizeof(u_short);
-
-    if (cmap->len != len) {
-	if (cmap->red)
-	    kfree(cmap->red);
-	if (cmap->green)
-	    kfree(cmap->green);
-	if (cmap->blue)
-	    kfree(cmap->blue);
-	if (cmap->transp)
-	    kfree(cmap->transp);
-	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
-	cmap->len = 0;
-	if (!len)
-	    return 0;
-	if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
-	    return -1;
-	if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
-	    return -1;
-	if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-	    return -1;
-	if (transp) {
-	    if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-		return -1;
-	} else
-	    cmap->transp = NULL;
-    }
-    cmap->start = 0;
-    cmap->len = len;
-    copy_cmap(get_default_colormap(len), cmap, 0);
-    return 0;
+	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+				    &fb_display[con].var, 1, vfb_setcolreg);
 }
 
 
 #ifdef MODULE
 int init_module(void)
 {
-    return(vfb_fb_init(NULL));
+    return(virtual_fb_init(NULL));
 }
 
 void cleanup_module(void)
--- linux-2.1.42/include/linux/fb.h.orig	Mon Jun 16 21:44:06 1997
+++ linux-2.1.42/include/linux/fb.h	Mon Jun 16 21:44:29 1997
@@ -231,13 +231,30 @@
    int (*setcmap)(struct fb_cmap *, int); /* tell fb to set the colormap */
 };
 
-int register_framebuffer(struct fb_info *fb_info);
-int unregister_framebuffer(const struct fb_info *fb_info);
+
+/* drivers/char/fbmem.c */
+extern int register_framebuffer(struct fb_info *fb_info);
+extern int unregister_framebuffer(const struct fb_info *fb_info);
 extern int probe_framebuffers(u_long *kmem_start);
 
-extern struct display fb_display[MAX_NR_CONSOLES];	/* fbcon.c */
-extern struct fb_info *registered_fb[FB_MAX];		/* fbmem.c */
-extern char con2fb_map[MAX_NR_CONSOLES];		/* fbmem.c */
+extern struct fb_info *registered_fb[FB_MAX];
+extern char con2fb_map[MAX_NR_CONSOLES];
+
+/* drivers/video/fbcon.c */
+extern struct display fb_display[MAX_NR_CONSOLES];
+
+/* drivers/video/fbcmap.c */
+extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to,
+			 int fsfromto);
+extern int fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+		       int kspc, int (*getcolreg)(u_int, u_int *, u_int *,
+		       				  u_int *, u_int *));
+extern int fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
+		       int kspc, int (*setcolreg)(u_int, u_int, u_int, u_int,
+		       				  u_int));
+extern struct fb_cmap *fb_default_cmap(int bpp);
+extern void fb_invert_cmaps(void);
 
 #endif /* __KERNEL__ */
 
--- linux-2.1.42/drivers/char/abscon.c.orig	Thu Jun 12 23:27:22 1997
+++ linux-2.1.42/drivers/char/abscon.c	Mon Jun 16 23:34:02 1997
@@ -42,12 +42,12 @@
  *				display that's accessible through a frame
  *				buffer device
  *
- *    - arch/m68k/gspcon.c:	Text console driver for video boards based on
+ *    - drivers/video/gspcon.c:	Text console driver for video boards based on
  *				the Texas Instruments TMS34010 Graphical Signal
  *				Processor (e.g. CBM A2410 and DMI Resolver on
  *				Amiga) [ work in progress ]
  *
- *    - arch/m68k/txtcon.c:	Skeleton for a simple text mode driver
+ *    - drivers/video/txtcon.c:	Skeleton for a simple text mode driver
  *
  *  To do:
  *
--- linux-2.1.42/drivers/char/mem.c.orig	Sun Jun  1 22:04:34 1997
+++ linux-2.1.42/drivers/char/mem.c	Mon Jun 16 23:58:20 1997
@@ -35,7 +35,7 @@
 void pcwatchdog_init(void);
 #endif
 
-#if defined(__mc68000__)
+#if defined(CONFIG_FB)
 extern void fbmem_init( void );
 #endif
 #if defined(CONFIG_AMIGA_GSP)
@@ -523,7 +523,7 @@
 	if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 	rand_initialize();
-#if defined (__mc68000__)
+#if defined (CONFIG_FB)
 	fbmem_init();
 #endif
 #if defined (CONFIG_AMIGA_GSP)

Greetings,

						Geert

--
Geert Uytterhoeven                   Geert.Uytterhoeven@thomas.kotnet.org
Linux/m68k on Amiga, Wavelets        http://www.cs.kuleuven.ac.be/~geert/
KotNET@Thomas Network Administration -- Make you bed part of Cyberspace!!


