Date: Thu, 18 Dec 1997 09:55:50 +0100 (CET)
From: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
To: Roman Hodek <rnhodek@faui22c.informatik.uni-erlangen.de>
cc: linux-m68k@lists.linux-m68k.org
Subject: Re: L68K: 2.1.72
In-Reply-To: <199712171400.OAA15329@faui21.informatik.uni-erlangen.de>
Sender: owner-linux-m68k@phil.uni-sb.de

On Wed, 17 Dec 1997, Roman Hodek wrote:
> The serial console compiles at it is now, but I couldn't test it yet.
> Maybe another fix follows tomorrow. But I want to put this thing out
> now, so that Geert can continue to build in the video stuff.

And here is my stuff:

  - updated video stuff (incl. mach64fb, tgafb, offb, vgacon)

  - add scrolldelta() to <linux/console.h>

  - we like keyboards that generate scancode 0

  - prototype fixes in arch/m68k/amiga/config.c

  - keep the correct { "console=", console_setup } entry in init/main.c

I hope everything patches fine. I suffered from floppy errors (Roman, please
increase the size of your patches so I will put them on DAT instead :-) and
thus got only part of the patch.

Roman, I have a small optimization for your Atari heartbeat: wouldn't it be
better to check for floppy access and disable/enable the interrupts when you
really need to do it, i.e. when you want to change the LED status? Now this is
done 100 times/second, while 4 times is sufficient. And Peter wants to add
support for the Apollo, so I think we should go for a mach_heartbeat()
function. mach_heartbeat(1) turns on the LED, mach_heartbeat(0) turns of the
LED.

--- m68k-2.1.72/init/main.c.orig	Wed Dec 17 22:56:46 1997
+++ m68k-2.1.72/init/main.c	Thu Dec 18 00:11:05 1997
@@ -367,6 +358,7 @@
 	{ "swap=", swap_setup },
 	{ "buff=", buff_setup },
 	{ "panic=", panic_setup },
+	{ "console=", console_setup },
 #ifdef CONFIG_VT
 	{ "no-scroll", no_scroll },
 #endif
@@ -597,9 +588,6 @@
 #ifdef CONFIG_PLIP
 	{ "plip=", plip_setup },
 #endif
-#ifdef CONFIG_SERIAL_CONSOLE
-	{ "console=", console_setup },
-#endif
 #ifdef CONFIG_SOUNDMODEM
 	{ "hfmodem=", hfmodem_setup },
 #endif
--- m68k-2.1.72/include/linux/console.h.orig	Wed Dec 17 22:56:46 1997
+++ m68k-2.1.72/include/linux/console.h	Wed Dec 17 23:55:41 1997
@@ -41,6 +41,7 @@
 	int	(*con_get_font)(struct vc_data *, int *, int *, char *);
 	int	(*con_set_font)(struct vc_data *, int, int, char *);
 	int	(*con_set_palette)(struct vc_data *, unsigned char *);
+	int	(*con_scrolldelta)(int);
 };
 
 extern struct consw *conswitchp;
--- m68k-2.1.72/include/linux/fb.h.orig	Wed Dec 17 22:56:46 1997
+++ m68k-2.1.72/include/linux/fb.h	Thu Dec 18 00:13:47 1997
@@ -7,9 +7,10 @@
 
 #define FB_MAJOR	29
 
-#define FB_MODES_SHIFT	5	/* 32 modes per framebuffer */
-#define FB_NUM_MINORS	256	/* 256 Minors               */
-#define FB_MAX		(FB_NUM_MINORS / (1 << FB_MODES_SHIFT))
+#define FB_MODES_SHIFT		5	/* 32 modes per framebuffer */
+#define FB_NUM_MINORS		256	/* 256 Minors               */
+#define FB_MAX			(FB_NUM_MINORS / (1 << FB_MODES_SHIFT))
+#define GET_FB_IDX(node)	(MINOR(node) >> FB_MODES_SHIFT)
 
 /* ioctls
    0x46 is 'F'								*/
@@ -76,6 +77,9 @@
 #define FB_ACCEL_AMIGABLITT	2	/* Amiga Blitter                */
 #define FB_ACCEL_CYBERVISION	3	/* Cybervision64 (S3 Trio64)    */
 #define FB_ACCEL_RETINAZ3	4	/* RetinaZ3 (NCR77C32BLT)       */
+#define FB_ACCEL_CYBERVISION3D	5	/* Cybervision64/3D (S3 ViRGE)	*/
+#define FB_ACCEL_MACH64		6	/* ATI Mach 64			*/
+#define FB_ACCEL_TGA		7	/* DEC 21030 TGA		*/
 
 #define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active	*/
 #define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
@@ -155,20 +159,20 @@
 	int (*fb_open) (int);
 	int (*fb_release) (int);
 	/* get non settable parameters	*/
-	int (*fb_get_fix) (struct fb_fix_screeninfo *, int); 
+	int (*fb_get_fix) (struct fb_fix_screeninfo *, int, int); 
 	/* get settable parameters	*/
-	int (*fb_get_var) (struct fb_var_screeninfo *, int);		
+	int (*fb_get_var) (struct fb_var_screeninfo *, int, int);		
 	/* set settable parameters	*/
-	int (*fb_set_var) (struct fb_var_screeninfo *, int);		
+	int (*fb_set_var) (struct fb_var_screeninfo *, int, int);		
 	/* get colormap			*/
-	int (*fb_get_cmap) (struct fb_cmap *, int, int);
+	int (*fb_get_cmap) (struct fb_cmap *, int, int, int);
 	/* set colormap			*/
-	int (*fb_set_cmap) (struct fb_cmap *, int, int);
+	int (*fb_set_cmap) (struct fb_cmap *, int, int, int);
 	/* pan display                   */
-	int (*fb_pan_display) (struct fb_var_screeninfo *, int);
+	int (*fb_pan_display) (struct fb_var_screeninfo *, int, int);
 	/* perform fb specific ioctl	*/
 	int (*fb_ioctl)(struct inode *, struct file *, unsigned int,
-			unsigned long, int);
+			unsigned long, int, int);
 };
 
 
@@ -221,20 +225,24 @@
 
 
 struct fb_info {
-   char modename[40];               /* at boottime detected video mode */
+   char modename[40];               /* default video mode */
    int node;
    struct fb_ops *fbops;
-   int fbvar_num;
-   struct fb_var_screeninfo *fbvar;
    struct display *disp;            /* initial display variable */
    char fontname[40];               /* default font name */
    int (*changevar)(int);           /* tell console var has changed */
    int (*switch_con)(int);          /* tell fb to switch consoles */
    int (*updatevar)(int);           /* tell fb to update the vars */
    void (*blank)(int);              /* tell fb to (un)blank the screen */
-   int (*setcmap)(struct fb_cmap *, int); /* tell fb to set the colormap */
 };
 
+
+struct fb_videomode {
+    const char *name;
+    struct fb_var_screeninfo var;
+};
+
+
 /* prototypes */
 typedef unsigned long fb_init_func(unsigned long);
 
@@ -243,6 +251,7 @@
 extern int unregister_framebuffer(const struct fb_info *fb_info);
 extern unsigned long probe_framebuffers(unsigned long kmem_start);
 
+extern int num_registered_fb;
 extern struct fb_info *registered_fb[FB_MAX];
 extern char con2fb_map[MAX_NR_CONSOLES];
 
@@ -329,10 +338,10 @@
 };
 
 struct fb_move {
-	__u32 src_x;
-	__u32 src_y;
-	__u32 dest_x;
-	__u32 dest_y;
+	__s32 src_x;
+	__s32 src_y;
+	__s32 dest_x;
+	__s32 dest_y;
 	__u32 height;
 	__u32 width;
 };
--- m68k-2.1.72/include/asm-m68k/font.h.orig	Thu Sep 11 22:30:56 1997
+++ m68k-2.1.72/include/asm-m68k/font.h	Thu Dec 18 00:01:03 1997
@@ -1,35 +0,0 @@
-/*
- *  asm-m68k/font.h -- `Soft' font definitions
- *
- *  Created 1995 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.
- */
-
-#ifndef _ASM_M68K_FONT_H_
-#define _ASM_M68K_FONT_H_
-
-#include <linux/types.h>
-
-
-   /*
-    *    Find a font with a specific name
-    */
-
-extern int findsoftfont(char *name, int *width, int *height, u_char *data[]);
-
-
-   /*
-    *    Get the default font for a specific screen size
-    */
-
-extern void getdefaultfont(int xres, int yres, char *name[], int *width,
-                           int *height, u_char *data[]);
-
-
-/* Max. length for the name of a predefined font */
-#define MAX_FONT_NAME	32
-
-#endif /* _ASM_M68K_FONT_H_ */
--- m68k-2.1.72/drivers/char/fbmem.c.orig	Wed Dec 17 22:56:43 1997
+++ m68k-2.1.72/drivers/char/fbmem.c	Wed Dec 17 23:55:14 1997
@@ -27,7 +27,9 @@
 #include <linux/kerneld.h>
 #endif
 
+#ifdef __mc68000__
 #include <asm/setup.h>
+#endif
 #include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -39,23 +41,24 @@
      *  Frame buffer device initialization and setup routines
      */
 
-extern unsigned long amiga_fb_init(unsigned long mem_start);
-extern void amiga_video_setup(char *options, int *ints);
-extern unsigned long atari_fb_init(unsigned long mem_start);
-extern void atari_video_setup(char *options, int *ints);
-extern unsigned long Cyber_fb_init(unsigned long mem_start);
-extern void Cyber_video_setup(char *options, int *ints);
-extern unsigned long retz3_fb_init(unsigned long mem_start);
-extern void retz3_video_setup(char *options, int *ints);
-extern unsigned long clgen_fb_init(unsigned long mem_start);
-extern void clgen_video_setup(char *options, int *ints);
-extern unsigned long virtual_fb_init(unsigned long mem_start);
-extern void vfb_video_setup(char *options, int *ints);
-extern unsigned long Mach64_fb_init(unsigned long mem_start);
-extern void Mach64_video_setup(char *options, int *ints);
+extern unsigned long amifb_init(unsigned long mem_start);
+extern void amifb_setup(char *options, int *ints);
+extern unsigned long atafb_init(unsigned long mem_start);
+extern void atafb_setup(char *options, int *ints);
+extern unsigned long cyberfb_init(unsigned long mem_start);
+extern void cyberfb_setup(char *options, int *ints);
+extern unsigned long retz3fb_init(unsigned long mem_start);
+extern void retz3fb_setup(char *options, int *ints);
+extern unsigned long clgenfb_init(unsigned long mem_start);
+extern void clgenfb_setup(char *options, int *ints);
+extern unsigned long vfb_init(unsigned long mem_start);
+extern void vfb_setup(char *options, int *ints);
+extern unsigned long offb_init(unsigned long mem_start);
+extern unsigned long dnfb_init(unsigned long mem_start);
+extern unsigned long mach64fb_init(unsigned long mem_start);
+extern void mach64fb_setup(char *options, int *ints);
+extern unsigned long tgafb_init(unsigned long mem_start);
 extern void resolver_video_setup(char *options, int *ints);
-extern void dn_fb_init(unsigned long mem_start);
-extern void dn_video_setup(char *options, int *ints);
 
 static struct {
 	const char *name;
@@ -63,30 +66,39 @@
 	void (*setup)(char *options, int *ints);
 } fb_drivers[] __initdata = {
 #ifdef CONFIG_FB_RETINAZ3
-	{ "retz3", retz3_fb_init, retz3_video_setup },
+	{ "retz3", retz3fb_init, retz3fb_setup },
 #endif
 #ifdef CONFIG_FB_AMIGA
-	{ "amifb", amiga_fb_init, amiga_video_setup },
+	{ "amifb", amifb_init, amifb_setup },
 #endif
 #ifdef CONFIG_FB_ATARI
-	{ "atafb", atari_fb_init, atari_video_setup },
+	{ "atafb", atafb_init, atafb_setup },
 #endif
 #ifdef CONFIG_FB_CYBER
-	{ "cyber", Cyber_fb_init, Cyber_video_setup },
+	{ "cyber", cyberfb_init, cyberfb_setup },
 #endif
 #ifdef CONFIG_FB_CLGEN
-	{ "clgen", clgen_fb_init, clgen_video_setup },
+	{ "clgen", clgenfb_init, clgenfb_setup },
 #endif
 #ifdef CONFIG_FB_VIRTUAL
-	{ "vfb", virtual_fb_init, vfb_video_setup },
+	{ "vfb", vfb_init, vfb_setup },
+#endif
+#ifdef CONFIG_FB_OPEN_FIRMWARE
+	{ "offb", offb_init, NULL },
+#endif
+#ifdef CONFIG_APOLLO
+	{ "apollo", dnfb_init, NULL },
+#endif
+#ifdef CONFIG_FB_MACH64
+      { "mach64", mach64fb_init, mach64fb_setup },
+#endif
+#ifdef CONFIG_FB_TGA
+      { "tga", tgafb_init, NULL },
 #endif
 #ifdef CONFIG_GSP_RESOLVER
 	/* Not a real frame buffer device... */
 	{ "resolver", NULL, resolver_video_setup },
 #endif
-#ifdef CONFIG_APOLLO
-	{ "apollo", dn_fb_init, dn_video_setup },
-#endif
 };
 
 #define NUM_FB_DRIVERS	(sizeof(fb_drivers)/sizeof(*fb_drivers))
@@ -96,13 +108,10 @@
 
 
 #define GET_INODE(i) MKDEV(FB_MAJOR, (i) << FB_MODES_SHIFT)
-#define GET_FB_IDX(node) (MINOR(node) >> FB_MODES_SHIFT)
 #define GET_FB_VAR_IDX(node) (MINOR(node) & ((1 << FB_MODES_SHIFT)-1)) 
 
 struct fb_info *registered_fb[FB_MAX];
 int num_registered_fb = 0;
-int fb_curr_open[FB_MAX];
-int fb_open_count[FB_MAX];
 
 char con2fb_map[MAX_NR_CONSOLES];
 
@@ -130,9 +139,8 @@
 	len = 0;
 	for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; fi++)
 		if (*fi)
-			len += sprintf(buf + len, "%d %d %s\n",
+			len += sprintf(buf + len, "%d %s\n",
 				       GET_FB_IDX((*fi)->node),
-				       GET_FB_VAR_IDX((*fi)->node),
 				       (*fi)->modename);
 	*start = buf + offset;
 	return len > offset ? len - offset : 0;
@@ -144,7 +152,8 @@
 {
 	unsigned long p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
-	struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)]->fbops;
+	int fbidx = GET_FB_IDX(inode->i_rdev);
+	struct fb_ops *fb = registered_fb[fbidx]->fbops;
 	struct fb_fix_screeninfo fix;
 	char *base_addr;
 	ssize_t copy_size;
@@ -152,7 +161,7 @@
 	if (! fb)
 		return -ENODEV;
 
-	fb->fb_get_fix(&fix,PROC_CONSOLE());
+	fb->fb_get_fix(&fix,PROC_CONSOLE(), fbidx);
 	base_addr=(char *) fix.smem_start;
 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
 	copy_to_user(buf, base_addr+p, copy_size);
@@ -165,14 +174,15 @@
 {
 	unsigned long p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
-	struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)]->fbops;
+	int fbidx = GET_FB_IDX(inode->i_rdev);
+	struct fb_ops *fb = registered_fb[fbidx]->fbops;
 	struct fb_fix_screeninfo fix;
 	char *base_addr;
 	ssize_t copy_size;
 
 	if (! fb)
 		return -ENODEV;
-	fb->fb_get_fix(&fix, PROC_CONSOLE());
+	fb->fb_get_fix(&fix, PROC_CONSOLE(), fbidx);
 	base_addr=(char *) fix.smem_start;
 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
 	copy_from_user(base_addr+p, buf, copy_size); 
@@ -225,57 +235,50 @@
 	struct fb_var_screeninfo var;
 	struct fb_fix_screeninfo fix;
 	struct fb_con2fbmap con2fb;
-	int i, fbidx, vidx;
+	int i, fbidx;
 	
 	if (! fb)
 		return -ENODEV;
 	switch (cmd) {
 	case FBIOGET_VSCREENINFO:
 		fbidx=GET_FB_IDX(inode->i_rdev);
-		vidx=GET_FB_VAR_IDX(inode->i_rdev);
-		if (! vidx) /* ask device driver for current */ {
-			if ((i = fb->fb_get_var(&var, PROC_CONSOLE())))
-				return i;
-		} else
-			var=registered_fb[fbidx]->fbvar[vidx-1];
+		if ((i = fb->fb_get_var(&var, PROC_CONSOLE(), fbidx)))
+			return i;
 		return copy_to_user((void *) arg, &var,
 				    sizeof(var)) ? -EFAULT : 0;
 	case FBIOPUT_VSCREENINFO:
+		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		if ((i = fb->fb_set_var(&var, PROC_CONSOLE())))
+		if ((i = fb->fb_set_var(&var, PROC_CONSOLE(), fbidx)))
 			return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
-		fbidx=GET_FB_IDX(inode->i_rdev);
-		vidx=GET_FB_VAR_IDX(inode->i_rdev);
-		if (vidx)
-			registered_fb[fbidx]->fbvar[vidx-1]=var;
 		return 0;
 	case FBIOGET_FSCREENINFO:
-		if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE())))
+		fbidx=GET_FB_IDX(inode->i_rdev);
+		if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE(), fbidx)))
 			return i;
 		return copy_to_user((void *) arg, &fix, sizeof(fix)) ?
 			-EFAULT : 0;
 	case FBIOPUTCMAP:
+		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
 			return -EFAULT;
-		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE()));
+		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(), fbidx));
 	case FBIOGETCMAP:
+		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
 			return -EFAULT;
-		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE()));
+		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(), fbidx));
 	case FBIOPAN_DISPLAY:
+		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE())))
+		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(), fbidx)))
 			return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
-		fbidx=GET_FB_IDX(inode->i_rdev);
-		vidx=GET_FB_VAR_IDX(inode->i_rdev);
-		if (! i && vidx)
-			registered_fb[fbidx]->fbvar[vidx-1]=var;
 		return i;
 	case FBIOGET_CON2FBMAP:
 		if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
@@ -306,21 +309,24 @@
 			set_con2fb_map(i, con2fb.framebuffer);
 		return 0;
 	default:
-		return (fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE()));
+		fbidx=GET_FB_IDX(inode->i_rdev);
+		return (fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(),
+				     fbidx));
 	}
 }
 
 static int 
 fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	struct fb_ops *fb = registered_fb[GET_FB_IDX(file->f_dentry->d_inode->i_rdev)]->fbops;
+	int fbidx = GET_FB_IDX(file->f_dentry->d_inode->i_rdev);
+	struct fb_ops *fb = registered_fb[fbidx]->fbops;
 	struct fb_fix_screeninfo fix;
 	unsigned char *start;
 	unsigned long len;
 
 	if (! fb)
 		return -ENODEV;
-	fb->fb_get_fix(&fix, PROC_CONSOLE());
+	fb->fb_get_fix(&fix, PROC_CONSOLE(), fbidx);
 	if (vma->vm_offset < fix.smem_len) {
 		/* frame buffer memory */
 		start = fix.smem_start;
@@ -333,10 +339,13 @@
 	}
 	if ((vma->vm_end - vma->vm_start + vma->vm_offset) > len)
 		return -EINVAL;
-	vma->vm_offset += __pa(start);
+#ifndef __powerpc__
+	start = (unsigned char *)__pa(start);
+#endif
+	vma->vm_offset += (unsigned long)start;
 	if (vma->vm_offset & ~PAGE_MASK)
 		return -ENXIO;
-#ifdef __mc68000__
+#if defined(__mc68000__)
 	if (CPU_IS_020_OR_030)
 		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
 	if (CPU_IS_040_OR_060) {
@@ -344,6 +353,8 @@
 		/* Use no-cache mode, serialized */
 		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
 	}
+#elif defined(__powerpc__)
+	pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
 #else
 #warning What do we have to do here??
 #endif
@@ -358,9 +369,6 @@
 fb_open(struct inode *inode, struct file *file)
 {
 	int fbidx=GET_FB_IDX(inode->i_rdev);
-	int vidx=GET_FB_VAR_IDX(inode->i_rdev);
-	struct fb_ops *fb;
-	int err;
 
 #ifdef CONFIG_KERNELD
 	if (!registered_fb[fbidx])
@@ -368,38 +376,15 @@
 #endif
 	if (!registered_fb[fbidx])
 		return -ENODEV;
-	fb = registered_fb[fbidx]->fbops;
-
-	if (! vidx)		/* fb?current always succeeds */ 
-		return fb->fb_open(fbidx);
-	if (vidx > registered_fb[fbidx]->fbvar_num)
-		return -EINVAL;
-	if (fb_curr_open[fbidx] && fb_curr_open[fbidx] != vidx)
-		return -EBUSY;
-	if ((err = fb->fb_open(fbidx)))
-		return(err);
- 	if (file->f_mode & 2) /* only set parameters if opened writeable */
-		if ((err=fb->fb_set_var(&registered_fb[fbidx]->fbvar[vidx-1],
-					PROC_CONSOLE()))) {
-			fb->fb_release(fbidx);
-			return err;
-		}
-	fb_curr_open[fbidx] = vidx;
-	fb_open_count[fbidx]++;
-	return 0;
+	return registered_fb[fbidx]->fbops->fb_open(fbidx);
 }
 
 static int 
 fb_release(struct inode *inode, struct file *file)
 {
 	int fbidx=GET_FB_IDX(inode->i_rdev);
-	int vidx=GET_FB_VAR_IDX(inode->i_rdev);
 
 	registered_fb[fbidx]->fbops->fb_release(fbidx);
-	if (! vidx)
-		return 0;
-	if (! (--fb_open_count[fbidx]))
-		fb_curr_open[fbidx]=0;
 	return 0;
 }
 
@@ -545,7 +530,7 @@
      * fuction.
      */
     for (i = 0; i < NUM_FB_DRIVERS; i++) {
-	    if (fb_drivers[i].init && fb_drivers[i].setup){
+	    if (fb_drivers[i].init && fb_drivers[i].setup) {
 		    pref_init_funcs[num_pref_init_funcs++] =
 			    fb_drivers[i].init;
 		    fb_drivers[i].init = NULL;
--- m68k-2.1.72/drivers/char/vt.c.orig	Wed Dec 17 22:56:43 1997
+++ m68k-2.1.72/drivers/char/vt.c	Wed Dec 17 23:55:14 1997
@@ -265,9 +265,12 @@
 		    if (kbd->kbdmode != VC_UNICODE)
 				return -EINVAL;
 
+		/* ++Geert: non-PC keyboards may generate keycode zero */
+#ifndef __mc68000__
 		/* assignment to entry 0 only tests validity of args */
 		if (!i)
 			break;
+#endif
 
 		if (!(key_map = key_maps[s])) {
 			int j;
--- m68k-2.1.72/drivers/video/Config.in.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/Config.in	Wed Dec 17 23:55:14 1997
@@ -21,7 +21,10 @@
   fi
   if [ "$CONFIG_ATARI" = "y" ]; then
     bool 'Atari native chipset support' CONFIG_FB_ATARI
-#    tristate 'Mach64 Frame Buffer support' CONFIG_FB_MACH64
+    tristate 'Mach64 Frame Buffer support' CONFIG_FB_MACH64
+  fi
+  if [ "$CONFIG_CHRP" = "y" -o "$CONFIG_PMAC" = "y" ]; then
+    bool 'Open Firmware frame buffer device support' CONFIG_FB_OPEN_FIRMWARE
   fi 
   tristate 'Virtual Frame Buffer support' CONFIG_FB_VIRTUAL
 
@@ -37,6 +40,7 @@
     tristate '16 bpp packed pixel support' CONFIG_FBCON_CFB16
     tristate 'Cybervision support (accelerated)' CONFIG_FBCON_CYBER
     tristate 'RetinaZ3 support (accelerated)' CONFIG_FBCON_RETINAZ3
+    tristate 'Mach64 support (accelerated)' CONFIG_FBCON_MACH64
   else
     if [ "$CONFIG_FB_AMIGA" != "n" -o "$CONFIG_FB_ATARI" != "n" -o \
 	 "$CONFIG_FB_CYBER" != "n" -o "$CONFIG_FB_RETINAZ3" != "n" -o \
@@ -52,8 +56,13 @@
       define_bool CONFIG_FBCON_IPLAN2P4 y
       define_bool CONFIG_FBCON_IPLAN2P8 y
     fi
-    if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
+    if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
+	 "$CONFIG_FB_OPEN_FIRMWARE" = "y" -o \
+	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB8 y
+    fi
+    if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
+	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB16 y
     fi
     if [ "$CONFIG_FB_CYBER" = "y" -o "$CONFIG_FB_CYBER" = "m" ]; then
@@ -61,6 +70,9 @@
     fi
     if [ "$CONFIG_FB_RETINAZ3" = "y" -o "$CONFIG_FB_RETINAZ3" = "m" ]; then
       define_bool CONFIG_FBCON_RETINAZ3 y
+    fi
+    if [ "$CONFIG_FB_MACH64" = "y" -o "$CONFIG_FB_MACH64" = "m" ]; then
+      define_bool CONFIG_FBCON_MACH64 y
     fi
   fi
 
--- m68k-2.1.72/drivers/video/Makefile.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/Makefile	Wed Dec 17 23:55:14 1997
@@ -19,15 +19,17 @@
 MX_OBJS  :=
 MOD_LIST_NAME := VIDEO_MODULES
 
-# Frame buffer devices
+# Frame Buffer Console
 
 ifeq ($(CONFIG_FB),y)
   L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o
   LX_OBJS += fbcon.o fbcmap.o
 endif
 
+# Frame buffer devices
+
 ifeq ($(CONFIG_APOLLO),y)
-L_OBJS += dn_fb.o
+L_OBJS += dnfb.o
 endif
 
 ifeq ($(CONFIG_FB_AMIGA),y)
@@ -70,6 +72,10 @@
   endif
 endif
 
+ifeq ($(CONFIG_FB_OPEN_FIRMWARE),y)
+L_OBJS += offb.o
+endif
+
 ifeq ($(CONFIG_FB_MACH64),y)
 L_OBJS += mach64fb.o
 else
@@ -78,6 +84,10 @@
   endif
 endif
 
+ifeq ($(CONFIG_FB_TGA),y)
+L_OBJS += tgafb.o
+endif
+
 # Low level drivers
 
 ifeq ($(CONFIG_FBCON_AFB),y)
@@ -168,8 +178,18 @@
   endif
 endif
 
+# GSP Console
+
 ifdef CONFIG_AMIGA_GSP
 L_OBJS := $(L_OBJS) gspcon.o gspcore.o
+endif
+
+# VGA Console
+
+ifdef CONFIG_ABSTRACT_CONSOLE
+ifdef CONFIG_VGA_CONSOLE
+L_OBJS := $(L_OBJS) vgacon.o
+endif
 endif
 
 include $(TOPDIR)/Rules.make
--- m68k-2.1.72/drivers/video/amifb.c.orig	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.72/drivers/video/amifb.c	Wed Dec 17 23:55:14 1997
@@ -672,7 +672,7 @@
 	 * Current Video Mode
 	 */
 
-static struct amiga_fb_par {
+static struct amifb_par {
 
 	/* General Values */
 
@@ -789,229 +789,198 @@
 	 * The rest of the name is filled in during initialization
 	 */
 
-static char amiga_fb_name[16] = "Amiga ";
+static char amifb_name[16] = "Amiga ";
 
-	/*
-	 * Predefined Video Mode Names
-	 *
-	 * The a2024-?? modes don't work yet because there's no A2024 driver.
-	 */
-
-static char *amiga_fb_modenames[] = {
-
-	/*
-	 * Autodetect (Default) Video Mode
-	 */
-
-	"default",
-
-	/*
-	 * AmigaOS Video Modes
-	 */
-
-	"ntsc",			/* 640x200, 15 kHz, 60 Hz (NTSC) */
-	"ntsc-lace",		/* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
-	"pal",			/* 640x256, 15 kHz, 50 Hz (PAL) */
-	"pal-lace",		/* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
-	"multiscan",		/* 640x480, 29 kHz, 57 Hz */
-	"multiscan-lace",	/* 640x960, 29 kHz, 57 Hz interlaced */
-	"a2024-10",		/* 1024x800, 10 Hz (Not yet supported) */
-	"a2024-15",		/* 1024x800, 15 Hz (Not yet supported) */
-	"euro36",		/* 640x200, 15 kHz, 72 Hz */
-	"euro36-lace",		/* 640x400, 15 kHz, 72 Hz interlaced */
-	"euro72",		/* 640x400, 29 kHz, 68 Hz */
-	"euro72-lace",		/* 640x800, 29 kHz, 68 Hz interlaced */
-	"super72",		/* 800x300, 23 kHz, 70 Hz */
-	"super72-lace",		/* 800x600, 23 kHz, 70 Hz interlaced */
-	"dblntsc",		/* 640x200, 27 kHz, 57 Hz doublescan */
-	"dblntsc-ff",		/* 640x400, 27 kHz, 57 Hz */
-	"dblntsc-lace",		/* 640x800, 27 kHz, 57 Hz interlaced */
-	"dblpal",		/* 640x256, 27 kHz, 47 Hz doublescan */
-	"dblpal-ff",		/* 640x512, 27 kHz, 47 Hz */
-	"dblpal-lace",		/* 640x1024, 27 kHz, 47 Hz interlaced */
 
 	/*
-	 * VGA Video Modes
-	 */
-
-	"vga",			/* 640x480, 31 kHz, 60 Hz (VGA) */
-	"vga70",		/* 640x400, 31 kHz, 70 Hz (VGA) */
-
-	/*
-	 * User Defined Video Modes: to be set after boot up using e.g. fbset
-	 */
-
-	"user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
-};
-
-static struct fb_var_screeninfo amiga_fb_predefined[] = {
-
-	/*
-	 * Autodetect (Default) Video Mode
-	 */
-
-	{ 0, },
-
-	/*
-	 * AmigaOS Video Modes
+	 * Predefined Video Modes
+	 *
 	 */
 
-	{
-		/* ntsc */
-		640, 200, 640, 200, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 44, 16, 76, 2,
-		FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* ntsc-lace */
-		640, 400, 640, 400, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 88, 33, 76, 4,
-		FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* pal */
-		640, 256, 640, 256, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 40, 14, 76, 2,
-		FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* pal-lace */
-		640, 512, 640, 512, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 80, 29, 76, 4,
-		FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* multiscan */
-		640, 480, 640, 480, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 96, 112, 29, 8, 72, 8,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-
-	}, {
-		/* multiscan-lace */
-		640, 960, 640, 960, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 96, 112, 58, 16, 72, 16,
-		0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* a2024-10 (Not yet supported) */
-		1024, 800, 1024, 800, 0, 0, 2, 0,
-		{0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 0, 0, 0, 0, 0, 0,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* a2024-15 (Not yet supported) */
-		1024, 800, 1024, 800, 0, 0, 2, 0,
-		{0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 0, 0, 0, 0, 0, 0,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* euro36 */
-		640, 200, 640, 200, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 92, 124, 6, 6, 52, 5,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* euro36-lace */
-		640, 400, 640, 400, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 92, 124, 12, 12, 52, 10,
-		0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* euro72 */
-		640, 400, 640, 400, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 164, 92, 9, 9, 80, 8,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* euro72-lace */
-		640, 800, 640, 800, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 164, 92, 18, 18, 80, 16,
-		0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* super72 */
-		800, 300, 800, 300, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 212, 140, 10, 11, 80, 7,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* super72-lace */
-		800, 600, 800, 600, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 212, 140, 20, 22, 80, 14,
-		0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* dblntsc */
-		640, 200, 640, 200, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 18, 17, 80, 4,
-		0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
-	}, {
-		/* dblntsc-ff */
-		640, 400, 640, 400, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 36, 35, 80, 7,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* dblntsc-lace */
-		640, 800, 640, 800, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 72, 70, 80, 14,
-		0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* dblpal */
-		640, 256, 640, 256, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 14, 13, 80, 4,
-		0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
-	}, {
-		/* dblpal-ff */
-		640, 512, 640, 512, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 28, 27, 80, 7,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* dblpal-lace */
-		640, 1024, 640, 1024, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 56, 54, 80, 14,
-		0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
-	},
-
-	/*
-	 * VGA Video Modes
-	 */
+static struct fb_videomode amifb_predefined[] __initdata = {
 
-	{
-		/* vga */
-		640, 480, 640, 480, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 64, 96, 30, 9, 112, 2,
-		0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	}, {
-		/* vga70 */
-		640, 400, 640, 400, 0, 0, 4, 0,
-		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-		0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 64, 96, 35, 12, 112, 2,
-		FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
-	},
+    /*
+     *  AmigaOS Video Modes
+     */
+
+    {
+	"ntsc", {		/* 640x200, 15 kHz, 60 Hz (NTSC) */
+	    640, 200, 640, 200, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 44, 16, 76, 2,
+	    FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"ntsc-lace", {		/* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
+	    640, 400, 640, 400, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 88, 33, 76, 4,
+	    FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"pal", {		/* 640x256, 15 kHz, 50 Hz (PAL) */
+	    640, 256, 640, 256, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 40, 14, 76, 2,
+	    FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"pal-lace", {		/* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
+	    640, 512, 640, 512, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 106, 86, 80, 29, 76, 4,
+	    FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"multiscan", {		/* 640x480, 29 kHz, 57 Hz */
+	    640, 480, 640, 480, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 96, 112, 29, 8, 72, 8,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"multiscan-lace", {	/* 640x960, 29 kHz, 57 Hz interlaced */
+	    640, 960, 640, 960, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 96, 112, 58, 16, 72, 16,
+	    0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"euro36", {		/* 640x200, 15 kHz, 72 Hz */
+	    640, 200, 640, 200, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 92, 124, 6, 6, 52, 5,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"euro36-lace", {	/* 640x400, 15 kHz, 72 Hz interlaced */
+	    640, 400, 640, 400, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 92, 124, 12, 12, 52, 10,
+	    0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"euro72", {		/* 640x400, 29 kHz, 68 Hz */
+	    640, 400, 640, 400, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 164, 92, 9, 9, 80, 8,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"euro72-lace", {	/* 640x800, 29 kHz, 68 Hz interlaced */
+	    640, 800, 640, 800, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 164, 92, 18, 18, 80, 16,
+	    0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"super72", {		/* 800x300, 23 kHz, 70 Hz */
+	    800, 300, 800, 300, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 212, 140, 10, 11, 80, 7,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"super72-lace", {	/* 800x600, 23 kHz, 70 Hz interlaced */
+	    800, 600, 800, 600, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 212, 140, 20, 22, 80, 14,
+	    0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"dblntsc", {		/* 640x200, 27 kHz, 57 Hz doublescan */
+	    640, 200, 640, 200, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 18, 17, 80, 4,
+	    0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
+	}
+    }, {
+	"dblntsc-ff", {		/* 640x400, 27 kHz, 57 Hz */
+	    640, 400, 640, 400, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 36, 35, 80, 7,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"dblntsc-lace", {	/* 640x800, 27 kHz, 57 Hz interlaced */
+	    640, 800, 640, 800, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 72, 70, 80, 14,
+	    0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"dblpal", {		/* 640x256, 27 kHz, 47 Hz doublescan */
+	    640, 256, 640, 256, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 14, 13, 80, 4,
+	    0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
+	}
+    }, {
+	"dblpal-ff", {		/* 640x512, 27 kHz, 47 Hz */
+	    640, 512, 640, 512, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 28, 27, 80, 7,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"dblpal-lace", {	/* 640x1024, 27 kHz, 47 Hz interlaced */
+	    640, 1024, 640, 1024, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 196, 124, 56, 54, 80, 14,
+	    0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+	}
+    },
+
+    /*
+     *  VGA Video Modes
+     */
+
+    {
+	"vga", {		/* 640x480, 31 kHz, 60 Hz (VGA) */
+	    640, 480, 640, 480, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 64, 96, 30, 9, 112, 2,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"vga70", {		/* 640x400, 31 kHz, 70 Hz (VGA) */
+	    640, 400, 640, 400, 0, 0, 4, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_SHRES, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    },
 
-	/*
-	 * User Defined Video Modes
-	 */
+#if 0
 
-	{ 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+    /*
+     *  A2024 video modes
+     *  These modes don't work yet because there's no A2024 driver.
+     */
+
+    {
+	"a2024-10", {		/* 1024x800, 10 Hz */
+	    1024, 800, 1024, 800, 0, 0, 2, 0,
+	    {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }, {
+	"a2024-15", {		/* 1024x800, 15 Hz */
+	    1024, 800, 1024, 800, 0, 0, 2, 0,
+	    {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+	    0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+	}
+    }
+#endif
 };
 
-#define NUM_USER_MODES   (8)
-#define NUM_TOTAL_MODES  arraysize(amiga_fb_predefined)
-#define NUM_PREDEF_MODES (NUM_TOTAL_MODES-NUM_USER_MODES)
+#define NUM_TOTAL_MODES  arraysize(amifb_predefined)
 
 static int amifb_ilbm = 0;	/* interleaved or normal bitplanes */
-
 static int amifb_inverse = 0;
-static int amifb_usermode = 0;
+static int amifb_usermode __initdata = 0;
 
 	/*
 	 * Some default modes
@@ -1023,6 +992,9 @@
 #define DEFMODE_AMBER_NTSC "ntsc-lace"	/* for flicker fixed NTSC (A3000) */
 #define DEFMODE_AGA        "vga70"	/* for AGA */
 
+static struct fb_var_screeninfo amifb_default;
+
+
 	/*
 	 * Macros for the conversion from real world values to hardware register
 	 * values
@@ -1181,34 +1153,38 @@
 	 * Interface used by the world
 	 */
 
-void amiga_video_setup(char *options, int *ints);
+void amifb_setup(char *options, int *ints);
 
-static int amiga_fb_open(int fbidx);
-static int amiga_fb_release(int fbidx);
-static int amiga_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
-static int amiga_fb_get_var(struct fb_var_screeninfo *var, int con);
-static int amiga_fb_set_var(struct fb_var_screeninfo *var, int con);
-static int amiga_fb_pan_display(struct fb_var_screeninfo *var, int con);
-static int amiga_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int amiga_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int amiga_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                          u_long arg, int con);
-
-static int amiga_fb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con);
-static int amiga_fb_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con);
-static int amiga_fb_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con);
-static int amiga_fb_get_cursorstate(struct fb_cursorstate *state, int con);
-static int amiga_fb_set_cursorstate(struct fb_cursorstate *state, int con);
+static int amifb_open(int fbidx);
+static int amifb_release(int fbidx);
+static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
+static int amifb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int amifb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int amifb_pan_display(struct fb_var_screeninfo *var, int con,
+				int fbidx);
+static int amifb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx);
+static int amifb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx);
+static int amifb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                          u_long arg, int con, int fbidx);
+
+static int amifb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con);
+static int amifb_get_var_cursorinfo(struct fb_var_cursorinfo *var,
+				       u_char *data, int con);
+static int amifb_set_var_cursorinfo(struct fb_var_cursorinfo *var,
+				       u_char *data, int con);
+static int amifb_get_cursorstate(struct fb_cursorstate *state, int con);
+static int amifb_set_cursorstate(struct fb_cursorstate *state, int con);
 
 	/*
 	 * Interface to the low level console driver
 	 */
 
-unsigned long amiga_fb_init(unsigned long mem_start);
+unsigned long amifb_init(unsigned long mem_start);
 static int amifbcon_switch(int con);
 static int amifbcon_updatevar(int con);
 static void amifbcon_blank(int blank);
-static int amifbcon_setcmap(struct fb_cmap *cmap, int con);
 
 	/*
 	 * Internal routines
@@ -1227,15 +1203,15 @@
 	 */
 
 static int ami_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct amiga_fb_par *par);
+                          struct amifb_par *par);
 static int ami_decode_var(struct fb_var_screeninfo *var,
-                          struct amiga_fb_par *par);
+                          struct amifb_par *par);
 static int ami_encode_var(struct fb_var_screeninfo *var,
-                          struct amiga_fb_par *par);
-static void ami_get_par(struct amiga_fb_par *par);
+                          struct amifb_par *par);
+static void ami_get_par(struct amifb_par *par);
 static void ami_set_var(struct fb_var_screeninfo *var);
 #ifdef DEBUG
-static void ami_set_par(struct amiga_fb_par *par);
+static void ami_set_par(struct amifb_par *par);
 #endif
 static void ami_pan_var(struct fb_var_screeninfo *var);
 static int ami_update_par(void);
@@ -1265,13 +1241,13 @@
 extern unsigned short ami_intena_vals[];
 
 
-static struct fb_ops amiga_fb_ops = {
-	amiga_fb_open, amiga_fb_release, amiga_fb_get_fix, amiga_fb_get_var,
-	amiga_fb_set_var, amiga_fb_get_cmap, amiga_fb_set_cmap,
-	amiga_fb_pan_display, amiga_fb_ioctl
+static struct fb_ops amifb_ops = {
+	amifb_open, amifb_release, amifb_get_fix, amifb_get_var,
+	amifb_set_var, amifb_get_cmap, amifb_set_cmap,
+	amifb_pan_display, amifb_ioctl
 };
 
-struct useropts {
+static struct useropts {
 	long xres;
 	long yres;
 	long xres_virtual;
@@ -1287,7 +1263,7 @@
     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-__initfunc(void amiga_video_setup(char *options, int *ints))
+__initfunc(void amifb_setup(char *options, int *ints))
 {
 	char *this_opt;
 	char mcap_spec[80];
@@ -1408,7 +1384,7 @@
 	 * Open/Release the frame buffer device
 	 */
 
-static int amiga_fb_open(int fbidx)
+static int amifb_open(int fbidx)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -1418,7 +1394,7 @@
 	return(0);
 }
 
-static int amiga_fb_release(int fbidx)
+static int amifb_release(int fbidx)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -1429,9 +1405,9 @@
 	 * Get the Fixed Part of the Display
 	 */
 
-static int amiga_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
 {
-	struct amiga_fb_par par;
+	struct amifb_par par;
 
 	if (con == -1)
 		ami_get_par(&par);
@@ -1448,12 +1424,12 @@
 	 * Get the User Defined Part of the Display
 	 */
 
-static int amiga_fb_get_var(struct fb_var_screeninfo *var, int con)
+static int amifb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	int err = 0;
 
 	if (con == -1) {
-		struct amiga_fb_par par;
+		struct amifb_par par;
 
 		ami_get_par(&par);
 		err = ami_encode_var(var, &par);
@@ -1466,11 +1442,11 @@
 	 * Set the User Defined Part of the Display
 	 */
 
-static int amiga_fb_set_var(struct fb_var_screeninfo *var, int con)
+static int amifb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	int err, activate = var->activate;
 	int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-	struct amiga_fb_par par;
+	struct amifb_par par;
 
 	struct display *display;
 	if (con >= 0)
@@ -1533,7 +1509,8 @@
 	 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
 	 */
 
-static int amiga_fb_pan_display(struct fb_var_screeninfo *var, int con)
+static int amifb_pan_display(struct fb_var_screeninfo *var, int con,
+				int fbidx)
 {
 	if (var->vmode & FB_VMODE_YWRAP) {
 		if (var->yoffset<0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
@@ -1562,7 +1539,8 @@
 	 * Get the Colormap
 	 */
 
-static int amiga_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int amifb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx)
 {
 	if (con == currcon) /* current console? */
 		return fb_get_cmap(cmap, &fb_display[con].var, kspc,
@@ -1579,7 +1557,8 @@
 	 * Set the Colormap
 	 */
 
-static int amiga_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int amifb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx)
 {
 	int err;
 
@@ -1601,8 +1580,8 @@
 	 * Amiga Frame Buffer Specific ioctls
 	 */
 
-static int amiga_fb_ioctl(struct inode *inode, struct file *file,
-                          u_int cmd, u_long arg, int con)
+static int amifb_ioctl(struct inode *inode, struct file *file,
+                          u_int cmd, u_long arg, int con, int fbidx)
 {
 	int i;
 
@@ -1612,7 +1591,7 @@
 			
 			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrfix));
 			if (!i) {
-				i = amiga_fb_get_fix_cursorinfo(&crsrfix, con);
+				i = amifb_get_fix_cursorinfo(&crsrfix, con);
 				copy_to_user((void *)arg, &crsrfix, sizeof(crsrfix));
 			}
 			return i;
@@ -1622,7 +1601,7 @@
 
 			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrvar));
 			if (!i) {
-				i = amiga_fb_get_var_cursorinfo(&crsrvar,
+				i = amifb_get_var_cursorinfo(&crsrvar,
 					((struct fb_var_cursorinfo *)arg)->data, con);
 				copy_to_user((void *)arg, &crsrvar, sizeof(crsrvar));
 			}
@@ -1634,7 +1613,7 @@
 			i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrvar));
 			if (!i) {
 				copy_from_user(&crsrvar, (void *)arg, sizeof(crsrvar));
-				i = amiga_fb_set_var_cursorinfo(&crsrvar,
+				i = amifb_set_var_cursorinfo(&crsrvar,
 					((struct fb_var_cursorinfo *)arg)->data, con);
 			}
 			return i;
@@ -1644,7 +1623,7 @@
 
 			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrstate));
 			if (!i) {
-				i = amiga_fb_get_cursorstate(&crsrstate, con);
+				i = amifb_get_cursorstate(&crsrstate, con);
 				copy_to_user((void *)arg, &crsrstate, sizeof(crsrstate));
 			}
 			return i;
@@ -1655,27 +1634,27 @@
 			i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrstate));
 			if (!i) {
 				copy_from_user(&crsrstate, (void *)arg, sizeof(crsrstate));
-				i = amiga_fb_set_cursorstate(&crsrstate, con);
+				i = amifb_set_cursorstate(&crsrstate, con);
 			}
 			return i;
 		}
 #ifdef DEBUG
 		case FBCMD_GET_CURRENTPAR : {
-			struct amiga_fb_par par;
+			struct amifb_par par;
 
-			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amiga_fb_par));
+			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amifb_par));
 			if (!i) {
 				ami_get_par(&par);
-				copy_to_user((void *)arg, &par, sizeof(struct amiga_fb_par));
+				copy_to_user((void *)arg, &par, sizeof(struct amifb_par));
 			}
 			return i;
 		}
 		case FBCMD_SET_CURRENTPAR : {
-			struct amiga_fb_par par;
+			struct amifb_par par;
 
-			i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amiga_fb_par));
+			i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amifb_par));
 			if (!i) {
-				copy_from_user(&par, (void *)arg, sizeof(struct amiga_fb_par));
+				copy_from_user(&par, (void *)arg, sizeof(struct amifb_par));
 				ami_set_par(&par);
 			}
 			return i;
@@ -1689,27 +1668,27 @@
 	 * Hardware Cursor
 	 */
 
-static int amiga_fb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con)
+static int amifb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con)
 {
 	return ami_get_fix_cursorinfo(fix, con);
 }
 
-static int amiga_fb_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
+static int amifb_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
 {
 	return ami_get_var_cursorinfo(var, data, con);
 }
 
-static int amiga_fb_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
+static int amifb_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
 {
 	return ami_set_var_cursorinfo(var, data, con);
 }
 
-static int amiga_fb_get_cursorstate(struct fb_cursorstate *state, int con)
+static int amifb_get_cursorstate(struct fb_cursorstate *state, int con)
 {
 	return ami_get_cursorstate(state, con);
 }
 
-static int amiga_fb_set_cursorstate(struct fb_cursorstate *state, int con)
+static int amifb_set_cursorstate(struct fb_cursorstate *state, int con)
 {
 	return ami_set_cursorstate(state, con);
 }
@@ -1719,7 +1698,7 @@
 	 * Initialisation
 	 */
 
-__initfunc(unsigned long amiga_fb_init(unsigned long mem_start))
+__initfunc(unsigned long amifb_init(unsigned long mem_start))
 {
 	int err, tag, i;
 	u_long chipptr;
@@ -1745,7 +1724,7 @@
 	switch (amiga_chipset) {
 #ifdef CONFIG_FB_AMIGA_OCS
 		case CS_OCS:
-			strcat(amiga_fb_name, "OCS");
+			strcat(amifb_name, "OCS");
 default_chipset:
 			chipset = TAG_OCS;
 			maxdepth[TAG_SHRES] = 0;	/* OCS means no SHRES */
@@ -1761,7 +1740,7 @@
 
 #ifdef CONFIG_FB_AMIGA_ECS
 		case CS_ECS:
-			strcat(amiga_fb_name, "ECS");
+			strcat(amifb_name, "ECS");
 			chipset = TAG_ECS;
 			maxdepth[TAG_SHRES] = 2;
 			maxdepth[TAG_HIRES] = 4;
@@ -1785,7 +1764,7 @@
 
 #ifdef CONFIG_FB_AMIGA_AGA
 		case CS_AGA:
-			strcat(amiga_fb_name, "AGA");
+			strcat(amifb_name, "AGA");
 			chipset = TAG_AGA;
 			maxdepth[TAG_SHRES] = 8;
 			maxdepth[TAG_HIRES] = 8;
@@ -1804,7 +1783,7 @@
 		default:
 #ifdef CONFIG_FB_AMIGA_OCS
 			printk("Unknown graphics chipset, defaulting to OCS\n");
-			strcat(amiga_fb_name, "Unknown");
+			strcat(amifb_name, "Unknown");
 			goto default_chipset;
 #else /* CONFIG_FB_AMIGA_OCS */
 			return mem_start;
@@ -1824,26 +1803,24 @@
 	 * Replace the Tag Values with the Real Pixel Clock Values
 	 */
 
-	for (i = 0; i < NUM_PREDEF_MODES; i++) {
-		tag = amiga_fb_predefined[i].pixclock;
+	for (i = 0; i < NUM_TOTAL_MODES; i++) {
+		struct fb_var_screeninfo *var = &amifb_predefined[i].var;
+		tag = var->pixclock;
 		if (tag == TAG_SHRES || tag == TAG_HIRES || tag == TAG_LORES) {
-			amiga_fb_predefined[i].pixclock = pixclock[tag];
-			if (amiga_fb_predefined[i].bits_per_pixel > maxdepth[tag])
-				amiga_fb_predefined[i].bits_per_pixel = maxdepth[tag];
+			var->pixclock = pixclock[tag];
+			if (var->bits_per_pixel > maxdepth[tag])
+				var->bits_per_pixel = maxdepth[tag];
 		}
 	}
 
-	strcpy(fb_info.modename, amiga_fb_name);
+	strcpy(fb_info.modename, amifb_name);
 	fb_info.changevar = NULL;
 	fb_info.node = -1;
-	fb_info.fbops = &amiga_fb_ops;
-	fb_info.fbvar_num = NUM_TOTAL_MODES;
-	fb_info.fbvar = amiga_fb_predefined;
+	fb_info.fbops = &amifb_ops;
 	fb_info.disp = &disp;
 	fb_info.switch_con = &amifbcon_switch;
 	fb_info.updatevar = &amifbcon_updatevar;
 	fb_info.blank = &amifbcon_blank;
-	fb_info.setcmap = &amifbcon_setcmap;
 
 	err = register_framebuffer(&fb_info);
 	if (err < 0)
@@ -1889,7 +1866,7 @@
 	custom.intena = IF_VERTB;
 	custom.intena = IF_SETCLR | IF_COPER;
 
-	amiga_fb_set_var(&amiga_fb_predefined[0], -1);
+	amifb_set_var(&amifb_default, -1, GET_FB_IDX(fb_info.node));
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, videomemorysize>>10);
@@ -1937,12 +1914,6 @@
 	 * Set the colormap
 	 */
 
-static int amifbcon_setcmap(struct fb_cmap *cmap, int con)
-{
-	return(amiga_fb_set_cmap(cmap, 1, con));
-}
-
-
 static void do_install_cmap(int con)
 {
 	if (con != currcon)
@@ -2039,32 +2010,32 @@
 {
 	int i;
 
-	for (i = 1; i < NUM_PREDEF_MODES; i++) {
-		if (!strcmp(name, amiga_fb_modenames[i])) {
-			amiga_fb_predefined[0] = amiga_fb_predefined[i];
+	for (i = 0; i < NUM_TOTAL_MODES; i++) {
+		if (!strcmp(name, amifb_predefined[i].name)) {
+			amifb_default = amifb_predefined[i].var;
 
 			if (useropts.xres != -1)
-				amiga_fb_predefined[0].xres = useropts.xres;
+				amifb_default.xres = useropts.xres;
 			if (useropts.yres != -1)
-				amiga_fb_predefined[0].yres = useropts.yres;
+				amifb_default.yres = useropts.yres;
 			if (useropts.xres_virtual != -1)
-				amiga_fb_predefined[0].xres_virtual = useropts.xres_virtual;
+				amifb_default.xres_virtual = useropts.xres_virtual;
 			if (useropts.yres_virtual != -1)
-				amiga_fb_predefined[0].yres_virtual = useropts.yres_virtual;
+				amifb_default.yres_virtual = useropts.yres_virtual;
 			if (useropts.bits_per_pixel != -1)
-				amiga_fb_predefined[0].bits_per_pixel = useropts.bits_per_pixel;
+				amifb_default.bits_per_pixel = useropts.bits_per_pixel;
 			if (useropts.left_margin != -1)
-				amiga_fb_predefined[0].left_margin = useropts.left_margin;
+				amifb_default.left_margin = useropts.left_margin;
 			if (useropts.right_margin != -1)
-				amiga_fb_predefined[0].right_margin = useropts.right_margin;
+				amifb_default.right_margin = useropts.right_margin;
 			if (useropts.upper_margin != -1)
-				amiga_fb_predefined[0].upper_margin = useropts.upper_margin;
+				amifb_default.upper_margin = useropts.upper_margin;
 			if (useropts.lower_margin != -1)
-				amiga_fb_predefined[0].lower_margin = useropts.lower_margin;
+				amifb_default.lower_margin = useropts.lower_margin;
 			if (useropts.hsync_len != -1)
-				amiga_fb_predefined[0].hsync_len = useropts.hsync_len;
+				amifb_default.hsync_len = useropts.hsync_len;
 			if (useropts.vsync_len != -1)
-				amiga_fb_predefined[0].vsync_len = useropts.vsync_len;
+				amifb_default.vsync_len = useropts.vsync_len;
 
 			amifb_usermode = i;
 			return;
@@ -2073,23 +2044,22 @@
 }
 
 	/*
-	 * Probe the  Video Modes
+	 *  Probe the Video Modes
 	 */
 
 __initfunc(static void check_default_mode(void))
 {
-	struct amiga_fb_par par;
+	struct amifb_par par;
 	int mode;
 
-	for (mode = 0; mode < NUM_PREDEF_MODES; mode++) {
-		if (!ami_decode_var(&amiga_fb_predefined[mode], &par)) {
-			if (mode)
-				amiga_fb_predefined[0] = amiga_fb_predefined[mode];
+	if (!ami_decode_var(&amifb_default, &par))
+		return;
+	printk("Can't use default video mode. Probing video modes...\n");
+	for (mode = 0; mode < NUM_TOTAL_MODES; mode++)
+		if (!ami_decode_var(&amifb_predefined[mode].var, &par)) {
+			amifb_default = amifb_predefined[mode].var;
 			return;
 		}
-		if (!mode)
-			printk("Can't use default video mode. Probing video modes...\n");
-	}
 	panic("Can't find any usable video mode");
 }
 
@@ -2141,10 +2111,10 @@
 	 */
 
 static int ami_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct amiga_fb_par *par)
+                          struct amifb_par *par)
 {
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id, amiga_fb_name);
+	strcpy(fix->id, amifb_name);
 	fix->smem_start = (char *)videomemory;
 	fix->smem_len = videomemorysize;
 
@@ -2178,7 +2148,7 @@
 	 */
 
 static int ami_decode_var(struct fb_var_screeninfo *var,
-                          struct amiga_fb_par *par)
+                          struct amifb_par *par)
 {
 	u_short clk_shift, line_shift;
 	u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
@@ -2560,7 +2530,7 @@
 	 */
 
 static int ami_encode_var(struct fb_var_screeninfo *var,
-                          struct amiga_fb_par *par)
+                          struct amifb_par *par)
 {
 	u_short clk_shift, line_shift;
 	int i;
@@ -2657,7 +2627,7 @@
 	 * Get current hardware setting
 	 */
 
-static void ami_get_par(struct amiga_fb_par *par)
+static void ami_get_par(struct amifb_par *par)
 {
 	*par = currentpar;
 }
@@ -2676,7 +2646,7 @@
 }
 
 #ifdef DEBUG
-static void ami_set_par(struct amiga_fb_par *par)
+static void ami_set_par(struct amifb_par *par)
 {
 	do_vmode_pan = 0;
 	do_vmode_full = 0;
@@ -2695,7 +2665,7 @@
 
 static void ami_pan_var(struct fb_var_screeninfo *var)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	par->xoffset = var->xoffset;
 	par->yoffset = var->yoffset;
@@ -2715,7 +2685,7 @@
 
 static int ami_update_par(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 	short clk_shift, vshift, fstrt, fsize, fstop, fconst,  shift, move, mod;
 
 	clk_shift = par->clk_shift;
@@ -2867,7 +2837,7 @@
 
 static void ami_update_display(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	custom.bplcon1 = par->bplcon1;
 	custom.bpl1mod = par->bpl1mod;
@@ -2882,7 +2852,7 @@
 
 static void ami_init_display(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
 	custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2;
@@ -2938,7 +2908,7 @@
 
 static void ami_do_blank(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 #if defined(CONFIG_FB_AMIGA_AGA)
 	u_short bplcon3 = par->bplcon3;
 #endif
@@ -3023,7 +2993,7 @@
 
 static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	fix->crsr_width = fix->crsr_xsize = par->crsr.width;
 	fix->crsr_height = fix->crsr_ysize = par->crsr.height;
@@ -3034,7 +3004,7 @@
 
 static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 	register u_short *lspr, *sspr;
 #ifdef __mc68000__
 	register u_long datawords asm ("d2");
@@ -3109,7 +3079,7 @@
 
 static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 	register u_short *lspr, *sspr;
 #ifdef __mc68000__
 	register u_long datawords asm ("d2");
@@ -3228,7 +3198,7 @@
 
 static int ami_get_cursorstate(struct fb_cursorstate *state, int con)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	state->xoffset = par->crsr.crsr_x;
 	state->yoffset = par->crsr.crsr_y;
@@ -3238,7 +3208,7 @@
 
 static int ami_set_cursorstate(struct fb_cursorstate *state, int con)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	par->crsr.crsr_x = state->xoffset;
 	par->crsr.crsr_y = state->yoffset;
@@ -3250,7 +3220,7 @@
 
 static void ami_set_sprite(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 	copins *copl, *cops;
 	u_short hs, vs, ve;
 	u_long pl, ps, pt;
@@ -3333,7 +3303,7 @@
 
 static void ami_reinit_copper(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 
 	copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0;
 	copdisplay.wait->l = CWAIT(32, par->diwstrt_v-4);
@@ -3345,7 +3315,7 @@
 
 static void ami_build_copper(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 	copins *copl, *cops;
 	u_long p;
 
@@ -3422,7 +3392,7 @@
 
 static void ami_rebuild_copper(void)
 {
-	struct amiga_fb_par *par = &currentpar;
+	struct amifb_par *par = &currentpar;
 	copins *copl, *cops;
 	u_short line, h_end1, h_end2;
 	short i;
@@ -3507,7 +3477,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-	return(amiga_fb_init(NULL));
+	return(amifb_init(NULL));
 }
 
 void cleanup_module(void)
--- m68k-2.1.72/drivers/video/atafb.c.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/atafb.c	Wed Dec 17 23:55:14 1997
@@ -47,6 +47,7 @@
 #define ATAFB_EXT
 #define ATAFB_FALCON
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -92,8 +93,9 @@
 static int sttt_xres=640,st_yres=400,tt_yres=480;
 static int sttt_xres_virtual=640,sttt_yres_virtual=400;
 static int ovsc_offset=0, ovsc_addlen=0;
+int        ovsc_switchmode=0;
 
-static struct atari_fb_par {
+static struct atafb_par {
 	unsigned long screen_base;
 	int yres_virtual;
 	union {
@@ -247,17 +249,17 @@
  *
  * int (*detect)( void )
  *   This function should detect the current video mode settings and
- *   store them in atari_fb_predefined[0] for later reference by the
+ *   store them in atafb_predefined[0] for later reference by the
  *   user. Return the index+1 of an equivalent predefined mode or 0
  *   if there is no such.
  * 
  * int (*encode_fix)( struct fb_fix_screeninfo *fix,
- *                    struct atari_fb_par *par )
+ *                    struct atafb_par *par )
  *   This function should fill in the 'fix' structure based on the
  *   values in the 'par' structure.
  *   
  * int (*decode_var)( struct fb_var_screeninfo *var,
- *                    struct atari_fb_par *par )
+ *                    struct atafb_par *par )
  *   Get the video params out of 'var'. If a value doesn't fit, round
  *   it up, if it's too big, return EINVAL.
  *   Round up in the following order: bits_per_pixel, xres, yres, 
@@ -265,14 +267,14 @@
  *   horizontal timing, vertical timing.
  *
  * int (*encode_var)( struct fb_var_screeninfo *var,
- *                    struct atari_fb_par *par );
+ *                    struct atafb_par *par );
  *   Fill the 'var' structure based on the values in 'par' and maybe
  *   other values read out of the hardware.
  *   
- * void (*get_par)( struct atari_fb_par *par )
+ * void (*get_par)( struct atafb_par *par )
  *   Fill the hardware's 'par' structure.
  *   
- * void (*set_par)( struct atari_fb_par *par )
+ * void (*set_par)( struct atafb_par *par )
  *   Set the hardware according to 'par'.
  *   
  * int (*setcolreg)( unsigned regno, unsigned red,
@@ -304,13 +306,13 @@
 static struct fb_hwswitch {
 	int  (*detect)( void );
 	int  (*encode_fix)( struct fb_fix_screeninfo *fix,
-						struct atari_fb_par *par );
+						struct atafb_par *par );
 	int  (*decode_var)( struct fb_var_screeninfo *var,
-						struct atari_fb_par *par );
+						struct atafb_par *par );
 	int  (*encode_var)( struct fb_var_screeninfo *var,
-						struct atari_fb_par *par );
-	void (*get_par)( struct atari_fb_par *par );
-	void (*set_par)( struct atari_fb_par *par );
+						struct atafb_par *par );
+	void (*get_par)( struct atafb_par *par );
+	void (*set_par)( struct atafb_par *par );
 	int  (*getcolreg)( unsigned regno, unsigned *red,
 					   unsigned *green, unsigned *blue,
 					   unsigned *transp );
@@ -320,7 +322,7 @@
 	void (*set_screen_base)( unsigned long s_base );
 	int  (*blank)( int blank_mode );
 	int  (*pan_display)( struct fb_var_screeninfo *var,
-						 struct atari_fb_par *par);
+						 struct atafb_par *par);
 } *fbhw;
 
 static char *autodetect_names[] = {"autodetect", NULL};
@@ -336,15 +338,6 @@
 static char *vga256_names[] = {"vga256", NULL};
 static char *falh2_names[] = {"falh2", NULL};
 static char *falh16_names[] = {"falh16", NULL};
-static char *user0_names[] = {"user0", NULL};
-static char *user1_names[] = {"user1", NULL};
-static char *user2_names[] = {"user2", NULL};
-static char *user3_names[] = {"user3", NULL};
-static char *user4_names[] = {"user4", NULL};
-static char *user5_names[] = {"user5", NULL};
-static char *user6_names[] = {"user6", NULL};
-static char *user7_names[] = {"user7", NULL};
-static char *dummy_names[] = {"dummy", NULL};
 
 static char **fb_var_names[] = {
 	/* Writing the name arrays directly in this array (via "(char *[]){...}")
@@ -364,22 +357,11 @@
 	vga256_names,
 	falh2_names,
 	falh16_names,
-	dummy_names, dummy_names, dummy_names, dummy_names,
-	dummy_names, dummy_names, dummy_names, dummy_names,
-	dummy_names, dummy_names,
-	user0_names,
-	user1_names,
-	user2_names,
-	user3_names,
-	user4_names,
-	user5_names,
-	user6_names,
-	user7_names,
 	NULL
 	/* ,NULL */ /* this causes a sigsegv on my gcc-2.5.8 */
 };
 
-static struct fb_var_screeninfo atari_fb_predefined[] = {
+static struct fb_var_screeninfo atafb_predefined[] = {
  	/*
  	 * yres_virtual==0 means use hw-scrolling if possible, else yres
  	 */
@@ -435,53 +417,9 @@
 	  896, 608, 896, 0, 0, 0, 4, 0,
 	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
 	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	/* Minor 14..23 free for more standard video modes */
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	{ 0, },
-	/* Minor 24..31 reserved for user defined video modes */
-	{ /* user0, initialized to Rx;y;d from commandline, if supplied */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user1 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user2 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user3 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user4 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user5 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user6 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ /* user7 */
-	  0, 0, 0, 0, 0, 0, 0, 0,
-	  {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
-	  0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
-static int num_atari_fb_predefined=arraysize(atari_fb_predefined);
+static int num_atafb_predefined=arraysize(atafb_predefined);
 
 
 static int
@@ -491,7 +429,7 @@
     char **name;
     int i;
     name_list=fb_var_names;
-    for (i = 0 ; i < num_atari_fb_predefined ; i++) {
+    for (i = 0 ; i < num_atafb_predefined ; i++) {
 	name=*(name_list++);
 	if (! name || ! *name)
 	    break;
@@ -511,7 +449,7 @@
 #ifdef ATAFB_TT
 
 static int tt_encode_fix( struct fb_fix_screeninfo *fix,
-						  struct atari_fb_par *par )
+						  struct atafb_par *par )
 
 {
 	int mode;
@@ -538,7 +476,7 @@
 
 
 static int tt_decode_var( struct fb_var_screeninfo *var,
-						  struct atari_fb_par *par )
+						  struct atafb_par *par )
 {
 	int xres=var->xres;
 	int yres=var->yres;
@@ -619,7 +557,7 @@
 }
 
 static int tt_encode_var( struct fb_var_screeninfo *var,
-						  struct atari_fb_par *par )
+						  struct atafb_par *par )
 {
 	int linelen, i;
 	var->red.offset=0;
@@ -715,7 +653,7 @@
 }
 
 
-static void tt_get_par( struct atari_fb_par *par )
+static void tt_get_par( struct atafb_par *par )
 {
 	unsigned long addr;
 	par->hw.tt.mode=shifter_tt.tt_shiftmode;
@@ -726,7 +664,7 @@
 	par->screen_base = PTOV(addr);
 }
 
-static void tt_set_par( struct atari_fb_par *par )
+static void tt_set_par( struct atafb_par *par )
 {
 	shifter_tt.tt_shiftmode=par->hw.tt.mode;
 	shifter.syncmode=par->hw.tt.sync;
@@ -771,7 +709,7 @@
 						  
 static int tt_detect( void )
 
-{	struct atari_fb_par par;
+{	struct atafb_par par;
 
 	/* Determine the connected monitor: The DMA sound must be
 	 * disabled before reading the MFP GPIP, because the Sound
@@ -788,7 +726,7 @@
 	mono_moni = (mfp.par_dt_reg & 0x80) == 0;
 
 	tt_get_par(&par);
-	tt_encode_var(&atari_fb_predefined[0], &par);
+	tt_encode_var(&atafb_predefined[0], &par);
 
 	return 1;
 }
@@ -836,7 +774,7 @@
 }
 
 static int falcon_encode_fix( struct fb_fix_screeninfo *fix,
-							  struct atari_fb_par *par )
+							  struct atafb_par *par )
 {
 	strcpy(fix->id, "Atari Builtin");
 	fix->smem_start = (char *)real_screen_base;
@@ -866,7 +804,7 @@
 
 
 static int falcon_decode_var( struct fb_var_screeninfo *var,
-							  struct atari_fb_par *par )
+							  struct atafb_par *par )
 {
 	int bpp = var->bits_per_pixel;
 	int xres = var->xres;
@@ -942,7 +880,7 @@
 
 	if (mon_type == F_MON_SM || DontCalcRes) {
 		/* Skip all calculations. VGA/TV/SC1224 only supported. */
-		struct fb_var_screeninfo *myvar = &atari_fb_predefined[0];
+		struct fb_var_screeninfo *myvar = &atafb_predefined[0];
 		
 		if (bpp > myvar->bits_per_pixel ||
 			var->xres > myvar->xres ||
@@ -1338,7 +1276,7 @@
 }
 
 static int falcon_encode_var( struct fb_var_screeninfo *var,
-							  struct atari_fb_par *par )
+							  struct atafb_par *par )
 {
 /* !!! only for VGA !!! */
 	int linelen, i;
@@ -1505,7 +1443,7 @@
 static struct falcon_hw f_new_mode;
 static int f_pan_display = 0;
 
-static void falcon_get_par( struct atari_fb_par *par )
+static void falcon_get_par( struct atafb_par *par )
 {
 	unsigned long addr;
 	struct falcon_hw *hw = &par->hw.falcon;
@@ -1542,7 +1480,7 @@
 	           ((hw->f_shift & 0x510)==0 && hw->st_shift==0x200);
 }
 
-static void falcon_set_par( struct atari_fb_par *par )
+static void falcon_set_par( struct atafb_par *par )
 {
 	f_change_mode = 0;
 
@@ -1550,10 +1488,9 @@
 	if (current_par.screen_base != par->screen_base)
 		fbhw->set_screen_base(par->screen_base);
 
-	/* Don't touch any other registers if we keep the default resolution
-	 * or SM124 Monitor is used (hardware scrolling supported only)
-	 */
-	if (mon_type == F_MON_SM || DontCalcRes)
+	/* Don't touch any other registers if we keep the default resolution */
+	if (DontCalcRes)
+		return;
 
 	/* Tell vbl-handler to change video mode.
 	 * We change modes only on next VBL, to avoid desynchronisation
@@ -1627,7 +1564,7 @@
 
 
 static int falcon_pan_display( struct fb_var_screeninfo *var,
-							   struct atari_fb_par *par )
+							   struct atafb_par *par )
 {
 	int xoffset;
 	int bpp = fb_display[currcon].var.bits_per_pixel;
@@ -1738,7 +1675,7 @@
  
 static int falcon_detect( void )
 {
-	struct atari_fb_par par;
+	struct atafb_par par;
 	unsigned char fhw;
 
 	/* Determine connected monitor and set monitor parameters */
@@ -1769,7 +1706,7 @@
 		fext.hsync = h_syncs[mon_type] / fext.t;
 
 	falcon_get_par(&par);
-	falcon_encode_var(&atari_fb_predefined[0], &par);
+	falcon_encode_var(&atafb_predefined[0], &par);
 
 	/* Detected mode is always the "autodetect" slot */
 	return 1;
@@ -1782,7 +1719,7 @@
 #ifdef ATAFB_STE
 
 static int stste_encode_fix( struct fb_fix_screeninfo *fix,
-							 struct atari_fb_par *par )
+							 struct atafb_par *par )
 
 {
 	int mode;
@@ -1813,7 +1750,7 @@
 
 
 static int stste_decode_var( struct fb_var_screeninfo *var,
-						  struct atari_fb_par *par )
+						  struct atafb_par *par )
 {
 	int xres=var->xres;
 	int yres=var->yres;
@@ -1871,7 +1808,7 @@
 }
 
 static int stste_encode_var( struct fb_var_screeninfo *var,
-						  struct atari_fb_par *par )
+						  struct atafb_par *par )
 {
 	int linelen, i;
 	var->red.offset=0;
@@ -1948,7 +1885,7 @@
 }
 
 
-static void stste_get_par( struct atari_fb_par *par )
+static void stste_get_par( struct atafb_par *par )
 {
 	unsigned long addr;
 	par->hw.st.mode=shifter_tt.st_shiftmode;
@@ -1960,7 +1897,7 @@
 	par->screen_base = PTOV(addr);
 }
 
-static void stste_set_par( struct atari_fb_par *par )
+static void stste_set_par( struct atafb_par *par )
 {
 	shifter_tt.st_shiftmode=par->hw.st.mode;
 	shifter.syncmode=par->hw.st.sync;
@@ -2015,7 +1952,7 @@
 						  
 static int stste_detect( void )
 
-{	struct atari_fb_par par;
+{	struct atafb_par par;
 
 	/* Determine the connected monitor: The DMA sound must be
 	 * disabled before reading the MFP GPIP, because the Sound
@@ -2028,7 +1965,7 @@
 	mono_moni = (mfp.par_dt_reg & 0x80) == 0;
 
 	stste_get_par(&par);
-	stste_encode_var(&atari_fb_predefined[0], &par);
+	stste_encode_var(&atafb_predefined[0], &par);
 
 	if (!ATARIHW_PRESENT(EXTD_SHIFTER))
 		use_hwscroll = 0;
@@ -2067,12 +2004,12 @@
 #define SYNC_DELAY  (mono_moni ? 1500 : 2000)
 
 /* SWITCH_ACIA may be used for Falcon (ScreenBlaster III internal!) */
-static void st_ovsc_switch(void)
+static void st_ovsc_switch(int switchmode)
 {
     unsigned long flags;
     register unsigned char old, new;
 
-    if (!(atari_switches & ATARI_SWITCH_OVSC_MASK))
+    if ((switchmode & (SWITCH_ACIA | SWITCH_SND6 | SWITCH_SND7)) == 0)
 	return;
     save_flags(flags);
     cli();
@@ -2093,15 +2030,11 @@
     mfp.tim_ct_b = 0x10;
     udelay(SYNC_DELAY);
 
-    if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
-	acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID | ACIA_RIE;
-    if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
-	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
-    if (atari_switches & (ATARI_SWITCH_OVSC_SND6|ATARI_SWITCH_OVSC_SND7)) {
+    if (switchmode == SWITCH_ACIA)
+	acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RHTID|ACIA_RIE);
+    else {
 	sound_ym.rd_data_reg_sel = 14;
-	sound_ym.wd_data = sound_ym.rd_data_reg_sel |
-			   ((atari_switches&ATARI_SWITCH_OVSC_SND6) ? 0x40:0) |
-			   ((atari_switches&ATARI_SWITCH_OVSC_SND7) ? 0x80:0);
+	sound_ym.wd_data = sound_ym.rd_data_reg_sel | switchmode;
     }
     restore_flags(flags);
 }
@@ -2111,7 +2044,7 @@
 #ifdef ATAFB_EXT
 
 static int ext_encode_fix( struct fb_fix_screeninfo *fix,
-						   struct atari_fb_par *par )
+						   struct atafb_par *par )
 
 {
 	strcpy(fix->id,"Unknown Extern");
@@ -2161,9 +2094,9 @@
 
 
 static int ext_decode_var( struct fb_var_screeninfo *var,
-						   struct atari_fb_par *par )
+						   struct atafb_par *par )
 {
-	struct fb_var_screeninfo *myvar = &atari_fb_predefined[0];
+	struct fb_var_screeninfo *myvar = &atafb_predefined[0];
 	
 	if (var->bits_per_pixel > myvar->bits_per_pixel ||
 		var->xres > myvar->xres ||
@@ -2177,7 +2110,7 @@
 
 
 static int ext_encode_var( struct fb_var_screeninfo *var,
-						   struct atari_fb_par *par )
+						   struct atafb_par *par )
 {
 	int i;
 
@@ -2221,19 +2154,19 @@
 }
 
 
-static void ext_get_par( struct atari_fb_par *par )
+static void ext_get_par( struct atafb_par *par )
 {
 	par->screen_base = external_addr;
 }
 
-static void ext_set_par( struct atari_fb_par *par )
+static void ext_set_par( struct atafb_par *par )
 {
 }
 
 #define OUTB(port,val) \
-	*((unsigned volatile char *) ((port)+base))=(val)
+	*((unsigned volatile char *) ((port)+external_vgaiobase))=(val)
 #define INB(port) \
-	({ unsigned char __v = (*((unsigned volatile char *)((port)+base))); __v;})
+	(*((unsigned volatile char *) ((port)+external_vgaiobase)))
 #define DACDelay 				\
 	do {					\
 		unsigned char tmp=INB(0x3da);	\
@@ -2259,9 +2192,8 @@
 						  unsigned transp )
 
 {	unsigned char colmask = (1 << external_bitspercol) - 1;
-	unsigned long base;
 
-	if (!(base = external_vgaiobase))
+	if (! external_vgaiobase)
 		return 1;
 
 	ext_color[regno].red = red;
@@ -2295,8 +2227,8 @@
 static int ext_detect( void )
 
 {
-	struct fb_var_screeninfo *myvar = &atari_fb_predefined[0];
-	struct atari_fb_par dummy_par;
+	struct fb_var_screeninfo *myvar = &atafb_predefined[0];
+	struct atafb_par dummy_par;
 
 	myvar->xres = external_xres;
 	myvar->xres_virtual = external_xres_virtual;
@@ -2322,7 +2254,7 @@
 
 
 static int pan_display( struct fb_var_screeninfo *var,
-                        struct atari_fb_par *par )
+                        struct atafb_par *par )
 {
 	if (!fbhw->set_screen_base ||
 		(!ATARIHW_PRESENT(EXTD_SHIFTER) && var->xoffset))
@@ -2372,7 +2304,7 @@
 
 
 
-static void atari_fb_get_par( struct atari_fb_par *par )
+static void atafb_get_par( struct atafb_par *par )
 {
 	if (current_par_valid) {
 		*par=current_par;
@@ -2382,7 +2314,7 @@
 }
 
 
-static void atari_fb_set_par( struct atari_fb_par *par )
+static void atafb_set_par( struct atafb_par *par )
 {
 	fbhw->set_par(par);
 	current_par=*par;
@@ -2415,12 +2347,12 @@
 do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
 {
 	int err,activate;
-	struct atari_fb_par par;
+	struct atafb_par par;
 	if ((err=fbhw->decode_var(var, &par)))
 		return err;
 	activate=var->activate;
 	if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
-		atari_fb_set_par(&par);
+		atafb_set_par(&par);
 	fbhw->encode_var(var, &par);
 	var->activate=activate;
 	return 0;
@@ -2447,7 +2379,7 @@
 	 * Open/Release the frame buffer device
 	 */
 
-static int atari_fb_open(int fbidx)
+static int atafb_open(int fbidx)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -2457,7 +2389,7 @@
 	return(0);
 }
 
-static int atari_fb_release(int fbidx)
+static int atafb_release(int fbidx)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -2465,11 +2397,11 @@
 
 
 static int
-atari_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+atafb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
 {
-	struct atari_fb_par par;
+	struct atafb_par par;
 	if (con == -1)
-		atari_fb_get_par(&par);
+		atafb_get_par(&par);
 	else
 		fbhw->decode_var(&fb_display[con].var,&par);
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
@@ -2477,11 +2409,11 @@
 }
 	
 static int
-atari_fb_get_var(struct fb_var_screeninfo *var, int con)
+atafb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
-	struct atari_fb_par par;
+	struct atafb_par par;
 	if (con == -1) {
-		atari_fb_get_par(&par);
+		atafb_get_par(&par);
 		fbhw->encode_var(var, &par);
 	}
 	else
@@ -2490,7 +2422,7 @@
 }
 
 static void
-atari_fb_set_disp(int con)
+atafb_set_disp(int con)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -2500,7 +2432,8 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	atari_fb_get_fix(&fix, con);
+	/* ### FN: Needs fixes later */
+	atafb_get_fix(&fix, con, 0);
 	if (con == -1)
 		con=0;
 	display->screen_base = (u_char *)fix.smem_start;
@@ -2520,7 +2453,7 @@
 }
 
 static int
-atari_fb_set_var(struct fb_var_screeninfo *var, int con)
+atafb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	int err,oldxres,oldyres,oldbpp,oldxres_virtual,
 	    oldyres_virtual,oldyoffset;
@@ -2539,7 +2472,7 @@
 		    || oldyres_virtual != var->yres_virtual
 		    || oldbpp != var->bits_per_pixel
 		    || oldyoffset != var->yoffset) {
-			atari_fb_set_disp(con);
+			atafb_set_disp(con);
 			(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
 			do_install_cmap(con);
@@ -2552,7 +2485,7 @@
 
 
 static int
-atari_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+atafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
 {
 	if (con == currcon) /* current console ? */
 		return fb_get_cmap(cmap, &(fb_display[con].var), kspc,
@@ -2567,7 +2500,7 @@
 }
 
 static int
-atari_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+atafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
 {
 	int err;
 	if (! fb_display[con].cmap.len) { /* no colormap allocated ? */
@@ -2585,7 +2518,7 @@
 }
 
 static int
-atari_fb_pan_display(struct fb_var_screeninfo *var, int con)
+atafb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	int xoffset = var->xoffset;
 	int yoffset = var->yoffset;
@@ -2609,33 +2542,33 @@
 }
 
 static int
-atari_fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	       unsigned long arg, int con)
+atafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	       unsigned long arg, int con, int fbidx)
 {
 	switch (cmd) {
 #ifdef FBCMD_GET_CURRENTPAR
 	case FBCMD_GET_CURRENTPAR:
 		if (copy_to_user((void *)arg, (void *)&current_par,
-				 sizeof(struct atari_fb_par)))
+				 sizeof(struct atafb_par)))
 			return -EFAULT;
 		return 0;
 #endif
 #ifdef FBCMD_SET_CURRENTPAR
 	case FBCMD_SET_CURRENTPAR:
 		if (copy_from_user((void *)&current_par, (void *)arg,
-				   sizeof(struct atari_fb_par)))
+				   sizeof(struct atafb_par)))
 			return -EFAULT;
-		atari_fb_set_par(&current_par);
+		atafb_set_par(&current_par);
 		return 0;
 #endif
 	}
 	return -EINVAL;
 }
 
-static struct fb_ops atari_fb_ops = {
-	atari_fb_open, atari_fb_release, atari_fb_get_fix, atari_fb_get_var,
-	atari_fb_set_var, atari_fb_get_cmap, atari_fb_set_cmap,
-	atari_fb_pan_display, atari_fb_ioctl	
+static struct fb_ops atafb_ops = {
+	atafb_open, atafb_release, atafb_get_fix, atafb_get_var,
+	atafb_set_var, atafb_get_cmap, atafb_set_cmap,
+	atafb_pan_display, atafb_ioctl	
 };
 
 static void
@@ -2648,14 +2581,14 @@
 
 	/* First try the user supplied mode */
 	if (default_par) {
-		var=atari_fb_predefined[default_par-1];
+		var=atafb_predefined[default_par-1];
 		var.activate = FB_ACTIVATE_TEST;
 		if (do_fb_set_var(&var,1))
 			default_par=0;		/* failed */
 	}
 	/* Next is the autodetected one */
 	if (! default_par) {
-		var=atari_fb_predefined[detected_mode-1]; /* autodetect */
+		var=atafb_predefined[detected_mode-1]; /* autodetect */
 		var.activate = FB_ACTIVATE_TEST;
 		if (!do_fb_set_var(&var,1))
 			default_par=detected_mode;
@@ -2668,7 +2601,7 @@
 			default_par=get_video_mode(default_name);
 			if (! default_par)
 				panic("can't set default video mode\n");
-			var=atari_fb_predefined[default_par-1];
+			var=atafb_predefined[default_par-1];
 			var.activate = FB_ACTIVATE_TEST;
 			if (! do_fb_set_var(&var,1))
 				break;	/* ok */
@@ -2722,13 +2655,7 @@
 		do_install_cmap(currcon);
 }
 
-static int
-atafb_setcmap(struct fb_cmap *cmap, int con)
-{
-	return(atari_fb_set_cmap(cmap, 1, con));
-}
-
-__initfunc(unsigned long atari_fb_init(unsigned long mem_start))
+__initfunc(unsigned long atafb_init(unsigned long mem_start))
 {
 	int err;
 	int pad;
@@ -2788,7 +2715,7 @@
 		screen_base+=pad;
 		real_screen_base=screen_base+ovsc_offset;
 		screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;
-		st_ovsc_switch();
+		st_ovsc_switch(ovsc_switchmode);
 		if (CPU_IS_040_OR_060) {
 			/* On a '040+, the cache mode of video RAM must be set to
 			 * write-through also for internal video hardware! */
@@ -2819,23 +2746,20 @@
 	strcpy(fb_info.modename, "Atari Builtin ");
 	fb_info.changevar = NULL;
 	fb_info.node = -1;
-	fb_info.fbops = &atari_fb_ops;
-	fb_info.fbvar_num = num_atari_fb_predefined;
-	fb_info.fbvar = atari_fb_predefined;
+	fb_info.fbops = &atafb_ops;
 	fb_info.disp = &disp;
 	fb_info.switch_con = &atafb_switch;
 	fb_info.updatevar = &fb_update_var;
 	fb_info.blank = &atafb_blank;
-	fb_info.setcmap = &atafb_setcmap;
-	do_fb_set_var(&atari_fb_predefined[default_par-1], 1);
+	do_fb_set_var(&atafb_predefined[default_par-1], 1);
 	strcat(fb_info.modename, fb_var_names[default_par-1][0]);
 
 	err=register_framebuffer(&fb_info);
 	if (err < 0)
 		return(err);
 
-	atari_fb_get_var(&disp.var, -1);
-	atari_fb_set_disp(-1);
+	atafb_get_var(&disp.var, -1, GET_FB_IDX(fb_info.node));
+	atafb_set_disp(-1);
 	printk("Determined %dx%d, depth %d\n",
 	       disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
 	if ((disp.var.xres != disp.var.xres_virtual) ||
@@ -2874,7 +2798,7 @@
   return sbegin;
 }
 
-__initfunc(void atari_video_setup( char *options, int *ints ))
+__initfunc(void atafb_setup( char *options, int *ints ))
 {
     char *this_opt;
     int temp;
@@ -2906,6 +2830,15 @@
 		if (hwscroll > 200)
 			hwscroll = 200;
 	}
+	else if (! strncmp(this_opt, "sw_",3)) {
+		if (! strcmp(this_opt+3, "acia"))
+			ovsc_switchmode = SWITCH_ACIA;
+		else if (! strcmp(this_opt+3, "snd6"))
+			ovsc_switchmode = SWITCH_SND6;
+		else if (! strcmp(this_opt+3, "snd7"))
+			ovsc_switchmode = SWITCH_SND7;
+		else ovsc_switchmode = SWITCH_NONE;
+	}
 #ifdef ATAFB_EXT
 	else if (!strcmp(this_opt,"mv300")) {
 		external_bitspercol = 8;
@@ -2971,7 +2904,7 @@
 		use_hwscroll=0;
     }
     else 
-      int_invalid:
+      int_invalid:	ovsc_switchmode = SWITCH_NONE;
 
 #ifdef ATAFB_EXT
     if (*ext_str) {
@@ -3121,9 +3054,9 @@
 		depth = simple_strtoul(p, NULL, 10);
 		if ((temp=get_video_mode("user0"))) {
 			default_par=temp;
-			atari_fb_predefined[default_par-1].xres = xres;
-			atari_fb_predefined[default_par-1].yres = yres;
-			atari_fb_predefined[default_par-1].bits_per_pixel = depth;
+			atafb_predefined[default_par-1].xres = xres;
+			atafb_predefined[default_par-1].yres = yres;
+			atafb_predefined[default_par-1].bits_per_pixel = depth;
 		}
 
 	  user_invalid:
@@ -3134,7 +3067,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-	return(atari_fb_init(NULL));
+	return(atafb_init(NULL));
 }
 
 void cleanup_module(void)
--- m68k-2.1.72/drivers/video/cyberfb.c.orig	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.72/drivers/video/cyberfb.c	Wed Dec 17 23:55:14 1997
@@ -41,13 +41,13 @@
 
 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
 
-struct Cyber_fb_par {
+struct cyberfb_par {
    int xres;
    int yres;
    int bpp;
 };
 
-static struct Cyber_fb_par current_par;
+static struct cyberfb_par current_par;
 
 static int current_par_valid = 0;
 static int currcon = 0;
@@ -68,9 +68,9 @@
 
    /* Display Control */
 
-   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct Cyber_fb_par *par);
-   int (*decode_var)(struct fb_var_screeninfo *var, struct Cyber_fb_par *par);
-   int (*encode_var)(struct fb_var_screeninfo *var, struct Cyber_fb_par *par);
+   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct cyberfb_par *par);
+   int (*decode_var)(struct fb_var_screeninfo *var, struct cyberfb_par *par);
+   int (*encode_var)(struct fb_var_screeninfo *var, struct cyberfb_par *par);
    int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
                     u_int *transp);
    int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
@@ -83,7 +83,7 @@
  *    Frame Buffer Name
  */
 
-static char Cyber_fb_name[16] = "Cybervision";
+static char cyberfb_name[16] = "Cybervision";
 
 
 /*
@@ -109,102 +109,43 @@
 
 
 /*
- *    Predefined Video Mode Names
+ *    Predefined Video Modes
  */
 
-static char *Cyber_fb_modenames[] = {
-
-   /*
-    *    Autodetect (Default) Video Mode
-    */
-
-   "default",
-
-   /*
-    *    Predefined Video Modes
-    */
-    
-   "cyber8",            /* Cybervision 8 bpp */
-   "cyber16",           /* Cybervision 16 bpp */
-   "800x600x8",
-   "640x480x8",
-
-   /*
-    *    Dummy Video Modes
-    */
-
-   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-   "dummy", "dummy",
-
-   /*
-    *    User Defined Video Modes
-    *
-    *    This doesn't work yet!!
-    */
-
-   "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
-};
-
-
-/*
- *    Predefined Video Mode Definitions
- */
-
-static struct fb_var_screeninfo cyber_fb_predefined[] = {
-
-   /*
-    *    Autodetect (Default) Video Mode
-    */
-
-   { 0, },
-
-   /*
-    *    Predefined Video Modes
-    */
-    
-   {
-      /* Cybervision 8 bpp */
-      CYBER8_WIDTH, CYBER8_HEIGHT, CYBER8_WIDTH, CYBER8_HEIGHT, 0, 0, 8, 0,
-      {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-      0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   }, {
-      /* Cybervision 16 bpp */
-      800, 600, 800, 600, 0, 0, 16, 0,
-      {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-      0, 0, -1, -1, FB_ACCEL_NONE, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   }, {
-      /* Cybervision 8 bpp */
-      800, 600, 800, 600, 0, 0, 8, 0,
-      {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-      0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   }, {
-      /* Cybervision 8 bpp */
-      640, 480, 640, 480, 0, 0, 8, 0,
-      {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-      0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
-      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   },
-   /*
-    *    Dummy Video Modes
-    */
-
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, 
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
-
-   /*
-    *    User Defined Video Modes
-    */
-
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+static struct fb_videomode cyberfb_predefined[] __initdata = {
+    {
+	"cyber8", {		/* Cybervision 8 bpp */
+	    CYBER8_WIDTH, CYBER8_HEIGHT, CYBER8_WIDTH, CYBER8_HEIGHT, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }, {
+	"cyber16", {		/* Cybervision 16 bpp */
+	    800, 600, 800, 600, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }, {
+	"800x600x8", {		/* Cybervision 8 bpp */
+	    800, 600, 800, 600, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }, {
+	"640x480x8", {		/* Cybervision 8 bpp */
+	    640, 480, 640, 480, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    },
 };
 
 
-#define NUM_TOTAL_MODES    arraysize(cyber_fb_predefined)
-#define NUM_PREDEF_MODES   (5)
+#define NUM_TOTAL_MODES    arraysize(cyberfb_predefined)
 
 
 static int Cyberfb_inverse = 0;
@@ -212,7 +153,6 @@
 static int Cyberfb_Cyber8 = 0;        /* Use Cybervision board */
 static int Cyberfb_Cyber16 = 0;       /* Use Cybervision board */
 #endif
-static int Cyberfb_mode = 0;
 
 
 /*
@@ -222,34 +162,38 @@
 #define CYBER8_DEFMODE     (1)
 #define CYBER16_DEFMODE    (2)
 
+static struct fb_var_screeninfo cyberfb_default;
+
 
 /*
  *    Interface used by the world
  */
 
-void Cyber_video_setup(char *options, int *ints);
+void cyberfb_setup(char *options, int *ints);
 
-static int Cyber_fb_open(int fbidx);
-static int Cyber_fb_release(int fbidx);
-static int Cyber_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
-static int Cyber_fb_get_var(struct fb_var_screeninfo *var, int con);
-static int Cyber_fb_set_var(struct fb_var_screeninfo *var, int con);
-static int Cyber_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int Cyber_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int Cyber_fb_pan_display(struct fb_var_screeninfo *var, int con);
-static int Cyber_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                          u_long arg, int con);
+static int cyberfb_open(int fbidx);
+static int cyberfb_release(int fbidx);
+static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
+static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx);
+static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx);
+static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
+				int fbidx);
+static int cyberfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                          u_long arg, int con, int fbidx);
 
 
 /*
  *    Interface to the low level console driver
  */
 
-unsigned long Cyber_fb_init(unsigned long mem_start);
+unsigned long cyberfb_init(unsigned long mem_start);
 static int Cyberfb_switch(int con);
 static int Cyberfb_updatevar(int con);
 static void Cyberfb_blank(int blank);
-static int Cyberfb_setcmap(struct fb_cmap *cmap, int con);
 
 
 /*
@@ -271,11 +215,11 @@
 
 static int Cyber_init(void);
 static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct Cyber_fb_par *par);
+                          struct cyberfb_par *par);
 static int Cyber_decode_var(struct fb_var_screeninfo *var,
-                          struct Cyber_fb_par *par);
+                          struct cyberfb_par *par);
 static int Cyber_encode_var(struct fb_var_screeninfo *var,
-                          struct Cyber_fb_par *par);
+                          struct cyberfb_par *par);
 static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
                          u_int *transp);
 static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
@@ -287,11 +231,11 @@
  *    Internal routines
  */
 
-static void Cyber_fb_get_par(struct Cyber_fb_par *par);
-static void Cyber_fb_set_par(struct Cyber_fb_par *par);
+static void cyberfb_get_par(struct cyberfb_par *par);
+static void cyberfb_set_par(struct cyberfb_par *par);
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
 static void do_install_cmap(int con);
-static void Cyber_fb_set_disp(int con);
+static void cyberfb_set_disp(int con);
 static int get_video_mode(const char *name);
 
 
@@ -311,16 +255,6 @@
 	char size;
 	volatile u_long *CursorBase;
 
-#if 0
-	if (Cyberfb_mode == -1)
-	{
-		if (Cyberfb_Cyber8)
-			Cyberfb_mode = CYBER8_DEFMODE;
-		else
-			Cyberfb_mode = CYBER16_DEFMODE;
-	}
-#endif
-
 	for (i = 0; i < 256; i++)
 
 		for (i = 0; i < 256; i++)
@@ -385,11 +319,11 @@
  */
 
 static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
-			    struct Cyber_fb_par *par)
+			    struct cyberfb_par *par)
 {
 	int i;
 
-	strcpy(fix->id, Cyber_fb_name);
+	strcpy(fix->id, cyberfb_name);
 	fix->smem_start = (caddr_t)CyberMem;
 	fix->smem_len = CyberSize;
 	fix->mmio_start = (unsigned char *)CyberRegs;
@@ -420,7 +354,7 @@
  */
 
 static int Cyber_decode_var(struct fb_var_screeninfo *var,
-			    struct Cyber_fb_par *par)
+			    struct cyberfb_par *par)
 {
 #if 1
 	par->xres = var->xres;
@@ -447,7 +381,7 @@
  */
 
 static int Cyber_encode_var(struct fb_var_screeninfo *var,
-			    struct Cyber_fb_par *par)
+			    struct cyberfb_par *par)
 {
 	int i;
 
@@ -714,16 +648,16 @@
  *    Fill the hardware's `par' structure.
  */
 
-static void Cyber_fb_get_par(struct Cyber_fb_par *par)
+static void cyberfb_get_par(struct cyberfb_par *par)
 {
 	if (current_par_valid)
 		*par = current_par;
 	else
-		fbhw->decode_var(&cyber_fb_predefined[Cyberfb_mode], par);
+		fbhw->decode_var(&cyberfb_default, par);
 }
 
 
-static void Cyber_fb_set_par(struct Cyber_fb_par *par)
+static void cyberfb_set_par(struct cyberfb_par *par)
 {
 	current_par = *par;
 	current_par_valid = 1;
@@ -744,13 +678,13 @@
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
 {
 	int err, activate;
-	struct Cyber_fb_par par;
+	struct cyberfb_par par;
 
 	if ((err = fbhw->decode_var(var, &par)))
 		return(err);
 	activate = var->activate;
 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
-		Cyber_fb_set_par(&par);
+		cyberfb_set_par(&par);
 	fbhw->encode_var(var, &par);
 	var->activate = activate;
 
@@ -776,7 +710,7 @@
  *  Open/Release the frame buffer device
  */
 
-static int Cyber_fb_open(int fbidx)
+static int cyberfb_open(int fbidx)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -786,7 +720,7 @@
 	return(0);
 }
 
-static int Cyber_fb_release(int fbidx)
+static int cyberfb_release(int fbidx)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -797,13 +731,13 @@
  *    Get the Fixed Part of the Display
  */
 
-static int Cyber_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
 {
-	struct Cyber_fb_par par;
+	struct cyberfb_par par;
 	int error = 0;
 
 	if (con == -1)
-		Cyber_fb_get_par(&par);
+		cyberfb_get_par(&par);
 	else
 		error = fbhw->decode_var(&fb_display[con].var, &par);
 	return(error ? error : fbhw->encode_fix(fix, &par));
@@ -814,13 +748,13 @@
  *    Get the User Defined Part of the Display
  */
 
-static int Cyber_fb_get_var(struct fb_var_screeninfo *var, int con)
+static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
-	struct Cyber_fb_par par;
+	struct cyberfb_par par;
 	int error = 0;
 
 	if (con == -1) {
-		Cyber_fb_get_par(&par);
+		cyberfb_get_par(&par);
 		error = fbhw->encode_var(var, &par);
 	} else
 		*var = fb_display[con].var;
@@ -828,7 +762,7 @@
 }
 
 
-static void Cyber_fb_set_disp(int con)
+static void cyberfb_set_disp(int con)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -838,7 +772,8 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	Cyber_fb_get_fix(&fix, con);
+	/* ### FN: Needs fixes later */
+	cyberfb_get_fix(&fix, con, 0);
 	if (con == -1)
 		con = 0;
 	display->screen_base = (u_char *)fix.smem_start;
@@ -856,7 +791,7 @@
  *    Set the User Defined Part of the Display
  */
 
-static int Cyber_fb_set_var(struct fb_var_screeninfo *var, int con)
+static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
 
@@ -873,7 +808,7 @@
 		    oldvxres != var->xres_virtual ||
 		    oldvyres != var->yres_virtual ||
 		    oldbpp != var->bits_per_pixel) {
-			Cyber_fb_set_disp(con);
+			cyberfb_set_disp(con);
 			(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
 			do_install_cmap(con);
@@ -888,7 +823,8 @@
  *    Get the Colormap
  */
 
-static int Cyber_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx)
 {
 	if (con == currcon) /* current console? */
 		return(fb_get_cmap(cmap, &fb_display[con].var,
@@ -906,7 +842,8 @@
  *    Set the Colormap
  */
 
-static int Cyber_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx)
 {
 	int err;
 
@@ -930,7 +867,7 @@
  *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  */
 
-static int Cyber_fb_pan_display(struct fb_var_screeninfo *var, int con)
+static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	return(-EINVAL);
 }
@@ -940,21 +877,21 @@
     *    Cybervision Frame Buffer Specific ioctls
     */
 
-static int Cyber_fb_ioctl(struct inode *inode, struct file *file,
-                          u_int cmd, u_long arg, int con)
+static int cyberfb_ioctl(struct inode *inode, struct file *file,
+                          u_int cmd, u_long arg, int con, int fbidx)
 {
 	return(-EINVAL);
 }
 
 
-static struct fb_ops Cyber_fb_ops = {
-	Cyber_fb_open, Cyber_fb_release, Cyber_fb_get_fix, Cyber_fb_get_var,
-	Cyber_fb_set_var, Cyber_fb_get_cmap, Cyber_fb_set_cmap,
-	Cyber_fb_pan_display, Cyber_fb_ioctl
+static struct fb_ops cyberfb_ops = {
+	cyberfb_open, cyberfb_release, cyberfb_get_fix, cyberfb_get_var,
+	cyberfb_set_var, cyberfb_get_cmap, cyberfb_set_cmap,
+	cyberfb_pan_display, cyberfb_ioctl
 };
 
 
-__initfunc(void Cyber_video_setup(char *options, int *ints))
+__initfunc(void cyberfb_setup(char *options, int *ints))
 {
 	char *this_opt;
 
@@ -969,14 +906,8 @@
 			fb_invert_cmaps();
 		} else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
-#if 0
-		else if (!strcmp (this_opt, "cyber8"))
-			Cyberfb_Cyber8 = 1;
-		else if (!strcmp (this_opt, "cyber16"))
-			Cyberfb_Cyber16 = 1;
-#endif
 		else
-			Cyberfb_mode = get_video_mode(this_opt);
+			get_video_mode(this_opt);
 }
 
 
@@ -984,10 +915,10 @@
  *    Initialization
  */
 
-__initfunc(unsigned long Cyber_fb_init(unsigned long mem_start))
+__initfunc(unsigned long cyberfb_init(unsigned long mem_start))
 {
 	int err;
-	struct Cyber_fb_par par;
+	struct cyberfb_par par;
 	unsigned long board_addr;
 	const struct ConfigDev *cd;
 
@@ -1005,29 +936,26 @@
 
 	fbhw = &Cyber_switch;
 
-	strcpy(fb_info.modename, Cyber_fb_name);
+	strcpy(fb_info.modename, cyberfb_name);
 	fb_info.changevar = NULL;
 	fb_info.node = -1;
-	fb_info.fbops = &Cyber_fb_ops;
-	fb_info.fbvar_num = NUM_TOTAL_MODES;
-	fb_info.fbvar = cyber_fb_predefined;
+	fb_info.fbops = &cyberfb_ops;
 	fb_info.disp = &disp;
 	fb_info.switch_con = &Cyberfb_switch;
 	fb_info.updatevar = &Cyberfb_updatevar;
 	fb_info.blank = &Cyberfb_blank;
-	fb_info.setcmap = &Cyberfb_setcmap;
 
 	err = register_framebuffer(&fb_info);
 	if (err < 0)
 		return mem_start;
 
 	fbhw->init();
-	fbhw->decode_var(&cyber_fb_predefined[Cyberfb_mode], &par);
-	fbhw->encode_var(&cyber_fb_predefined[0], &par);
+	fbhw->decode_var(&cyberfb_default, &par);
+	fbhw->encode_var(&cyberfb_default, &par);
 
-	do_fb_set_var(&cyber_fb_predefined[0], 1);
-	Cyber_fb_get_var(&fb_display[0].var, -1);
-	Cyber_fb_set_disp(-1);
+	do_fb_set_var(&cyberfb_default, 1);
+	cyberfb_get_var(&fb_display[0].var, -1, GET_FB_IDX(fb_info.node));
+	cyberfb_set_disp(-1);
 	do_install_cmap(0);
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
@@ -1079,26 +1007,16 @@
 
 
 /*
- *    Set the colormap
- */
-
-static int Cyberfb_setcmap(struct fb_cmap *cmap, int con)
-{
-	return(Cyber_fb_set_cmap(cmap, 1, con));
-}
-
-
-/*
  *    Get a Video Mode
  */
 
-static int get_video_mode(const char *name)
+__initfunc(static int get_video_mode(const char *name))
 {
 	int i;
 
-	for (i = 1; i < NUM_PREDEF_MODES; i++)
-		if (!strcmp(name, Cyber_fb_modenames[i]))
-			cyber_fb_predefined[0] = cyber_fb_predefined[i];
+	for (i = 0; i < NUM_TOTAL_MODES; i++)
+		if (!strcmp(name, cyberfb_predefined[i].name))
+			cyberfb_default = cyberfb_predefined[i].var;
 			return(i);
 	return(0);
 }
@@ -1107,7 +1025,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-	return(Cyber_fb_init(NULL));
+	return(cyberfb_init(NULL));
 }
 
 void cleanup_module(void)
--- m68k-2.1.72/drivers/video/dn_fb.c.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/dn_fb.c	Wed Dec 17 23:55:14 1997
@@ -1,391 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/malloc.h>
-#include <linux/delay.h>
-#include <linux/config.h>
-#include <linux/interrupt.h>
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#include <asm/apollohw.h>
-#include <linux/fb.h>
-#include <linux/module.h>
-
-/* apollo video HW definitions */
-
-/*
- * Control Registers.   IOBASE + $x
- *
- * Note: these are the Memory/IO BASE definitions for a mono card set to the
- * alternate address
- *
- * Control 3A and 3B serve identical functions except that 3A
- * deals with control 1 and 3b deals with Color LUT reg.
- */
-
-#define AP_IOBASE       0x5d80          /* Base address of 1 plane board. */
-#define AP_STATUS       0x5d80          /* Status register.  Read */
-#define AP_WRITE_ENABLE 0x5d80          /* Write Enable Register Write */
-#define AP_DEVICE_ID    0x5d81          /* Device ID Register. Read */
-#define AP_ROP_1        0x5d82          /* Raster Operation reg. Write Word */
-#define AP_DIAG_MEM_REQ 0x5d84          /* Diagnostic Memory Request. Write Word */
-#define AP_CONTROL_0    0x5d88          /* Control Register 0.  Read/Write */
-#define AP_CONTROL_1    0x5d8a          /* Control Register 1.  Read/Write */
-#define AP_CONTROL_3A   0x5d8e          /* Control Register 3a. Read/Write */
-#define AP_CONTROL_2    0x5d8c          /* Control Register 2. Read/Write */
-
-
-#define FRAME_BUFFER_START 0x0FA0000
-#define FRAME_BUFFER_LEN 0x40000
-
-/* CREG 0 */
-#define VECTOR_MODE 0x40 /* 010x.xxxx */
-#define DBLT_MODE   0x80 /* 100x.xxxx */
-#define NORMAL_MODE 0xE0 /* 111x.xxxx */
-#define SHIFT_BITS  0x1F /* xxx1.1111 */
-        /* other bits are Shift value */
-
-/* CREG 1 */
-#define AD_BLT      0x80 /* 1xxx.xxxx */
-#define NORMAL      0x80 /* 1xxx.xxxx */   /* What is happening here ?? */
-#define INVERSE     0x00 /* 0xxx.xxxx */   /* Clearing this reverses the screen */
-#define PIX_BLT     0x00 /* 0xxx.xxxx */
-
-#define AD_HIBIT        0x40 /* xIxx.xxxx */
-
-#define ROP_EN          0x10 /* xxx1.xxxx */
-#define DST_EQ_SRC      0x00 /* xxx0.xxxx */
-#define nRESET_SYNC     0x08 /* xxxx.1xxx */
-#define SYNC_ENAB       0x02 /* xxxx.xx1x */
-
-#define BLANK_DISP      0x00 /* xxxx.xxx0 */
-#define ENAB_DISP       0x01 /* xxxx.xxx1 */
-
-#define NORM_CREG1      (nRESET_SYNC | SYNC_ENAB | ENAB_DISP) /* no reset sync */
-
-/* CREG 2 */
-
-/*
- * Following 3 defines are common to 1, 4 and 8 plane.
- */
-
-#define S_DATA_1s   0x00 /* 00xx.xxxx */ /* set source to all 1's -- vector drawing */
-#define S_DATA_PIX  0x40 /* 01xx.xxxx */ /* takes source from ls-bits and replicates over 16 bits */
-#define S_DATA_PLN  0xC0 /* 11xx.xxxx */ /* normal, each data access =16-bits in
- one plane of image mem */
-
-/* CREG 3A/CREG 3B */
-#       define RESET_CREG 0x80 /* 1000.0000 */
-
-/* ROP REG  -  all one nibble */
-/*      ********* NOTE : this is used r0,r1,r2,r3 *********** */
-#define ROP(r2,r3,r0,r1) ( (U_SHORT)((r0)|((r1)<<4)|((r2)<<8)|((r3)<<12)) )
-#define DEST_ZERO               0x0
-#define SRC_AND_DEST    0x1
-#define SRC_AND_nDEST   0x2
-#define SRC                             0x3
-#define nSRC_AND_DEST   0x4
-#define DEST                    0x5
-#define SRC_XOR_DEST    0x6
-#define SRC_OR_DEST             0x7
-#define SRC_NOR_DEST    0x8
-#define SRC_XNOR_DEST   0x9
-#define nDEST                   0xA
-#define SRC_OR_nDEST    0xB
-#define nSRC                    0xC
-#define nSRC_OR_DEST    0xD
-#define SRC_NAND_DEST   0xE
-#define DEST_ONE                0xF
-
-#define SWAP(A) ((A>>8) | ((A&0xff) <<8))
-
-#if 0
-#define outb(a,d) *(char *)(a)=(d)
-#define outw(a,d) *(unsigned short *)a=d
-#endif
-
-
-void dn_video_setup(char *options, int *ints);
-
-/* frame buffer operations */
-
-static int dn_fb_open(int fbidx);
-static int dn_fb_release(int fbidx);
-static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
-static int dn_fb_get_var(struct fb_var_screeninfo *var, int con);
-static int dn_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con);
-static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con);
-static int dn_fb_pan_display(struct fb_var_screeninfo *var, int con);
-static int dn_fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		       unsigned long arg, int con);
-
-static int dnfbcon_switch(int con);
-static int dnfbcon_updatevar(int con);
-static void dnfbcon_blank(int blank);
-
-static void dn_fb_set_disp(int con);
-
-static struct display disp[MAX_NR_CONSOLES];
-static struct fb_info fb_info;
-static struct fb_ops dn_fb_ops = { 
-	dn_fb_open,dn_fb_release, dn_fb_get_fix, dn_fb_get_var, dn_fb_set_var,
-	dn_fb_get_cmap, dn_fb_set_cmap, dn_fb_pan_display, dn_fb_ioctl
-};
-
-static int currcon=0;
-
-#define NUM_TOTAL_MODES 1
-struct fb_var_screeninfo dn_fb_predefined[] = {
-
-	{ 0, },
-
-};
-
-static char dn_fb_name[]="Apollo ";
-
-static int dn_fb_open(int fbidx)
-{
-        /*
-         * Nothing, only a usage count for the moment
-         */
-
-        MOD_INC_USE_COUNT;
-        return(0);
-}
-
-static int dn_fb_release(int fbidx)
-{
-        MOD_DEC_USE_COUNT;
-        return(0);
-}
-
-static int dn_fb_get_fix(struct fb_fix_screeninfo *fix, int con) {
-
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id,"Apollo Mono");
-	fix->smem_start=(char*)(FRAME_BUFFER_START+IO_BASE);
-	fix->smem_len=FRAME_BUFFER_LEN;
-	fix->type=FB_TYPE_PACKED_PIXELS;
-	fix->type_aux=0;
-	fix->visual=FB_VISUAL_MONO10;
-	fix->xpanstep=0;
-	fix->ypanstep=0;
-	fix->ywrapstep=0;
-        fix->line_length=256;
-
-	return 0;
-
-}
-        
-static int dn_fb_get_var(struct fb_var_screeninfo *var, int con) {
-		
-	var->xres=1280;
-	var->yres=1024;
-	var->xres_virtual=2048;
-	var->yres_virtual=1024;
-	var->xoffset=0;
-	var->yoffset=0;
-	var->bits_per_pixel=1;
-	var->grayscale=0;
-	var->nonstd=0;
-	var->activate=0;
-	var->height=-1;
-	var->width=-1;
-	var->pixclock=0;
-	var->left_margin=0;
-	var->right_margin=0;
-	var->hsync_len=0;
-	var->vsync_len=0;
-	var->sync=0;
-	var->vmode=FB_VMODE_NONINTERLACED;
-	var->accel=FB_ACCEL_NONE;
-
-	return 0;
-
-}
-
-static int dn_fb_set_var(struct fb_var_screeninfo *var, int isactive) {
-
-        printk("fb_set_var\n");
-	if(var->xres!=1280) 
-		return -EINVAL;
-	if(var->yres!=1024)
-		return -EINVAL;
-	if(var->xres_virtual!=2048)
-		return -EINVAL;
-	if(var->yres_virtual!=1024)
-		return -EINVAL;
-	if(var->xoffset!=0)
-		return -EINVAL;
-	if(var->yoffset!=0)
-		return -EINVAL;
-	if(var->bits_per_pixel!=1)
-		return -EINVAL;
-	if(var->grayscale!=0)
-		return -EINVAL;
-	if(var->nonstd!=0)
-		return -EINVAL;
-	if(var->activate!=0)
-		return -EINVAL;
-	if(var->pixclock!=0)
-		return -EINVAL;
-	if(var->left_margin!=0)
-		return -EINVAL;
-	if(var->right_margin!=0)
-		return -EINVAL;
-	if(var->hsync_len!=0)
-		return -EINVAL;
-	if(var->vsync_len!=0)
-		return -EINVAL;
-	if(var->sync!=0)
-		return -EINVAL;
-	if(var->vmode!=FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-	if(var->accel!=FB_ACCEL_NONE)
-		return -EINVAL;
-
-	return 0;
-
-}
-
-static int dn_fb_get_cmap(struct fb_cmap *cmap,int kspc,int con) {
-
-	printk("get cmap not supported\n");
-
-	return -EINVAL;
-}
-
-static int dn_fb_set_cmap(struct fb_cmap *cmap,int kspc,int con) {
-
-	printk("set cmap not supported\n");
-
-	return -EINVAL;
-
-}
-
-static int dn_fb_pan_display(struct fb_var_screeninfo *var, int con) {
-
-	printk("panning not supported\n");
-
-	return -EINVAL;
-
-}
-
-static int dn_fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		    unsigned long arg, int con) {
-
-	printk("no IOCTLs as of yet.\n");
-
-	return -EINVAL;
-
-}
-
-static void dn_fb_set_disp(int con) {
-
-  struct fb_fix_screeninfo fix;
-
-  dn_fb_get_fix(&fix,con);
-  if(con==-1) 
-    con=0;
-
-   disp[con].screen_base = (u_char *)fix.smem_start;
-printk("screenbase: %p\n",fix.smem_start);
-   disp[con].visual = fix.visual;
-   disp[con].type = fix.type;
-   disp[con].type_aux = fix.type_aux;
-   disp[con].ypanstep = fix.ypanstep;
-   disp[con].ywrapstep = fix.ywrapstep;
-   disp[con].can_soft_blank = 1;
-   disp[con].inverse = 0;
-   disp[con].line_length = fix.line_length;
-}
-  
-unsigned long dn_fb_init(unsigned long mem_start) {
-
-	int err;
-       
-printk("dn_fb_init\n");
-
-	fb_info.changevar=NULL;
-	strcpy(&fb_info.modename[0],dn_fb_name);
-	fb_info.fontname[0]=0;
-	fb_info.disp=disp;
-	fb_info.switch_con=&dnfbcon_switch;
-	fb_info.updatevar=&dnfbcon_updatevar;
-	fb_info.blank=&dnfbcon_blank;	
-	fb_info.node = -1;
-	fb_info.fbops = &dn_fb_ops;
-	fb_info.fbvar = dn_fb_predefined;
-	fb_info.fbvar_num = NUM_TOTAL_MODES;
-	
-printk("dn_fb_init: register\n");
-	err=register_framebuffer(&fb_info);
-	if(err < 0) {
-		panic("unable to register apollo frame buffer\n");
-	}
- 
-	/* now we have registered we can safely setup the hardware */
-
-        outb(RESET_CREG, AP_CONTROL_3A);
-        outw(0x0, AP_WRITE_ENABLE);
-        outb(NORMAL_MODE,AP_CONTROL_0); 
-        outb((AD_BLT | DST_EQ_SRC | NORM_CREG1), AP_CONTROL_1);
-        outb(S_DATA_PLN, AP_CONTROL_2);
-        outw(SWAP(0x3),AP_ROP_1);
-
-        printk("apollo frame buffer alive and kicking !\n");
-
-	
-        dn_fb_get_var(&disp[0].var,0);
-
-	dn_fb_set_disp(-1);
-
-	return mem_start;
-
-}	
-
-	
-static int dnfbcon_switch(int con) { 
-
-	currcon=con;
-	
-	return 0;
-
-}
-
-static int dnfbcon_updatevar(int con) {
-
-	return 0;
-
-}
-
-static void dnfbcon_blank(int blank) {
-
-	printk("dnfbcon_blank: %d\n",blank);
-	if(blank)  {
-        	outb(0, AP_CONTROL_3A);
-		outb((AD_BLT | DST_EQ_SRC | NORM_CREG1) & ~ENAB_DISP,
-		     AP_CONTROL_1);
-	}
-	else {
-	        outb(1, AP_CONTROL_3A);
-        	outb((AD_BLT | DST_EQ_SRC | NORM_CREG1), AP_CONTROL_1);
-	}
-
-	return ;
-
-}
-
-void dn_video_setup(char *options, int *ints) {
-	
-	return;
-
-}
-
--- m68k-2.1.72/drivers/video/dnfb.c.orig	Wed Dec 17 23:54:42 1997
+++ m68k-2.1.72/drivers/video/dnfb.c	Wed Dec 17 23:56:07 1997
@@ -0,0 +1,361 @@
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/apollohw.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+
+/* apollo video HW definitions */
+
+/*
+ * Control Registers.   IOBASE + $x
+ *
+ * Note: these are the Memory/IO BASE definitions for a mono card set to the
+ * alternate address
+ *
+ * Control 3A and 3B serve identical functions except that 3A
+ * deals with control 1 and 3b deals with Color LUT reg.
+ */
+
+#define AP_IOBASE       0x5d80          /* Base address of 1 plane board. */
+#define AP_STATUS       0x5d80          /* Status register.  Read */
+#define AP_WRITE_ENABLE 0x5d80          /* Write Enable Register Write */
+#define AP_DEVICE_ID    0x5d81          /* Device ID Register. Read */
+#define AP_ROP_1        0x5d82          /* Raster Operation reg. Write Word */
+#define AP_DIAG_MEM_REQ 0x5d84          /* Diagnostic Memory Request. Write Word */
+#define AP_CONTROL_0    0x5d88          /* Control Register 0.  Read/Write */
+#define AP_CONTROL_1    0x5d8a          /* Control Register 1.  Read/Write */
+#define AP_CONTROL_3A   0x5d8e          /* Control Register 3a. Read/Write */
+#define AP_CONTROL_2    0x5d8c          /* Control Register 2. Read/Write */
+
+
+#define FRAME_BUFFER_START 0x0FA0000
+#define FRAME_BUFFER_LEN 0x40000
+
+/* CREG 0 */
+#define VECTOR_MODE 0x40 /* 010x.xxxx */
+#define DBLT_MODE   0x80 /* 100x.xxxx */
+#define NORMAL_MODE 0xE0 /* 111x.xxxx */
+#define SHIFT_BITS  0x1F /* xxx1.1111 */
+        /* other bits are Shift value */
+
+/* CREG 1 */
+#define AD_BLT      0x80 /* 1xxx.xxxx */
+#define NORMAL      0x80 /* 1xxx.xxxx */   /* What is happening here ?? */
+#define INVERSE     0x00 /* 0xxx.xxxx */   /* Clearing this reverses the screen */
+#define PIX_BLT     0x00 /* 0xxx.xxxx */
+
+#define AD_HIBIT        0x40 /* xIxx.xxxx */
+
+#define ROP_EN          0x10 /* xxx1.xxxx */
+#define DST_EQ_SRC      0x00 /* xxx0.xxxx */
+#define nRESET_SYNC     0x08 /* xxxx.1xxx */
+#define SYNC_ENAB       0x02 /* xxxx.xx1x */
+
+#define BLANK_DISP      0x00 /* xxxx.xxx0 */
+#define ENAB_DISP       0x01 /* xxxx.xxx1 */
+
+#define NORM_CREG1      (nRESET_SYNC | SYNC_ENAB | ENAB_DISP) /* no reset sync */
+
+/* CREG 2 */
+
+/*
+ * Following 3 defines are common to 1, 4 and 8 plane.
+ */
+
+#define S_DATA_1s   0x00 /* 00xx.xxxx */ /* set source to all 1's -- vector drawing */
+#define S_DATA_PIX  0x40 /* 01xx.xxxx */ /* takes source from ls-bits and replicates over 16 bits */
+#define S_DATA_PLN  0xC0 /* 11xx.xxxx */ /* normal, each data access =16-bits in
+ one plane of image mem */
+
+/* CREG 3A/CREG 3B */
+#       define RESET_CREG 0x80 /* 1000.0000 */
+
+/* ROP REG  -  all one nibble */
+/*      ********* NOTE : this is used r0,r1,r2,r3 *********** */
+#define ROP(r2,r3,r0,r1) ( (U_SHORT)((r0)|((r1)<<4)|((r2)<<8)|((r3)<<12)) )
+#define DEST_ZERO               0x0
+#define SRC_AND_DEST    0x1
+#define SRC_AND_nDEST   0x2
+#define SRC                             0x3
+#define nSRC_AND_DEST   0x4
+#define DEST                    0x5
+#define SRC_XOR_DEST    0x6
+#define SRC_OR_DEST             0x7
+#define SRC_NOR_DEST    0x8
+#define SRC_XNOR_DEST   0x9
+#define nDEST                   0xA
+#define SRC_OR_nDEST    0xB
+#define nSRC                    0xC
+#define nSRC_OR_DEST    0xD
+#define SRC_NAND_DEST   0xE
+#define DEST_ONE                0xF
+
+#define SWAP(A) ((A>>8) | ((A&0xff) <<8))
+
+#if 0
+#define outb(a,d) *(char *)(a)=(d)
+#define outw(a,d) *(unsigned short *)a=d
+#endif
+
+
+/* frame buffer operations */
+
+static int dnfb_open(int fbidx);
+static int dnfb_release(int fbidx);
+static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
+static int dnfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int dnfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int dnfb_get_cmap(struct fb_cmap *cmap,int kspc,int con, int fbidx);
+static int dnfb_set_cmap(struct fb_cmap *cmap,int kspc,int con, int fbidx);
+static int dnfb_pan_display(struct fb_var_screeninfo *var, int con,
+			     int fbidx);
+static int dnfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       int fbidx);
+
+static int dnfbcon_switch(int con);
+static int dnfbcon_updatevar(int con);
+static void dnfbcon_blank(int blank);
+
+static void dnfb_set_disp(int con);
+
+static struct display disp[MAX_NR_CONSOLES];
+static struct fb_info fb_info;
+static struct fb_ops dnfb_ops = { 
+	dnfb_open,dnfb_release, dnfb_get_fix, dnfb_get_var, dnfb_set_var,
+	dnfb_get_cmap, dnfb_set_cmap, dnfb_pan_display, dnfb_ioctl
+};
+
+static int currcon=0;
+
+static char dnfb_name[]="Apollo";
+
+static int dnfb_open(int fbidx)
+{
+        /*
+         * Nothing, only a usage count for the moment
+         */
+
+        MOD_INC_USE_COUNT;
+        return(0);
+}
+
+static int dnfb_release(int fbidx)
+{
+        MOD_DEC_USE_COUNT;
+        return(0);
+}
+
+static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id,"Apollo Mono");
+	fix->smem_start=(char*)(FRAME_BUFFER_START+IO_BASE);
+	fix->smem_len=FRAME_BUFFER_LEN;
+	fix->type=FB_TYPE_PACKED_PIXELS;
+	fix->type_aux=0;
+	fix->visual=FB_VISUAL_MONO10;
+	fix->xpanstep=0;
+	fix->ypanstep=0;
+	fix->ywrapstep=0;
+        fix->line_length=256;
+
+	return 0;
+
+}
+        
+static int dnfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+	var->xres=1280;
+	var->yres=1024;
+	var->xres_virtual=2048;
+	var->yres_virtual=1024;
+	var->xoffset=0;
+	var->yoffset=0;
+	var->bits_per_pixel=1;
+	var->grayscale=0;
+	var->nonstd=0;
+	var->activate=0;
+	var->height=-1;
+	var->width=-1;
+	var->pixclock=0;
+	var->left_margin=0;
+	var->right_margin=0;
+	var->hsync_len=0;
+	var->vsync_len=0;
+	var->sync=0;
+	var->vmode=FB_VMODE_NONINTERLACED;
+	var->accel=FB_ACCEL_NONE;
+
+	return 0;
+
+}
+
+static int dnfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+	if(var->xres!=1280) 
+		return -EINVAL;
+	if(var->yres!=1024)
+		return -EINVAL;
+	if(var->xres_virtual!=2048)
+		return -EINVAL;
+	if(var->yres_virtual!=1024)
+		return -EINVAL;
+	if(var->xoffset!=0)
+		return -EINVAL;
+	if(var->yoffset!=0)
+		return -EINVAL;
+	if(var->bits_per_pixel!=1)
+		return -EINVAL;
+	if(var->grayscale!=0)
+		return -EINVAL;
+	if(var->nonstd!=0)
+		return -EINVAL;
+	if(var->activate!=0)
+		return -EINVAL;
+	if(var->pixclock!=0)
+		return -EINVAL;
+	if(var->left_margin!=0)
+		return -EINVAL;
+	if(var->right_margin!=0)
+		return -EINVAL;
+	if(var->hsync_len!=0)
+		return -EINVAL;
+	if(var->vsync_len!=0)
+		return -EINVAL;
+	if(var->sync!=0)
+		return -EINVAL;
+	if(var->vmode!=FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+	if(var->accel!=FB_ACCEL_NONE)
+		return -EINVAL;
+
+	return 0;
+
+}
+
+static int dnfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+{
+	printk("get cmap not supported\n");
+
+	return -EINVAL;
+}
+
+static int dnfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+{
+	printk("set cmap not supported\n");
+
+	return -EINVAL;
+
+}
+
+static int dnfb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+	printk("panning not supported\n");
+
+	return -EINVAL;
+
+}
+
+static int dnfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con, int fbidx)
+{
+	return -EINVAL;
+}
+
+static void dnfb_set_disp(int con)
+{
+  struct fb_fix_screeninfo fix;
+
+  /* ### FN: Needs fixes later */
+  dnfb_get_fix(&fix, con, 0);
+  if(con==-1) 
+    con=0;
+
+   disp[con].screen_base = (u_char *)fix.smem_start;
+   disp[con].visual = fix.visual;
+   disp[con].type = fix.type;
+   disp[con].type_aux = fix.type_aux;
+   disp[con].ypanstep = fix.ypanstep;
+   disp[con].ywrapstep = fix.ywrapstep;
+   disp[con].can_soft_blank = 1;
+   disp[con].inverse = 0;
+   disp[con].line_length = fix.line_length;
+}
+  
+unsigned long dnfb_init(unsigned long mem_start)
+{
+	int err;
+       
+	fb_info.changevar=NULL;
+	strcpy(&fb_info.modename[0],dnfb_name);
+	fb_info.fontname[0]=0;
+	fb_info.disp=disp;
+	fb_info.switch_con=&dnfbcon_switch;
+	fb_info.updatevar=&dnfbcon_updatevar;
+	fb_info.blank=&dnfbcon_blank;	
+	fb_info.node = -1;
+	fb_info.fbops = &dnfb_ops;
+	
+	err=register_framebuffer(&fb_info);
+	if(err < 0) {
+		panic("unable to register apollo frame buffer\n");
+	}
+ 
+	/* now we have registered we can safely setup the hardware */
+
+        outb(RESET_CREG, AP_CONTROL_3A);
+        outw(0x0, AP_WRITE_ENABLE);
+        outb(NORMAL_MODE,AP_CONTROL_0); 
+        outb((AD_BLT | DST_EQ_SRC | NORM_CREG1), AP_CONTROL_1);
+        outb(S_DATA_PLN, AP_CONTROL_2);
+        outw(SWAP(0x3),AP_ROP_1);
+
+        printk("apollo frame buffer alive and kicking !\n");
+
+	
+        dnfb_get_var(&disp[0].var, 0, GET_FB_IDX(fb_info.node));
+
+	dnfb_set_disp(-1);
+
+	return mem_start;
+
+}	
+
+	
+static int dnfbcon_switch(int con)
+{ 
+	currcon=con;
+	
+	return 0;
+
+}
+
+static int dnfbcon_updatevar(int con)
+{
+	return 0;
+}
+
+static void dnfbcon_blank(int blank)
+{
+	if(blank)  {
+        	outb(0, AP_CONTROL_3A);
+		outb((AD_BLT | DST_EQ_SRC | NORM_CREG1) & ~ENAB_DISP,
+		     AP_CONTROL_1);
+	}
+	else {
+	        outb(1, AP_CONTROL_3A);
+        	outb((AD_BLT | DST_EQ_SRC | NORM_CREG1), AP_CONTROL_1);
+	}
+}
--- m68k-2.1.72/drivers/video/fbcon-mach64.c.orig	Wed Dec 17 23:55:26 1997
+++ m68k-2.1.72/drivers/video/fbcon-mach64.c	Wed Dec 17 23:56:19 1997
@@ -0,0 +1,520 @@
+/*
+ *  linux/drivers/video/fbcon-mach64.c -- Low level frame buffer operations for 
+ *					  Ati Mach64 (accelerated)
+ *
+ *	Created 20 Jun 1997 by Bernd Harries
+ *
+ *  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/console.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/fb.h>
+
+#include "fbcon.h"
+#include "fbcon-mach64.h"
+#include "mach64fb.h"
+
+/*============================================================================*/
+/* Defines */
+
+#define  _USE_HW_ACCEL_BLT_
+#define  _USE_HW_ACCEL_FILL_
+
+
+#ifdef  BHA_DEBUG
+
+#define  FuncId       if(mach64_debug & 0x00000100) printk
+#define  FuncDone     if(mach64_debug & 0x00000200) printk
+#define  CFuncId      if(mach64_debug & 0x00000400) printk
+#define  CFuncDone    if(mach64_debug & 0x00000800) printk
+
+
+/* Busy */
+#define  Bprint       if(mach64_debug & 0x01000000) printk
+/* Debug */
+#define  Dprint       if(mach64_debug & 0x00800000) printk
+
+/* Message */
+#define  Mprint       if(mach64_debug & 0x00004000) printk
+/* Info */
+#define  Iprint       if(mach64_debug & 0x00008000) printk
+/* Warn */
+#define  Wprint       if(mach64_debug & 0x00010000) printk
+/* Error */
+#define  Eprint       if(mach64_debug & 0x00020000) printk
+/* Fatal */
+#define  Fprint       if(mach64_debug & 0x00040000) printk
+/* Panic */
+#define  Pprint       if(mach64_debug & 0x00040000) printk
+
+#else
+
+#define  FuncId
+#define  FuncDone
+#define  CFuncId
+#define  CFuncDone
+
+#endif  /* BHA_DEBUG*/
+
+/*============================================================================*/
+/* Types */
+
+/*============================================================================*/
+/* Extern Functions*/
+
+
+
+/*============================================================================*/
+/* Intern Functions*/
+
+    /*
+     *  Prototypes
+     */
+
+int fbcon_init_mach64(void);
+
+static int open_mach64(struct display *p);
+static void release_mach64(void);
+static void bmove_mach64(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static void clear_mach64(struct vc_data *conp, struct display *p, int sy,
+		       int sx, int height, int width);
+static void putc_mach64(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_mach64(struct vc_data *conp, struct display *p,
+		       const char *s, int count, int yy, int xx);
+static void rev_char_mach64(struct display *p, int xx, int yy);
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Intern Variables */
+
+/*--------------------------------------------------------------------------*/
+/* BSS */
+
+/*--------------------------------------------------------------------------*/
+/* Data */
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch    dispsw_mach64 = 
+{
+  open_mach64,
+  release_mach64,
+  bmove_mach64,
+  clear_mach64,
+  putc_mach64,
+  putcs_mach64,
+  rev_char_mach64
+};
+
+
+    /*
+     *  8 bpp packed pixels => 4 pixel / 32 Bit => 1/2 FontByte 
+     */
+
+static u_int nibbletab_mach64[16] = 
+{
+  0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+  0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+  0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+  0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
+};
+
+static  unsigned int    mach64_debug = 0x018FCF00;
+
+/*============================================================================*/
+/*============================================================================*/
+/* Functions */
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+open_mach64(struct display * p)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("open_mach64($%08lX) : ", p);
+  if(p->type != FB_TYPE_PACKED_PIXELS || p->var.accel != FB_ACCEL_MACH64)
+  {
+    FuncDone(" Fail! \n");
+    return -EINVAL;  /* This driver can only do Mach64 boards! */
+  }
+  /*endif*/
+
+  p->next_line = (p->var.xres_virtual * p->var.bits_per_pixel) >> 3;
+  p->next_plane = 0;
+  MOD_INC_USE_COUNT;
+
+  FuncDone(" Match! \n");
+  return 0;
+}
+/*endproc open_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+release_mach64(void)
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("release_mach64() \n");
+    MOD_DEC_USE_COUNT;
+}
+/*endproc release_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+bmove_mach64(struct display * p,
+  int sy,
+  int sx,
+  int dy,
+  int dx,
+  int height,
+  int width)
+
+/*--------------------------------------------------------------------------*/
+{
+  u_char * src, * dst;
+  int                           bytes = p->next_line,
+                                linesize = bytes * p->fontheight,
+                                rows;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("bmove_mach64($%04X, $%04X, $%04X, $%04X) \n",
+    sy, sx, dy, dx, height, width);
+
+#ifdef _USE_HW_ACCEL_BLT_
+
+  Mach64_BitBLT(
+    (sx << 3),
+    (sy * p->fontheight),
+    (dx << 3),
+    (dy * p->fontheight),
+    (width << 3),
+    (height * p->fontheight),
+    3);                 /*  MIX_SRC); see XGCValues GCFunction = GXCopy */
+
+#else
+
+  if(sx == 0 && dx == 0 && width * 8 == bytes)   /* full stride */
+
+    mymemmove(p->screen_base + dy * linesize,
+      p->screen_base + sy * linesize,
+      height * linesize);
+
+  else if (dy < sy || (dy == sy && dx < sx))
+  {
+    src = p->screen_base + sy * linesize + sx * 8;
+    dst = p->screen_base + dy * linesize + dx * 8;
+    for (rows = height * p->fontheight ; rows-- ;)
+    {
+      mymemmove(dst, src, (width << 3));
+      src += bytes;
+      dst += bytes;
+    }
+    /*next rows*/
+  }
+  else
+  {
+    src = p->screen_base + (sy+height) * linesize + sx * 8 - bytes;
+    dst = p->screen_base + (dy+height) * linesize + dx * 8 - bytes;
+    for(rows = height * p->fontheight ; rows-- ;)
+    {
+      mymemmove(dst, src, (width << 3));
+      src -= bytes;
+      dst -= bytes;
+    }
+    /*next rows*/
+  }
+  /*endif*/
+
+#endif  /* _USE_HW_ACCEL_BLT_ */
+
+  return;
+}
+/*endproc bmove_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+clear_mach64(struct vc_data * conp,
+  struct display * p,
+  int sy,                       /* in Characters von oben */
+  int sx,
+  int height,                   /* in Characters */
+  int width)                    /* in Characters */
+
+/*--------------------------------------------------------------------------*/
+{
+  register u_int *              dest;
+  register u_int                bgx;
+  register int                  i;
+
+  u_char *                      dest0;
+
+  int                           bytes_p_line = p->next_line,
+                                lines_w = height * p->fontheight,
+                                rows;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("clear_mach64($%04X, $%04X, $%04X, $%04X) \n",
+    sy, sx, height, width);
+
+  bgx = attr_bgcol_ec(p, conp);
+  bgx |= (bgx << 8);
+  bgx |= (bgx << 16);
+
+#ifdef _USE_HW_ACCEL_FILL_
+
+  Mach64_RectFill(
+    (sx << 3),
+    (sy * p->fontheight),
+    (width << 3),
+    (height * p->fontheight),
+    3,                            /* MIX_SRC, see XGCValues GCFunction  */
+    bgx);
+
+#else
+
+  dest0 = p->screen_base + sy * p->fontheight * bytes_p_line + sx * 8;
+  if(sx == 0 && (width << 3) == bytes_p_line)     /* full stride */
+  {
+    lines_w *= width;
+    dest = (u_int*)dest0;
+    for(i = 0 ; i < lines_w ; i++)
+    {
+      *dest++ = bgx;          /* clears 4 pixels == half Char */
+      *dest++ = bgx;
+    }
+  }
+  else                                     /* only part of the width */
+  {
+    for(rows = lines_w; rows-- ; dest0 += bytes_p_line)
+    {
+      dest = (u_int*)dest0;
+      for(i = 0 ; i < width ; i++)
+      {
+        *dest++ = bgx;        /* clears 4 pixels */
+        *dest++ = bgx;
+      }
+      /*next i*/
+    }
+  }
+  /*endif*/
+
+#endif  /* _USE_HW_ACCEL_FILL_ */
+
+  return;
+}
+/*endproc clear_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+putc_mach64(struct vc_data * conp,
+  struct display * p,
+  int c,                   /* ASCII */
+  int yy,                  /* Text column */
+  int xx)                  /* Text row */
+
+/*--------------------------------------------------------------------------*/
+{
+  register u_char *             dest_p;
+  register u_char *             cdat_p;
+  register u_char               cdat;
+  register u_int                eorx, fgx, bgx;
+  int                           bytes = p->next_line; /*must be multiple of 4*/
+  int                           rows;
+
+  /*--------------------------------------------------------------------------*/
+  c &= 0xFF;
+
+  dest_p = p->screen_base + yy * p->fontheight * bytes + (xx << 3);
+  cdat_p = p->fontdata + c * p->fontheight;
+
+  fgx=attr_fgcol(p, conp);
+  bgx=attr_bgcol(p,conp);
+
+  fgx |= (fgx << 8);
+  fgx |= (fgx << 16);
+  bgx |= (bgx << 8);
+  bgx |= (bgx << 16);
+  eorx = fgx ^ bgx;
+
+  /* Mach64_WaitBlit(); */    /* We will have to sync with HW Blit */
+  for(rows = p->fontheight ; rows-- ; dest_p += bytes) /* byte* add = natural */
+  {
+    cdat = *cdat_p++;
+    *((u_int*)dest_p) = (nibbletab_mach64[cdat >> 4] & eorx) ^ bgx;
+    ((u_int *)dest_p)[1] = (nibbletab_mach64[cdat & 0xF] & eorx) ^ bgx;
+  }
+  /*next row*/
+
+  return;
+}
+/*endproc putc_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+putcs_mach64(struct vc_data * conp,
+  struct display * p,
+  const char * s,
+  int count,
+  int yy,
+  int xx)
+
+/*--------------------------------------------------------------------------*/
+{
+  register u_char *             dest_p;
+  register u_char *             cdat_p;
+  register u_char               cdat;
+  register u_int                eorx, fgx, bgx;
+  u_char *                      dest0;
+  int                           bytes = p->next_line; /*must be multiple of 4*/
+  int                           rows;
+  u_char                        c;
+
+  /*--------------------------------------------------------------------------*/
+
+  dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+  fgx=attr_fgcol(p,conp);
+  bgx=attr_bgcol(p,conp);
+
+  fgx |= (fgx << 8);
+  fgx |= (fgx << 16);
+  bgx |= (bgx << 8);
+  bgx |= (bgx << 16);
+  eorx = fgx ^ bgx;
+
+  /* Mach64_WaitBlit(); */    /* We will have to sync with HW Blit */
+  while(count--)        /* character count 8 x h */
+  {
+    c = *s++;
+    cdat_p = p->fontdata + c * p->fontheight;
+
+    for(rows = p->fontheight, dest_p = dest0; rows-- ; dest_p += bytes)
+    {
+      cdat = *cdat_p++;
+      *((u_int*)dest_p) = (nibbletab_mach64[cdat >> 4] & eorx) ^ bgx;
+      ((u_int *)dest_p)[1] = (nibbletab_mach64[cdat & 0xF] & eorx) ^ bgx;
+    }
+    /*next rows*/
+    dest0 += 8;
+  }
+  /*endwhile*/
+
+  return;
+}
+/*endproc putcs_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+rev_char_mach64(struct display *p, int xx, int yy)
+
+/*--------------------------------------------------------------------------*/
+{
+    u_char *dest;
+    int bytes=p->next_line, rows;
+
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	((u_long *)dest)[0] ^= 0x0f0f0f0f;
+	((u_long *)dest)[1] ^= 0x0f0f0f0f;
+    }
+}
+/*endproc rev_char_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef MODULE
+int 
+init_module(void)
+#else
+int 
+fbcon_init_mach64(void)
+#endif
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("fbcon_init_mach64() \n");
+  /* We want to be added to the list of accelerated drivers */
+  return(fbcon_register_driver(&dispsw_mach64, 1));
+}
+/*endproc fbcon_init_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef MODULE
+void 
+cleanup_module(void)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("cleanup_module() \n");
+    fbcon_unregister_driver(&dispsw_mach64);
+}
+/*endproc cleanup_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+#endif /* MODULE */
+/*============================================================================*/
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+  static char
+  rcs_id_c[] =
+    "@(#) Linux-m68k: 1997 10 05 14:53:32 BHA: fbcon-mach64.c ";
+
+  static char
+  rcs_id_h[] = FBCON_MACH64_H_ID;
+
+/*============================================================================*/
--- m68k-2.1.72/drivers/video/fbcon-mach64.h.orig	Wed Dec 17 23:55:36 1997
+++ m68k-2.1.72/drivers/video/fbcon-mach64.h	Wed Dec 17 23:56:26 1997
@@ -0,0 +1,31 @@
+
+
+#ifndef _FBCON_MACH64_H_LOADED_
+#define _FBCON_MACH64_H_LOADED_
+
+
+
+
+
+
+
+/*============================================================================*/
+	/*
+	 * Support for Graphics Boards
+	 */
+
+#ifdef CONFIG_FBCON_MACH64			/* ATI Mach 64 */
+
+int fbcon_init_mach64(void);
+
+#endif /* CONFIG_FBCON_MACH64 */	
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define FBCON_MACH64_H_ID \
+  "@(#) Linux-m68k: 1997 06 25 17:34:18 BHA: fbcon-mach64.h "
+
+/*============================================================================*/
+
+#endif /* _FBCON_MACH64_H_LOADED_ */
--- m68k-2.1.72/drivers/video/fbcon.c.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/fbcon.c	Wed Dec 17 23:55:40 1997
@@ -42,6 +42,7 @@
  *
  *	  o cyber	 CyberVision64 packed pixels (accelerated)
  *	  o retz3	 Retina Z3 packed pixels (accelerated)
+ *	  o mach64	 ATI Mach 64 packed pixels (accelerated)
  *
  *  To do:
  *
@@ -55,6 +56,8 @@
  *  more details.
  */
 
+#define SUPPORT_SCROLLBACK	0
+#define FLASHING_CURSOR		1
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -75,10 +78,7 @@
 #include <linux/kerneld.h>
 #endif
 
-#include <asm/setup.h>
 #include <asm/irq.h>
-#include <asm/font.h>
-#include <asm/machdep.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #ifdef CONFIG_AMIGA
@@ -88,9 +88,14 @@
 #ifdef CONFIG_ATARI
 #include <asm/atariints.h>
 #endif
+#ifdef __mc68000__
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#endif
 #include <asm/linux_logo.h>
 
 #include "fbcon.h"
+#include "font.h"
 
 
 struct display fb_display[MAX_NR_CONSOLES];
@@ -99,6 +104,7 @@
 /* ++Geert: Sorry, no hardware cursor support at the moment;
    use Atari alike software cursor */
 
+#if FLASHING_CURSOR
 static int cursor_drawn = 0;
 
 #define CURSOR_DRAW_DELAY		(2)
@@ -106,6 +112,7 @@
 /* # VBL ints between cursor state changes */
 #define AMIGA_CURSOR_BLINK_RATE		(20)
 #define ATARI_CURSOR_BLINK_RATE		(42)
+#define DEFAULT_CURSOR_BLINK_RATE	(20)
 
 static int vbl_cursor_cnt = 0;
 static int cursor_on = 0;
@@ -119,6 +126,7 @@
     cursor_drawn = 0;
     return(cursor_was_drawn);
 }
+#endif
 
 /*
  *  Scroll Method
@@ -155,6 +163,7 @@
 static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
 static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data);
 static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
+static int fbcon_scrolldelta(int lines);
 int fbcon_register_driver(struct display_switch *dispsw, int is_accel);
 int fbcon_unregister_driver(struct display_switch *dispsw);
 
@@ -165,10 +174,19 @@
 
 static void fbcon_setup(int con, int setcol, int init);
 static __inline__ int real_y(struct display *p, int ypos);
+#if FLASHING_CURSOR
 static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
+#endif
 static __inline__ void updatescrollmode(struct display *p);
+#if SUPPORT_SCROLLBACK
+static __inline__ void ywrap_up(int unit, struct vc_data *conp,
+				struct display *p, int count);
+static __inline__ void ywrap_down(int unit, struct vc_data *conp,
+				  struct display *p, int count);
+#else
 static __inline__ void ywrap_up(int unit, struct display *p, int count);
 static __inline__ void ywrap_down(int unit, struct display *p, int count);
+#endif
 static __inline__ void ypan_up(int unit, struct vc_data *conp,
 			       struct display *p, int count);
 static __inline__ void ypan_down(int unit, struct vc_data *conp,
@@ -184,6 +202,22 @@
 static struct display_switch *fbcon_get_driver(struct display *disp);
 static int fbcon_show_logo(void);
 
+#if FLASHING_CURSOR
+static void cursor_timer_handler(unsigned long dev_addr);
+
+static struct timer_list cursor_timer = {
+    NULL, NULL, 0, 0L, cursor_timer_handler
+};
+
+static void cursor_timer_handler(unsigned long dev_addr)
+{
+      fbcon_vbl_handler(0, NULL, NULL);
+      cursor_timer.expires = jiffies+2;
+      cursor_timer.data = 0;
+      cursor_timer.next = cursor_timer.next = NULL;
+      add_timer(&cursor_timer);
+}
+#endif
 
 /*
  *  Low Level Operations
@@ -215,14 +249,21 @@
 #ifdef CONFIG_FBCON_CFB16
 extern int fbcon_init_cfb16(void);
 #endif
+#ifdef CONFIG_FBCON_CFB24
+extern int fbcon_init_cfb24(void);
+#endif
+#ifdef CONFIG_FBCON_CFB32
+extern int fbcon_init_cfb32(void);
+#endif
 #ifdef CONFIG_FBCON_CYBER
 extern int fbcon_init_cyber(void);
 #endif
 #ifdef CONFIG_FBCON_RETINAZ3
 extern int fbcon_init_retz3(void);
 #endif
-
-extern int num_registered_fb;
+#ifdef CONFIG_FBCON_MACH64
+extern int fbcon_init_mach64(void);
+#endif
 
 __initfunc(static unsigned long fbcon_startup(unsigned long kmem_start,
 					      const char **display_desc))
@@ -264,16 +305,17 @@
     fbcon_init_cfb16();
 #endif
 #ifdef CONFIG_FBCON_CFB24
-    /* Not yet implemented */
-    fbcon_init_24_packed();
+    fbcon_init_cfb24();
 #endif
 #ifdef CONFIG_FBCON_CFB32
-    /* Not yet implemented */
-    fbcon_init_32_packed();
+    fbcon_init_cfb32();
 #endif
 #ifdef CONFIG_FBCON_CYBER
     fbcon_init_cyber();
 #endif
+#ifdef CONFIG_FBCON_MACH64
+    fbcon_init_mach64();
+#endif
 
     *display_desc = "frame buffer device";
 
@@ -291,19 +333,13 @@
 			     "console/cursor", fbcon_vbl_handler);
     }
 #endif /* CONFIG_ATARI */
-#ifdef CONFIG_APOLLO
-   if(MACH_IS_APOLLO) {
-   	cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
-   	cursor_timer.expires=jiffies+2;
-   	cursor_timer.data=0;
-   	cursor_timer.next=cursor_timer.prev=NULL;
-   	add_timer(&cursor_timer);
-   	irqres=0;
-   }
-#endif /* CONFIG_APOLLO */
-
-    if (irqres)
-	panic("fbcon_startup: Couldn't add vblank interrupt");
+    if (irqres) {
+	cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
+	cursor_timer.expires = jiffies+2;
+	cursor_timer.data = 0;
+	cursor_timer.next = cursor_timer.prev = NULL;
+	add_timer(&cursor_timer);
+    }
 
     if (!console_show_logo)
 	console_show_logo = fbcon_show_logo;
@@ -547,6 +583,7 @@
 }
 
 
+#if FLASHING_CURSOR
 static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
 {
     struct display *p;
@@ -564,9 +601,19 @@
 	vbl_cursor_cnt = cursor_blink_rate;
     }
 }
+#endif
 
+#if SUPPORT_SCROLLBACK
+static int scrollback_max = 0;
+static int scrollback_current = 0;
+#endif
 
+#if SUPPORT_SCROLLBACK
+static __inline__ void ywrap_up(int unit, struct vc_data *conp,
+				struct display *p, int count)
+#else
 static __inline__ void ywrap_up(int unit, struct display *p, int count)
+#endif
 {
     p->yscroll += count;
     if (p->yscroll >= p->vrows)	/* Deal with wrap */
@@ -575,10 +622,21 @@
     p->var.yoffset = p->yscroll*p->fontheight;
     p->var.vmode |= FB_VMODE_YWRAP;
     p->fb_info->updatevar(unit);
+#if SUPPORT_SCROLLBACK
+    scrollback_max += count;
+    if (scrollback_max > p->vrows-conp->vc_rows)
+	scrollback_max = p->vrows-conp->vc_rows;
+    scrollback_current = 0;
+#endif
 }
 
 
+#if SUPPORT_SCROLLBACK
+static __inline__ void ywrap_down(int unit, struct vc_data *conp,
+				  struct display *p, int count)
+#else
 static __inline__ void ywrap_down(int unit, struct display *p, int count)
+#endif
 {
     p->yscroll -= count;
     if (p->yscroll < 0)		/* Deal with wrap */
@@ -587,6 +645,12 @@
     p->var.yoffset = p->yscroll*p->fontheight;
     p->var.vmode |= FB_VMODE_YWRAP;
     p->fb_info->updatevar(unit);
+#if SUPPORT_SCROLLBACK
+    scrollback_max -= count;
+    if (scrollback_max < 0)
+	scrollback_max = 0;
+    scrollback_current = 0;
+#endif
 }
 
 
@@ -647,7 +711,11 @@
 			    if (t > 0)
 				fbcon_bmove(conp, 0, 0, count, 0, t,
 					    conp->vc_cols);
+#if SUPPORT_SCROLLBACK
+			    ywrap_up(unit, conp, p, count);
+#else
 			    ywrap_up(unit, p, count);
+#endif
 			    if (conp->vc_rows-b > 0)
 				fbcon_bmove(conp, b-count, 0, b, 0,
 					    conp->vc_rows-b, conp->vc_cols);
@@ -674,7 +742,7 @@
 
 		    case SCROLL_YMOVE:
 			p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
-			conp->vc_cols);
+					 conp->vc_cols);
 			p->dispsw->clear(conp, p, b-count, 0, count,
 					 conp->vc_cols);
 			break;
@@ -695,7 +763,11 @@
 			    if (conp->vc_rows-b > 0)
 				fbcon_bmove(conp, b, 0, b-count, 0,
 					    conp->vc_rows-b, conp->vc_cols);
+#if SUPPORT_SCROLLBACK
+			    ywrap_down(unit, conp, p, count);
+#else
 			    ywrap_down(unit, p, count);
+#endif
 			    if (t > 0)
 				fbcon_bmove(conp, count, 0, 0, 0, t,
 					    conp->vc_cols);
@@ -821,6 +893,10 @@
 
     if (info && info->switch_con)
 	(*info->switch_con)(conp->vc_num);
+#if SUPPORT_SCROLLBACK
+    scrollback_max = 0;
+    scrollback_current = 0;
+#endif
     return(0);
 }
 
@@ -1000,13 +1076,47 @@
     palette_cmap.len = 1<<p->var.bits_per_pixel;
     if (palette_cmap.len > 16)
 	palette_cmap.len = 16;
-    return(p->fb_info->setcmap(&palette_cmap, unit));
+    return(p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit,
+					  con2fb_map[unit]));
 }
 
+static int fbcon_scrolldelta(int lines)
+{
+#if SUPPORT_SCROLLBACK
+    int unit = fg_console; /* xxx */
+    struct display *p = &fb_display[unit];
+    int offset;
+
+    if (!p->can_soft_blank && console_blanked ||
+	vt_cons[unit]->vc_mode != KD_TEXT || !lines ||
+	p->scrollmode != SCROLL_YWRAP)
+	return 0;
+
+    fbcon_cursor(conp, CM_ERASE);
+
+    scrollback_current -= lines;
+    if (scrollback_current < 0)
+	scrollback_current = 0;
+    else if (scrollback_current > scrollback_max)
+	scrollback_current = scrollback_max;
+
+    offset = p->yscroll-scrollback_current;
+    if (offset < 0)
+	offset += p->vrows;
+    else if (offset > p->vrows)
+	offset -= p->vrows;
+    p->var.vmode |= FB_VMODE_YWRAP;
+    p->var.xoffset = 0;
+    p->var.yoffset = offset*p->fontheight;
+    p->fb_info->updatevar(unit);
+#else
+    return -ENOSYS;
+#endif
+}
 
 
-#define LOGO_H		80
-#define LOGO_W		80
+#define LOGO_H			80
+#define LOGO_W			80
 #define LOGO_LINE	(LOGO_W/8)
 
 __initfunc(static int fbcon_show_logo( void ))
@@ -1055,7 +1165,8 @@
 		palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];
 		palette_cmap.blue[j]  = (blue[i+j] << 8) | blue[i+j];
 	    }
-	    p->fb_info->setcmap( &palette_cmap, fg_console );
+	    p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
+					   con2fb_map[fg_console]);
 	}
 	fb_display[fg_console].cmap.len = old_cmap_len;
     }
@@ -1204,7 +1315,8 @@
 struct consw fb_con = {
     fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc,
     fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch,
-    fbcon_blank, fbcon_get_font, fbcon_set_font, fbcon_set_palette
+    fbcon_blank, fbcon_get_font, fbcon_set_font, fbcon_set_palette,
+    fbcon_scrolldelta
 };
 
 
--- m68k-2.1.72/drivers/video/font.h.orig	Wed Dec 17 23:54:53 1997
+++ m68k-2.1.72/drivers/video/font.h	Thu Dec 18 00:15:52 1997
@@ -0,0 +1,35 @@
+/*
+ *  font.h -- `Soft' font definitions
+ *
+ *  Created 1995 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.
+ */
+
+#ifndef _FONT_H_
+#define _FONT_H_
+
+#include <linux/types.h>
+
+
+   /*
+    *    Find a font with a specific name
+    */
+
+extern int findsoftfont(char *name, int *width, int *height, u_char *data[]);
+
+
+   /*
+    *    Get the default font for a specific screen size
+    */
+
+extern void getdefaultfont(int xres, int yres, char *name[], int *width,
+                           int *height, u_char *data[]);
+
+
+/* Max. length for the name of a predefined font */
+#define MAX_FONT_NAME	32
+
+#endif /* _FONT_H_ */
--- m68k-2.1.72/drivers/video/fonts.c.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/fonts.c	Wed Dec 17 23:55:40 1997
@@ -11,8 +11,10 @@
 
 #include <linux/types.h>
 #include <linux/string.h>
+#ifdef __mc68000__
 #include <asm/setup.h>
-#include <asm/font.h>
+#endif
+#include "font.h"
 
 
    /*
@@ -91,9 +93,13 @@
 {
     int i;
     
-    if (yres < 400)
-	i = MACH_IS_AMIGA ? PEARL8x8_IDX : VGA8x8_IDX;
-    else
+    if (yres < 400) {
+	i = VGA8x8_IDX;
+#ifdef CONFIG_AMIGA
+	if (MACH_IS_AMIGA)
+	    i = PEARL8x8_IDX;
+#endif
+    } else
 	i = VGA8x16_IDX;
 
     if (name)
--- m68k-2.1.72/drivers/video/mach64fb.c.orig	Wed Dec 17 23:54:15 1997
+++ m68k-2.1.72/drivers/video/mach64fb.c	Wed Dec 17 23:56:36 1997
@@ -0,0 +1,2507 @@
+/*
+ * linux/drivers/video/mach64fb.c -- Low level implementation of the
+ *                                   ATI Mach64 frame buffer device
+ *
+ *    Copyright (C) 1997 Bernd Harries
+ *
+ *
+ * This file is based on the Atari frame buffer device (atafb.c):
+ *
+ *  Copyright (C) 1994 Martin Schaller & Roman Hodek
+ *  
+ *
+ * and the Amiga frame buffer device (amifb.c):
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * History:
+ *   - 09 Aug 97: Original version by Bernd Harries
+ *   - 27 Aug 97: Extra Parameter for GUIreg-Base for Panther 64
+ *   - 03 Oct 97: Minor changes by Bernd Harries
+ *
+ *
+ * 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.
+ */
+
+/*============================================================================*/
+/* Includes */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/zorro.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+
+#include "mach64regs.h"
+
+#include "mach64fb.h"
+
+
+unsigned long mach64fb_init(unsigned long mem_start);
+void mach64fb_setup(char *options, int *ints);
+
+/*============================================================================*/
+/* Defines */
+
+#define _NOT_MAP_768K_IO_
+
+#define _MAP_GUIREGS_0BFC00_
+
+
+#define _NOT_DUMP_IO_REGS_
+
+#define _NOT_DUMP_GUIREGS_0BFC00_
+
+#define _NOT_DUMP_GUIREGS_3FFC00_
+
+#define _NOT_DUMP_KMAP_RANGE_
+
+
+#ifdef MULTI_MACH
+
+#define MACH_MAX 8
+
+#define DECLARE_STATIC_UINT08___MN_  static unsigned char          m64_num;
+#define DECLARE_UINT08___MN_         unsigned char m64_num;
+#define ARG_UINT08___MN_             unsigned char m64_num
+#define ADD_ARG_UINT08___MN_         , unsigned char m64_num
+
+#define _ARRAY_       [MACH_MAX]
+#define __MN__        [m64_num]
+#define _MN_           m64_num
+#define _INC_MN_       m64_num++
+#define _ARG_MN_       m64_num
+#define _ADD_ARG_MN_   , m64_num
+
+#else      /*---------------------*/
+
+#define DECLARE_STATIC_UINT08___MN_
+#define DECLARE_UINT08___MN_
+#define ARG_UINT08___MN_           void
+#define ADD_ARG_UINT08___MN_
+
+#define _ARRAY_    
+#define __MN__         
+#define _MN_           0
+#define _INC_MN_       
+#define _ARG_MN_       
+#define _ADD_ARG_MN_   
+
+#endif     /* MULTI_MACH */
+
+/*--------------------------------------------------------------------------*/
+  
+#define MACH_MAX 8
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+#define  FuncId       if(mach64fb_debug & 0x00000100) printk
+#define  FuncDone     if(mach64fb_debug & 0x00000200) printk
+#define  CFuncId      if(mach64fb_debug & 0x00000400) printk
+#define  CFuncDone    if(mach64fb_debug & 0x00000800) printk
+#define  OFuncId      if(mach64fb_debug & 0x00001000) printk
+#define  OFuncDone    if(mach64fb_debug & 0x00002000) printk
+
+
+/* Busy */
+#define  Bprint       if(mach64fb_debug & 0x01000000) printk
+/* Debug */
+#define  Dprint       if(mach64fb_debug & 0x00800000) printk
+
+/* Message */
+#define  Mprint       if(mach64fb_debug & 0x00004000) printk
+/* Info */
+#define  Iprint       if(mach64fb_debug & 0x00008000) printk
+/* Warn */
+#define  Wprint       if(mach64fb_debug & 0x00010000) printk
+/* Error */
+#define  Eprint       if(mach64fb_debug & 0x00020000) printk
+/* Fatal */
+#define  Fprint       if(mach64fb_debug & 0x00040000) printk
+/* Panic */
+#define  Pprint       if(mach64fb_debug & 0x00080000) printk
+
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * This Fragment is for learning and for future expansion so far:
+ *
+ * Byte swaping is probably not needed on Alpha CPUs but The IO is memory
+ * mapped anyway and writing data < 32 bit is impossible on the actual
+ * CPUs unless the board has a sparse space. 
+ *
+ * The DEC Alpha CPUs have write buffers that hold data to be written
+ * to memory. The data is NOT necessarily written to memory immediately
+ * after the instruction.
+ * Darum: The machine instruction MB (memory barrier, wbflush on Mips CPUs) 
+ * has to be executed to force the flush of these buffers, or a write
+ * instruction at least $1000 bytes apart from the access to be flushed 
+ * (may be more in future CPUs) has to follow. This can be done by using
+ * mirrored registers if available. The Mach64 GUI registers are all within
+ * 1 $1000 byte area and are not always mirrored. => MB instruction. 
+ *
+ */
+
+#ifdef __alpha__
+
+#define barrier() __asm__ __volatile__("mb": : :"memory")
+
+#else /* __alpha__ */
+
+#ifdef __mips
+
+#define barrier() __asm__ __volatile__ ("wbflush": : :"memory")
+
+#else
+/*
+#define barrier()  / * Serialized Nocaching => Not used on 680x0 today  * /
+*/
+#endif /* __mips__ */
+#endif /* __alpha__ */
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef _MAP_768K_IO_
+
+#define OUTB(port,val) \
+  *((unsigned volatile char *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )) = (val)
+
+#define INB(port) \
+  (*((unsigned volatile char *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )))
+
+/*
+#define OUTL(port,val) \
+  *((unsigned volatile int *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )) = (val)
+
+#define INL(port) \
+  (*((unsigned volatile int *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )))
+*/
+
+#else
+
+#define OUTB(port,val) \
+  *((unsigned volatile char *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+#define INB(port) \
+  (*((unsigned volatile char *) ((port) + virt_vgaiobase __MN__  )))
+
+/*
+#define OUTL(port,val) \
+  *((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+#define INL(port) \
+  (*((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )))
+*/
+
+#endif  /* _MAP_768K_IO_ */
+
+#define DACDelay                    \
+  do {                              \
+    unsigned char tmp = INB(0x3da); \
+    tmp = INB(0x3da);               \
+  } while (0)
+
+/*============================================================================*/
+
+/*
+#define regwr(port, val) \
+  *((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+
+#define regrd(port) \
+  (*((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )))
+*/
+
+/*============================================================================*/
+/* Types */
+
+struct mach64fb_par
+{
+   int xres;
+   int yres;
+   int bpp;
+};
+
+/*============================================================================*/
+/* Extern Functions*/
+
+
+
+/*============================================================================*/
+/* Intern Functions*/
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Interface to the low level console driver exported with fb_info
+    */
+
+static int  Mach64fb_switch(int con);
+static int  Mach64fb_updatevar(int con);
+static void Mach64fb_blank(int blank);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Interface fb_ops used by the world exported with fb_info.fb_ops
+    */
+
+static int M64_op_open(int fbidx);
+static int M64_op_release(int fbidx);
+static int M64_op_get_fix(struct fb_fix_screeninfo * fix, int con, int fbidx);
+static int M64_op_get_var(struct fb_var_screeninfo * var, int con, int fbidx);
+static int M64_op_set_var(struct fb_var_screeninfo * var, int con, int fbidx);
+static int M64_op_get_cmap(struct fb_cmap * cmap, int kspc, int con,
+			   int fbidx);
+static int M64_op_set_cmap(struct fb_cmap * cmap, int kspc, int con,
+			   int fbidx);
+static int M64_op_pan_display(struct fb_var_screeninfo * var, int con,
+			      int fbidx);
+
+static int 
+M64_op_ioctl(
+  struct inode * inode,
+  struct file *file,
+  u_int cmd,
+  u_long arg,
+  int con,
+  int fbidx);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *   Internal Routines
+    */
+
+static int 
+do_fb_set_var(struct fb_var_screeninfo * var, int isactive);
+
+static void 
+do_install_cmap(int con);
+
+static void 
+mach64fb_set_disp(int con);
+
+static int 
+get_video_mode(const char * name);
+
+static int 
+store_video_par(char* videopar  ADD_ARG_UINT08___MN_ );
+
+static char * 
+strtoke(char * s,const char * ct);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *   Hardware Specific Routines
+    */
+
+static int 
+M64_hw_init( ARG_UINT08___MN_ );
+
+static int 
+M64_hw_encode_fix(struct fb_fix_screeninfo * fix, struct mach64fb_par * par);
+
+static int 
+M64_hw_decode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+
+static int 
+M64_hw_encode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+
+static void 
+M64_hw_get_par(struct mach64fb_par * par);
+
+static void 
+M64_hw_set_par(struct mach64fb_par * par);
+
+static int 
+M64_hw_getcolreg(
+  u_int regno,
+  u_int * red,
+  u_int * green,
+  u_int * blue,
+  u_int * transp);
+
+static int 
+M64_hw_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp);
+
+static void 
+M64_hw_blank(int blank);
+
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Intern Variables */
+
+/*--------------------------------------------------------------------------*/
+/* BSS */
+
+
+static unsigned long            phys_vmembase _ARRAY_ ;
+static unsigned long            phys_size _ARRAY_ ;
+static unsigned long            phys_vgaiobase _ARRAY_ ;
+static unsigned long            phys_guiregbase _ARRAY_ ;
+
+static unsigned long            virt_vmembase _ARRAY_ ;
+static unsigned long            virt_size _ARRAY_ ;
+static unsigned long            virt_vgaiobase _ARRAY_ ;
+static unsigned long            virt_guiregbase _ARRAY_ ;
+
+static unsigned int             mach64_xres _ARRAY_ ;
+static unsigned int             mach64_yres _ARRAY_ ;
+static unsigned int             mach64_depth _ARRAY_ ;
+
+
+static struct mach64fb_par     current_par _ARRAY_ ;
+static struct display           m_disp _ARRAY_ ;
+static struct fb_info           fb_info _ARRAY_ ;
+
+static u_short                  mach64_colormap  _ARRAY_ [256][4];
+
+static u_int                    mach64_key;
+static u_int                    mach64_bitspercol _ARRAY_ ;
+
+static int                      currcon;
+
+
+static u_short                  mach64_inverse _ARRAY_ ;
+static short int                mach64_pmode _ARRAY_ ;
+static short int                mach64_mode _ARRAY_ ;   /* 0..31 */
+static short int                mach64_use_accel _ARRAY_ ;
+static char                     current_par_valid _ARRAY_ ;
+
+static unsigned char            mach64_count;
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Switch for Chipset Independency
+    */
+
+static struct fb_hwswitch
+{
+
+  /* Initialisation */
+
+  int (*init)( ARG_UINT08___MN_ );
+
+  /* Display Control */
+
+  int (*encode_fix)(struct fb_fix_screeninfo * fix, struct mach64fb_par * par);
+  int (*decode_var)(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+  int (*encode_var)(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+  void (*get_par)(struct mach64fb_par * par );
+  void (*set_par)(struct mach64fb_par * par );
+  int (*getcolreg)(u_int regno, u_int * red, u_int * green, u_int * blue,
+    u_int * transp);
+  int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
+    u_int transp);
+  void (*blank)(int blank);
+  void (*set_screen_base)( unsigned long s_base );
+  int  (*pan_display)( struct fb_var_screeninfo * var);
+} 
+* fbhws_ptr;
+
+
+/*--------------------------------------------------------------------------*/
+/* Data */
+
+
+/* -------------- local Interfaces to hardware functions ---------------- */
+
+/* see XGCValues GCFunction */
+int 
+mach64alu[16] =
+{
+    MIX_0,
+    MIX_AND,
+    MIX_SRC_AND_NOT_DST,
+    MIX_SRC,
+    MIX_NOT_SRC_AND_DST,
+    MIX_DST,
+    MIX_XOR,
+    MIX_OR,
+    MIX_NOR,
+    MIX_XNOR,
+    MIX_NOT_DST,
+    MIX_SRC_OR_NOT_DST,
+    MIX_NOT_SRC,
+    MIX_NOT_SRC_OR_DST,
+    MIX_NAND,
+    MIX_1
+};
+
+static struct fb_hwswitch 
+mach64_switch = 
+{
+  M64_hw_init,
+  M64_hw_encode_fix,
+  M64_hw_decode_var,
+  M64_hw_encode_var,
+  NULL,                    /* M64_hw_get_par, */
+  NULL,                    /* M64_hw_set_par, */
+  M64_hw_getcolreg,
+  M64_hw_setcolreg,
+  M64_hw_blank,
+  NULL,
+  NULL
+};
+
+/* ------ Interfaces to hardware functions to export with fb_info  ------ */
+
+static struct fb_ops 
+mach64fb_ops =
+{
+  M64_op_open,
+  M64_op_release,
+  M64_op_get_fix,
+  M64_op_get_var,
+  M64_op_set_var,
+  M64_op_get_cmap,
+  M64_op_set_cmap,
+  M64_op_pan_display,
+  M64_op_ioctl
+};
+
+static  unsigned int    mach64fb_debug = 0x018FCF00;
+
+   /*
+    *    Frame Buffer Name
+    */
+
+static char     mach64fb_name[16] = "ATI Mach64 ";
+
+
+   /*
+    *    Ati Mach64 Graphics Board
+    */
+
+#define M64_8_WIDTH 1152
+#define M64_8_HEIGHT 912
+#define M64_8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+
+#define M64_16_WIDTH 800
+#define M64_16_HEIGHT 600
+#define M64_16_PIXCLOCK 25000   /* ++Geert: Just a guess */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Predefined Video Mode Names
+    */
+/*--------------------------------------------------------------------------*/
+
+static char *                   fb_var_names[] =
+{
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   "autodetect",
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   "Mach64_8",            /* Mach64 8 bpp */
+   "Mach64_16",           /* Mach64 16 bpp */
+};
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Predefined Video Mode Definitions
+    */
+/*--------------------------------------------------------------------------*/
+
+static struct fb_var_screeninfo mach64fb_predefined[] = 
+{
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   { 0, },
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   {
+      /* Cybervision 8 bpp */
+      M64_8_WIDTH, M64_8_HEIGHT, M64_8_WIDTH, M64_8_HEIGHT, 0, 0, 8, 0,
+      {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+      0, 0, -1, -1, FB_ACCEL_NONE, M64_8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+   }, {
+      /* Cybervision 16 bpp */
+      M64_16_WIDTH, M64_16_HEIGHT, M64_16_WIDTH, M64_16_HEIGHT, 0, 0, 16, 0,
+      {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+      0, 0, -1, -1, FB_ACCEL_NONE, M64_16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+   },
+};
+
+
+#define NUM_TOTAL_MODES    arraysize(mach64fb_predefined)
+#define NUM_PREDEF_MODES   (3)
+
+
+   /*
+    *    Some default modes
+    */
+
+#define M64_8_DEFMODE     (1)
+#define M64_16_DEFMODE    (2)
+
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Functions */
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*============================================================================*/
+
+__inline__ void 
+regwr(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regrd(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwrb(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+
+#ifdef _MAP_768K_IO_
+
+__inline__ void
+OUTL(unsigned int port, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + 0x00080000 + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+INL(unsigned int port)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + 0x00080000 + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regw(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regr(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwB(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+#else
+
+__inline__ void 
+OUTL(unsigned int port, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+INL(unsigned int port)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+
+
+__inline__ void 
+regw(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regr(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwB(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+#endif  /* _MAP_768K_IO_ */
+
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_open(int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_open(%02d) \n", fbidx);
+  /*
+   * Nothing, only a usage count for the moment
+   */
+
+  MOD_INC_USE_COUNT;
+
+  return(0);
+}
+/*endproc M64_op_open() */
+
+/*============================================================================*/
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_release(int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("M64_op_release() \n");
+  MOD_DEC_USE_COUNT;
+  return(0);
+}
+/*endproc M64_op_release() */
+
+/*============================================================================*/
+
+
+/* -------------------- Hardware specific routines ------------------------ */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Initialization
+    *
+    *    Set the default video mode for this chipset. If a video mode was
+    *    specified on the command line, it will override the default mode.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_init( ARG_UINT08___MN_ )
+
+/*--------------------------------------------------------------------------*/
+{
+  struct fb_var_screeninfo *    var_ptr = &mach64fb_predefined[0];
+  struct mach64fb_par          dummy_par;
+
+  unsigned long                 board_addr;
+  u_int *                       u32_ptr;
+  u_int                         read_val;
+  int                           n;
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("M64_hw_init() \n");
+
+  if(mach64_mode __MN__   == -1)
+  {
+    mach64_mode __MN__   = M64_8_DEFMODE;
+  }
+  /*endif*/
+
+  board_addr = virt_vmembase __MN__  ;
+  for (i = 0; i < 256; i++)
+  {
+    mach64_colormap  __MN__  [i][0] = i;
+    mach64_colormap  __MN__  [i][1] = i;
+    mach64_colormap  __MN__  [i][2] = i;
+    mach64_colormap  __MN__  [i][3] = 0;
+  }
+
+#ifdef _DUMP_IO_REGS_
+  u32_ptr = (u_int *)(0x000002EC + virt_vgaiobase __MN__ );
+  n = 0;
+  while(n < 0x20)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    u32_ptr += 0x0400;
+  }
+  /*endwhile*/
+  Dprint("\n" );
+#endif
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+  read_val = regr(GEN_TEST_CNTL);
+  if(0)
+  {
+    regw(GEN_TEST_CNTL, read_val | 0x0200);
+  }
+  else
+  {
+    regw(GEN_TEST_CNTL, read_val & ~0x0200);
+  }
+  /*endif*/
+
+  WaitQueue(13);
+  regw(SRC_OFF_PITCH, (mach64_xres __MN__  << 19));
+  regw(DST_OFF_PITCH, (mach64_xres __MN__  << 19));
+  regw(SC_LEFT_RIGHT, (mach64_xres __MN__  -1) << 16);
+  regw(SC_TOP_BOTTOM, (mach64_yres __MN__  -1) << 16);
+
+  regw(DP_BKGD_CLR, 0x00000000);
+  regw(DP_FRGD_CLR, 0x00000001);
+
+  regw(DP_WRITE_MASK, 0x000000FF  /* pGC->planemask */ );
+  regw(DP_PIX_WIDTH, BYTE_ORDER_MSB_TO_LSB | HOST_8BPP | SRC_8BPP | DST_8BPP);
+  regw(DP_MIX, FRGD_MIX_S | BKGD_MIX_D);
+  regw(DP_SRC, FRGD_SRC_BLIT | BKGD_SRC_BKGD_CLR);
+
+  regw(CLR_CMP_CNTL, 0x00000000);
+  regw(CLR_CMP_CLR, 0x00000000);
+
+  regw(GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+
+
+#ifdef  _DUMP_GUIREGS_0BFC00_
+
+#ifdef _MAP_768K_IO_
+  u32_ptr = (u_int *)(0x0003FC00 + virt_vgaiobase __MN__ );
+#else
+  u32_ptr = (u_int *)(0x0000FC00 + virt_guiregbase __MN__ );
+#endif
+  n = 0;
+  while(n < 0x100)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    u32_ptr += 4;
+  }
+  /*endwhile*/
+  Dprint("\n" );
+#endif
+
+#ifdef  _DUMP_GUIREGS_3FFC00_
+  u32_ptr = (u_int *)(0x003FFC00 + virt_vmembase __MN__ );
+  n = 0;
+  while(n < 0x100)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    u32_ptr += 4;
+  }
+  /*endwhile*/
+
+  Dprint("\n" );
+#endif
+
+
+
+  dummy_par.xres = mach64_xres __MN__  ;
+  dummy_par.yres = mach64_yres __MN__  ;
+  dummy_par.bpp = mach64_depth __MN__  ;
+  M64_hw_encode_var(var_ptr, &dummy_par);
+
+  mach64fb_debug = 0x018FC100;
+
+  M64_hw_setcolreg (255, 56, 100, 160, 0);
+  M64_hw_setcolreg (254, 0, 0, 0, 0);
+
+  FuncDone("M64_hw_init() done.\n");
+  return(1);    /* detected_mode */
+}
+/*endproc M64_hw_init() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    This function should fill in the `fix' structure based on the
+    *    values in the `par' structure.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_encode_fix(struct fb_fix_screeninfo * fix, struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_encode_fix() \n");
+
+  strcpy(fix->id, mach64fb_name);
+  fix->id[15] =  _MN_ ;
+  fix->smem_start = (caddr_t) virt_vmembase __MN__  ;
+
+  /* aufrunden */
+  fix->smem_len = (phys_size __MN__   + PAGE_SIZE - 0x00200001) & PAGE_MASK;
+
+  if(mach64_depth __MN__   == 1)
+  {
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    /* The letters 'n' and 'i' in the "video=Mach64:" stand
+     * for "normal" and "inverted", rsp., in the monochrome case */
+    fix->visual =
+      (mach64_pmode __MN__   == FB_TYPE_INTERLEAVED_PLANES ||
+      mach64_pmode __MN__   == FB_TYPE_PACKED_PIXELS) ?
+      FB_VISUAL_MONO10 : FB_VISUAL_MONO01;
+  }
+  else   /* depth > 1 */
+  {
+    switch(mach64_pmode __MN__  )
+    {
+      /* All visuals are STATIC, because we don't know how to change
+       * colors :-(
+       */
+      case -1:              /* truecolor */
+        fix->type = FB_TYPE_PACKED_PIXELS;
+        fix->visual = FB_VISUAL_TRUECOLOR;
+        break;
+      case FB_TYPE_PACKED_PIXELS:
+        fix->type = FB_TYPE_PACKED_PIXELS;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+      case FB_TYPE_PLANES:
+        fix->type = FB_TYPE_PLANES;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+      case FB_TYPE_INTERLEAVED_PLANES:
+        fix->type = FB_TYPE_INTERLEAVED_PLANES;
+        fix->type_aux = 2;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+    }
+    /*endswitch*/
+  }
+  /*endif*/
+  fix->xpanstep = 0;
+  fix->ypanstep = 0;
+  fix->ywrapstep = 0;
+  fix->line_length = 0;
+
+  for(i = 0; i < arraysize(fix->reserved); i++)
+    fix->reserved[i] = 0;
+
+  CFuncId("M64_hw_encode_fix() done. \n");
+  return(0);
+}
+/*endproc _encode_fix() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the video params out of `var'. If a value doesn't fit, round
+    *    it up, if it's too big, return -EINVAL.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_decode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_decode_var() \n");
+
+  par->xres = var->xres;
+  par->yres = var->yres;
+  par->bpp = var->bits_per_pixel;
+
+  return(0);
+}
+/*endproc _decode_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Fill the `var' structure based on the values in `par' and maybe
+    *    other values read out of the hardware.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_encode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_encode_var() \n");
+
+  var->xres = par->xres;
+  var->yres = par->yres;
+  var->xres_virtual = par->xres;
+  var->yres_virtual = par->yres;
+  var->xoffset = 0;
+  var->yoffset = 0;
+
+  var->bits_per_pixel = par->bpp;
+  var->grayscale = 0;
+
+  if(par->bpp == 8)
+  {
+    var->red.offset = 0;
+    var->red.length =
+      (virt_vgaiobase __MN__   ? mach64_bitspercol __MN__  : 0);
+    var->red.msb_right = 0;
+    var->blue = var->green = var->red;
+  }
+  else
+  {
+    var->red.offset = 11;
+    var->red.length = 5;
+    var->red.msb_right = 0;
+    var->green.offset = 5;
+    var->green.length = 6;
+    var->green.msb_right = 0;
+    var->blue.offset = 0;
+    var->blue.length = 5;
+    var->blue.msb_right = 0;
+  }
+  var->transp.offset = 0;
+  var->transp.length = 0;
+  var->transp.msb_right = 0;
+
+  var->nonstd = 0;
+  var->activate = 0;
+
+  var->height = -1;
+  var->width = -1;
+  var->accel = mach64_use_accel __MN__  ;
+  var->vmode = FB_VMODE_NONINTERLACED;
+
+  /* Dummy values */
+
+  if (par->bpp == 8)
+    var->pixclock = M64_8_PIXCLOCK;
+  else
+    var->pixclock = M64_16_PIXCLOCK;
+  var->sync = 0;
+  var->left_margin = 64;
+  var->right_margin = 96;
+  var->upper_margin = 35;
+  var->lower_margin = 12;
+  var->hsync_len = 112;
+  var->vsync_len = 2;
+
+  for(i = 0; i < arraysize(var->reserved); i++)
+    var->reserved[i] = 0;
+
+  return(0);
+}
+/*endproc _encode_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Set a single color register. The values supplied are already
+    *    rounded down to the hardware's capabilities (according to the
+    *    entries in the var structure). Return != 0 for invalid regno.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_setcolreg(u_int regno,
+  u_int red,
+  u_int green,
+  u_int blue,
+  u_int transp)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  unsigned short                colmask;
+  unsigned short                colshift;
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_hw_setcolreg(%02X) \n", regno);
+
+  if(regno > 255)  return (1);
+  mach64_colormap  __MN__  [regno][0] = red;
+  mach64_colormap  __MN__  [regno][1] = green;
+  mach64_colormap  __MN__  [regno][2] = blue;
+  mach64_colormap  __MN__  [regno][3] = transp;
+
+  if(! phys_vgaiobase)  return 1;
+
+  colmask = (1 << mach64_bitspercol __MN__  ) - 1;
+  colshift = 8 - mach64_bitspercol __MN__  ;
+
+  OUTB(0x3c8, regno);
+  DACDelay;
+  OUTB(0x3c9, (red >> colshift) & colmask);
+  DACDelay;
+  OUTB(0x3c9, (green >> colshift) & colmask);
+  DACDelay;
+  OUTB(0x3c9, (blue >> colshift) & colmask);
+  DACDelay;
+
+  return (0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Read a single color register and split it into
+    *    colors/transparent. Return != 0 for invalid regno.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_getcolreg(u_int regno,
+  u_int * red,
+  u_int * green,
+  u_int * blue,
+  u_int * transp)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_hw_getcolreg() \n");
+
+  if(regno >= 256)  return (1);
+
+  *red    = mach64_colormap  __MN__  [regno][0];
+  *green  = mach64_colormap  __MN__  [regno][1];
+  *blue   = mach64_colormap  __MN__  [regno][2];
+  *transp = mach64_colormap  __MN__  [regno][3];
+
+  /*
+  OUTB(0x3c7, regno);
+  DACDelay;
+  *red = INB(0x3c9) & colmask;
+  DACDelay;
+  *green = INB(0x3c9) & colmask;
+  DACDelay;
+  *blue = INB(0x3c9) & colmask;
+  DACDelay;
+  */
+	    
+  return (0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    (Un)Blank the screen: Set all colors = RGB 000 or back
+    */
+/*--------------------------------------------------------------------------*/
+
+void 
+M64_hw_blank(int blank)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int regno;
+
+  unsigned short                colmask;
+  unsigned short                colshift;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_blank() \n");
+
+  if(blank)
+  {
+    for(regno = 0; regno < 256; regno++)
+    {
+      OUTB(0x3c8, regno);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+
+    }
+    /*nexxt regno*/
+  }
+  else
+  {
+    colmask = (1 << mach64_bitspercol __MN__  ) - 1;
+    colshift = 8 - mach64_bitspercol __MN__  ;
+    for (regno = 0; regno < 256; regno++)
+    {
+      OUTB(0x3c8, regno);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][0] >> colshift) & colmask);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][1] >> colshift) & colmask);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][2] >> colshift) & colmask);
+    }
+    /*nexxt regno*/
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We are waiting for "fifo" FIFO-slots empty
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_WaitQueue (u_short fifo)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_WaitQueue() \n");
+
+  WaitQueue(16);
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We are waiting for Hardware (Graphics Engine) not busy
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_WaitBlit (void)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_WaitBlit() \n");
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * BitBLT - Through the Plane
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_BitBLT (
+  int     xSrc,
+  int     ySrc,
+  int     xDst,
+  int     yDst,
+  u_int   wSrc,
+  u_int   hSrc,
+  u_short mode)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  u_int                         direction;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("BB(%03X,%03X,%03X,%03X,%03X,%03X,%X) ",
+    xSrc, ySrc, xDst, yDst, wSrc, hSrc, mode);
+  /* Set drawing direction */
+  /* -Y, X maj, -X (default) */
+
+#if 1
+
+  direction = 0;
+
+  if(ySrc < yDst)
+  {
+    yDst += hSrc - 1;
+    ySrc += hSrc - 1;
+  }
+  else
+  {
+    direction |= DST_Y_TOP_TO_BOTTOM;
+  }
+  /*endif*/
+  if(xSrc < xDst)
+  {
+    xDst += wSrc - 1;
+    xSrc += wSrc - 1;
+  }
+  else
+  {
+    direction |= DST_X_LEFT_TO_RIGHT;
+  }
+  /*endif*/
+
+
+  WaitQueue(4);
+  regw(DP_WRITE_MASK, 0x000000FF          /* pGC->planemask */ );
+  regw(DP_MIX, (mach64alu[mode] << 16) |  MIX_DST);
+  regw(DP_SRC, FRGD_SRC_BLIT);
+
+  regw(GUI_TRAJ_CNTL, direction);
+
+/*
+  MACH64_BIT_BLT(xSrc, ySrc, xDst, yDst, wSrc, hSrc, direction);
+*/
+    WaitQueue(4);
+    regw(SRC_Y_X, (((xSrc) << 16) | (ySrc) ));
+    regw(SRC_WIDTH1, (wSrc));
+    regw(DST_Y_X, (((xDst) << 16) | (yDst) ));
+    regw(DST_HEIGHT_WIDTH, (((wSrc) << 16) | (hSrc) ));
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+  /*
+   * Make sure that the destination trajectory is correctly set
+   * for subsequent calls.  MACH64_BIT_BLT is the only function that
+   * currently changes the destination trajectory from L->R and T->B.
+   */
+  regw(DST_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+
+#endif
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * Rectangle Fill Solid
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_RectFill(
+  int     x,
+  int     y,
+  u_int   wSrc,
+  u_int   hSrc,
+  u_int   mode,
+  u_int   color)
+
+/*--------------------------------------------------------------------------*/
+{
+
+#if 1
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("RF(%03X,%03X,%03X,%03X,%X) ",
+    x, y, wSrc, hSrc, mode);
+
+  WaitQueue(5);
+  regw(DP_FRGD_CLR, color              /* pGC->fgPixel */ );
+  regw(DP_WRITE_MASK, 0x000000FF       /* pGC->planemask */ );
+  regw(DP_MIX, (mach64alu[mode] << 16) | MIX_DST);
+  regw(DP_SRC, FRGD_SRC_FRGD_CLR);
+
+  regw(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+  if ((wSrc > 0) && (hSrc > 0))
+  {
+    /* Bprint("q\n"); */
+    WaitQueue(2);
+    regw(DST_Y_X, (((u_int)x << 16) | ((u_int)y & 0x0000ffff)));
+    regw(DST_HEIGHT_WIDTH, (((u_int)wSrc << 16) | hSrc));
+  }
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+#endif
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * Move cursor to x, y
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_MoveCursor (u_short x, u_short y)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_MoveCursor() \n");
+
+
+  return;
+}
+/*endproc Mach64_MoveCursor()*/
+
+/*============================================================================*/
+
+
+/* -------------------- Generic routines ------------------------------------ */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Fill the hardware's `par' structure.
+    */
+/*--------------------------------------------------------------------------*/
+
+static void 
+M64_hw_get_par(struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_get_par() \n");
+  if(current_par_valid __MN__  )
+  {
+    *par = current_par __MN__  ;
+  }
+  else    /* use a default, initialize */
+  {
+    fbhws_ptr->decode_var(
+      &mach64fb_predefined[mach64_mode __MN__  ],
+      par);
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+M64_hw_set_par(struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_set_par() \n");
+  current_par __MN__   = *par;
+  current_par_valid __MN__   = 1;
+
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+do_fb_set_var(struct fb_var_screeninfo * var, int isactive)
+
+/*--------------------------------------------------------------------------*/
+{
+  int                           err, activate;
+  struct mach64fb_par          par;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("do_fb_set_var() \n");
+  if((err = fbhws_ptr->decode_var(var, &par)))
+    return(err);
+  activate = var->activate;
+  if((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+  {
+    M64_hw_set_par(&par);
+  }
+  /*endif*/
+  fbhws_ptr->encode_var(var, &par);
+  var->activate = activate;
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+do_install_cmap(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("do_install_cmap() \n");
+
+  if(con != currcon)  return;
+
+  if(fb_display[con].cmap.len)
+  {
+    fb_set_cmap(&fb_display[con].cmap,
+      &fb_display[con].var,
+      1,
+      fbhws_ptr->setcolreg);
+  }
+  else
+  {
+    fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+      &fb_display[con].var,
+      1,
+      fbhws_ptr->setcolreg);
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the Fixed Part of the Display
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_fix(struct fb_fix_screeninfo * fix, int con, int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+  struct mach64fb_par          par;
+  int                           status = 0;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_get_fix() \n");
+  if (con == -1)
+  {
+    M64_hw_get_par(&par);
+  }
+  else
+  {
+    status = fbhws_ptr->decode_var(&fb_display[con].var, &par);
+  }
+  /*endif*/
+  return(status ? status : fbhws_ptr->encode_fix(fix, &par));
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the User Defined Part of the Display
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+  struct mach64fb_par          par;
+  int                           status = 0;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_get_var() \n");
+  if(con == -1)
+  {
+    M64_hw_get_par(&par);
+    status = fbhws_ptr->encode_var(var, &par);
+  }
+  else
+  {
+    *var = fb_display[con].var;
+  }
+  /*endif*/
+  return(status);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+mach64fb_set_disp(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  struct display *              disp_p;
+  struct fb_fix_screeninfo      fix;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("mach64fb_set_disp() \n");
+
+  if(con >= 0)
+    disp_p = &fb_display[con];
+  else
+    disp_p = &m_disp __MN__  ;  	/* used during initialization */
+
+  /* ### FN: Needs fixes later */
+  M64_op_get_fix(&fix, con, 0);
+
+  if(con == -1)  con = 0;
+
+  disp_p->screen_base = (u_char *)fix.smem_start;
+  disp_p->visual = fix.visual;
+  disp_p->type = fix.type;
+  disp_p->type_aux = fix.type_aux;
+  disp_p->ypanstep = fix.ypanstep;
+  disp_p->ywrapstep = fix.ywrapstep;
+  disp_p->line_length = fix.line_length;
+  if(fix.visual != FB_VISUAL_PSEUDOCOLOR && fix.visual != FB_VISUAL_DIRECTCOLOR)
+  {
+    disp_p->can_soft_blank = 0;                   /* aus atari_ */
+  }
+  else
+  {
+    disp_p->can_soft_blank = 1;
+  }
+  /*endif*/
+
+  disp_p->can_soft_blank = 1;                       /* aus Cyber_ */
+  disp_p->inverse = mach64_inverse __MN__  ;
+
+  return;
+}
+/*endproc mach64fb_set_disp() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+  /*
+   *    Set the User Defined Part of the Display
+   */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_set_var(struct fb_var_screeninfo * var, int con, int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int       err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_set_var() \n");
+
+  if((err = do_fb_set_var(var, con == currcon)))
+    return(err);
+  if((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+  {
+    oldxres = fb_display[con].var.xres;
+    oldyres = fb_display[con].var.yres;
+    oldvxres = fb_display[con].var.xres_virtual;
+    oldvyres = fb_display[con].var.yres_virtual;
+    oldbpp = fb_display[con].var.bits_per_pixel;
+    fb_display[con].var = *var;
+    if(oldxres != var->xres || oldyres != var->yres ||
+      oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+      oldbpp != var->bits_per_pixel)
+    {
+      mach64fb_set_disp(con);
+      (*fb_info __MN__  .changevar)(con);
+      fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
+      do_install_cmap(con);
+    }
+  }
+  /*endif*/
+  var->activate = 0;
+
+  return(0);
+}
+/*endproc M64_op_set_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the Colormap
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_cmap(struct fb_cmap * cmap, int kspc, int con, int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_get_cmap() \n");
+
+  if(con == currcon) /* current console? */
+  {
+    return(fb_get_cmap(cmap, &fb_display[con].var, kspc, fbhws_ptr->getcolreg));
+  }
+  else if(fb_display[con].cmap.len) /* non default colormap? */
+  {
+    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+  }
+  else
+  {
+    fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+      cmap, kspc ? 0 : 2);
+  }
+  /*endif*/
+
+  return(0);
+}
+/*endproc M64_op_get_cmap() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Set the Colormap
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_set_cmap(struct fb_cmap * cmap, int kspc, int con, int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+  int err;
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_set_cmap() \n");
+
+  if (!fb_display[con].cmap.len)       /* no colormap allocated? */
+  {
+    err = fb_alloc_cmap(&fb_display[con].cmap,
+      1 << fb_display[con].var.bits_per_pixel,
+      0);
+    if(err)
+    {
+      return(err);
+    }
+    /*endif*/
+  }
+  /*endif*/
+  if(con == currcon)              /* current console? */
+  {
+    return(fb_set_cmap(cmap, &fb_display[con].var, kspc, fbhws_ptr->setcolreg));
+  }
+  else
+  {
+    fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+  }
+  /*endif*/
+
+  return(0);
+}
+/*endproc M64_op_set_cmap() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Pan or Wrap the Display
+    *
+    *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_pan_display() \n");
+
+  return(-EINVAL);
+}
+/*endproc M64_op_pan_display() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Mach 64 Frame Buffer Specific ioctls
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_ioctl(
+  struct inode * inode,
+  struct file *  file,
+  u_int          cmd,
+  u_long         arg,
+  int            con,
+  int            fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_ioctl($%08X %d) \n", cmd, con);
+  switch (cmd)
+  {
+
+#ifdef FBCMD_GET_CURRENTPAR
+    case FBCMD_GET_CURRENTPAR:
+    {
+      if (copy_to_user((void *)arg, (void *)&current_par __MN__  ,
+         sizeof(struct mach64fb_par)))
+        return -EFAULT;
+      return 0;
+    }
+    /*endcase*/
+#endif
+
+#ifdef FBCMD_SET_CURRENTPAR
+    case FBCMD_SET_CURRENTPAR:
+    {
+
+      if (copy_from_user((void *)&current_par __MN__  , (void *)arg,
+        sizeof(struct mach64fb_par)))
+        return -EFAULT;
+      M64_hw_set_par(&current_par __MN__  );
+      return 0;
+    }
+    /*endcase*/
+#endif
+
+  }
+  /*endswitch*/
+  return(-EINVAL);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+int 
+Mach64_probe(void)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("Mach64_probe() \n");
+  mach64_key = 0;
+  return(mach64_key);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+__initfunc(
+void 
+mach64fb_setup(char * options, int * ints)
+)
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  char *        this_opt;
+  char          mach64_str[80];
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("mach64fb_setup() '%s'\n", options);
+
+  fb_info __MN__  .fontname[0] = '\0';
+
+  if(!options || !*options)  return;
+
+  for(this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
+  {
+    if (!strcmp(this_opt, "inverse"))
+    {
+      mach64_inverse __MN__   = 1;
+      fb_invert_cmaps();
+    }
+    else if (!strncmp(this_opt, "font:", 5))
+    {
+      strcpy(fb_info __MN__  .fontname, this_opt + 5);
+    }
+    else if (!strncmp(this_opt,"Mach64:", 7))
+    {
+      strncpy(mach64_str, this_opt + 7, 80);
+      store_video_par(mach64_str  _ADD_ARG_MN_ );
+      _INC_MN_ ;
+      mach64_count =  _MN_ ;
+    }
+    else
+    {
+      mach64_mode __MN__   = get_video_mode(this_opt);
+    }
+    /*endif*/
+  }
+  /*next this_opt*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+store_video_par(char* video_str ADD_ARG_UINT08___MN_ )
+
+/*--------------------------------------------------------------------------*/
+{
+  char *                        p;
+  unsigned  long                sm_addr, sm_size;
+
+  int                           xres, yres, depth;
+  short int                     pmode;
+  short int                     use_accel;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("store_video_par(%d) \n",  _MN_ );
+  /* Format is: <xres>;<yres>;<depth>;<plane organ.>;
+   *            <screen mem addr>
+   *        [;<screen mem length>[;<vgaiobase>[;<colorreg-type>]]]
+   */
+
+  use_accel = 0;
+  if (!(p = strtoke(video_str, ";")) || !*p)  goto mach64_invalid;
+  xres = simple_strtoul(p, NULL, 10);
+  if (xres <= 0)  goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  yres = simple_strtoul(p, NULL, 10);
+  if (yres <= 0) goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  depth = simple_strtoul(p, NULL, 10);
+  if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
+      depth != 16 && depth != 24)  goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  if (*p == 'i')
+    pmode = FB_TYPE_INTERLEAVED_PLANES;
+  else if (*p == 'p')
+    pmode = FB_TYPE_PACKED_PIXELS;
+  else if (*p == 'n')
+    pmode = FB_TYPE_PLANES;
+  else if (*p == 't')
+    pmode = -1; /* true color */
+  else
+    goto mach64_invalid;
+
+
+  if (!(p = strtoke(NULL, ";")) ||!*p)  goto mach64_invalid;
+  sm_addr = simple_strtoul(p, NULL, 0);
+
+  if (!(p = strtoke(NULL, ";")) ||!*p)
+    sm_size = xres * yres * depth / 8;
+  else
+    sm_size = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+    phys_vgaiobase __MN__   = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+  {
+    mach64_bitspercol __MN__   = simple_strtoul(p, NULL, 0);
+    if (mach64_bitspercol __MN__   > 8)
+      mach64_bitspercol __MN__   = 8;
+    else if (mach64_bitspercol __MN__   < 1)
+      mach64_bitspercol __MN__   = 1;
+  }
+  /*endif*/
+
+  if ((p = strtoke(NULL, ";")) && *p)
+    phys_guiregbase __MN__   = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+  {
+    if(*p == 'a')  use_accel = FB_ACCEL_MACH64;
+  
+  }
+  /*endif*/
+
+  mach64_xres __MN__    = xres;
+  mach64_yres __MN__    = yres;
+  mach64_depth __MN__   = depth;
+  mach64_pmode __MN__   = pmode;
+  mach64_use_accel __MN__   = use_accel;
+  phys_vmembase __MN__   = sm_addr;
+  phys_size __MN__    = sm_size;
+
+  return(0);
+
+  /*--------------------------------------------------------------------------*/
+  mach64_invalid:
+
+  phys_vmembase __MN__   = 0;
+
+  return(-1);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/* a strtok which returns empty strings, too */
+
+/*--------------------------------------------------------------------------*/
+
+static char * 
+strtoke(char * s, const char * ct)
+
+/*--------------------------------------------------------------------------*/
+{
+  static char    *ssave = NULL;
+  char          *sbegin, *send;
+  
+  /*--------------------------------------------------------------------------*/
+  sbegin  = s ? s : ssave;
+  if (!sbegin) {
+    return NULL;
+  }
+  if (*sbegin == '\0') {
+    ssave = NULL;
+    return NULL;
+  }
+  send = strpbrk(sbegin, ct);
+  if (send && *send != '\0')
+    *send++ = '\0';
+  ssave = send;
+  return sbegin;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Initialization
+    */
+/*--------------------------------------------------------------------------*/
+
+__initfunc(
+unsigned long
+mach64fb_init(unsigned long mem_start)
+)
+/*--------------------------------------------------------------------------*/
+{
+  static unsigned long          virt_dummy;
+  static u_char                 fb_init_count;
+  DECLARE_STATIC_UINT08___MN_
+
+  struct mach64fb_par          par;
+  int                           err;
+  DECLARE_UINT08___MN_
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("mach64fb_init($%08lX) \n", mem_start);
+
+  /*
+  _MN_ = fb_init_count;
+  */
+  if(phys_vmembase __MN__   == 0)  return mem_start;
+
+  fb_init_count++;
+
+  fbhws_ptr = &mach64_switch;
+
+  /* Map the video memory (physical address given) to somewhere
+   * in the kernel address space.
+   */
+  mem_start = (mem_start + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+  virt_vmembase __MN__   = kernel_map(
+    phys_vmembase __MN__  ,
+    phys_size __MN__  ,
+#ifdef  _OHNE_HW_ACCEL_
+    KERNELMAP_NO_COPYBACK,    /* must be changed if hardware blit */
+#else
+    KERNELMAP_NOCACHE_SER,
+#endif
+    &mem_start);
+
+#ifdef  _MAP_GUIREGS_0BFC00_
+    
+  if(phys_guiregbase __MN__  )
+  {
+    virt_guiregbase __MN__   = kernel_map(
+      phys_guiregbase __MN__  ,
+      0x10000,                           /* 64 K */
+      KERNELMAP_NOCACHE_SER,
+      &mem_start);
+  }
+  /*endif*/
+
+#endif
+
+  if(phys_vgaiobase __MN__  )
+  {
+/*
+    phys_guiregbase __MN__   = phys_vgaiobase __MN__  - 0x00100000 + 0x000B0000;
+*/
+
+#ifdef _MAP_768K_IO_
+
+    virt_vgaiobase __MN__   = kernel_map(
+      phys_vgaiobase __MN__  - 0x00080000,
+      0x0C0000,                          /* 768 K */
+      KERNELMAP_NOCACHE_SER,
+      &mem_start);
+
+#else
+
+    if(phys_guiregbase __MN__  )
+    {
+      virt_vgaiobase __MN__   = kernel_map(
+        phys_vgaiobase __MN__  ,
+        0x10000,                           /* 64 K */
+        KERNELMAP_NOCACHE_SER,
+        &mem_start);
+    }
+    else
+    {
+      virt_vgaiobase __MN__   = 0x00080000 + kernel_map(
+        phys_vgaiobase __MN__  - 0x00080000,
+        0x0C0000,                          /* 768 K */
+        KERNELMAP_NOCACHE_SER,
+        &mem_start);
+
+      Dprint(" faking virt_guiregbase to virt_vgaiobase - 0x00050000 \n");
+      virt_guiregbase __MN__   = virt_vgaiobase __MN__  - 0x00050000;
+    }
+    /*endif*/
+
+#endif  /* _MAP_768K_IO_ */
+  }
+  /*endif*/
+
+  Dprint(" phys_guiregbase=$%08lX virt_dummy=$%08lX\n",
+    phys_guiregbase __MN__  ,
+    virt_dummy);
+
+    
+#ifdef  _DUMP_KMAP_RANGE_
+  dump_kmap_range();
+#endif
+
+
+  virt_size __MN__   = phys_size __MN__   & PAGE_MASK;  /* abrunden */
+  virt_size __MN__   = (phys_size __MN__  - 0x00200000) & PAGE_MASK;  /* abrunden */
+
+  Dprint(" PAGE_MASK=$%08lX phys_size=$%08lX \n", PAGE_MASK, phys_size __MN__ );
+  /*
+  memset((char *) virt_vmembase __MN__  , 0, virt_size __MN__  );
+  */
+
+  strcpy(fb_info __MN__  .modename, mach64fb_name);
+  fb_info __MN__  .changevar = NULL;
+  fb_info __MN__  .node = -1;
+  fb_info __MN__  .fbops = &mach64fb_ops;
+  fb_info __MN__  .disp = &m_disp __MN__  ;
+  fb_info __MN__  .switch_con = &Mach64fb_switch;
+  fb_info __MN__  .updatevar = &Mach64fb_updatevar;
+  fb_info __MN__  .blank = &Mach64fb_blank;
+  strcat(fb_info __MN__  .modename, fb_var_names[mach64_mode __MN__  ]);
+  fb_info __MN__  .modename[39] =  _MN_ ;
+
+  err = register_framebuffer(&fb_info __MN__  );
+  if(err < 0)
+  {
+    Eprint(" Cannot register frame buffer() \n" );
+    return mem_start;
+  }
+  /*endif*/
+
+  fbhws_ptr->init( _ARG_MN_ );
+  fbhws_ptr->decode_var(&mach64fb_predefined[mach64_mode __MN__  ], &par);
+  fbhws_ptr->encode_var(&mach64fb_predefined[0], &par); /* store resolution */
+
+  do_fb_set_var(&mach64fb_predefined[0], 1);
+
+  M64_op_get_var(&m_disp __MN__  .var, -1, GET_FB_IDX(fb_info.node));
+					    /* fill in m_disp.var */
+  mach64fb_set_disp(-1);                    /* fill in the rest of m_disp  */
+
+  Iprint(" Determined %dx%d, depth %d $%08lX MEM @ $%08lX IO @ $%08lX $%08lX\n",
+    m_disp __MN__  .var.xres,
+    m_disp __MN__  .var.yres,
+    m_disp __MN__  .var.bits_per_pixel,
+    phys_size __MN__  ,
+    phys_vmembase __MN__  ,
+    phys_vgaiobase __MN__  ,
+    phys_guiregbase __MN__  );
+  do_install_cmap(0);
+
+  Iprint(
+    " %s FB device %d, using %ldK of video MEM @ $%08lX IO @ $%08lX $%08lX\n",
+    fb_info __MN__  .modename,
+     _MN_ ,
+    virt_size __MN__   >> 10,
+    virt_vmembase __MN__  ,
+    virt_vgaiobase __MN__  ,
+    virt_guiregbase __MN__  );
+
+  _INC_MN_ ;
+
+  return mem_start;
+}
+/*endproc mach64fb_init() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+Mach64fb_switch(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_switch(%d) \n", con);
+  /* Do we have to save the colormap? */
+  if (fb_display[currcon].cmap.len)
+  {
+    fb_get_cmap(&fb_display[currcon].cmap,
+      &fb_display[currcon].var,
+      1,
+      fbhws_ptr->getcolreg);
+  }
+  /*endif*/
+  do_fb_set_var(&fb_display[con].var, 1);
+  currcon = con;
+  /* Install new colormap */
+  do_install_cmap(con);
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Update the `var' structure (called by fbcon.c)
+    *
+    *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+    *    Since it's called by a kernel driver, no range checking is done.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+Mach64fb_updatevar(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_updatevar() \n");
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Blank the display.
+    */
+/*--------------------------------------------------------------------------*/
+
+static void 
+Mach64fb_blank(int blank)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_blank() \n");
+  fbhws_ptr->blank(blank);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get a Video Mode
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+get_video_mode(const char * name)
+
+/*--------------------------------------------------------------------------*/
+{
+  int i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("get_video_mode(%s) \n", name);
+
+  for (i = 1; i < NUM_PREDEF_MODES; i++)
+  {
+    if (!strcmp(name, fb_var_names[i]))  return(i);
+  }
+  /*next i*/
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+  static char
+  rcs_id_h[] = MACH64FB_H_ID;
+
+  static char
+  rcs_id_regs_h[] = MACH64REGS_H_ID;
+
+  static char
+  rcs_id_c[] =
+    "@(#) Linux-m68k: 1997 11 21 17:13:00 BHA: mach64fb.c ";
+
+/*                                        ^^^                         */
+/* Please update this & put your initials here on every modification. */
+/* It can be checked with '  strings vmlinux | grep "@(#) "  '        */
+/*============================================================================*/
--- m68k-2.1.72/drivers/video/mach64fb.h.orig	Wed Dec 17 23:54:16 1997
+++ m68k-2.1.72/drivers/video/mach64fb.h	Wed Dec 17 23:56:40 1997
@@ -0,0 +1,49 @@
+
+
+#ifndef _MACH64FB_H_LOADED_
+#define _MACH64FB_H_LOADED_
+
+
+   /*
+    *    Accelerated Functions used by the low level console driver
+    */
+
+void Mach64_WaitQueue(u_short fifo);
+
+void Mach64_WaitBlit(void);
+
+void 
+Mach64_BitBLT(
+  int srcx,
+  int srcy,
+  int destx,
+  int desty,
+  u_int width,
+  u_int height,
+  u_short mode);
+
+
+void 
+Mach64_RectFill(
+  int     xpos,
+  int     ypos,
+  u_int   width,
+  u_int   height,
+  u_int   mode,
+  u_int   fcolor);
+
+void Mach64_MoveCursor(u_short xpos, u_short ypos);
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define MACH64FB_H_ID \
+  "@(#) Linux-m68k: 1997 11 21 17:12:18 BHA: mach64fb.h "
+
+/*                                      ^^^                           */
+/* Please update this & put your initials here on every modification. */
+/* It can be checked with '  strings vmlinux | grep "@(#) "  '        */
+/*============================================================================*/
+
+#endif /* _MACH64FB_H_LOADED_ */
--- m68k-2.1.72/drivers/video/mach64regs.h.orig	Wed Dec 17 23:54:18 1997
+++ m68k-2.1.72/drivers/video/mach64regs.h	Wed Dec 17 23:56:46 1997
@@ -0,0 +1,703 @@
+/* $Id: mach64regs.h,v 1.3 1997/11/19 18:09:00 ecd Exp $
+ * mach64regs.h: ISA/Ultra/PCI mach64 driver constants etc.
+ *
+ * Copyright 1997 David S. Miller (davem@caip.rutgers.edu)
+ *              & Bernd Harries   (harries@atlas.de)
+ *
+ *  This is the file to be included by mach64 drivers.
+ *  Files using the interfaces of the mach64fb driver 
+ *  (functions & IOCTL options) include mach64fb.h.
+ */
+
+
+#ifndef MACH64REGS_H
+#define MACH64REGS_H
+
+struct mach64_info {
+	unsigned int color_mode;
+	unsigned int flags;
+	unsigned int total_vram;
+};
+
+/* The mach64_info flag bits. */
+#define MACH64_MASK_VT	0x00000001
+
+
+/* NON-GUI IO MAPPED Registers */
+
+extern unsigned ioCONFIG_CHIP_ID;
+extern unsigned ioCONFIG_CNTL;
+extern unsigned ioSCRATCH_REG0;
+extern unsigned ioSCRATCH_REG1;
+extern unsigned ioCONFIG_STAT0;
+extern unsigned ioMEM_CNTL;
+extern unsigned ioDAC_REGS;
+extern unsigned ioDAC_CNTL;
+extern unsigned ioGEN_TEST_CNTL;
+extern unsigned ioCLOCK_CNTL;
+extern unsigned ioCRTC_GEN_CNTL;
+
+/* NON-GUI sparse IO register offsets */
+
+#define sioCONFIG_CHIP_ID       0x1B
+#define sioCONFIG_CNTL          0x1A
+#define sioSCRATCH_REG0         0x10
+#define sioSCRATCH_REG1         0x11
+#define sioCONFIG_STAT0         0x1C
+#define sioMEM_CNTL             0x14
+#define sioDAC_REGS             0x17
+#define sioDAC_CNTL             0x18
+#define sioGEN_TEST_CNTL        0x19
+#define sioCLOCK_CNTL           0x12
+#define sioCRTC_GEN_CNTL        0x07
+
+/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
+
+#define CRTC_H_TOTAL_DISP       0x0000  /* Dword offset 00 */
+#define CRTC_H_SYNC_STRT_WID    0x0004  /* Dword offset 01 */
+#define CRTC_H_SYNC_STRT        0x0004
+#define CRTC_H_SYNC_DLY         0x0005
+#define CRTC_H_SYNC_WID         0x0006
+
+#define CRTC_V_TOTAL_DISP       0x0008  /* Dword offset 02 */
+#define CRTC_V_TOTAL            0x0008
+#define CRTC_V_DISP             0x000A
+#define CRTC_V_SYNC_STRT_WID    0x000C  /* Dword offset 03 */
+#define CRTC_V_SYNC_STRT        0x000C
+#define CRTC_V_SYNC_WID         0x000E
+
+#define CRTC_VLINE_CRNT_VLINE   0x0010  /* Dword offset 04 */
+#define CRTC_OFF_PITCH          0x0014  /* Dword offset 05 */
+#define CRTC_INT_CNTL           0x0018  /* Dword offset 06 */
+#define CRTC_GEN_CNTL           0x001C  /* Dword offset 07 */
+
+#define OVR_CLR                 0x0040  /* Dword offset 10 */
+#define OVR_WID_LEFT_RIGHT      0x0044  /* Dword offset 11 */
+#define OVR_WID_TOP_BOTTOM      0x0048  /* Dword offset 12 */
+
+#define CUR_CLR0                0x0060  /* Dword offset 18 */
+#define CUR_CLR1                0x0064  /* Dword offset 19 */
+#define CUR_OFFSET              0x0068  /* Dword offset 1A */
+#define CUR_HORZ_VERT_POSN      0x006C  /* Dword offset 1B */
+#define CRTC_PIX_WIDTH          0x001D
+#define CRTC_FIFO               0x001E
+#define CRTC_EXT_DISP           0x001F
+
+#define CUR_HORZ_VERT_OFF       0x0070  /* Dword offset 1C */
+
+#define SCRATCH_REG0            0x0080  /* Dword offset 20 */
+#define SCRATCH_REG1            0x0084  /* Dword offset 21 */
+
+#define CLOCK_CNTL              0x0090  /* Dword offset 24 */
+
+#define BUS_CNTL                0x00A0  /* Dword offset 28 */
+
+#define MEM_CNTL                0x00B0  /* Dword offset 2C */
+
+#define MEM_VGA_WP_SEL          0x00B4  /* Dword offset 2D */
+#define MEM_VGA_RP_SEL          0x00B8  /* Dword offset 2E */
+
+#define DAC_REGS                0x00C0  /* Dword offset 30 */
+#define DAC_W_INDEX             0x00C0  /* Dword offset 30 */
+#define DAC_DATA                0x00C1  /* Dword offset 30 */
+#define DAC_MASK                0x00C2  /* Dword offset 30 */
+#define DAC_R_INDEX             0x00C3  /* Dword offset 30 */
+#define DAC_CNTL                0x00C4  /* Dword offset 31 */
+
+#define GEN_TEST_CNTL           0x00D0  /* Dword offset 34 */
+
+#define CONFIG_CNTL             0x00DC  /* Dword offset 37 (CT, ET, VT) */
+#define CONFIG_CHIP_ID          0x00E0  /* Dword offset 38 */
+#define CONFIG_STAT0            0x00E4  /* Dword offset 39 */
+#define CONFIG_STAT1            0x00E8  /* Dword offset 3A */
+
+
+/* GUI MEMORY MAPPED Registers */
+
+#define DST_OFF_PITCH           0x0100  /* Dword offset 40 */
+#define DST_X                   0x0104  /* Dword offset 41 */
+#define DST_Y                   0x0108  /* Dword offset 42 */
+#define DST_Y_X                 0x010C  /* Dword offset 43 */
+#define DST_WIDTH               0x0110  /* Dword offset 44 */
+#define DST_HEIGHT              0x0114  /* Dword offset 45 */
+#define DST_HEIGHT_WIDTH        0x0118  /* Dword offset 46 */
+#define DST_X_WIDTH             0x011C  /* Dword offset 47 */
+#define DST_BRES_LNTH           0x0120  /* Dword offset 48 */
+#define DST_BRES_ERR            0x0124  /* Dword offset 49 */
+#define DST_BRES_INC            0x0128  /* Dword offset 4A */
+#define DST_BRES_DEC            0x012C  /* Dword offset 4B */
+#define DST_CNTL                0x0130  /* Dword offset 4C */
+
+#define SRC_OFF_PITCH           0x0180  /* Dword offset 60 */
+#define SRC_X                   0x0184  /* Dword offset 61 */
+#define SRC_Y                   0x0188  /* Dword offset 62 */
+#define SRC_Y_X                 0x018C  /* Dword offset 63 */
+#define SRC_WIDTH1              0x0190  /* Dword offset 64 */
+#define SRC_HEIGHT1             0x0194  /* Dword offset 65 */
+#define SRC_HEIGHT1_WIDTH1      0x0198  /* Dword offset 66 */
+#define SRC_X_START             0x019C  /* Dword offset 67 */
+#define SRC_Y_START             0x01A0  /* Dword offset 68 */
+#define SRC_Y_X_START           0x01A4  /* Dword offset 69 */
+#define SRC_WIDTH2              0x01A8  /* Dword offset 6A */
+#define SRC_HEIGHT2             0x01AC  /* Dword offset 6B */
+#define SRC_HEIGHT2_WIDTH2      0x01B0  /* Dword offset 6C */
+#define SRC_CNTL                0x01B4  /* Dword offset 6D */
+
+#define HOST_DATA0              0x0200  /* Dword offset 80 */
+#define HOST_DATA1              0x0204  /* Dword offset 81 */
+#define HOST_DATA2              0x0208  /* Dword offset 82 */
+#define HOST_DATA3              0x020C  /* Dword offset 83 */
+#define HOST_DATA4              0x0210  /* Dword offset 84 */
+#define HOST_DATA5              0x0214  /* Dword offset 85 */
+#define HOST_DATA6              0x0218  /* Dword offset 86 */
+#define HOST_DATA7              0x021C  /* Dword offset 87 */
+#define HOST_DATA8              0x0220  /* Dword offset 88 */
+#define HOST_DATA9              0x0224  /* Dword offset 89 */
+#define HOST_DATAA              0x0228  /* Dword offset 8A */
+#define HOST_DATAB              0x022C  /* Dword offset 8B */
+#define HOST_DATAC              0x0230  /* Dword offset 8C */
+#define HOST_DATAD              0x0234  /* Dword offset 8D */
+#define HOST_DATAE              0x0238  /* Dword offset 8E */
+#define HOST_DATAF              0x023C  /* Dword offset 8F */
+#define HOST_CNTL               0x0240  /* Dword offset 90 */
+
+#define PAT_REG0                0x0280  /* Dword offset A0 */
+#define PAT_REG1                0x0284  /* Dword offset A1 */
+#define PAT_CNTL                0x0288  /* Dword offset A2 */
+
+#define SC_LEFT                 0x02A0  /* Dword offset A8 */
+#define SC_RIGHT                0x02A4  /* Dword offset A9 */
+#define SC_LEFT_RIGHT           0x02A8  /* Dword offset AA */
+#define SC_TOP                  0x02AC  /* Dword offset AB */
+#define SC_BOTTOM               0x02B0  /* Dword offset AC */
+#define SC_TOP_BOTTOM           0x02B4  /* Dword offset AD */
+
+#define DP_BKGD_CLR             0x02C0  /* Dword offset B0 */
+#define DP_FRGD_CLR             0x02C4  /* Dword offset B1 */
+#define DP_WRITE_MASK           0x02C8  /* Dword offset B2 */
+#define DP_CHAIN_MASK           0x02CC  /* Dword offset B3 */
+#define DP_PIX_WIDTH            0x02D0  /* Dword offset B4 */
+#define DP_MIX                  0x02D4  /* Dword offset B5 */
+#define DP_SRC                  0x02D8  /* Dword offset B6 */
+
+#define CLR_CMP_CLR             0x0300  /* Dword offset C0 */
+#define CLR_CMP_MASK            0x0304  /* Dword offset C1 */
+#define CLR_CMP_CNTL            0x0308  /* Dword offset C2 */
+
+#define FIFO_STAT               0x0310  /* Dword offset C4 */
+
+#define CONTEXT_MASK            0x0320  /* Dword offset C8 */
+#define CONTEXT_LOAD_CNTL       0x032C  /* Dword offset CB */
+
+#define GUI_TRAJ_CNTL           0x0330  /* Dword offset CC */
+#define GUI_STAT                0x0338  /* Dword offset CE */
+
+
+/* CRTC control values */
+
+#define CRTC_H_SYNC_NEG         0x00200000
+#define CRTC_V_SYNC_NEG         0x00200000
+
+#define CRTC_DBL_SCAN_EN        0x00000001
+#define CRTC_INTERLACE_EN       0x00000002
+#define CRTC_HSYNC_DIS          0x00000004
+#define CRTC_VSYNC_DIS          0x00000008
+#define CRTC_CSYNC_EN           0x00000010
+#define CRTC_PIX_BY_2_EN        0x00000020
+
+#define CRTC_PIX_WIDTH          0x00000700
+#define CRTC_PIX_WIDTH_4BPP     0x00000100
+#define CRTC_PIX_WIDTH_8BPP     0x00000200
+#define CRTC_PIX_WIDTH_15BPP    0x00000300
+#define CRTC_PIX_WIDTH_16BPP    0x00000400
+#define CRTC_PIX_WIDTH_24BPP    0x00000500
+#define CRTC_PIX_WIDTH_32BPP    0x00000600
+
+#define CRTC_BYTE_PIX_ORDER     0x00000800
+#define CRTC_PIX_ORDER_MSN_LSN  0x00000000
+#define CRTC_PIX_ORDER_LSN_MSN  0x00000800
+
+#define CRTC_FIFO_LWM           0x000f0000
+#define CRTC_EXT_DISP_EN        0x01000000
+#define CRTC_EXT_EN             0x02000000
+
+#define CRTC_CRNT_VLINE         0x07f00000
+#define CRTC_VBLANK             0x00000001
+
+/* DAC control values */
+
+#define DAC_EXT_SEL_RS2         0x01
+#define DAC_EXT_SEL_RS3         0x02
+#define DAC_8BIT_EN             0x00000100
+#define DAC_PIX_DLY_MASK        0x00000600
+#define DAC_PIX_DLY_0NS         0x00000000
+#define DAC_PIX_DLY_2NS         0x00000200
+#define DAC_PIX_DLY_4NS         0x00000400
+#define DAC_BLANK_ADJ_MASK      0x00001800
+#define DAC_BLANK_ADJ_0         0x00000000
+#define DAC_BLANK_ADJ_1         0x00000800
+#define DAC_BLANK_ADJ_2         0x00001000
+
+
+/* Mix control values */
+
+#define MIX_NOT_DST             0x0000
+#define MIX_0                   0x0001
+#define MIX_1                   0x0002
+#define MIX_DST                 0x0003
+#define MIX_NOT_SRC             0x0004
+#define MIX_XOR                 0x0005
+#define MIX_XNOR                0x0006
+#define MIX_SRC                 0x0007
+#define MIX_NAND                0x0008
+#define MIX_NOT_SRC_OR_DST      0x0009
+#define MIX_SRC_OR_NOT_DST      0x000a
+#define MIX_OR                  0x000b
+#define MIX_AND                 0x000c
+#define MIX_SRC_AND_NOT_DST     0x000d
+#define MIX_NOT_SRC_AND_DST     0x000e
+#define MIX_NOR                 0x000f
+
+/* Maximum engine dimensions */
+#define ENGINE_MIN_X            0
+#define ENGINE_MIN_Y            0
+#define ENGINE_MAX_X            4095
+#define ENGINE_MAX_Y            16383
+
+/* Mach64 engine bit constants - these are typically ORed together */
+
+/* BUS_CNTL register constants */
+#define BUS_FIFO_ERR_ACK        0x00200000
+#define BUS_HOST_ERR_ACK        0x00800000
+
+/* GEN_TEST_CNTL register constants */
+#define GEN_OVR_OUTPUT_EN       0x20
+#define HWCURSOR_ENABLE         0x80
+#define GUI_ENGINE_ENABLE       0x100
+#define BLOCK_WRITE_ENABLE      0x200
+
+/* CLOCK_CNTL register constants */
+#define CLOCK_SEL               0x0f
+#define CLOCK_DIV               0x30
+#define CLOCK_DIV1              0x00
+#define CLOCK_DIV2              0x10
+#define CLOCK_DIV4              0x20
+#define CLOCK_STROBE            0x40
+#define PLL_WR_EN               0x02
+
+/* PLL registers */
+#define PLL_MACRO_CNTL          0x01
+#define PLL_REF_DIV             0x02
+#define PLL_GEN_CNTL            0x03
+#define MCLK_FB_DIV             0x04
+#define PLL_VCLK_CNTL           0x05
+#define VCLK_POST_DIV           0x06
+#define VCLK0_FB_DIV            0x07
+#define VCLK1_FB_DIV            0x08
+#define VCLK2_FB_DIV            0x09
+#define VCLK3_FB_DIV            0x0A
+#define PLL_XCLK_CNTL           0x0B
+#define PLL_TEST_CTRL           0x0E
+#define PLL_TEST_COUNT          0x0F
+
+/* Fields in PLL registers */
+#define PLL_PC_GAIN             0x07
+#define PLL_VC_GAIN             0x18
+#define PLL_DUTY_CYC            0xE0
+#define PLL_OVERRIDE            0x01
+#define PLL_MCLK_RST            0x02
+#define OSC_EN                  0x04
+#define EXT_CLK_EN              0x08
+#define MCLK_SRC_SEL            0x70
+#define EXT_CLK_CNTL            0x80
+#define VCLK_SRC_SEL            0x03
+#define PLL_VCLK_RST            0x04
+#define VCLK_INVERT             0x08
+#define VCLK0_POST              0x03
+#define VCLK1_POST              0x0C
+#define VCLK2_POST              0x30
+#define VCLK3_POST              0xC0
+
+/* CONFIG_CNTL register constants */
+#define APERTURE_4M_ENABLE      1
+#define APERTURE_8M_ENABLE      2
+#define VGA_APERTURE_ENABLE     4
+
+/* CONFIG_STAT0 register constants (GX, CX) */
+#define CFG_BUS_TYPE            0x00000007
+#define CFG_MEM_TYPE            0x00000038
+#define CFG_INIT_DAC_TYPE       0x00000e00
+
+/* CONFIG_STAT0 register constants (CT, ET, VT) */
+#define CFG_MEM_TYPE_xT         0x00000007
+
+#define ISA                     0
+#define EISA                    1
+#define LOCAL_BUS               6
+#define PCI                     7
+
+/* Memory types for GX, CX */
+#define DRAMx4                  0
+#define VRAMx16                 1
+#define VRAMx16ssr              2
+#define DRAMx16                 3
+#define GraphicsDRAMx16         4
+#define EnhancedVRAMx16         5
+#define EnhancedVRAMx16ssr      6
+
+/* Memory types for CT, ET, VT, GT */
+#define DRAM                    0
+#define EDO_DRAM                1
+#define PSEUDO_EDO              2
+#define SDRAM                   3
+
+#define DAC_INTERNAL            0x00
+#define DAC_IBMRGB514           0x01
+#define DAC_ATI68875            0x02
+#define DAC_TVP3026_A           0x72
+#define DAC_BT476               0x03
+#define DAC_BT481               0x04
+#define DAC_ATT20C491           0x14
+#define DAC_SC15026             0x24
+#define DAC_MU9C1880            0x34
+#define DAC_IMSG174             0x44
+#define DAC_ATI68860_B          0x05
+#define DAC_ATI68860_C          0x15
+#define DAC_TVP3026_B           0x75
+#define DAC_STG1700             0x06
+#define DAC_ATT498              0x16
+#define DAC_STG1702             0x07
+#define DAC_SC15021             0x17
+#define DAC_ATT21C498           0x27
+#define DAC_STG1703             0x37
+#define DAC_CH8398              0x47
+#define DAC_ATT20C408           0x57
+
+#define CLK_ATI18818_0          0
+#define CLK_ATI18818_1          1
+#define CLK_STG1703             2
+#define CLK_CH8398              3
+#define CLK_INTERNAL            4
+#define CLK_ATT20C408           5
+#define CLK_IBMRGB514           6
+
+/* MEM_CNTL register constants */
+#define MEM_SIZE_ALIAS          0x00000007
+#define MEM_SIZE_512K           0x00000000
+#define MEM_SIZE_1M             0x00000001
+#define MEM_SIZE_2M             0x00000002
+#define MEM_SIZE_4M             0x00000003
+#define MEM_SIZE_6M             0x00000004
+#define MEM_SIZE_8M             0x00000005
+#define MEM_SIZE_ALIAS_GTB      0x0000000F
+#define MEM_SIZE_2M_GTB         0x00000003
+#define MEM_SIZE_4M_GTB         0x00000007
+#define MEM_SIZE_6M_GTB         0x00000009
+#define MEM_SIZE_8M_GTB         0x0000000B
+#define MEM_BNDRY               0x00030000
+#define MEM_BNDRY_0K            0x00000000
+#define MEM_BNDRY_256K          0x00010000
+#define MEM_BNDRY_512K          0x00020000
+#define MEM_BNDRY_1M            0x00030000
+#define MEM_BNDRY_EN            0x00040000
+
+/* ATI PCI constants */
+#define PCI_ATI_VENDOR_ID       0x1002
+#define PCI_MACH64_GX           0x4758
+#define PCI_MACH64_CX           0x4358
+#define PCI_MACH64_CT           0x4354
+#define PCI_MACH64_ET           0x4554
+#define PCI_MACH64_VT           0x5654
+#define PCI_MACH64_GT           0x4754
+
+/* CONFIG_CHIP_ID register constants */
+#define CFG_CHIP_TYPE           0x0000FFFF
+#define CFG_CHIP_CLASS          0x00FF0000
+#define CFG_CHIP_REV            0xFF000000
+#define CFG_CHIP_VERSION        0x07000000
+#define CFG_CHIP_FOUNDRY        0x38000000
+#define CFG_CHIP_REVISION       0xC0000000
+
+/* Chip IDs read from CONFIG_CHIP_ID */
+#define MACH64_GX_ID            0xD7
+#define MACH64_CX_ID            0x57
+#define MACH64_CT_ID            0x4354
+#define MACH64_ET_ID            0x4554
+#define MACH64_VT_ID            0x5654
+#define MACH64_GT_ID            0x4754
+
+/* Mach64 chip types */
+#define MACH64_UNKNOWN	0
+#define MACH64_GX	1
+#define MACH64_CX	2
+#define MACH64_CT	3
+#define MACH64_ET	4
+#define MACH64_VT	5
+#define MACH64_GT	6
+
+/* DST_CNTL register constants */
+#define DST_X_RIGHT_TO_LEFT     0
+#define DST_X_LEFT_TO_RIGHT     1
+#define DST_Y_BOTTOM_TO_TOP     0
+#define DST_Y_TOP_TO_BOTTOM     2
+#define DST_X_MAJOR             0
+#define DST_Y_MAJOR             4
+#define DST_X_TILE              8
+#define DST_Y_TILE              0x10
+#define DST_LAST_PEL            0x20
+#define DST_POLYGON_ENABLE      0x40
+#define DST_24_ROTATION_ENABLE  0x80
+
+/* SRC_CNTL register constants */
+#define SRC_PATTERN_ENABLE      1
+#define SRC_ROTATION_ENABLE     2
+#define SRC_LINEAR_ENABLE       4
+#define SRC_BYTE_ALIGN          8
+#define SRC_LINE_X_RIGHT_TO_LEFT 0
+#define SRC_LINE_X_LEFT_TO_RIGHT 0x10
+
+/* HOST_CNTL register constants */
+#define HOST_BYTE_ALIGN         1
+
+/* GUI_TRAJ_CNTL register constants */
+#define PAT_MONO_8x8_ENABLE     0x01000000
+#define PAT_CLR_4x2_ENABLE      0x02000000
+#define PAT_CLR_8x1_ENABLE      0x04000000
+
+/* DP_CHAIN_MASK register constants */
+#define DP_CHAIN_4BPP	0x8888
+#define DP_CHAIN_7BPP	0xD2D2
+#define DP_CHAIN_8BPP	0x8080
+#define DP_CHAIN_8BPP_RGB	0x9292
+#define DP_CHAIN_15BPP	0x4210
+#define DP_CHAIN_16BPP	0x8410
+#define DP_CHAIN_24BPP	0x8080
+#define DP_CHAIN_32BPP	0x8080
+
+/* DP_PIX_WIDTH register constants */
+#define DST_1BPP                0
+#define DST_4BPP                1
+#define DST_8BPP                2
+#define DST_15BPP               3
+#define DST_16BPP               4
+#define DST_32BPP               6
+#define SRC_1BPP                0
+#define SRC_4BPP                0x100
+#define SRC_8BPP                0x200
+#define SRC_15BPP               0x300
+#define SRC_16BPP               0x400
+#define SRC_32BPP               0x600
+#define HOST_1BPP               0
+#define HOST_4BPP               0x10000
+#define HOST_8BPP               0x20000
+#define HOST_15BPP              0x30000
+#define HOST_16BPP              0x40000
+#define HOST_32BPP              0x60000
+#define BYTE_ORDER_MSB_TO_LSB   0
+#define BYTE_ORDER_LSB_TO_MSB   0x1000000
+
+/* DP_MIX register constants */
+#define BKGD_MIX_NOT_D              0
+#define BKGD_MIX_ZERO               1
+#define BKGD_MIX_ONE                2
+#define BKGD_MIX_D                  3
+#define BKGD_MIX_NOT_S              4
+#define BKGD_MIX_D_XOR_S            5
+#define BKGD_MIX_NOT_D_XOR_S        6
+#define BKGD_MIX_S                  7
+#define BKGD_MIX_NOT_D_OR_NOT_S     8
+#define BKGD_MIX_D_OR_NOT_S         9
+#define BKGD_MIX_NOT_D_OR_S         10
+#define BKGD_MIX_D_OR_S             11
+#define BKGD_MIX_D_AND_S            12
+#define BKGD_MIX_NOT_D_AND_S        13
+#define BKGD_MIX_D_AND_NOT_S        14
+#define BKGD_MIX_NOT_D_AND_NOT_S    15
+#define BKGD_MIX_D_PLUS_S_DIV2      0x17
+#define FRGD_MIX_NOT_D              0
+#define FRGD_MIX_ZERO               0x10000
+#define FRGD_MIX_ONE                0x20000
+#define FRGD_MIX_D                  0x30000
+#define FRGD_MIX_NOT_S              0x40000
+#define FRGD_MIX_D_XOR_S            0x50000
+#define FRGD_MIX_NOT_D_XOR_S        0x60000
+#define FRGD_MIX_S                  0x70000
+#define FRGD_MIX_NOT_D_OR_NOT_S     0x80000
+#define FRGD_MIX_D_OR_NOT_S         0x90000
+#define FRGD_MIX_NOT_D_OR_S         0xa0000
+#define FRGD_MIX_D_OR_S             0xb0000
+#define FRGD_MIX_D_AND_S            0xc0000
+#define FRGD_MIX_NOT_D_AND_S        0xd0000
+#define FRGD_MIX_D_AND_NOT_S        0xe0000
+#define FRGD_MIX_NOT_D_AND_NOT_S    0xf0000
+#define FRGD_MIX_D_PLUS_S_DIV2      0x170000
+
+/* DP_SRC register constants */
+#define BKGD_SRC_BKGD_CLR           0
+#define BKGD_SRC_FRGD_CLR           1
+#define BKGD_SRC_HOST               2
+#define BKGD_SRC_BLIT               3
+#define BKGD_SRC_PATTERN            4
+#define FRGD_SRC_BKGD_CLR           0
+#define FRGD_SRC_FRGD_CLR           0x100
+#define FRGD_SRC_HOST               0x200
+#define FRGD_SRC_BLIT               0x300
+#define FRGD_SRC_PATTERN            0x400
+#define MONO_SRC_ONE                0
+#define MONO_SRC_PATTERN            0x10000
+#define MONO_SRC_HOST               0x20000
+#define MONO_SRC_BLIT               0x30000
+
+/* CLR_CMP_CNTL register constants */
+#define COMPARE_FALSE               0
+#define COMPARE_TRUE                1
+#define COMPARE_NOT_EQUAL           4
+#define COMPARE_EQUAL               5
+#define COMPARE_DESTINATION         0
+#define COMPARE_SOURCE              0x1000000
+
+/* FIFO_STAT register constants */
+#define FIFO_ERR                    0x80000000
+
+/* CONTEXT_LOAD_CNTL constants */
+#define CONTEXT_NO_LOAD             0
+#define CONTEXT_LOAD                0x10000
+#define CONTEXT_LOAD_AND_DO_FILL    0x20000
+#define CONTEXT_LOAD_AND_DO_LINE    0x30000
+#define CONTEXT_EXECUTE             0
+#define CONTEXT_CMD_DISABLE         0x80000000
+
+/* GUI_STAT register constants */
+#define ENGINE_IDLE                 0
+#define ENGINE_BUSY                 1
+#define SCISSOR_LEFT_FLAG           0x10
+#define SCISSOR_RIGHT_FLAG          0x20
+#define SCISSOR_TOP_FLAG            0x40
+#define SCISSOR_BOTTOM_FLAG         0x80
+
+/* ATI VGA Extended Regsiters */
+#define sioATIEXT	0x1ce
+#define bioATIEXT	0x3ce
+extern unsigned ATIExtReg;
+#define ATI2E		0xae
+#define ATI32		0xb2
+#define ATI36		0xb6
+
+/* VGA Graphics Controller Registers */
+#define VGAGRA		0x3ce
+#define GRA06		0x06
+
+/* VGA Seququencer Registers */
+#define VGASEQ		0x3c4
+#define SEQ02		0x02
+#define SEQ04		0x04
+
+#define MACH64_MAX_X	ENGINE_MAX_X
+#define MACH64_MAX_Y	ENGINE_MAX_Y
+
+#define INC_X                   0x0020
+#define INC_Y                   0x0080
+
+#define RGB16_555               0x0000
+#define RGB16_565               0x0040
+#define RGB16_655               0x0080
+#define RGB16_664               0x00c0
+
+#define POLY_TEXT_TYPE          0x0001
+#define IMAGE_TEXT_TYPE         0x0002
+#define TEXT_TYPE_8_BIT         0x0004
+#define TEXT_TYPE_16_BIT        0x0008
+#define POLY_TEXT_TYPE_8        (POLY_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define IMAGE_TEXT_TYPE_8       (IMAGE_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define POLY_TEXT_TYPE_16       (POLY_TEXT_TYPE | TEXT_TYPE_16_BIT)
+#define IMAGE_TEXT_TYPE_16      (IMAGE_TEXT_TYPE | TEXT_TYPE_16_BIT)
+
+#define MACH64_NUM_CLOCKS	16
+#define MACH64_NUM_FREQS	50
+
+/*============================================================================*/
+
+typedef struct
+{
+    unsigned char h_disp;
+    unsigned char dacmask;
+    unsigned char ram_req;
+    unsigned char max_dot_clock;
+    unsigned char color_depth;
+}
+mach64FreqRec;
+
+typedef struct
+{
+    unsigned char r, g, b;
+}
+LUTENTRY;
+
+typedef struct
+{
+    unsigned long h_total_disp, h_sync_strt_wid;
+    unsigned long v_total_disp, v_sync_strt_wid;
+    unsigned long crtc_gen_cntl;
+    unsigned long color_depth;
+    unsigned long clock_cntl;
+    unsigned long dot_clock;
+    unsigned long fifo_v1;
+}
+mach64CRTCRegRec, * mach64CRTCRegPtr;
+
+
+/* Wait until "v" queue entries are free */
+#define WaitQueue(v)  \
+{ \
+  int   __cntr = 0;      \
+  while((regr(FIFO_STAT) & 0xFFFF) > ((unsigned short)(0x8000 >> (v))))  \
+  { \
+    if(__cntr++ > 500000)    \
+    { \
+      Eprint(" Timeout Waiting for FIFO. \n"); \
+    } \
+  } \
+}
+
+/* Wait until GP is idle and queue is empty */
+#define WaitIdleEmpty() \
+{  \
+  int   __cntr = 0;      \
+  WaitQueue(16); \
+  while ((regr(GUI_STAT) & 1) != 0) \
+  { \
+    if(__cntr++ > 500000)    \
+    { \
+      Eprint(" Timeout Waiting for BLT engine. \n"); \
+    } \
+  } \
+}
+
+#define SKIP_2(_v) ((((_v)<<1)&0xFFF8)|((_v)&0x3)|(((_v)&0x80)>>5))
+
+#define MACH64_BIT_BLT(_srcx, _srcy, _dstx, _dsty, _w, _h, _dir) \
+{ \
+  WaitQueue(5); \
+  regw(SRC_Y_X, (((_srcx) << 16) | ((_srcy) & 0x0000FFFF))); \
+  regw(SRC_WIDTH1, (_w)); \
+  regw(DST_CNTL, (_dir)); \
+  regw(DST_Y_X, (((_dstx) << 16) | ((_dsty) & 0x0000FFFF))); \
+  regw(DST_HEIGHT_WIDTH, (((_w) << 16) | ((_h) & 0x0000FFFF))); \
+}
+
+#ifndef NULL
+#define NULL    0
+#endif
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define MACH64REGS_H_ID \
+  "@(#) Linux-m68k: 1997 11 21 17:00:18 BHA: mach64regs.h "
+
+/*                                      ^^^                           */
+/* Please update this & put your initials here on every modification. */
+/* It can be checked with '  strings vmlinux | grep "@(#) "  '        */
+/*============================================================================*/
+
+#endif /* MACH64REGS_H */
--- m68k-2.1.72/drivers/video/offb.c.orig	Wed Dec 17 23:54:30 1997
+++ m68k-2.1.72/drivers/video/offb.c	Wed Dec 17 23:56:50 1997
@@ -0,0 +1,454 @@
+/*
+ *  linux/drivers/video/offb.c -- Open Firmware based frame buffer device
+ *
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This driver is partly based on the PowerMac console driver:
+ *
+ *	Copyright (C) 1996 Paul Mackerras
+ *
+ *  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/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+
+static volatile unsigned char *unknown_cmap_adr = NULL;
+static volatile unsigned char *unknown_cmap_data = NULL;
+
+static struct fb_fix_screeninfo fb_fix = { { "OFfb ", } };
+static struct fb_var_screeninfo fb_var = { 0, };
+
+#ifdef __powerpc__
+#define mach_eieio()	eieio()
+#else
+#define mach_eieio()	do {} while (0)
+#endif
+
+
+    /*
+     *  Interface used by the world
+     */
+
+static int offb_open(int fbidx);
+static int offb_release(int fbidx);
+static int offb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
+static int offb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int offb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int offb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx);
+static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
+static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
+static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			    u_long arg, int con, int fbidx);
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+unsigned long offb_init(unsigned long mem_start);
+static int offbcon_switch(int con);
+static int offbcon_updatevar(int con);
+static void offbcon_blank(int blank);
+
+
+    /*
+     *  Internal routines
+     */
+
+static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp);
+static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp);
+static void do_install_cmap(int con);
+
+
+static struct fb_ops offb_ops = {
+    offb_open, offb_release, offb_get_fix, offb_get_var, offb_set_var,
+    offb_get_cmap, offb_set_cmap, offb_pan_display, offb_ioctl
+};
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int offb_open(int fbidx)                                       
+{
+    /*                                                                     
+     *  Nothing, only a usage count for the moment                          
+     */                                                                    
+
+    MOD_INC_USE_COUNT;
+    return(0);                              
+}
+        
+static int offb_release(int fbidx)
+{
+    MOD_DEC_USE_COUNT;
+    return(0);                                                    
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int offb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+{
+    memcpy(fix, &fb_fix, sizeof(fb_fix));
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int offb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+    memcpy(var, &fb_var, sizeof(fb_var));
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int offb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+    struct display *display;
+    int oldbpp = -1, err;
+
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &disp;	/* used during initialization */
+
+    if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
+	var->xres_virtual > fb_var.xres_virtual ||
+	var->yres_virtual > fb_var.yres_virtual ||
+	var->bits_per_pixel > fb_var.bits_per_pixel ||
+	var->nonstd ||
+	(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+	return -EINVAL;
+    memcpy(var, &fb_var, sizeof(fb_var));
+
+    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	oldbpp = display->var.bits_per_pixel;
+	display->var = *var;
+    }
+    if (oldbpp != var->bits_per_pixel) {
+	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+	    return err;
+	do_install_cmap(con);
+    }
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int offb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+    if (var->xoffset || var->yoffset)
+	return -EINVAL;
+    else
+	return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, offb_getcolreg);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+{
+    int err;
+
+    if (!unknown_cmap_adr)
+	return -ENOSYS;
+
+    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 fb_set_cmap(cmap, &fb_display[con].var, kspc, offb_setcolreg);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		      u_long arg, int con, int fbidx)
+{
+    return -EINVAL;
+}
+
+
+    /*
+     *  Initialisation
+     */
+
+__initfunc(unsigned long offb_init(unsigned long mem_start))
+{
+    struct device_node *dp;
+    int i, err, *pp, len;
+    unsigned *up, address;
+
+    if (!prom_display_path[0])
+	return mem_start;
+    if (!(dp = find_path_device(prom_display_path)))
+	return mem_start;
+
+    strncat(fb_fix.id, dp->name, sizeof(fb_fix.id));
+    fb_fix.id[sizeof(fb_fix.id)-1] = '\0';
+
+    if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
+	&& len == sizeof(int) && *pp != 8) {
+	printk("%s: can't use depth = %d\n", dp->full_name, *pp);
+	return mem_start;
+    }
+    if ((pp = (int *)get_property(dp, "width", &len)) != NULL
+	&& len == sizeof(int))
+	fb_var.xres = fb_var.xres_virtual = *pp;
+    if ((pp = (int *)get_property(dp, "height", &len)) != NULL
+	&& len == sizeof(int))
+	fb_var.yres = fb_var.yres_virtual = *pp;
+    if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
+	&& len == sizeof(int))
+	fb_fix.line_length = *pp;
+    else
+	fb_fix.line_length = fb_var.xres_virtual;
+    fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
+    if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
+	&& len == sizeof(unsigned))
+	address = (u_long)*up;
+    else {
+	for (i = 0; i < dp->n_addrs; ++i)
+	    if (dp->addrs[i].size >= len)
+		break;
+	if (i >= dp->n_addrs) {
+	    printk("no framebuffer address found for %s\n", dp->full_name);
+	    return mem_start;
+	}
+	address = (u_long)dp->addrs[i].address;
+    }
+    fb_fix.smem_start = ioremap(address, fb_fix.smem_len);
+    fb_fix.type = FB_TYPE_PACKED_PIXELS;
+    fb_fix.type_aux = 0;
+
+    /* XXX kludge for ati */
+    if (strncmp(dp->name, "ATY,", 4) == 0) {
+	unknown_cmap_adr = ioremap(address + 0x7ff000, 0x1000) + 0xcc0;
+	unknown_cmap_data = unknown_cmap_adr + 1;
+    }
+
+    fb_fix.visual = unknown_cmap_adr ? FB_VISUAL_PSEUDOCOLOR :
+				       FB_VISUAL_STATIC_PSEUDOCOLOR;
+
+    fb_var.xoffset = fb_var.yoffset = 0;
+    fb_var.bits_per_pixel = 8;
+    fb_var.grayscale = 0;
+    fb_var.red.offset = fb_var.green.offset = fb_var.blue.offset = 0;
+    fb_var.red.length = fb_var.green.length = fb_var.blue.length = 8;
+    fb_var.red.msb_right = fb_var.green.msb_right = fb_var.blue.msb_right = 0;
+    fb_var.transp.offset = fb_var.transp.length = fb_var.transp.msb_right = 0;
+    fb_var.nonstd = 0;
+    fb_var.activate = 0;
+    fb_var.height = fb_var.width = -1;
+    fb_var.accel = FB_ACCEL_NONE;
+    fb_var.pixclock = 10000;
+    fb_var.left_margin = fb_var.right_margin = 16;
+    fb_var.upper_margin = fb_var.lower_margin = 16;
+    fb_var.hsync_len = fb_var.vsync_len = 8;
+    fb_var.sync = 0;
+    fb_var.vmode = FB_VMODE_NONINTERLACED;
+
+    disp.var = fb_var;
+    disp.cmap.start = 0;
+    disp.cmap.len = 0;
+    disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
+    disp.screen_base = fb_fix.smem_start;
+    disp.visual = fb_fix.visual;
+    disp.type = fb_fix.type;
+    disp.type_aux = fb_fix.type_aux;
+    disp.ypanstep = 0;
+    disp.ywrapstep = 0;
+    disp.line_length = fb_fix.line_length;
+    disp.can_soft_blank = unknown_cmap_adr ? 1 : 0;
+    disp.inverse = 0;
+
+    strcpy(fb_info.modename, "OFfb ");
+    strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
+    fb_info.node = -1;
+    fb_info.fbops = &offb_ops;
+    fb_info.disp = &disp;
+    fb_info.fontname[0] = '\0';
+    fb_info.changevar = NULL;
+    fb_info.switch_con = &offbcon_switch;
+    fb_info.updatevar = &offbcon_updatevar;
+    fb_info.blank = &offbcon_blank;
+
+    err = register_framebuffer(&fb_info);
+    if (err < 0)
+	return mem_start;
+
+    for (i = 0; i < 16; i++) {
+	int j = color_table[i];
+	palette[i].red = default_red[j];
+	palette[i].green = default_grn[j];
+	palette[i].blue = default_blu[j];
+    }
+    offb_set_var(&fb_var, -1, GET_FB_IDX(fb_info.node));
+
+    printk("Open Firmware frame buffer device on %s\n", dp->full_name);
+    return mem_start;
+}
+
+
+static int offbcon_switch(int con)
+{
+    /* Do we have to save the colormap? */
+    if (fb_display[currcon].cmap.len)
+	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+		    offb_getcolreg);
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int offbcon_updatevar(int con)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void offbcon_blank(int blank)
+{
+    int i, j;
+
+    if (!unknown_cmap_adr)
+	return;
+
+    if (blank)
+	for (i = 0; i < 256; i++) {
+	    *unknown_cmap_adr = i;
+	    mach_eieio();
+	    for (j = 0; j < 3; j++) {
+		*unknown_cmap_data = 0;
+		mach_eieio();
+	    }
+	}
+    else
+	do_install_cmap(currcon);
+}
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp)
+{
+    if (!unknown_cmap_adr || regno > 255)
+	return 1;
+    *red = palette[regno].red;
+    *green = palette[regno].green;
+    *blue = palette[regno].blue;
+    return 0;
+}
+
+
+    /*
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
+     */
+
+static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp)
+{
+    if (!unknown_cmap_adr || regno > 255)
+	return 1;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+    *unknown_cmap_adr = regno;
+    mach_eieio();
+    *unknown_cmap_data = red;
+    mach_eieio();
+    *unknown_cmap_data = green;
+    mach_eieio();
+    *unknown_cmap_data = blue;
+    mach_eieio();
+    return 0;
+}
+
+
+static void do_install_cmap(int con)
+{
+    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+		    offb_setcolreg);
+    else
+	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+				    &fb_display[con].var, 1, offb_setcolreg);
+}
--- m68k-2.1.72/drivers/video/retz3fb.c.orig	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.72/drivers/video/retz3fb.c	Wed Dec 17 23:55:41 1997
@@ -54,7 +54,7 @@
 
 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
 
-struct retz3_fb_par {
+struct retz3fb_par {
 	int xres;
 	int yres;
 	int xres_vir;
@@ -93,7 +93,7 @@
 	long v_dispend;		/* Horizontal Display End */
 };
 
-static struct retz3_fb_par current_par;
+static struct retz3fb_par current_par;
 
 static int current_par_valid = 0;
 static int currcon = 0;
@@ -114,9 +114,9 @@
 
    /* Display Control */
 
-   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3_fb_par *par);
-   int (*decode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par);
-   int (*encode_var)(struct fb_var_screeninfo *var, struct retz3_fb_par *par);
+   int (*encode_fix)(struct fb_fix_screeninfo *fix, struct retz3fb_par *par);
+   int (*decode_var)(struct fb_var_screeninfo *var, struct retz3fb_par *par);
+   int (*encode_var)(struct fb_var_screeninfo *var, struct retz3fb_par *par);
    int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned
 		    int *green, unsigned int *blue, unsigned int *transp);
    int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int
@@ -129,7 +129,7 @@
  *    Frame Buffer Name
  */
 
-static char retz3_fb_name[16] = "RetinaZ3";
+static char retz3fb_name[16] = "RetinaZ3";
 
 
 static unsigned char retz3_color_table [256][4];
@@ -140,46 +140,6 @@
 
 
 /*
- *    Predefined Video Mode Names
- */
-
-static char *retz3_fb_modenames[] = {
-
-	/*
-	 *    Autodetect (Default) Video Mode
-	 */
-
-	"default",
-
-	/*
-	 *    Predefined Video Modes
-	 */
-
-	"640x480",		/* RetinaZ3 8 bpp */
-	"800x600",		/* RetinaZ3 8 bpp */
-	"1024x768i",
-	"640x480-16",		/* RetinaZ3 16 bpp */
-	"640x480-24",		/* RetinaZ3 24 bpp */
-	
-	/*
-	 *    Dummy Video Modes
-	 */
-
-	"dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-	"dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-	"dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
-
-	/*
-	 *    User Defined Video Modes
-	 *
-	 *    This doesn't work yet!!
-	 */
-
-	"user0", "user1", "user2", "user3",
-	"user4", "user5", "user6", "user7"
-};
-
-/*
  * A small info on how to convert XFree86 timing values into fb
  * timings - by Frank Neumann:
  *
@@ -217,117 +177,101 @@
 */
 
 /*
- *    Predefined Video Mode Definitions
+ *    Predefined Video Modes
  */
 
-static struct fb_var_screeninfo retz3_fb_predefined[] = {
-
-   /*
-    *    Autodetect (Default) Video Mode
-    */
-
-   { 0, },
-
-   /*
-    *    Predefined Video Modes
-    */
-
-   /*
-    * NB: it is very important to adjust the pixel-clock to the color-depth.
-    */
-
-   {
-	   640, 480, 640, 480, 0, 0, 8, 0,
-	   {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	   0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2,
-	   FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   },
-   /*
-    ModeLine "800x600" 36 800 824 896 1024 600 601 603 625
-             < name > DCF HR  SH1 SH2  HFL VR  SV1 SV2 VFL
-    */
-   {
-	   /* 800 x 600, 8 bpp */
-	   800, 600, 800, 600, 0, 0, 8, 0,
-	   {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	   0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2,
-	   FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   },
-   /*
-    ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace
-              < name >   DCF HR  SH1  SH2  HFL  VR  SV1 SV2 VFL
-    */
-   {
-	   /* 1024 x 768, 8 bpp, interlaced */
-	   1024, 768, 1024, 768, 0, 0, 8, 0,
-	   {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	   0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8,
-	   FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED
-   },
-   {
-	   640, 480, 640, 480, 0, 0, 16, 0,
-	   {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	   0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2,
-	   FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   },
-   {
-	   640, 480, 640, 480, 0, 0, 24, 0,
-	   {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, 
-	   0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2,
-	   FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-   },
-
-   /*
-    *    Dummy Video Modes
-    */
-
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
-   { 0, }, { 0, },
-
-   /*
-    *    User Defined Video Modes
-    */
-
-   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+static struct fb_videomode retz3fb_predefined[] __initdata = {
+    /*
+     * NB: it is very important to adjust the pixel-clock to the color-depth.
+     */
+
+    {
+	"640x480", {		/* 640x480, 8 bpp */
+	    640, 480, 640, 480, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461, 28, 32, 12, 10, 96, 2,
+	    FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    },
+    /*
+     ModeLine "800x600" 36 800 824 896 1024 600 601 603 625
+	      < name > DCF HR  SH1 SH2  HFL VR  SV1 SV2 VFL
+     */
+    {
+	"800x600", {		/* 800x600, 8 bpp */
+	    800, 600, 800, 600, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_RETINAZ3, 27778, 64, 24, 22, 1, 120, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    },
+    /*
+     ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace
+	       < name >   DCF HR  SH1  SH2  HFL  VR  SV1 SV2 VFL
+     */
+    {
+	"1024x768i", {		/* 1024x768, 8 bpp, interlaced */
+	    1024, 768, 1024, 768, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_RETINAZ3, 22222, 40, 40, 32, 9, 160, 8,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED
+	}
+    }, {
+	"640x480-16", {		/* 640x480, 16 bpp */
+	    640, 480, 640, 480, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/2, 28, 32, 12, 10, 96, 2,
+	    FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }, {
+	"640x480-24", {		/* 640x480, 24 bpp */
+	    640, 480, 640, 480, 0, 0, 24, 0,
+	    {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0}, 
+	    0, 0, -1, -1, FB_ACCEL_RETINAZ3, 38461/3, 28, 32, 12, 10, 96, 2,
+	    FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    },
 };
 
 
-#define NUM_TOTAL_MODES    arraysize(retz3_fb_predefined)
-#define NUM_PREDEF_MODES   5
+#define NUM_TOTAL_MODES    arraysize(retz3fb_predefined)
 
+static struct fb_var_screeninfo retz3fb_default;
 
 static int z3fb_inverse = 0;
-static int z3fb_mode = 0;
+static int z3fb_mode __initdata = 0;
 
 
 /*
  *    Interface used by the world
  */
 
-void retz3_video_setup(char *options, int *ints);
+void retz3fb_setup(char *options, int *ints);
 
-static int retz3_fb_open(int fbidx);
-static int retz3_fb_release(int fbidx);
-static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
-static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con);
-static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con);
-static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con);
-static int retz3_fb_ioctl(struct inode *inode, struct file *file,
-			  unsigned int cmd, unsigned long arg, int con);
+static int retz3fb_open(int fbidx);
+static int retz3fb_release(int fbidx);
+static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
+static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx);
+static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx);
+static int retz3fb_pan_display(struct fb_var_screeninfo *var, int con,
+				int fbidx);
+static int retz3fb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg, int con,
+			  int fbidx);
 
 
 /*
  *    Interface to the low level console driver
  */
 
-unsigned long retz3_fb_init(unsigned long mem_start);
+unsigned long retz3fb_init(unsigned long mem_start);
 static int z3fb_switch(int con);
 static int z3fb_updatevar(int con);
 static void z3fb_blank(int blank);
-static int z3fb_setcmap(struct fb_cmap *cmap, int con);
 
 
 /*
@@ -349,11 +293,11 @@
 
 static int retz3_init(void);
 static int retz3_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct retz3_fb_par *par);
+                          struct retz3fb_par *par);
 static int retz3_decode_var(struct fb_var_screeninfo *var,
-                          struct retz3_fb_par *par);
+                          struct retz3fb_par *par);
 static int retz3_encode_var(struct fb_var_screeninfo *var,
-                          struct retz3_fb_par *par);
+                          struct retz3fb_par *par);
 static int retz3_getcolreg(unsigned int regno, unsigned int *red,
 			   unsigned int *green, unsigned int *blue,
 			   unsigned int *transp);
@@ -367,12 +311,12 @@
  *    Internal routines
  */
 
-static void retz3_fb_get_par(struct retz3_fb_par *par);
-static void retz3_fb_set_par(struct retz3_fb_par *par);
+static void retz3fb_get_par(struct retz3fb_par *par);
+static void retz3fb_set_par(struct retz3fb_par *par);
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
 static void do_install_cmap(int con);
 /*
-static void retz3_fb_set_disp(int con);
+static void retz3fb_set_disp(int con);
 */
 static int get_video_mode(const char *name);
 
@@ -424,7 +368,7 @@
 
 
 static int retz3_set_video(struct fb_var_screeninfo *var,
-			   struct retz3_fb_par *par)
+			   struct retz3fb_par *par)
 {
 	float freq_f;
 	long freq;
@@ -867,11 +811,11 @@
  */
 
 static int retz3_encode_fix(struct fb_fix_screeninfo *fix,
-			    struct retz3_fb_par *par)
+			    struct retz3fb_par *par)
 {
 	short i;
 
-	strcpy(fix->id, retz3_fb_name);
+	strcpy(fix->id, retz3fb_name);
 	fix->smem_start = (char *)z3_fbmem;
 	fix->smem_len = z3_size;
 	fix->mmio_start = (unsigned char *)z3_regs;
@@ -902,7 +846,7 @@
  */
 
 static int retz3_decode_var(struct fb_var_screeninfo *var,
-			    struct retz3_fb_par *par)
+			    struct retz3fb_par *par)
 {
 	par->xres = var->xres;
 	par->yres = var->yres;
@@ -934,7 +878,7 @@
  */
 
 static int retz3_encode_var(struct fb_var_screeninfo *var,
-			    struct retz3_fb_par *par)
+			    struct retz3fb_par *par)
 {
 	short i;
 
@@ -1189,16 +1133,16 @@
  *    Fill the hardware's `par' structure.
  */
 
-static void retz3_fb_get_par(struct retz3_fb_par *par)
+static void retz3fb_get_par(struct retz3fb_par *par)
 {
 	if (current_par_valid)
 		*par = current_par;
 	else
-		fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], par);
+		fbhw->decode_var(&retz3fb_default, par);
 }
 
 
-static void retz3_fb_set_par(struct retz3_fb_par *par)
+static void retz3fb_set_par(struct retz3fb_par *par)
 {
 	current_par = *par;
 	current_par_valid = 1;
@@ -1208,7 +1152,7 @@
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
 {
 	int err, activate;
-	struct retz3_fb_par par;
+	struct retz3fb_par par;
 
 	if ((err = fbhw->decode_var(var, &par)))
 		return err;
@@ -1217,7 +1161,7 @@
 	/* XXX ... what to do about isactive ? */
 
 	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
-		retz3_fb_set_par(&par);
+		retz3fb_set_par(&par);
 	fbhw->encode_var(var, &par);
 	var->activate = activate;
 
@@ -1245,7 +1189,7 @@
  *    Open/Release the frame buffer device
  */
 
-static int retz3_fb_open(int fbidx)
+static int retz3fb_open(int fbidx)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -1255,7 +1199,7 @@
 	return 0;
 }
 
-static int retz3_fb_release(int fbidx)
+static int retz3fb_release(int fbidx)
 {
 	MOD_DEC_USE_COUNT;
 	return 0;
@@ -1266,13 +1210,13 @@
  *    Get the Fixed Part of the Display
  */
 
-static int retz3_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
 {
-	struct retz3_fb_par par;
+	struct retz3fb_par par;
 	int error = 0;
 
 	if (con == -1)
-		retz3_fb_get_par(&par);
+		retz3fb_get_par(&par);
 	else
 		error = fbhw->decode_var(&fb_display[con].var, &par);
 	return(error ? error : fbhw->encode_fix(fix, &par));
@@ -1283,13 +1227,13 @@
  *    Get the User Defined Part of the Display
  */
 
-static int retz3_fb_get_var(struct fb_var_screeninfo *var, int con)
+static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
-	struct retz3_fb_par par;
+	struct retz3fb_par par;
 	int error = 0;
 
 	if (con == -1) {
-		retz3_fb_get_par(&par);
+		retz3fb_get_par(&par);
 		error = fbhw->encode_var(var, &par);
 	} else
 		*var = fb_display[con].var;
@@ -1298,7 +1242,7 @@
 
 
 #if 1
-static void retz3_fb_set_disp(int con)
+static void retz3fb_set_disp(int con)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -1308,7 +1252,8 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	retz3_fb_get_fix(&fix, con);
+	/* ### FN: Needs fixes later */
+	retz3fb_get_fix(&fix, con, 0);
 
 	if (con == -1)
 		con = 0;
@@ -1328,7 +1273,7 @@
  *    Set the User Defined Part of the Display
  */
 
-static int retz3_fb_set_var(struct fb_var_screeninfo *var, int con)
+static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
 	struct display *display;
@@ -1359,7 +1304,7 @@
 		    oldbpp != var->bits_per_pixel) {
 
 			struct fb_fix_screeninfo fix;
-			retz3_fb_get_fix(&fix, con);
+			retz3fb_get_fix(&fix, con, fbidx);
 
 			display->screen_base = fix.smem_start;
 			display->visual = fix.visual;
@@ -1371,7 +1316,7 @@
 			display->can_soft_blank = 1;
 			display->inverse = z3fb_inverse;
 /*
-	retz3_fb_set_disp(con);
+	retz3fb_set_disp(con);
 */
 			if (fb_info.changevar)
 				(*fb_info.changevar)(con);
@@ -1391,7 +1336,8 @@
  *    Get the Colormap
  */
 
-static int retz3_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx)
 {
 	if (con == currcon) /* current console? */
 		return(fb_get_cmap(cmap, &fb_display[con].var, kspc,
@@ -1409,7 +1355,8 @@
  *    Set the Colormap
  */
 
-static int retz3_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			     int fbidx)
 {
 	int err;
 
@@ -1434,7 +1381,8 @@
  *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  */
 
-static int retz3_fb_pan_display(struct fb_var_screeninfo *var, int con)
+static int retz3fb_pan_display(struct fb_var_screeninfo *var, int con,
+				int fbidx)
 {
 	return -EINVAL;
 }
@@ -1444,21 +1392,22 @@
  *    RetinaZ3 Frame Buffer Specific ioctls
  */
 
-static int retz3_fb_ioctl(struct inode *inode, struct file *file,
-                          unsigned int cmd, unsigned long arg, int con)
+static int retz3fb_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, unsigned long arg, int con,
+                          int fbidx)
 {
 	return -EINVAL;
 }
 
 
-static struct fb_ops retz3_fb_ops = {
-	retz3_fb_open, retz3_fb_release, retz3_fb_get_fix, retz3_fb_get_var,
-	retz3_fb_set_var, retz3_fb_get_cmap, retz3_fb_set_cmap,
-	retz3_fb_pan_display, retz3_fb_ioctl
+static struct fb_ops retz3fb_ops = {
+	retz3fb_open, retz3fb_release, retz3fb_get_fix, retz3fb_get_var,
+	retz3fb_set_var, retz3fb_get_cmap, retz3fb_set_cmap,
+	retz3fb_pan_display, retz3fb_ioctl
 };
 
 
-__initfunc(void retz3_video_setup(char *options, int *ints))
+__initfunc(void retz3fb_setup(char *options, int *ints))
 {
 	char *this_opt;
 
@@ -1484,14 +1433,14 @@
  *    Initialization
  */
 
-__initfunc(unsigned long retz3_fb_init(unsigned long mem_start))
+__initfunc(unsigned long retz3fb_init(unsigned long mem_start))
 {
 	int err;
 	unsigned long board_addr, board_size;
 	unsigned int key;
 	const struct ConfigDev *cd;
 
-	struct retz3_fb_par par;
+	struct retz3fb_par par;
 
 	if (!(key = zorro_find(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, 0, 0)))
 		return mem_start;
@@ -1517,32 +1466,29 @@
 
 	fbhw->init();
 
-	strcpy(fb_info.modename, retz3_fb_name);
+	strcpy(fb_info.modename, retz3fb_name);
 	fb_info.changevar = NULL;
 	fb_info.node = -1;
-	fb_info.fbops = &retz3_fb_ops;
-	fb_info.fbvar_num = NUM_TOTAL_MODES;
-	fb_info.fbvar = retz3_fb_predefined;
+	fb_info.fbops = &retz3fb_ops;
 	fb_info.disp = &disp;
 	fb_info.switch_con = &z3fb_switch;
 	fb_info.updatevar = &z3fb_updatevar;
 	fb_info.blank = &z3fb_blank;
-	fb_info.setcmap = &z3fb_setcmap;
 
 	err = register_framebuffer(&fb_info);
 	if (err < 0)
 		return mem_start;
 
 	if (z3fb_mode == -1)
-		z3fb_mode = 1;
+		retz3fb_default = retz3fb_predefined[0].var;
 
-	fbhw->decode_var(&retz3_fb_predefined[z3fb_mode], &par);
-	fbhw->encode_var(&retz3_fb_predefined[0], &par);
+	fbhw->decode_var(&retz3fb_default, &par);
+	fbhw->encode_var(&retz3fb_default, &par);
 
-	do_fb_set_var(&retz3_fb_predefined[0], 0);
-	retz3_fb_get_var(&disp.var, -1);
+	do_fb_set_var(&retz3fb_default, 0);
+	retz3fb_get_var(&disp.var, -1, GET_FB_IDX(fb_info.node));
 
-	retz3_fb_set_disp(-1);
+	retz3fb_set_disp(-1);
 
 	do_install_cmap(0);
 
@@ -1595,26 +1541,16 @@
 
 
 /*
- *    Set the colormap
- */
-
-static int z3fb_setcmap(struct fb_cmap *cmap, int con)
-{
-	return(retz3_fb_set_cmap(cmap, 1, con));
-}
-
-
-/*
  *    Get a Video Mode
  */
 
-static int get_video_mode(const char *name)
+__initfunc(static int get_video_mode(const char *name))
 {
 	short i;
 
-	for (i = 1; i <= NUM_PREDEF_MODES; i++)
-		if (!strcmp(name, retz3_fb_modenames[i])){
-			retz3_fb_predefined[0] = retz3_fb_predefined[i];
+	for (i = 0; i <= NUM_TOTAL_MODES; i++)
+		if (!strcmp(name, retz3fb_predefined[i].name)){
+			retz3fb_default = retz3fb_predefined[i].var;
 			return i;
 		}
 	return -1;
@@ -1624,7 +1560,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-	return(retz3_fb_init(NULL));
+	return(retz3fb_init(NULL));
 }
 
 void cleanup_module(void)
--- m68k-2.1.72/drivers/video/tgafb.c.orig	Wed Dec 17 23:54:33 1997
+++ m68k-2.1.72/drivers/video/tgafb.c	Wed Dec 17 23:56:55 1997
@@ -0,0 +1,930 @@
+/*
+ *  linux/drivers/video/tgafb.c -- DEC 21030 TGA frame buffer device
+ *
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This driver is partly based on the original TGA console driver
+ *
+ *	Copyright (C) 1995  Jay Estabrook
+ *
+ *  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.
+ */
+
+
+/* KNOWN PROBLEMS/TO DO ===================================================== *
+ *
+ *	- How to set a single color register?
+ *
+ *	- We don't have support for CFB32 yet (fbcon-cfb32.c)
+ *
+ *	- Hardware cursor (useful for other graphics boards too)
+ *
+ * KNOWN PROBLEMS/TO DO ==================================================== */
+
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/bios32.h>
+#include <linux/pci.h>
+#include <linux/selection.h>
+#include <asm/io.h>
+
+
+/* TGA hardware description (minimal) */
+/*
+ * Offsets within Memory Space
+ */
+#define	TGA_ROM_OFFSET			0x0000000
+#define	TGA_REGS_OFFSET			0x0100000
+#define	TGA_8PLANE_FB_OFFSET		0x0200000
+#define	TGA_24PLANE_FB_OFFSET		0x0804000
+#define	TGA_24PLUSZ_FB_OFFSET		0x1004000
+
+#define	TGA_PLANEMASK_REG		0x0028
+#define	TGA_MODE_REG			0x0030
+#define	TGA_RASTEROP_REG		0x0034
+#define	TGA_DEEP_REG			0x0050
+#define	TGA_PIXELMASK_REG		0x005c
+#define	TGA_CURSOR_BASE_REG		0x0060
+#define	TGA_HORIZ_REG			0x0064
+#define	TGA_VERT_REG			0x0068
+#define	TGA_BASE_ADDR_REG		0x006c
+#define	TGA_VALID_REG			0x0070
+#define	TGA_CURSOR_XY_REG		0x0074
+#define	TGA_INTR_STAT_REG		0x007c
+#define	TGA_RAMDAC_SETUP_REG		0x00c0
+#define	TGA_BLOCK_COLOR0_REG		0x0140
+#define	TGA_BLOCK_COLOR1_REG		0x0144
+#define	TGA_CLOCK_REG			0x01e8
+#define	TGA_RAMDAC_REG			0x01f0
+#define	TGA_CMD_STAT_REG		0x01f8
+
+/*
+ * useful defines for managing the BT485 on the 8-plane TGA
+ */
+#define	BT485_READ_BIT			0x01
+#define	BT485_WRITE_BIT			0x00
+
+#define	BT485_ADDR_PAL_WRITE		0x00
+#define	BT485_DATA_PAL			0x02
+#define	BT485_PIXEL_MASK		0x04
+#define	BT485_ADDR_PAL_READ		0x06
+#define	BT485_ADDR_CUR_WRITE		0x08
+#define	BT485_DATA_CUR			0x0a
+#define	BT485_CMD_0			0x0c
+#define	BT485_ADDR_CUR_READ		0x0e
+#define	BT485_CMD_1			0x10
+#define	BT485_CMD_2			0x12
+#define	BT485_STATUS			0x14
+#define	BT485_CMD_3			0x14
+#define	BT485_CUR_RAM			0x16
+#define	BT485_CUR_LOW_X			0x18
+#define	BT485_CUR_HIGH_X		0x1a
+#define	BT485_CUR_LOW_Y			0x1c
+#define	BT485_CUR_HIGH_Y		0x1e
+
+/*
+ * useful defines for managing the BT463 on the 24-plane TGAs
+ */
+#define	BT463_ADDR_LO		0x0
+#define	BT463_ADDR_HI		0x1
+#define	BT463_REG_ACC		0x2
+#define	BT463_PALETTE		0x3
+
+#define	BT463_CUR_CLR_0		0x0100
+#define	BT463_CUR_CLR_1		0x0101
+
+#define	BT463_CMD_REG_0		0x0201
+#define	BT463_CMD_REG_1		0x0202
+#define	BT463_CMD_REG_2		0x0203
+
+#define	BT463_READ_MASK_0	0x0205
+#define	BT463_READ_MASK_1	0x0206
+#define	BT463_READ_MASK_2	0x0207
+#define	BT463_READ_MASK_3	0x0208
+
+#define	BT463_BLINK_MASK_0	0x0209
+#define	BT463_BLINK_MASK_1	0x020a
+#define	BT463_BLINK_MASK_2	0x020b
+#define	BT463_BLINK_MASK_3	0x020c
+
+#define	BT463_WINDOW_TYPE_BASE	0x0300
+
+
+int tga_type;
+unsigned int tga_mem_base;
+unsigned long tga_fb_base;
+unsigned long tga_regs_base;
+
+static unsigned int fb_offset_presets[4] __initdata = {
+	TGA_8PLANE_FB_OFFSET,
+	TGA_24PLANE_FB_OFFSET,
+	0xffffffff,
+	TGA_24PLUSZ_FB_OFFSET
+};
+
+static unsigned int deep_presets[4] __initdata = {
+  0x00014000,
+  0x0001440d,
+  0xffffffff,
+  0x0001441d
+};
+
+static unsigned int rasterop_presets[4] __initdata = {
+  0x00000003,
+  0x00000303,
+  0xffffffff,
+  0x00000303
+};
+
+static unsigned int mode_presets[4] __initdata = {
+  0x00002000,
+  0x00002300,
+  0xffffffff,
+  0x00002300
+};
+
+static unsigned int base_addr_presets[4] __initdata = {
+  0x00000000,
+  0x00000001,
+  0xffffffff,
+  0x00000001
+};
+
+#define TGA_WRITE_REG(v,r) \
+	{ writel((v), tga_regs_base+(r)); mb(); }
+
+#define TGA_READ_REG(r) readl(tga_regs_base+(r))
+
+#define BT485_WRITE(v,r) \
+	  TGA_WRITE_REG((r),TGA_RAMDAC_SETUP_REG);		\
+	  TGA_WRITE_REG(((v)&0xff)|((r)<<8),TGA_RAMDAC_REG);
+
+#define BT463_LOAD_ADDR(a) \
+	TGA_WRITE_REG(BT463_ADDR_LO<<2, TGA_RAMDAC_SETUP_REG); \
+	TGA_WRITE_REG((BT463_ADDR_LO<<10)|((a)&0xff), TGA_RAMDAC_REG); \
+	TGA_WRITE_REG(BT463_ADDR_HI<<2, TGA_RAMDAC_SETUP_REG); \
+	TGA_WRITE_REG((BT463_ADDR_HI<<10)|(((a)>>8)&0xff), TGA_RAMDAC_REG);
+
+#define BT463_WRITE(m,a,v) \
+	BT463_LOAD_ADDR((a)); \
+	TGA_WRITE_REG(((m)<<2),TGA_RAMDAC_SETUP_REG); \
+	TGA_WRITE_REG(((m)<<10)|((v)&0xff),TGA_RAMDAC_REG);
+
+
+unsigned char PLLbits[7] __initdata = { 0x80, 0x04, 0x00, 0x24, 0x44, 0x80, 0xb8 };
+
+const unsigned long bt485_cursor_source[64] __initdata = {
+#if 1
+  0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,
+  0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,
+  0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,
+  0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000,
+#else
+  0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,
+  0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,
+  0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,
+  0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,0x00000000000000ff,
+#endif
+  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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+const unsigned int bt463_cursor_source[256] __initdata = {
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  0xffff0000, 0x00000000, 0x00000000, 0x00000000,
+  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,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,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,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,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,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
+};
+
+
+#define arraysize(x)	(sizeof(x)/sizeof(*(x)))
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+
+static struct fb_fix_screeninfo fb_fix = { { "DEC TGA ", } };
+static struct fb_var_screeninfo fb_var = { 0, };
+
+
+    /*
+     *  Interface used by the world
+     */
+
+static int tgafb_open(int fbidx);
+static int tgafb_release(int fbidx);
+static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
+static int tgafb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int tgafb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int tgafb_pan_display(struct fb_var_screeninfo *var, int con,
+			     int fbidx);
+static int tgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
+static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
+static int tgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg, int con, int fbidx);
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+unsigned long tgafb_init(unsigned long mem_start);
+static int tgafbcon_switch(int con);
+static int tgafbcon_updatevar(int con);
+static void tgafbcon_blank(int blank);
+
+
+    /*
+     *  Internal routines
+     */
+
+static int tgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+			   u_int *transp);
+static int tgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			   u_int transp);
+#if 1
+static void tga_update_palette(void);
+#endif
+static void do_install_cmap(int con);
+
+
+static struct fb_ops tgafb_ops = {
+    tgafb_open, tgafb_release, tgafb_get_fix, tgafb_get_var, tgafb_set_var,
+    tgafb_get_cmap, tgafb_set_cmap, tgafb_pan_display, tgafb_ioctl
+};
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int tgafb_open(int fbidx)                                       
+{
+    /*                                                                     
+     *  Nothing, only a usage count for the moment                          
+     */                                                                    
+
+    MOD_INC_USE_COUNT;
+    return(0);                              
+}
+        
+static int tgafb_release(int fbidx)
+{
+    MOD_DEC_USE_COUNT;
+    return(0);                                                    
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+{
+    memcpy(fix, &fb_fix, sizeof(fb_fix));
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int tgafb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+    memcpy(var, &fb_var, sizeof(fb_var));
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int tgafb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+    struct display *display;
+    int oldbpp = -1, err;
+
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &disp;	/* used during initialization */
+
+    if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
+	var->xres_virtual > fb_var.xres_virtual ||
+	var->yres_virtual > fb_var.yres_virtual ||
+	var->bits_per_pixel > fb_var.bits_per_pixel ||
+	var->nonstd ||
+	(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+	return -EINVAL;
+    memcpy(var, &fb_var, sizeof(fb_var));
+
+    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	oldbpp = display->var.bits_per_pixel;
+	display->var = *var;
+    }
+    if (oldbpp != var->bits_per_pixel) {
+	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+	    return err;
+	do_install_cmap(con);
+    }
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int tgafb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+{
+    if (var->xoffset || var->yoffset)
+	return -EINVAL;
+    else
+	return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int tgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, tgafb_getcolreg);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+{
+    int err;
+
+    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? */
+	err = fb_set_cmap(cmap, &fb_display[con].var, kspc, tgafb_setcolreg);
+#if 1
+	tga_update_palette();
+#endif
+	return err;
+    } else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+static int tgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg, int con, int fbidx)
+{
+    return -EINVAL;
+}
+
+
+    /*
+     *  Initialisation
+     */
+
+__initfunc(unsigned long tgafb_init(unsigned long mem_start))
+{
+    unsigned char pci_bus, pci_devfn;
+    int status;
+    int i, j, temp, err;
+    unsigned char *cbp;
+
+    status = pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA,
+				  0, &pci_bus, &pci_devfn);
+    if (status == PCIBIOS_DEVICE_NOT_FOUND)
+	return mem_start;
+
+    /*
+     * read BASE_REG_0 for memory address
+     */
+    pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0,
+			      &tga_mem_base);
+    tga_mem_base &= ~15;
+#ifdef DEBUG
+    printk("tgafb_init: mem_base 0x%x\n", tga_mem_base);
+#endif /* DEBUG */
+
+    tga_type = (readl((unsigned long)tga_mem_base) >> 12) & 0x0f;
+    switch (tga_type) {
+	case 0:
+	    strcat(fb_fix.id, "8plane");
+	    break;
+	case 1:
+	    strcat(fb_fix.id, "24plane");
+	    break;
+	case 3:
+	    strcat(fb_fix.id, "24plusZ");
+	    break;
+	default:
+	    printk("TGA type (0x%x) unrecognized!\n", tga_type);
+	    return mem_start;
+    }
+
+    tga_regs_base = ((unsigned long)tga_mem_base + TGA_REGS_OFFSET);
+    tga_fb_base = ((unsigned long)tga_mem_base + fb_offset_presets[tga_type]);
+
+    /* first, disable video timing */
+    TGA_WRITE_REG(0x03, TGA_VALID_REG); /* SCANNING and BLANK */
+
+    /* write the DEEP register */
+    while (TGA_READ_REG(TGA_CMD_STAT_REG) & 1) /* wait for not busy */
+      continue;
+
+    mb();
+    TGA_WRITE_REG(deep_presets[tga_type], TGA_DEEP_REG);
+    while (TGA_READ_REG(TGA_CMD_STAT_REG) & 1) /* wait for not busy */
+	continue;
+    mb();
+
+    /* write some more registers */
+    TGA_WRITE_REG(rasterop_presets[tga_type], TGA_RASTEROP_REG);
+    TGA_WRITE_REG(mode_presets[tga_type], TGA_MODE_REG);
+    TGA_WRITE_REG(base_addr_presets[tga_type], TGA_BASE_ADDR_REG);
+
+    /* write the PLL for 640x480 @ 60Hz */
+    for (i = 0; i <= 6; i++) {
+	for (j = 0; j <= 7; j++) {
+	    temp = (PLLbits[i] >> (7-j)) & 1;
+	    if (i == 6 && j == 7)
+		temp |= 2;
+	    TGA_WRITE_REG(temp, TGA_CLOCK_REG);
+	}
+    }
+
+    /* write some more registers */
+    TGA_WRITE_REG(0xffffffff, TGA_PLANEMASK_REG);
+    TGA_WRITE_REG(0xffffffff, TGA_PIXELMASK_REG);
+    TGA_WRITE_REG(0x12345678, TGA_BLOCK_COLOR0_REG);
+    TGA_WRITE_REG(0x12345678, TGA_BLOCK_COLOR1_REG);
+
+    /* init video timing regs for 640x480 @ 60 Hz */
+    TGA_WRITE_REG(0x018608a0, TGA_HORIZ_REG);
+    TGA_WRITE_REG(0x084251e0, TGA_VERT_REG);
+
+    if (tga_type == 0) { /* 8-plane */
+
+	fb_var.bits_per_pixel = 8;
+	fb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+	/* init BT485 RAMDAC registers */
+	BT485_WRITE(0xa2, BT485_CMD_0);
+	BT485_WRITE(0x01, BT485_ADDR_PAL_WRITE);
+	BT485_WRITE(0x14, BT485_CMD_3); /* cursor 64x64 */
+	BT485_WRITE(0x40, BT485_CMD_1);
+	BT485_WRITE(0x22, BT485_CMD_2); /* WIN cursor type */
+	BT485_WRITE(0xff, BT485_PIXEL_MASK);
+
+	/* fill palette registers */
+	BT485_WRITE(0x00, BT485_ADDR_PAL_WRITE);
+	TGA_WRITE_REG(BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
+
+	for (i = 0; i < 16; i++) {
+	    j = color_table[i];
+	    TGA_WRITE_REG(default_red[j]|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(default_grn[j]|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(default_blu[j]|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	    palette[i].red=default_red[j];
+	    palette[i].green=default_grn[j];
+	    palette[i].blue=default_blu[j];
+	}
+	for (i = 0; i < 240*3; i += 4) {
+	    TGA_WRITE_REG(0x55|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x00|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x00|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x00|(BT485_DATA_PAL<<8), TGA_RAMDAC_REG);
+	}	  
+
+	/* initialize RAMDAC cursor colors */
+	BT485_WRITE(0, BT485_ADDR_CUR_WRITE);
+
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* overscan WHITE */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* overscan WHITE */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* overscan WHITE */
+
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 1 BLACK */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 1 BLACK */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 1 BLACK */
+
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 2 BLACK */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 2 BLACK */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 2 BLACK */
+
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 3 BLACK */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 3 BLACK */
+	BT485_WRITE(0x00, BT485_DATA_CUR); /* color 3 BLACK */
+
+	/* initialize RAMDAC cursor RAM */
+	BT485_WRITE(0x00, BT485_ADDR_PAL_WRITE);
+	cbp = (unsigned char *)bt485_cursor_source;
+	for (i = 0; i < 512; i++) {
+	    BT485_WRITE(*cbp++, BT485_CUR_RAM);
+	}
+	for (i = 0; i < 512; i++) {
+	    BT485_WRITE(0xff, BT485_CUR_RAM);
+	}
+
+    } else { /* 24-plane or 24plusZ */
+
+	fb_var.bits_per_pixel = 32;
+	fb_fix.visual = FB_VISUAL_TRUECOLOR;
+
+	TGA_WRITE_REG(0x01, TGA_VALID_REG); /* SCANNING */
+
+	/*
+	 * init some registers
+	 */
+	BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_0, 0x40);
+	BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_1, 0x08);
+	BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_2, 0x40);
+
+	BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_0, 0xff);
+	BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_1, 0xff);
+	BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_2, 0xff);
+	BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_3, 0x0f);
+
+	BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_0, 0x00);
+	BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_1, 0x00);
+	BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_2, 0x00);
+	BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_3, 0x00);
+
+	/*
+	 * fill the palette
+	 */
+	BT463_LOAD_ADDR(0x0000);
+	TGA_WRITE_REG((BT463_PALETTE<<2), TGA_RAMDAC_REG);
+
+	for (i = 0; i < 16; i++) {
+	    j = color_table[i];
+	    TGA_WRITE_REG(default_red[j]|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(default_grn[j]|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(default_blu[j]|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	}
+	for (i = 0; i < 512*3; i += 4) {
+	    TGA_WRITE_REG(0x55|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x00|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x00|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x00|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	}	  
+
+	/*
+	 * fill window type table after start of vertical retrace
+	 */
+	while (!(TGA_READ_REG(TGA_INTR_STAT_REG) & 0x01))
+	    continue;
+	TGA_WRITE_REG(0x01, TGA_INTR_STAT_REG);
+	mb();
+	while (!(TGA_READ_REG(TGA_INTR_STAT_REG) & 0x01))
+	    continue;
+	TGA_WRITE_REG(0x01, TGA_INTR_STAT_REG);
+
+	BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE);
+	TGA_WRITE_REG((BT463_REG_ACC<<2), TGA_RAMDAC_SETUP_REG);
+	
+	for (i = 0; i < 16; i++) {
+	    TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x01|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(0x80|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	}
+
+	/*
+	 * init cursor colors
+	 */
+	BT463_LOAD_ADDR(BT463_CUR_CLR_0);
+
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); /* background */
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); /* background */
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); /* background */
+
+	TGA_WRITE_REG(0xff|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); /* foreground */
+	TGA_WRITE_REG(0xff|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); /* foreground */
+	TGA_WRITE_REG(0xff|(BT463_REG_ACC<<10), TGA_RAMDAC_REG); /* foreground */
+
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+	TGA_WRITE_REG(0x00|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+
+	/*
+	 * finally, init the cursor shape
+	 */
+	temp = tga_fb_base - 1024; /* this assumes video starts at base
+				     and base is beyond memory start*/
+
+	for (i = 0; i < 256; i++) {
+	    writel(bt463_cursor_source[i], temp + i*4);
+	}
+	TGA_WRITE_REG(temp & 0x000fffff, TGA_CURSOR_BASE_REG);
+    }
+
+    /* finally, enable video scan & cursor
+       (and pray for the monitor... :-) */
+    TGA_WRITE_REG(0x05, TGA_VALID_REG); /* SCANNING and CURSOR */
+
+    fb_var.xres = fb_var.xres_virtual = 640;
+    fb_var.yres = fb_var.yres_virtual = 480;
+    fb_fix.line_length = 80*fb_var.bits_per_pixel;
+    fb_fix.smem_start = (char *)(tga_fb_base + LCA_DENSE_MEM);
+    fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
+    fb_fix.type = FB_TYPE_PACKED_PIXELS;
+    fb_fix.type_aux = 0;
+    fb_fix.mmio_start = (unsigned char *)tga_regs_base;
+    fb_fix.mmio_len = 0x1000;		/* Is this sufficient? */
+
+    fb_var.xoffset = fb_var.yoffset = 0;
+    fb_var.grayscale = 0;
+    fb_var.red.offset = fb_var.green.offset = fb_var.blue.offset = 0;
+    fb_var.red.length = fb_var.green.length = fb_var.blue.length = 8;
+    fb_var.red.msb_right = fb_var.green.msb_right = fb_var.blue.msb_right = 0;
+    fb_var.transp.offset = fb_var.transp.length = fb_var.transp.msb_right = 0;
+    fb_var.nonstd = 0;
+    fb_var.activate = 0;
+    fb_var.height = fb_var.width = -1;
+    fb_var.accel = FB_ACCEL_TGA;
+    fb_var.pixclock = 39722;
+    fb_var.left_margin = 40;
+    fb_var.right_margin = 24;
+    fb_var.upper_margin = 32;
+    fb_var.lower_margin = 11;
+    fb_var.hsync_len = 96;
+    fb_var.vsync_len = 2;
+    fb_var.sync = 0;
+    fb_var.vmode = FB_VMODE_NONINTERLACED;
+
+    disp.var = fb_var;
+    disp.cmap.start = 0;
+    disp.cmap.len = 0;
+    disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
+    disp.screen_base = fb_fix.smem_start;
+    disp.visual = fb_fix.visual;
+    disp.type = fb_fix.type;
+    disp.type_aux = fb_fix.type_aux;
+    disp.ypanstep = 0;
+    disp.ywrapstep = 0;
+    disp.line_length = fb_fix.line_length;
+    disp.can_soft_blank = 1;
+    disp.inverse = 0;
+
+    strcpy(fb_info.modename, fb_fix.id);
+    fb_info.node = -1;
+    fb_info.fbops = &tgafb_ops;
+    fb_info.disp = &disp;
+    fb_info.fontname[0] = '\0';
+    fb_info.changevar = NULL;
+    fb_info.switch_con = &tgafbcon_switch;
+    fb_info.updatevar = &tgafbcon_updatevar;
+    fb_info.blank = &tgafbcon_blank;
+
+    err = register_framebuffer(&fb_info);
+    if (err < 0)
+	return mem_start;
+
+    tgafb_set_var(&fb_var, -1, GET_FB_IDX(fb_info.node));
+
+    printk("%s frame buffer device\n", fb_fix.id);
+    return mem_start;
+}
+
+
+static int tgafbcon_switch(int con)
+{
+    /* Do we have to save the colormap? */
+    if (fb_display[currcon].cmap.len)
+	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+		    tgafb_getcolreg);
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int tgafbcon_updatevar(int con)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void tgafbcon_blank(int blank)
+{
+    /* Nothing */
+}
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int tgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp)
+{
+    if (regno > 255)
+	return 1;
+    *red = palette[regno].red;
+    *green = palette[regno].green;
+    *blue = palette[regno].blue;
+    return 0;
+}
+
+
+    /*
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
+     */
+
+static int tgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp)
+{
+    if (regno > 255)
+	return 1;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+
+    /* How to set a single color register?? */
+
+    return 0;
+}
+
+
+#if 1
+    /*
+     *	FIXME: since I don't know how to set a single arbitrary color register,
+     *  all color palette registers have to be updated
+     */
+
+static void tga_update_palette(void)
+{
+    int i;
+
+    if (tga_type == 0) { /* 8-plane */
+	BT485_WRITE(0x00, BT485_ADDR_PAL_WRITE);
+	TGA_WRITE_REG(BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
+	for (i = 0; i < 256; i++) {
+	    TGA_WRITE_REG(palette[i].red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(palette[i].green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(palette[i].blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
+	}
+    } else {
+	BT463_LOAD_ADDR(0x0000);
+	TGA_WRITE_REG((BT463_PALETTE<<2), TGA_RAMDAC_REG);
+
+	for (i = 0; i < 256; i++) {
+	    TGA_WRITE_REG(palette[i].red|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(palette[i].green|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	    TGA_WRITE_REG(palette[i].blue|(BT463_PALETTE<<10), TGA_RAMDAC_REG);
+	}
+    }
+}
+#endif
+
+static void do_install_cmap(int con)
+{
+    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+		    tgafb_setcolreg);
+    else
+	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+				    &fb_display[con].var, 1, tgafb_setcolreg);
+#if 1
+    tga_update_palette();
+#endif
+}
+
+#if 0	/* No cursor stuff yet */
+
+/*
+ * Hide the cursor from view, during blanking, usually...
+ */
+void
+hide_cursor(void)
+{
+	unsigned long flags;
+	save_flags(flags); cli();
+
+	if (tga_type == 0) {
+	  BT485_WRITE(0x20, BT485_CMD_2);
+	} else {
+	  TGA_WRITE_REG(0x03, TGA_VALID_REG); /* SCANNING and BLANK */
+	}
+
+	restore_flags(flags);
+}
+
+void
+set_cursor(int currcons)
+{
+  unsigned int idx, xt, yt, row, col;
+  unsigned long flags;
+
+  if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
+    return;
+
+  if (__real_origin != __origin)
+    __set_origin(__real_origin);
+
+  save_flags(flags); cli();
+
+  if (deccm) {
+    idx = (pos - video_mem_base) >> 1;
+    col = idx % 80;
+    row = (idx - col) / 80;
+
+    if (tga_type == 0) { /* 8-plane */
+
+      xt = col * TGA_F_WIDTH + 64;
+      yt = row * TGA_F_HEIGHT_PADDED + 64;
+
+      /* make sure it's enabled */
+      BT485_WRITE(0x22, BT485_CMD_2); /* WIN cursor type */
+
+      BT485_WRITE(xt, BT485_CUR_LOW_X);
+      BT485_WRITE((xt >> 8), BT485_CUR_HIGH_X);
+      BT485_WRITE(yt, BT485_CUR_LOW_Y);
+      BT485_WRITE((yt >> 8), BT485_CUR_HIGH_Y);
+
+    } else {
+
+      xt = col * TGA_F_WIDTH + 144;
+      yt = row * TGA_F_HEIGHT_PADDED + 35;
+
+      TGA_WRITE_REG(0x05, TGA_VALID_REG); /* SCANNING and CURSOR */
+      TGA_WRITE_REG(xt | (yt << 12), TGA_CURSOR_XY_REG);
+    }
+
+  } else
+    hide_cursor();
+  restore_flags(flags);
+}
+
+#endif
--- m68k-2.1.72/drivers/video/txtcon.c.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/txtcon.c	Wed Dec 17 23:55:41 1997
@@ -39,6 +39,7 @@
 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_scrolldelta(int lines);
 
 
 static int txtcon_startup(u_long *kmem_start, const char **display_desc)
@@ -54,7 +55,7 @@
 
 static int txtcon_deinit(struct vc_data *conp)
 {
-   return(0);
+   return 0;
 }
 
 
@@ -66,69 +67,75 @@
 static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
                         int width)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_putc(struct vc_data *conp, int c, int y, int x)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
                         int x)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_cursor(struct vc_data *conp, int mode)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
                         int height, int width)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_switch(struct vc_data *conp)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_blank(int blank)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data)
 {
-   return(0);
+   return -ENOSYS;
 }
 
 
 static int txtcon_set_palette(struct vc_data *conp, unsigned char *table)
 {
-   return(0);
+   return -ENOSYS;
+}
+
+
+static int txtcon_scrolldelta(int lines)
+{
+   return -ENOSYS;
 }
 
 
@@ -141,5 +148,6 @@
 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
+   txtcon_blank, txtcon_get_font, txtcon_set_font, txtcon_set_palette,
+   txtcon_scrolldelta
 };
--- m68k-2.1.72/drivers/video/vfb.c.orig	Wed Dec 17 22:56:44 1997
+++ m68k-2.1.72/drivers/video/vfb.c	Wed Dec 17 23:55:41 1997
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/fb/vfb.c -- Virtual frame buffer device
+ *  linux/drivers/video/vfb.c -- Virtual frame buffer device
  *
  *	Copyright (C) 1997 Geert Uytterhoeven
  *
@@ -41,61 +41,49 @@
 static struct display disp;
 static struct fb_info fb_info;
 static struct { u_char red, green, blue, pad; } palette[256];
-static char virtual_fb_name[16] = "Virtual FB";
+static char vfb_name[16] = "Virtual FB";
 
-static struct fb_var_screeninfo virtual_fb_predefined[] = {
-
-    /*
-     *  Autodetect (Default) Video Mode
-     */
-
-    {
-	/* 640x480, 8 bpp */
-	640, 480, 640, 480, 0, 0, 8, 0,
-	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	0, 0, -1, -1, FB_ACCEL_NONE, 20000, 64, 64, 32, 32, 64, 2,
-	0, FB_VMODE_NONINTERLACED
-    },
-
-    /*
-     *  User Defined Video Modes (8)
-     */
-
-    { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+static struct fb_var_screeninfo vfb_default = {
+    /* 640x480, 8 bpp */
+    640, 480, 640, 480, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, FB_ACCEL_NONE, 20000, 64, 64, 32, 32, 64, 2,
+    0, FB_VMODE_NONINTERLACED
 };
 
-#define NUM_USER_MODES		(8)
-#define NUM_TOTAL_MODES		arraysize(virtual_fb_predefined)
-#define NUM_PREDEF_MODES	(1)
-
 
     /*
      *  Interface used by the world
      */
 
-void vfb_video_setup(char *options, int *ints);
+void vfb_setup(char *options, int *ints);
 
-static int virtual_fb_open(int fbidx);
-static int virtual_fb_release(int fbidx);
-static int virtual_fb_get_fix(struct fb_fix_screeninfo *fix, int con);
-static int virtual_fb_get_var(struct fb_var_screeninfo *var, int con);
-static int virtual_fb_set_var(struct fb_var_screeninfo *var, int con);
-static int virtual_fb_pan_display(struct fb_var_screeninfo *var, int con);
-static int virtual_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int virtual_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con);
-static int virtual_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			    u_long arg, int con);
+static int vfb_open(int fbidx);
+static int vfb_release(int fbidx);
+static int vfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			      int fbidx);
+static int vfb_get_var(struct fb_var_screeninfo *var, int con,
+			      int fbidx);
+static int vfb_set_var(struct fb_var_screeninfo *var, int con,
+			      int fbidx);
+static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
+				  int fbidx);
+static int vfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			       int fbidx);
+static int vfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			       int fbidx);
+static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			    u_long arg, int con, int fbidx);
 
 
     /*
      *  Interface to the low level console driver
      */
 
-unsigned long virtual_fb_init(unsigned long mem_start);
+unsigned long vfb_init(unsigned long mem_start);
 static int vfbcon_switch(int con);
 static int vfbcon_updatevar(int con);
 static void vfbcon_blank(int blank);
-static int vfbcon_setcmap(struct fb_cmap *cmap, int con);
 
 
     /*
@@ -113,10 +101,10 @@
 static void do_install_cmap(int con);
 
 
-static struct fb_ops virtual_fb_ops = {
-    virtual_fb_open, virtual_fb_release, virtual_fb_get_fix,
-    virtual_fb_get_var, virtual_fb_set_var, virtual_fb_get_cmap,
-    virtual_fb_set_cmap, virtual_fb_pan_display, virtual_fb_ioctl
+static struct fb_ops vfb_ops = {
+    vfb_open, vfb_release, vfb_get_fix,
+    vfb_get_var, vfb_set_var, vfb_get_cmap,
+    vfb_set_cmap, vfb_pan_display, vfb_ioctl
 };
 
 
@@ -124,7 +112,7 @@
      *  Open/Release the frame buffer device
      */
 
-static int virtual_fb_open(int fbidx)                                       
+static int vfb_open(int fbidx)                                       
 {
     /*                                                                     
      *  Nothing, only a usage count for the moment                          
@@ -134,7 +122,7 @@
     return(0);                              
 }
         
-static int virtual_fb_release(int fbidx)
+static int vfb_release(int fbidx)
 {
     MOD_DEC_USE_COUNT;
     return(0);                                                    
@@ -145,12 +133,13 @@
      *  Get the Fixed Part of the Display
      */
 
-static int virtual_fb_get_fix(struct fb_fix_screeninfo *fix, int con)
+static int vfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			      int fbidx)
 {
     struct fb_var_screeninfo *var;
 
     if (con == -1)
-	var = &virtual_fb_predefined[0];
+	var = &vfb_default;
     else
 	var = &fb_display[con].var;
     vfb_encode_fix(fix, var);
@@ -162,10 +151,11 @@
      *  Get the User Defined Part of the Display
      */
 
-static int virtual_fb_get_var(struct fb_var_screeninfo *var, int con)
+static int vfb_get_var(struct fb_var_screeninfo *var, int con,
+			      int fbidx)
 {
     if (con == -1)
-	*var = virtual_fb_predefined[0];
+	*var = vfb_default;
     else
 	*var = fb_display[con].var;
     set_color_bitfields(var);
@@ -177,7 +167,8 @@
      *  Set the User Defined Part of the Display
      */
 
-static int virtual_fb_set_var(struct fb_var_screeninfo *var, int con)
+static int vfb_set_var(struct fb_var_screeninfo *var, int con,
+			      int fbidx)
 {
     int err, activate = var->activate;
     int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
@@ -277,7 +268,8 @@
      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
      */
 
-static int virtual_fb_pan_display(struct fb_var_screeninfo *var, int con)
+static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
+				  int fbidx)
 {
     if (var->vmode & FB_VMODE_YWRAP) {
 	if (var->yoffset < 0 ||
@@ -304,7 +296,8 @@
      *  Get the Colormap
      */
 
-static int virtual_fb_get_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int vfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			       int fbidx)
 {
     if (con == currcon) /* current console? */
 	return fb_get_cmap(cmap, &fb_display[con].var, kspc, vfb_getcolreg);
@@ -320,7 +313,8 @@
      *  Set the Colormap
      */
 
-static int virtual_fb_set_cmap(struct fb_cmap *cmap, int kspc, int con)
+static int vfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			       int fbidx)
 {
     int err;
 
@@ -341,14 +335,14 @@
      *  Virtual Frame Buffer Specific ioctls
      */
 
-static int virtual_fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			    u_long arg, int con)
+static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			    u_long arg, int con, int fbidx)
 {
     return -EINVAL;
 }
 
 
-__initfunc(void vfb_video_setup(char *options, int *ints))
+__initfunc(void vfb_setup(char *options, int *ints))
 {
     char *this_opt;
 
@@ -369,7 +363,7 @@
      *  Initialisation
      */
 
-__initfunc(unsigned long virtual_fb_init(unsigned long mem_start))
+__initfunc(unsigned long vfb_init(unsigned long mem_start))
 {
     int err;
 
@@ -382,23 +376,20 @@
     if (!videomemory)
 	return mem_start;
 
-    strcpy(fb_info.modename, virtual_fb_name);
+    strcpy(fb_info.modename, vfb_name);
     fb_info.changevar = NULL;
     fb_info.node = -1;
-    fb_info.fbops = &virtual_fb_ops;
-    fb_info.fbvar_num = NUM_TOTAL_MODES;
-    fb_info.fbvar = virtual_fb_predefined;
+    fb_info.fbops = &vfb_ops;
     fb_info.disp = &disp;
     fb_info.switch_con = &vfbcon_switch;
     fb_info.updatevar = &vfbcon_updatevar;
     fb_info.blank = &vfbcon_blank;
-    fb_info.setcmap = &vfbcon_setcmap;
 
     err = register_framebuffer(&fb_info);
     if (err < 0)
 	return mem_start;
 
-    virtual_fb_set_var(&virtual_fb_predefined[0], -1);
+    vfb_set_var(&vfb_default, -1, GET_FB_IDX(fb_info.node));
 
     printk("Virtual frame buffer device, using %ldK of video memory\n",
 	   videomemorysize>>10);
@@ -438,16 +429,6 @@
     /* Nothing */
 }
 
-    /*
-     *  Set the colormap
-     */
-
-static int vfbcon_setcmap(struct fb_cmap *cmap, int con)
-{
-    return(virtual_fb_set_cmap(cmap, 1, con));
-}
-
-
 static u_long get_line_length(int xres_virtual, int bpp)
 {
     u_long length;
@@ -462,7 +443,7 @@
 			   struct fb_var_screeninfo *var)
 {
     memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-    strcpy(fix->id, virtual_fb_name);
+    strcpy(fix->id, vfb_name);
     fix->smem_start = (caddr_t)videomemory;
     fix->smem_len = videomemorysize;
     fix->type = FB_TYPE_PACKED_PIXELS;
@@ -589,7 +570,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-    return(virtual_fb_init(NULL));
+    return(vfb_init(NULL));
 }
 
 void cleanup_module(void)
--- m68k-2.1.72/drivers/video/vgacon.c.orig	Wed Dec 17 23:54:26 1997
+++ m68k-2.1.72/drivers/video/vgacon.c	Wed Dec 17 23:57:01 1997
@@ -0,0 +1,590 @@
+/*
+ *  linux/drivers/video/vgacon.c -- Low level VGA based console driver
+ *
+ *	Created 28 Sep 1997 by Geert Uytterhoeven
+ *
+ *  This file is based on the old console.c, vga.c and vesa_blank.c drivers.
+ *
+ *	Copyright (C) 1991, 1992  Linus Torvalds
+ *			    1995  Jay Estabrook
+ *
+ *	User definable mapping table and font loading by Eugene G. Crosser,
+ *	<crosser@pccross.msk.su>
+ *
+ *	Improved loadable font/UTF-8 support by H. Peter Anvin
+ *	Feb-Sep 1995 <peter.anvin@linux.org>
+ *
+ *	Colour palette handling, by Simon Tatham
+ *	17-Jun-95 <sgt20@cam.ac.uk>
+ *
+ *	if 512 char mode is already enabled don't re-enable it,
+ *	because it causes screen to flicker, by Mitja Horvat
+ *	5-May-96 <mitja.horvat@guest.arnes.si>
+ *
+ *	Use 2 outw instead of 4 outb_p to reduce erroneous text
+ *	flashing on RHS of screen during heavy console scrolling .
+ *	Oct 1996, Paul Gortmaker.
+ *
+ *
+ *  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.
+ */
+
+
+
+
+/* KNOWN PROBLEMS/TO DO ===================================================== *
+ *
+ *	- monochrome attribute encoding (convert abscon <-> VGA style)
+ *
+ *	- speed up scrolling by changing the screen origin
+ *
+ *	- add support for palette, loadable fonts and VESA blanking
+ *
+ * KNOWN PROBLEMS/TO DO ==================================================== */
+
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/console_struct.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/linux_logo.h>
+
+
+#define BLANK 0x0020
+
+#define CAN_LOAD_EGA_FONTS	/* undefine if the user must not do this */
+#define CAN_LOAD_PALETTE	/* undefine if the user must not do this */
+
+#define dac_reg	(0x3c8)
+#define dac_val	(0x3c9)
+
+#ifdef __powerpc__
+#define VGA_OFFSET _ISA_MEM_BASE;
+#else
+#define VGA_OFFSET 0x0
+#endif
+
+
+/*
+ *  Interface used by the world
+ */
+
+static unsigned long vgacon_startup(unsigned long kmem_start,
+				   const char **display_desc);
+static void vgacon_init(struct vc_data *conp);
+static int vgacon_deinit(struct vc_data *conp);
+static int vgacon_clear(struct vc_data *conp, int sy, int sx, int height,
+		       int width);
+static int vgacon_putc(struct vc_data *conp, int c, int ypos, int xpos);
+static int vgacon_putcs(struct vc_data *conp, const char *s, int count,
+		       int ypos, int xpos);
+static int vgacon_cursor(struct vc_data *conp, int mode);
+static int vgacon_scroll(struct vc_data *conp, int t, int b,
+			int dir, int count);
+static int vgacon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static int vgacon_switch(struct vc_data *conp);
+static int vgacon_blank(int blank);
+static int vgacon_get_font(struct vc_data *conp, int *w, int *h, char *data);
+static int vgacon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int vgacon_set_palette(struct vc_data *conp, unsigned char *table);
+static int vgacon_scrolldelta(int lines);
+
+
+/*
+ *  Internal routines
+ */
+
+static int vgacon_show_logo(void);
+
+
+/* Description of the hardware situation */
+static unsigned long   vga_video_mem_base;	/* Base of video memory */
+static unsigned long   vga_video_mem_term;	/* End of video memory */
+static unsigned short  vga_video_port_reg;	/* Video register select port */
+static unsigned short  vga_video_port_val;	/* Video register value port */
+static unsigned long   vga_video_num_columns;	/* Number of text columns */
+static unsigned long   vga_video_num_lines;	/* Number of text lines */
+static unsigned long   vga_video_size_row;
+static unsigned long   vga_video_screen_size;
+
+static int vga_can_do_color = 0;
+static unsigned long vga_default_font_height;	/* Height of default screen font */
+
+static unsigned char vga_video_type;
+static unsigned char vga_has_wrapped;		/* all of videomem is data of fg_console */
+static unsigned char vga_hardscroll_enabled;
+static unsigned char vga_hardscroll_disabled_by_init = 0;
+
+
+
+    /*
+     *  VGA screen access
+     */ 
+
+static inline void vga_writew(unsigned short val, unsigned short * addr)
+{
+#ifdef __powerpc__
+	st_le16(addr, val);
+#else
+	writew(val, (unsigned long) addr);
+#endif /* !__powerpc__ */
+}
+
+static inline unsigned short vga_readw(unsigned short * addr)
+{
+#ifdef __powerpc__
+	return ld_le16(addr);
+#else
+	return readw((unsigned long) addr);
+#endif /* !__powerpc__ */	
+}
+
+static inline void vga_memsetw(void * s, unsigned short c, unsigned int count)
+{
+	unsigned short * addr = (unsigned short *) s;
+
+	while (count) {
+		count--;
+		vga_writew(c, addr++);
+	}
+}
+
+static inline void vga_memmovew(unsigned short *to, unsigned short *from,
+				unsigned int count)
+{
+	if (to < from) {
+	    while (count) {
+		    count--;
+		    vga_writew(vga_readw(from++), to++);
+	    }
+	} else {
+	    from += count;
+	    to += count;
+	    while (count) {
+		    count--;
+		    vga_writew(vga_readw(--from), --to);
+	    }
+	}
+}
+
+
+/*
+ * By replacing the four outb_p with two back to back outw, we can reduce
+ * the window of opportunity to see text mislocated to the RHS of the
+ * console during heavy scrolling activity. However there is the remote
+ * possibility that some pre-dinosaur hardware won't like the back to back
+ * I/O. Since the Xservers get away with it, we should be able to as well.
+ */
+static inline void write_vga(unsigned char reg, unsigned int val)
+{
+#ifndef SLOW_VGA
+	unsigned int v1, v2;
+
+	v1 = reg + (val & 0xff00);
+	v2 = reg + 1 + ((val << 8) & 0xff00);
+	outw(v1, vga_video_port_reg);
+	outw(v2, vga_video_port_reg);
+#else
+	outb_p(reg, vga_video_port_reg);
+	outb_p(val >> 8, vga_video_port_val);
+	outb_p(reg+1, vga_video_port_reg);
+	outb_p(val & 0xff, vga_video_port_val);
+#endif
+}
+
+
+__initfunc(static unsigned long vgacon_startup(unsigned long kmem_start,
+					       const char **display_desc))
+{
+	unsigned short saved;
+	unsigned short *p;
+
+	vga_video_num_lines = ORIG_VIDEO_LINES;
+	vga_video_num_columns = ORIG_VIDEO_COLS;
+	vga_video_size_row = 2 * ORIG_VIDEO_COLS;
+	vga_video_screen_size = vga_video_num_lines * vga_video_size_row;
+
+	if (ORIG_VIDEO_MODE == 7)	/* Is this a monochrome display? */
+	{
+		vga_video_mem_base = 0xb0000 + VGA_OFFSET;
+		vga_video_port_reg = 0x3b4;
+		vga_video_port_val = 0x3b5;
+		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
+		{
+			vga_video_type = VIDEO_TYPE_EGAM;
+			vga_video_mem_term = 0xb8000 + VGA_OFFSET;
+			*display_desc = "EGA+";
+			request_region(0x3b0,16,"ega");
+		}
+		else
+		{
+			vga_video_type = VIDEO_TYPE_MDA;
+			vga_video_mem_term = 0xb2000 + VGA_OFFSET;
+			*display_desc = "*MDA";
+			request_region(0x3b0,12,"mda");
+			request_region(0x3bf, 1,"mda");
+		}
+	}
+	else				/* If not, it is color. */
+	{
+		vga_can_do_color = 1;
+		vga_video_mem_base = 0xb8000  + VGA_OFFSET;
+		vga_video_port_reg	= 0x3d4;
+		vga_video_port_val	= 0x3d5;
+		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
+		{
+			int i ;
+
+			vga_video_mem_term = 0xc0000 + VGA_OFFSET;
+
+			if (!ORIG_VIDEO_ISVGA) {
+				vga_video_type = VIDEO_TYPE_EGAC;
+				*display_desc = "EGA";
+				request_region(0x3c0,32,"ega");
+			} else {
+				vga_video_type = VIDEO_TYPE_VGAC;
+				*display_desc = "VGA+";
+				request_region(0x3c0,32,"vga+");
+
+#ifdef VGA_CAN_DO_64KB
+				/*
+				 * get 64K rather than 32K of video RAM.
+				 * This doesn't actually work on all "VGA"
+				 * controllers (it seems like setting MM=01
+				 * and COE=1 isn't necessarily a good idea)
+				 */
+				vga_video_mem_base = 0xa0000  + VGA_OFFSET;
+				vga_video_mem_term = 0xb0000  + VGA_OFFSET;
+				outb_p (6, 0x3ce) ;
+				outb_p (6, 0x3cf) ;
+#endif
+
+				/*
+				 * Normalise the palette registers, to point
+				 * the 16 screen colours to the first 16
+				 * DAC entries.
+				 */
+
+				for (i=0; i<16; i++) {
+					inb_p (0x3da) ;
+					outb_p (i, 0x3c0) ;
+					outb_p (i, 0x3c0) ;
+				}
+				outb_p (0x20, 0x3c0) ;
+
+				/* now set the DAC registers back to their
+				 * default values */
+
+				for (i=0; i<16; i++) {
+					outb_p (color_table[i], 0x3c8) ;
+					outb_p (default_red[i], 0x3c9) ;
+					outb_p (default_grn[i], 0x3c9) ;
+					outb_p (default_blu[i], 0x3c9) ;
+				}
+			}
+		}
+		else
+		{
+			vga_video_type = VIDEO_TYPE_CGA;
+			vga_video_mem_term = 0xba000 + VGA_OFFSET;
+			*display_desc = "*CGA";
+			request_region(0x3d4,2,"cga");
+		}
+	}
+
+	/*
+	 *	Find out if there is a graphics card present.
+	 *	Are there smarter methods around?
+	 */
+	p = (unsigned short *)video_mem_base;
+	saved = vga_readw(p);
+	vga_writew(0xAA55, p);
+	if (vga_readw(p) != 0xAA55) {
+		vga_writew(saved, p);
+		return kmem_start;
+	}
+	vga_writew(0x55AA, p);
+	if (vga_readw(p) != 0x55AA) {
+		vga_writew(saved, p);
+		return kmem_start;
+	}
+	vga_writew(saved, p);
+
+	vga_hardscroll_enabled = (vga_hardscroll_disabled_by_init ? 0 :
+	  (vga_video_type == VIDEO_TYPE_EGAC
+	    || vga_video_type == VIDEO_TYPE_VGAC
+	    || vga_video_type == VIDEO_TYPE_EGAM));
+	vga_has_wrapped = 0;
+
+	if (vga_video_type == VIDEO_TYPE_VGAC
+	    || vga_video_type == VIDEO_TYPE_EGAC
+	    || vga_video_type == VIDEO_TYPE_EGAM)
+	{
+		vga_default_font_height = ORIG_VIDEO_POINTS;
+		video_font_height = ORIG_VIDEO_POINTS;
+		/* This may be suboptimal but is a safe bet - go with it */
+		video_scan_lines =
+			video_font_height * vga_video_num_lines;
+	}
+
+	if (!console_show_logo)
+	    console_show_logo = vgacon_show_logo;
+
+	return kmem_start;
+}
+
+
+static void vgacon_init(struct vc_data *conp)
+{
+    conp->vc_cols = vga_video_num_columns;
+    conp->vc_rows = vga_video_num_lines;
+    conp->vc_can_do_color = vga_can_do_color;
+}
+
+static int vgacon_deinit(struct vc_data *conp)
+{
+    return 0;
+}
+
+
+/* ====================================================================== */
+
+static int vgacon_clear(struct vc_data *conp, int sy, int sx, int height,
+			      int width)
+{
+    int rows;
+    unsigned long dest;
+
+    if (console_blanked)
+	return 0;
+
+    dest = vga_video_mem_base + sy*vga_video_size_row + sx*2;
+    if (sx == 0 && width == vga_video_num_columns)      
+	vga_memsetw((void *)dest, conp->vc_video_erase_char, height * width);
+    else
+        for (rows = height; rows-- ; dest += vga_video_size_row)
+	    vga_memsetw((void *)dest, conp->vc_video_erase_char, width);
+    return 0;
+}
+
+
+static int vgacon_putc(struct vc_data *conp, int c, int ypos, int xpos)
+{
+    u_short *p;
+
+    if (console_blanked)
+	    return 0;
+
+    p = (u_short *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
+    vga_writew(conp->vc_attr << 8 | c, p);
+    return 0;
+}
+
+
+static int vgacon_putcs(struct vc_data *conp, const char *s, int count,
+		       int ypos, int xpos)
+{
+    u_short *p;
+    u_short sattr;
+
+    if (console_blanked)
+	    return 0;
+
+    p = (u_short *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
+    sattr = conp->vc_attr << 8;
+    while (count--)
+	vga_writew(sattr | *s++, p++);
+    return 0;
+}
+
+
+static int vgacon_cursor(struct vc_data *conp, int mode)
+{
+    switch (mode) {
+	case CM_ERASE:
+	    write_vga(14, (vga_video_mem_term - vga_video_mem_base - 1)>>1);
+	    break;
+
+	case CM_MOVE:
+	case CM_DRAW:
+	    write_vga(14, conp->vc_y*vga_video_num_columns+conp->vc_x);
+	    break;
+    }
+    return 0;
+}
+
+
+static int vgacon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+    if (console_blanked)
+	return 0;
+
+    vgacon_cursor(conp, CM_ERASE);
+
+    switch (dir) {
+	case SM_UP:
+	    if (count > conp->vc_rows)	/* Maximum realistic size */
+		count = conp->vc_rows;
+	    vgacon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
+	    vgacon_clear(conp, b-count, 0, count, conp->vc_cols);
+	    break;
+
+	case SM_DOWN:
+	    if (count > conp->vc_rows)	/* Maximum realistic size */
+		count = conp->vc_rows;
+	    /*
+	     *  Fixed bmove() should end Arno's frustration with copying?
+	     *  Confucius says:
+	     *	Man who copies in wrong direction, end up with trashed
+	     *	data
+	     */
+	    vgacon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
+	    vgacon_clear(conp, t, 0, count, conp->vc_cols);
+	    break;
+
+	case SM_LEFT:
+	    vgacon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
+	    vgacon_clear(conp, 0, b-count, conp->vc_rows, count);
+	    break;
+
+	case SM_RIGHT:
+	    vgacon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
+	    vgacon_clear(conp, 0, t, conp->vc_rows, count);
+	    break;
+    }
+
+    return 0;
+}
+
+
+static int vgacon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+		       int height, int width)
+{
+    unsigned long src, dst;
+    int rows;
+
+    if (console_blanked)
+	return 0;
+
+    if (sx == 0 && dx == 0 && width == vga_video_num_columns) {
+	src = vga_video_mem_base + sy * vga_video_size_row;
+	dst = vga_video_mem_base + dy * vga_video_size_row;
+	vga_memmovew((unsigned short *)dst, (unsigned short *)src,
+		     height * width);
+    } else if (dy < sy || (dy == sy && dx < sx)) {
+	src = vga_video_mem_base + sy * vga_video_size_row + sx * 2;
+	dst = vga_video_mem_base + dy * vga_video_size_row + dx * 2;
+	for (rows = height; rows-- ;) {
+	    vga_memmovew((unsigned short *)dst, (unsigned short *)src, width);
+	    src += vga_video_size_row;
+	    dst += vga_video_size_row;
+	}
+    } else {
+	src = vga_video_mem_base + (sy+height-1) * vga_video_size_row + sx * 2;
+	dst = vga_video_mem_base + (dy+height-1) * vga_video_size_row + dx * 2;
+	for (rows = height; rows-- ;) {
+	    vga_memmovew((unsigned short *)dst, (unsigned short *)src, width);
+	    src -= vga_video_size_row;
+	    dst -= vga_video_size_row;
+	}
+    }
+    return 0;
+}
+
+
+static int vgacon_switch(struct vc_data *conp)
+{
+    return 0;
+}
+
+
+static int vgacon_blank(int blank)
+{
+    if (blank) {
+	vga_memsetw((void *)vga_video_mem_base, BLANK, vga_video_screen_size/2);
+	return 0;
+    } else {
+	/* Tell console.c that it has to restore the screen itself */
+	return(1);
+    }
+    return 0;
+}
+
+
+static int vgacon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+    /* TODO */
+    return -ENOSYS;
+}
+
+
+static int vgacon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+    /* TODO */
+    return -ENOSYS;
+}
+
+static int vgacon_set_palette(struct vc_data *conp, unsigned char *table)
+{
+	int i, j ;
+
+	if (vga_video_type != VIDEO_TYPE_VGAC || console_blanked ||
+	    vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+		return -EINVAL;
+
+	for (i=j=0; i<16; i++) {
+		outb_p (table[i], dac_reg) ;
+		outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
+		outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
+		outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
+	}
+	return 0;
+}
+
+static int vgacon_scrolldelta(int lines)
+{
+    /* TODO */
+    return -ENOSYS;
+}
+
+
+__initfunc(static int vgacon_show_logo( void ))
+{
+    int height = 0;
+    char *p;
+
+    printk(linux_serial_image);
+    for (p = linux_serial_image; *p; p++)
+	if (*p == '\n')
+	    height++;
+    return height;
+}
+
+
+
+/*
+ *  The console `switch' structure for the VGA based console
+ */
+
+struct consw vga_con = {
+    vgacon_startup, vgacon_init, vgacon_deinit, vgacon_clear, vgacon_putc,
+    vgacon_putcs, vgacon_cursor, vgacon_scroll, vgacon_bmove, vgacon_switch,
+    vgacon_blank, vgacon_get_font, vgacon_set_font, vgacon_set_palette,
+    vgacon_scrolldelta
+};
--- m68k-2.1.72/arch/m68k/amiga/config.c.orig	Wed Dec 17 23:07:29 1997
+++ m68k-2.1.72/arch/m68k/amiga/config.c	Thu Dec 18 00:26:42 1997
@@ -75,13 +75,15 @@
 extern void amiga_floppy_setup(char *, int *);
 #endif
 static void amiga_reset (void);
+static int amiga_wait_key (struct console *co);
 extern struct consw fb_con;
 extern void zorro_init(void);
 extern void amiga_init_sound(void);
 static void amiga_savekmsg_init(void);
 static void amiga_mem_console_write(struct console *co, const char *b,
 				    unsigned int count);
- void amiga_serial_console_write(const char *s, unsigned int count);
+void amiga_serial_console_write(struct console *co, const char *s,
+				unsigned int count);
 static void amiga_debug_init(void);
 
 static struct console amiga_console_driver = {

Greetings,

						Geert

--
Geert Uytterhoeven                     Geert.Uytterhoeven@cs.kuleuven.ac.be
Wavelets, Linux/{m68k~Amiga,PPC~CHRP}  http://www.cs.kuleuven.ac.be/~geert/
Department of Computer Science -- Katholieke Universiteit Leuven -- Belgium

