Date: Wed, 18 Feb 1998 10:16:02 +0100 (CET)
From: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
To: Linux/m68k <linux-m68k@lists.linux-m68k.org>
Subject: L68K: video patches for 2.1.85
Sender: owner-linux-m68k@phil.uni-sb.de


Here are the video patches for 2.1.85. Looks like they compile (I don't have a
video board in my Amiga).

--- m68k-2.1.85/drivers/video/Config.in.orig	Fri Feb 13 10:08:36 1998
+++ m68k-2.1.85/drivers/video/Config.in	Tue Feb 17 23:24:21 1998
@@ -19,7 +19,7 @@
     fi
     tristate 'Amiga CyberVision support' CONFIG_FB_CYBER
     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#      bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_CV3D
+      bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE
       tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3
     fi
   fi
@@ -66,7 +66,7 @@
   else
     if [ "$CONFIG_FB_AMIGA" != "n" -o "$CONFIG_FB_ATARI" != "n" -o \
 	 "$CONFIG_FB_CYBER" != "n" -o "$CONFIG_FB_RETINAZ3" != "n" -o \
-	 "$CONFIG_FB_CV3D" != "n" -o "$CONFIG_FB_MAC" != "n" -o \
+	 "$CONFIG_FB_VIRGE" != "n" -o "$CONFIG_FB_MAC" != "n" -o \
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_MFB y
     fi
@@ -101,21 +101,6 @@
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB32 y
     fi
-    if [ "$CONFIG_FB_CYBER" = "y" -o "$CONFIG_FB_CYBER" = "m" ]; then
-      define_bool CONFIG_FBCON_CYBER y
-    fi
-    if [ "$CONFIG_FB_CV3D" = "y" ]; then
-      define_bool CONFIG_FBCON_VIRGE y
-    fi
-    if [ "$CONFIG_FB_RETINAZ3" = "y" -o "$CONFIG_FB_RETINAZ3" = "m" ]; then
-      define_bool CONFIG_FBCON_RETINAZ3 y
-    fi
-    if [ "$CONFIG_FB_ATY" = "y" ]; then
-      define_bool CONFIG_FBCON_ATY y
-    fi
-#   if [ "$CONFIG_FB_S3TRIO" = "y" -o "$CONFIG_FB_S3TRIO" = "m" ]; then
-#     define_bool CONFIG_FBCON_TRIO y
-#   fi
   fi
 
   endmenu
--- m68k-2.1.85/drivers/video/S3triofb.c.orig	Tue Feb 17 23:24:21 1998
+++ m68k-2.1.85/drivers/video/S3triofb.c	Tue Feb 17 23:24:21 1998
@@ -0,0 +1,862 @@
+/*
+ *  linux/drivers/video/S3Triofb.c -- Open Firmware based frame buffer device
+ *
+ *	Copyright (C) 1997 Peter De Schrijver
+ *
+ *  This driver is partly based on the PowerMac console driver:
+ *
+ *	Copyright (C) 1996 Paul Mackerras
+ *
+ *  and on the Open Firmware based frame buffer device:
+ *
+ *	Copyright (C) 1997 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.
+ */
+
+/*
+	Bugs : + OF dependencies should be removed.
+               + This driver should be merged with the CyberVision driver. The
+                 CyberVision is a Zorro III implementation of the S3Trio64 chip.
+
+*/
+
+#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/init.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <linux/pci.h>
+
+#include "fbcon-cfb8.h"
+
+
+#define mem_in8(addr)           in_8((void *)(addr))
+#define mem_in16(addr)          in_le16((void *)(addr))
+#define mem_in32(addr)          in_le32((void *)(addr))
+
+#define mem_out8(val, addr)     out_8((void *)(addr), val)
+#define mem_out16(val, addr)    out_le16((void *)(addr), val)
+#define mem_out32(val, addr)    out_le32((void *)(addr), val)
+
+#define IO_OUT16VAL(v, r)       (((v) << 8) | (r))
+
+#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 char s3trio_name[16] = "S3Trio ";
+
+
+static struct fb_fix_screeninfo fb_fix;
+static struct fb_var_screeninfo fb_var = { 0, };
+
+
+    /*
+     *  Interface used by the world
+     */
+
+void of_video_setup(char *options, int *ints);
+
+static int s3trio_open(struct fb_info *info);
+static int s3trio_release(struct fb_info *info);
+static int s3trio_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info);
+static int s3trio_get_var(struct fb_var_screeninfo *var, struct fb_info *info);
+static int s3trio_set_var(struct fb_var_screeninfo *var, struct fb_info *info);
+static int s3trio_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info);
+static int s3trio_get_cmap(struct fb_cmap *cmap, int kspc,
+			   struct fb_info *info);
+static int s3trio_set_cmap(struct fb_cmap *cmap, int kspc,
+			   struct fb_info *info);
+static int s3trio_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			    u_long arg, struct fb_info *info);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+extern struct vc_mode display_info;
+extern int (*console_setmode_ptr)(struct vc_mode *, int);
+static int s3trio_console_setmode(struct vc_mode *mode, int doit);
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+unsigned long s3trio_fb_init(unsigned long mem_start);
+static int s3triofbcon_switch(int con, struct fb_info *info);
+static int s3triofbcon_updatevar(int con, struct fb_info *info);
+static void s3triofbcon_blank(int blank, struct fb_info *info);
+static int s3triofbcon_setcmap(struct fb_cmap *cmap, int con);
+
+    /*
+     *  Text console acceleration
+     */
+
+static struct display_switch fbcon_trio8;
+
+    /*
+     *    Accelerated Functions used by the low level console driver
+     */
+
+static void Trio_WaitQueue(u_short fifo);
+static void Trio_WaitBlit(void);
+static void Trio_BitBLT(u_short curx, u_short cury, u_short destx,
+			u_short desty, u_short width, u_short height,
+			u_short mode);
+static void Trio_RectFill(u_short x, u_short y, u_short width, u_short height,
+			  u_short mode, u_short color);
+static void Trio_MoveCursor(u_short x, u_short y);
+
+
+    /*
+     *  Internal routines
+     */
+
+static int s3trio_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info);
+static int s3trio_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info);
+static void do_install_cmap(int con);
+
+
+static struct fb_ops s3trio_ops = {
+    s3trio_open, s3trio_release, s3trio_get_fix, s3trio_get_var, s3trio_set_var,
+    s3trio_get_cmap, s3trio_set_cmap, s3trio_pan_display, s3trio_ioctl
+};
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int s3trio_open(struct fb_info *info)
+{
+    /*
+     *  Nothing, only a usage count for the moment
+     */
+
+    MOD_INC_USE_COUNT;
+    return(0);
+}
+
+static int s3trio_release(struct fb_info *info)
+{
+    MOD_DEC_USE_COUNT;
+    return(0);
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int s3trio_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
+{
+    memcpy(fix, &fb_fix, sizeof(fb_fix));
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int s3trio_get_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+    memcpy(var, &fb_var, sizeof(fb_var));
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int s3trio_set_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+    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_NONINTERLACED)
+	return -EINVAL;
+    memcpy(var, &fb_var, sizeof(fb_var));
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int s3trio_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info)
+{
+    if (var->xoffset || var->yoffset)
+	return -EINVAL;
+    else
+	return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int s3trio_get_cmap(struct fb_cmap *cmap, int kspc,
+			   struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, s3trio_getcolreg,
+			   info);
+    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 s3trio_set_cmap(struct fb_cmap *cmap, int kspc,
+			   struct fb_info *info)
+{
+    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? */
+	return fb_set_cmap(cmap, &fb_display[con].var, kspc, s3trio_setcolreg,
+			   info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+static int s3trio_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			u_long arg, struct fb_info *info)
+{
+    return -EINVAL;
+}
+
+__initfunc(int s3trio_resetaccel(void)) {
+
+
+#define EC01_ENH_ENB    0x0005
+#define EC01_LAW_ENB    0x0010
+#define EC01_MMIO_ENB   0x0020
+
+#define EC00_RESET      0x8000
+#define EC00_ENABLE     0x4000
+#define MF_MULT_MISC    0xE000
+#define SRC_FOREGROUND  0x0020
+#define SRC_BACKGROUND  0x0000
+#define MIX_SRC                 0x0007
+#define MF_T_CLIP       0x1000
+#define MF_L_CLIP       0x2000
+#define MF_B_CLIP       0x3000
+#define MF_R_CLIP       0x4000
+#define MF_PIX_CONTROL  0xA000
+#define MFA_SRC_FOREGR_MIX      0x0000
+#define MF_PIX_CONTROL  0xA000
+
+	outw(EC00_RESET,  0x42e8);
+	inw(  0x42e8);
+	outw(EC00_ENABLE,  0x42e8);
+	inw(  0x42e8);
+	outw(EC01_ENH_ENB | EC01_LAW_ENB,
+		   0x4ae8);
+	outw(MF_MULT_MISC,  0xbee8); /* 16 bit I/O registers */
+
+	/* Now set some basic accelerator registers */
+	Trio_WaitQueue(0x0400);
+	outw(SRC_FOREGROUND | MIX_SRC, 0xbae8);
+	outw(SRC_BACKGROUND | MIX_SRC,  0xb6e8);/* direct color*/
+	outw(MF_T_CLIP | 0, 0xbee8 );     /* clip virtual area  */
+	outw(MF_L_CLIP | 0, 0xbee8 );
+	outw(MF_R_CLIP | (640 - 1), 0xbee8);
+	outw(MF_B_CLIP | (480 - 1),  0xbee8);
+	Trio_WaitQueue(0x0400);
+	outw(0xffff,  0xaae8);       /* Enable all planes */
+	outw(0xffff, 0xaae8);       /* Enable all planes */
+	outw( MF_PIX_CONTROL | MFA_SRC_FOREGR_MIX,  0xbee8);
+
+}
+
+__initfunc(int s3trio_init(void)) {
+
+    u_char bus, dev;
+    unsigned int t32;
+    unsigned short cmd;
+    int i;
+
+	bus=0;
+	dev=(3<<3);
+                pcibios_read_config_dword(bus, dev, PCI_VENDOR_ID, &t32);
+                if(t32 == (PCI_DEVICE_ID_S3_TRIO << 16) + PCI_VENDOR_ID_S3) {
+                        pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
+                        pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_1, &t32);
+			pcibios_read_config_word(bus, dev, PCI_COMMAND,&cmd);
+
+			pcibios_write_config_word(bus, dev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+			pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_0,0xffffffff);
+                        pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
+
+/* This is a gross hack as OF only maps enough memory for the framebuffer and
+   we want to use MMIO too. We should find out which chunk of address space
+   we can use here */
+			pcibios_write_config_dword(bus,dev,PCI_BASE_ADDRESS_0,0xc6000000);
+
+			/* unlock s3 */
+
+			outb(0x01, 0x3C3);
+
+			outb(inb(0x03CC) | 1, 0x3c2);
+
+			outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
+			outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
+			outb(0x33,0x3d4);
+			outw(IO_OUT16VAL( inb(0x3d5) & ~(0x2 |
+			 0x10 | 0x40) , 0x33),0x3d4);
+
+			outw(IO_OUT16VAL(0x6,0x8), 0x3c4);
+
+			/* switch to MMIO only mode */
+
+			outb(0x58,0x3d4);
+			outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10,0x58),0x3d4);
+			outw(IO_OUT16VAL(8,0x53),0x3d4);
+
+			/* switch off I/O accesses */
+
+#if 0
+			pcibios_write_config_word(bus, dev, PCI_COMMAND,
+				        PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+#endif
+                }
+
+	return 0;
+}
+
+
+    /*
+     *  Initialisation
+     *  We heavily rely on OF for the moment. This needs fixing.
+     */
+
+__initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
+{
+    struct device_node *dp;
+    int i, err, *pp, len;
+    unsigned *up, address;
+    u_long *CursorBase;
+
+    if (!prom_display_paths[0])
+	return mem_start;
+    if (!(dp = find_path_device(prom_display_paths[0])))
+	return mem_start;
+
+    strncat(s3trio_name, dp->name, sizeof(s3trio_name));
+    s3trio_name[sizeof(s3trio_name)-1] = '\0';
+    strcpy(fb_fix.id, s3trio_name);
+
+    if((pp = (int *)get_property(dp, "vendor-id", &len)) != NULL
+	&& *pp!=PCI_VENDOR_ID_S3) {
+	printk("%s: can't find S3 Trio board\n", dp->full_name);
+	return mem_start;
+    }
+
+    if((pp = (int *)get_property(dp, "device-id", &len)) != NULL
+	&& *pp!=PCI_DEVICE_ID_S3_TRIO) {
+	printk("%s: can't find S3 Trio board\n", dp->full_name);
+	return mem_start;
+    }
+
+    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;
+
+    s3trio_init();
+    address=0xc6000000;
+    fb_fix.smem_start = ioremap(address,64*1024*1024);
+    fb_fix.type = FB_TYPE_PACKED_PIXELS;
+    fb_fix.type_aux = 0;
+
+
+    s3trio_resetaccel();
+
+	mem_out8(0x30,fb_fix.smem_start+0x1008000 + 0x03D4);
+	mem_out8(0x2d,fb_fix.smem_start+0x1008000 + 0x03D4);
+	mem_out8(0x2e,fb_fix.smem_start+0x1008000 + 0x03D4);
+
+	mem_out8(0x50,fb_fix.smem_start+0x1008000 + 0x03D4);
+
+    /* disable HW cursor */
+
+    mem_out8(0x39,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0xa0,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x45,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x4e,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x4f,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    /* init HW cursor */
+
+    CursorBase=(u_long *)(fb_fix.smem_start + 2*1024*1024 - 0x400);
+	for (i=0; i < 8; i++) {
+		*(CursorBase  +(i*4)) = 0xffffff00;
+		*(CursorBase+1+(i*4)) = 0xffff0000;
+		*(CursorBase+2+(i*4)) = 0xffff0000;
+		*(CursorBase+3+(i*4)) = 0xffff0000;
+	}
+	for (i=8; i < 64; i++) {
+		*(CursorBase  +(i*4)) = 0xffff0000;
+		*(CursorBase+1+(i*4)) = 0xffff0000;
+		*(CursorBase+2+(i*4)) = 0xffff0000;
+		*(CursorBase+3+(i*4)) = 0xffff0000;
+	}
+
+
+    mem_out8(0x4c,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(((2*1024 - 1)&0xf00)>>8,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x4d,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8((2*1024 - 1) & 0xff,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x45,fb_fix.smem_start+0x1008000 + 0x03D4);
+	mem_in8(fb_fix.smem_start+0x1008000 + 0x03D4);
+
+    mem_out8(0x4a,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0x80,fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x80,fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x80,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x4b,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0x00,fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x00,fb_fix.smem_start+0x1008000 + 0x03D5);
+    mem_out8(0x00,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    mem_out8(0x45,fb_fix.smem_start+0x1008000 + 0x03D4);
+    mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+
+    s3trio_setcolreg(255, 56, 100, 160, 0, NULL /* not used */);
+    s3trio_setcolreg(254, 0, 0, 0, 0, NULL /* not used */);
+    memset((char *)fb_fix.smem_start,0,640*480);
+
+#if 0
+    Trio_RectFill(0,0,90,90,7,1);
+#endif
+
+    fb_fix.visual = FB_VISUAL_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 = 5;
+    fb_var.pixclock = 1;
+    fb_var.left_margin = fb_var.right_margin = 0;
+    fb_var.upper_margin = fb_var.lower_margin = 0;
+    fb_var.hsync_len = fb_var.vsync_len = 0;
+    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;
+    disp.dispsw = &fbcon_trio8;
+
+    strcpy(fb_info.modename, "Trio64 ");
+    strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
+    fb_info.node = -1;
+    fb_info.fbops = &s3trio_ops;
+#if 0
+    fb_info.fbvar_num = 1;
+    fb_info.fbvar = &fb_var;
+#endif
+    fb_info.disp = &disp;
+    fb_info.fontname[0] = '\0';
+    fb_info.changevar = NULL;
+    fb_info.switch_con = &s3triofbcon_switch;
+    fb_info.updatevar = &s3triofbcon_updatevar;
+    fb_info.blank = &s3triofbcon_blank;
+#if 0
+    fb_info.setcmap = &s3triofbcon_setcmap;
+#endif
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+    display_info.height = fb_var.yres;
+    display_info.width = fb_var.xres;
+    display_info.depth = 8;
+    display_info.pitch = fb_fix.line_length;
+    display_info.mode = 0;
+    strncpy(display_info.name, dp->name, sizeof(display_info.name));
+    display_info.fb_address = (unsigned long)fb_fix.smem_start;
+    display_info.disp_reg_address = address + 0x1008000;
+    display_info.cmap_adr_address = address + 0x1008000 + 0x3c8;
+    display_info.cmap_data_address = address + 0x1008000 + 0x3c9;
+    console_setmode_ptr = s3trio_console_setmode;
+#endif /* CONFIG_FB_COMPAT_XPMAC) */
+
+    err = register_framebuffer(&fb_info);
+    if (err < 0)
+	return mem_start;
+
+    printk("S3 Trio frame buffer device on %s\n", dp->full_name);
+
+    return mem_start;
+}
+
+
+static int s3triofbcon_switch(int con, struct fb_info *info)
+{
+    /* 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,
+		    s3trio_getcolreg, info);
+
+    currcon = con;
+    /* Install new colormap */
+    do_install_cmap(con);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int s3triofbcon_updatevar(int con, struct fb_info *info)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void s3triofbcon_blank(int blank, struct fb_info *info)
+{
+    /* Nothing */
+}
+
+    /*
+     *  Set the colormap
+     */
+
+static int s3triofbcon_setcmap(struct fb_cmap *cmap, int con)
+{
+    return(s3trio_set_cmap(cmap, 1, con));
+}
+
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int s3trio_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *info)
+{
+    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 s3trio_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                            u_int transp, struct fb_info *info)
+{
+    if (regno > 255)
+	return 1;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+
+    mem_out8(regno,fb_fix.smem_start+0x1008000 + 0x3c8);
+    mem_out8((red & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
+    mem_out8((green & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
+    mem_out8((blue & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
+
+    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,
+		    s3trio_setcolreg, info);
+    else
+	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		    &fb_display[con].var, 1, s3trio_setcolreg, info);
+}
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+
+    /*
+     *  Backward compatibility mode for Xpmac
+     */
+
+static int s3trio_console_setmode(struct vc_mode *mode, int doit)
+{
+    int err;
+    struct fb_var_screeninfo var;
+    struct s3trio_par par;
+
+    if (mode->mode <= 0 || mode->mode > VMODE_MAX )
+        return -EINVAL;
+    par.video_mode = mode->mode;
+
+    switch (mode->depth) {
+        case 24:
+        case 32:
+            par.color_mode = CMODE_32;
+            break;
+        case 16:
+            par.color_mode = CMODE_16;
+            break;
+        case 8:
+        case 0:			/* (default) */
+            par.color_mode = CMODE_8;
+            break;
+        default:
+            return -EINVAL;
+    }
+    encode_var(&var, &par);
+    if ((err = decode_var(&var, &par)))
+        return err;
+    if (doit)
+        s3trio_set_var(&var, currcon, 0);
+    return 0;
+}
+
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+void s3trio_video_setup(char *options, int *ints) {
+
+        return;
+
+}
+
+static void Trio_WaitQueue(u_short fifo) {
+
+	u_short status;
+
+        do
+        {
+		status = mem_in16(fb_fix.smem_start + 0x1000000 + 0x9AE8);
+	}  while (!(status & fifo));
+
+}
+
+static void Trio_WaitBlit(void) {
+
+	u_short status;
+
+        do
+        {
+		status = mem_in16(fb_fix.smem_start + 0x1000000 + 0x9AE8);
+	}  while (status & 0x200);
+
+}
+
+static void Trio_BitBLT(u_short curx, u_short cury, u_short destx,
+			u_short desty, u_short width, u_short height,
+			u_short mode) {
+
+	u_short blitcmd = 0xc011;
+
+	/* Set drawing direction */
+        /* -Y, X maj, -X (default) */
+
+	if (curx > destx)
+		blitcmd |= 0x0020;  /* Drawing direction +X */
+	else {
+		curx  += (width - 1);
+		destx += (width - 1);
+	}
+
+	if (cury > desty)
+		blitcmd |= 0x0080;  /* Drawing direction +Y */
+	else {
+		cury  += (height - 1);
+		desty += (height - 1);
+	}
+
+	Trio_WaitQueue(0x0400);
+
+	outw(0xa000,  0xBEE8);
+	outw(0x60 | mode,  0xBAE8);
+
+	outw(curx,  0x86E8);
+	outw(cury,  0x82E8);
+
+	outw(destx,  0x8EE8);
+	outw(desty,  0x8AE8);
+
+	outw(height - 1,  0xBEE8);
+	outw(width - 1,  0x96E8);
+
+	outw(blitcmd,  0x9AE8);
+
+}
+
+static void Trio_RectFill(u_short x, u_short y, u_short width, u_short height,
+			  u_short mode, u_short color) {
+
+	u_short blitcmd = 0x40b1;
+
+	Trio_WaitQueue(0x0400);
+
+	outw(0xa000,  0xBEE8);
+	outw((0x20 | mode),  0xBAE8);
+	outw(0xe000,  0xBEE8);
+	outw(color,  0xA6E8);
+	outw(x,  0x86E8);
+	outw(y,  0x82E8);
+	outw((height - 1), 0xBEE8);
+	outw((width - 1), 0x96E8);
+	outw(blitcmd,  0x9AE8);
+
+}
+
+
+static void Trio_MoveCursor(u_short x, u_short y) {
+
+	mem_out8(0x39, fb_fix.smem_start + 0x1008000 + 0x3d4);
+	mem_out8(0xa0, fb_fix.smem_start + 0x1008000 + 0x3d5);
+
+	mem_out8(0x46, fb_fix.smem_start + 0x1008000 + 0x3d4);
+	mem_out8((x & 0x0700) >> 8, fb_fix.smem_start + 0x1008000 + 0x3d5);
+	mem_out8(0x47, fb_fix.smem_start + 0x1008000 + 0x3d4);
+	mem_out8(x & 0x00ff, fb_fix.smem_start + 0x1008000 + 0x3d5);
+
+	mem_out8(0x48, fb_fix.smem_start + 0x1008000 + 0x3d4);
+	mem_out8((y & 0x0700) >> 8, fb_fix.smem_start + 0x1008000 + 0x3d5);
+	mem_out8(0x49, fb_fix.smem_start + 0x1008000 + 0x3d4);
+	mem_out8(y & 0x00ff, fb_fix.smem_start + 0x1008000 + 0x3d5);
+
+}
+
+
+    /*
+     *  Text console acceleration
+     */
+
+static void fbcon_trio8_bmove(struct display *p, int sy, int sx, int dy,
+			      int dx, int height, int width)
+{
+    sx *= 8; dx *= 8; width *= 8;
+    Trio_BitBLT((u_short)sx, (u_short)(sy*p->fontheight), (u_short)dx,
+		 (u_short)(dy*p->fontheight), (u_short)width,
+		 (u_short)(height*p->fontheight), (u_short)S3_NEW);
+}
+
+static void fbcon_trio8_clear(struct vc_data *conp, struct display *p, int sy,
+			      int sx, int height, int width)
+{
+    unsigned char bg;
+
+    sx *= 8; width *= 8;
+    bg = attr_bgcol_ec(p,conp);
+    Trio_RectFill((u_short)sx,
+		   (u_short)(sy*p->fontheight),
+		   (u_short)width,
+		   (u_short)(height*p->fontheight),
+		   (u_short)S3_NEW,
+		   (u_short)bg);
+}
+
+static void fbcon_trio8_putc(struct vc_data *conp, struct display *p, int c,
+			     int yy, int xx)
+{
+    Trio_WaitBlit();
+    fbcon_cfb8_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_trio8_putcs(struct vc_data *conp, struct display *p,
+			      const char *s, int count, int yy, int xx)
+{
+    Trio_WaitBlit();
+    fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_trio8_revc(struct display *p, int xx, int yy)
+{
+    Trio_WaitBlit();
+    fbcon_cfb8_revc(p, xx, yy);
+}
+
+static struct display_switch fbcon_trio8 = {
+   fbcon_cfb8_setup, fbcon_trio8_bmove, fbcon_trio8_clear, fbcon_trio8_putc,
+   fbcon_trio8_putcs, fbcon_trio8_revc
+};
--- m68k-2.1.85/drivers/video/cyberfb.c.orig	Sun Feb  8 22:35:50 1998
+++ m68k-2.1.85/drivers/video/cyberfb.c	Tue Feb 17 23:24:21 1998
@@ -21,6 +21,7 @@
  */
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -36,11 +37,27 @@
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
+#include <asm/amigahw.h>
+
 #include "s3blit.h"
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+
 
+#ifdef CYBERFBDEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
 
 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
 
+
+#define wb_64(reg,dat) (*((unsigned char volatile *)CyberRegs + reg) = dat)
+
+
+
 struct cyberfb_par {
    int xres;
    int yres;
@@ -72,9 +89,9 @@
    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);
+                    u_int *transp, struct fb_info *info);
    int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
-                    u_int transp);
+                    u_int transp, struct fb_info *info);
    void (*blank)(int blank);
 } *fbhw;
 
@@ -106,7 +123,7 @@
 static unsigned long CyberMem;
 static unsigned long CyberSize;
 static volatile char *CyberRegs;
-
+ 
 
 /*
  *    Predefined Video Modes
@@ -114,34 +131,55 @@
 
 static struct fb_videomode cyberfb_predefined[] __initdata = {
     {
-	"cyber8", {		/* Cybervision 8 bpp */
-	    CYBER8_WIDTH, CYBER8_HEIGHT, CYBER8_WIDTH, CYBER8_HEIGHT, 0, 0, 8, 0,
+	"640x480-8", {		/* 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
 	}
     }, {
-	"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,
+	"800x600-8", {		/* 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
 	}
     }, {
-	"800x600x8", {		/* Cybervision 8 bpp */
-	    800, 600, 800, 600, 0, 0, 8, 0,
+	"1024x768-8", {		/* Cybervision 8 bpp */
+	    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_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,
+	"1152x886-8", {		/* Cybervision 8 bpp */
+	    1152, 886, 1152, 886, 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
 	}
-    },
+    }, {
+	"1280x1024-8", {	/* Cybervision 8 bpp */
+	    1280, 1024, 1280, 1024, 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
+	}
+    }, {
+	"1600x1200-8", {	/* Cybervision 8 bpp */
+	    1600, 1200, 1600, 1200, 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
+	}
+    }, {
+	"800x600-16", {		/* 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
+	}
+    }
 };
 
 
@@ -154,13 +192,12 @@
 static int Cyberfb_Cyber16 = 0;       /* Use Cybervision board */
 #endif
 
-
 /*
  *    Some default modes
  */
 
-#define CYBER8_DEFMODE     (1)
-#define CYBER16_DEFMODE    (2)
+#define CYBER8_DEFMODE     (0)
+#define CYBER16_DEFMODE    (6)
 
 static struct fb_var_screeninfo cyberfb_default;
 
@@ -171,19 +208,22 @@
 
 void cyberfb_setup(char *options, int *ints);
 
-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_open(struct fb_info *info);
+static int cyberfb_release(struct fb_info *info);
+static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct
+fb_info *info);
+static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, struct
+fb_info *info);
+static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, struct
+fb_info *info);
 static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
-				int fbidx);
+			       struct fb_info *info);
 static int cyberfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                          u_long arg, int con, int fbidx);
+                         u_long arg, int con, struct fb_info *info);
 
 
 /*
@@ -191,22 +231,30 @@
  */
 
 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_switch(int con, struct fb_info *info);
+static int Cyberfb_updatevar(int con, struct fb_info *info);
+static void Cyberfb_blank(int blank, struct fb_info *info);
+
+
+/*
+ *    Text console acceleration
+ */
+
+static struct display_switch fbcon_cyber8;
 
 
 /*
  *    Accelerated Functions used by the low level console driver
  */
 
-void Cyber_WaitQueue(u_short fifo);
-void Cyber_WaitBlit(void);
-void Cyber_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
-                  u_short width, u_short height, u_short mode);
-void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
-                    u_short mode, u_short color);
-void Cyber_MoveCursor(u_short x, u_short y);
+static void Cyber_WaitQueue(u_short fifo);
+static void Cyber_WaitBlit(void);
+static void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
+			 u_short desty, u_short width, u_short height,
+			 u_short mode);
+static void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
+			   u_short mode, u_short color);
+static void Cyber_MoveCursor(u_short x, u_short y);
 
 
 /*
@@ -221,9 +269,9 @@
 static int Cyber_encode_var(struct fb_var_screeninfo *var,
                           struct cyberfb_par *par);
 static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp);
+                         u_int *transp, struct fb_info *info);
 static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp);
+                         u_int transp, struct fb_info *info);
 static void Cyber_blank(int blank);
 
 
@@ -234,8 +282,8 @@
 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 cyberfb_set_disp(int con);
+static void do_install_cmap(int con, struct fb_info *info);
+static void cyberfb_set_disp(int con, struct fb_info *info);
 static int get_video_mode(const char *name);
 
 
@@ -256,30 +304,31 @@
 	volatile u_long *CursorBase;
 
 	for (i = 0; i < 256; i++)
-
-		for (i = 0; i < 256; i++)
-		{
-			Cyber_colour_table [i][0] = i;
-			Cyber_colour_table [i][1] = i;
-			Cyber_colour_table [i][2] = i;
-			Cyber_colour_table [i][3] = 0;
-		}
+	{
+		Cyber_colour_table [i][0] = i;
+		Cyber_colour_table [i][1] = i;
+		Cyber_colour_table [i][2] = i;
+		Cyber_colour_table [i][3] = 0;
+	}
 
 	/*
 	 * Just clear the thing for the biggest mode.
+	 *
+	 * ++Andre, TODO: determine size first, then clear all memory
+	 *                (the 3D penguin might need texture memory :-) )
 	 */
 
-	memset ((char*)CyberMem, 0, CYBER8_WIDTH * CYBER8_HEIGHT);
+	memset ((char*)CyberMem, 0, 1600 * 1200);
 
 	/* Disable hardware cursor */
-	*(CyberRegs + S3_CRTC_ADR)  = S3_REG_LOCK2;
-	*(CyberRegs + S3_CRTC_DATA) = 0xa0;
-	*(CyberRegs + S3_CRTC_ADR)  = S3_HGC_MODE;
-	*(CyberRegs + S3_CRTC_DATA) = 0x00;
-	*(CyberRegs + S3_CRTC_ADR)  = S3_HWGC_DX;
-	*(CyberRegs + S3_CRTC_DATA) = 0x00;
-	*(CyberRegs + S3_CRTC_ADR)  = S3_HWGC_DY;
-	*(CyberRegs + S3_CRTC_DATA) = 0x00;
+	wb_64(S3_CRTC_ADR, S3_REG_LOCK2);
+	wb_64(S3_CRTC_DATA, 0xa0);
+	wb_64(S3_CRTC_ADR, S3_HGC_MODE);
+	wb_64(S3_CRTC_DATA, 0x00);
+	wb_64(S3_CRTC_ADR, S3_HWGC_DX);
+	wb_64(S3_CRTC_DATA, 0x00);
+	wb_64(S3_CRTC_ADR, S3_HWGC_DY);
+	wb_64(S3_CRTC_DATA, 0x00);
 
 	/* Get memory size (if not 2MB it is 4MB) */
 	*(CyberRegs + S3_CRTC_ADR) = S3_LAW_CTL;
@@ -306,8 +355,8 @@
 		*(CursorBase+3+(i*4)) = 0xffff0000;
 	}
 
-	Cyber_setcolreg (255, 56, 100, 160, 0);
-	Cyber_setcolreg (254, 0, 0, 0, 0);
+	Cyber_setcolreg (255, 56, 100, 160, 0, NULL /* unused */);
+	Cyber_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);
 
 	return 0;
 }
@@ -420,7 +469,10 @@
 
 	var->height = -1;
 	var->width = -1;
+
 	var->accel = FB_ACCEL_CYBERVISION;
+	DPRINTK("accel CV64\n");
+
 	var->vmode = FB_VMODE_NONINTERLACED;
 
 	/* Dummy values */
@@ -451,20 +503,22 @@
  */
 
 static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			   u_int transp)
+			   u_int transp, struct fb_info *info)
 {
 	if (regno > 255)
+	{
 		return (1);
+	}
 
-	*(CyberRegs + 0x3c8) = (char)regno;
+	wb_64(0x3c8, (unsigned char) regno);
 	Cyber_colour_table [regno][0] = red & 0xff;
 	Cyber_colour_table [regno][1] = green & 0xff;
 	Cyber_colour_table [regno][2] = blue & 0xff;
 	Cyber_colour_table [regno][3] = transp;
 
-	*(CyberRegs + 0x3c9) = (red & 0xff) >> 2;
-	*(CyberRegs + 0x3c9) = (green & 0xff) >> 2;
-	*(CyberRegs + 0x3c9) = (blue & 0xff) >> 2;
+	wb_64(0x3c9, (red & 0xff) >> 2);
+	wb_64(0x3c9, (green & 0xff) >> 2);
+	wb_64(0x3c9, (blue & 0xff) >> 2);
 
 	return (0);
 }
@@ -476,13 +530,13 @@
  */
 
 static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			   u_int *transp)
+			   u_int *transp, struct fb_info *info)
 {
 	if (regno >= 256)
 		return (1);
-	*red    = Cyber_colour_table [regno][0];
-	*green  = Cyber_colour_table [regno][1];
-	*blue   = Cyber_colour_table [regno][2];
+	*red	= Cyber_colour_table [regno][0];
+	*green	= Cyber_colour_table [regno][1];
+	*blue	= Cyber_colour_table [regno][2];
 	*transp = Cyber_colour_table [regno][3];
 	return (0);
 }
@@ -497,28 +551,32 @@
 	int i;
 
 	if (blank)
+	{
 		for (i = 0; i < 256; i++)
 		{
-			*(CyberRegs + 0x3c8) = i;
-			*(CyberRegs + 0x3c9) = 0;
-			*(CyberRegs + 0x3c9) = 0;
-			*(CyberRegs + 0x3c9) = 0;
+			wb_64(0x3c8, (unsigned char) i);
+			wb_64(0x3c9, 0);
+			wb_64(0x3c9, 0);
+			wb_64(0x3c9, 0);
 		}
+	}
 	else
+	{
 		for (i = 0; i < 256; i++)
 		{
-			*(CyberRegs + 0x3c8) = i;
-			*(CyberRegs + 0x3c9) = Cyber_colour_table [i][0] >> 2;
-			*(CyberRegs + 0x3c9) = Cyber_colour_table [i][1] >> 2;
-			*(CyberRegs + 0x3c9) = Cyber_colour_table [i][2] >> 2;
+			wb_64(0x3c8, (unsigned char) i);
+			wb_64(0x3c9, Cyber_colour_table[i][0] >> 2);
+			wb_64(0x3c9, Cyber_colour_table[i][1] >> 2);
+			wb_64(0x3c9, Cyber_colour_table[i][2] >> 2);
 		}
+	}
 }
 
 
 /**************************************************************
  * We are waiting for "fifo" FIFO-slots empty
  */
-void Cyber_WaitQueue (u_short fifo)
+static void Cyber_WaitQueue (u_short fifo)
 {
 	u_short status;
 
@@ -532,7 +590,7 @@
 /**************************************************************
  * We are waiting for Hardware (Graphics Engine) not busy
  */
-void Cyber_WaitBlit (void)
+static void Cyber_WaitBlit (void)
 {
 	u_short status;
 
@@ -546,8 +604,9 @@
 /**************************************************************
  * BitBLT - Through the Plane
  */
-void Cyber_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
-                   u_short width, u_short height, u_short mode)
+static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx,
+			  u_short desty, u_short width, u_short height,
+			  u_short mode)
 {
 	u_short blitcmd = S3_BITBLT;
 
@@ -589,8 +648,8 @@
 /**************************************************************
  * Rectangle Fill Solid
  */
-void Cyber_RectFill (u_short x, u_short y, u_short width, u_short height,
-                     u_short mode, u_short color)
+static void Cyber_RectFill (u_short x, u_short y, u_short width,
+			    u_short height, u_short mode, u_short color)
 {
 	u_short blitcmd = S3_FILLEDRECT;
 
@@ -611,11 +670,10 @@
 	*((u_short volatile *)(CyberRegs + S3_CMD)) = blitcmd;
 }
 
-
 /**************************************************************
  * Move cursor to x, y
  */
-void Cyber_MoveCursor (u_short x, u_short y)
+static void Cyber_MoveCursor (u_short x, u_short y)
 {
 	*(CyberRegs + S3_CRTC_ADR)  = 0x39;
 	*(CyberRegs + S3_CRTC_DATA) = 0xa0;
@@ -651,9 +709,13 @@
 static void cyberfb_get_par(struct cyberfb_par *par)
 {
 	if (current_par_valid)
+	{
 		*par = current_par;
+	}
 	else
+	{
 		fbhw->decode_var(&cyberfb_default, par);
+	}
 }
 
 
@@ -667,6 +729,7 @@
 static void cyber_set_video(struct fb_var_screeninfo *var)
 {
 	/* Set clipping rectangle to current screen size */
+ 
 	*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x1000;
 	*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x2000;
 
@@ -693,16 +756,16 @@
 }
 
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-			    fbhw->setcolreg);
+			    fbhw->setcolreg, info);
 	else
-		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
-			    &fb_display[con].var, 1, fbhw->setcolreg);
+		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+			    &fb_display[con].var, 1, fbhw->setcolreg, info);
 }
 
 
@@ -710,7 +773,7 @@
  *  Open/Release the frame buffer device
  */
 
-static int cyberfb_open(int fbidx)
+static int cyberfb_open(struct fb_info *info)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -720,7 +783,7 @@
 	return(0);
 }
 
-static int cyberfb_release(int fbidx)
+static int cyberfb_release(struct fb_info *info)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -731,7 +794,8 @@
  *    Get the Fixed Part of the Display
  */
 
-static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			   struct fb_info *info)
 {
 	struct cyberfb_par par;
 	int error = 0;
@@ -748,21 +812,28 @@
  *    Get the User Defined Part of the Display
  */
 
-static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
 {
 	struct cyberfb_par par;
 	int error = 0;
 
-	if (con == -1) {
+	if (con == -1)
+	{
 		cyberfb_get_par(&par);
 		error = fbhw->encode_var(var, &par);
-	} else
+		disp.var = *var;   /* ++Andre: don't know if this is the right place */
+	}
+	else
+	{
 		*var = fb_display[con].var;
+	}
+
 	return(error);
 }
 
 
-static void cyberfb_set_disp(int con)
+static void cyberfb_set_disp(int con, struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -772,8 +843,7 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	/* ### FN: Needs fixes later */
-	cyberfb_get_fix(&fix, con, 0);
+	cyberfb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
 	display->screen_base = (u_char *)fix.smem_start;
@@ -784,6 +854,17 @@
 	display->ywrapstep = fix.ywrapstep;
 	display->can_soft_blank = 1;
 	display->inverse = Cyberfb_inverse;
+	switch (display->var.bits_per_pixel) {
+	    case 8:
+		display->dispsw = &fbcon_cyber8;
+		break;
+	    case 16:
+		display->dispsw = &fbcon_cfb16;
+		break;
+	    default:
+		display->dispsw = NULL;
+		break;
+	}
 }
 
 
@@ -791,7 +872,8 @@
  *    Set the User Defined Part of the Display
  */
 
-static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
 
@@ -808,10 +890,10 @@
 		    oldvxres != var->xres_virtual ||
 		    oldvyres != var->yres_virtual ||
 		    oldbpp != var->bits_per_pixel) {
-			cyberfb_set_disp(con);
+			cyberfb_set_disp(con, info);
 			(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
-			do_install_cmap(con);
+			do_install_cmap(con, info);
 		}
 	}
 	var->activate = 0;
@@ -824,15 +906,15 @@
  */
 
 static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			    struct fb_info *info)
 {
 	if (con == currcon) /* current console? */
 		return(fb_get_cmap(cmap, &fb_display[con].var,
-				   kspc, fbhw->getcolreg));
+				   kspc, fbhw->getcolreg, info));
 	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),
+		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			     cmap, kspc ? 0 : 2);
 	return(0);
 }
@@ -843,7 +925,7 @@
  */
 
 static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			    struct fb_info *info)
 {
 	int err;
 
@@ -852,9 +934,9 @@
 				 1<<fb_display[con].var.bits_per_pixel, 0)))
 			return(err);
 	}
-	if (con == currcon)              /* current console? */
+	if (con == currcon)		 /* current console? */
 		return(fb_set_cmap(cmap, &fb_display[con].var,
-				   kspc, fbhw->setcolreg));
+				   kspc, fbhw->setcolreg, info));
 	else
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return(0);
@@ -867,18 +949,19 @@
  *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  */
 
-static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
+			       struct fb_info *info)
 {
 	return(-EINVAL);
 }
 
 
 /*
-    *    Cybervision Frame Buffer Specific ioctls
+    *	 Cybervision Frame Buffer Specific ioctls
     */
 
 static int cyberfb_ioctl(struct inode *inode, struct file *file,
-                          u_int cmd, u_long arg, int con, int fbidx)
+			 u_int cmd, u_long arg, int con, struct fb_info *info)
 {
 	return(-EINVAL);
 }
@@ -906,8 +989,18 @@
 			fb_invert_cmaps();
 		} else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
+		else if (!strcmp (this_opt, "cyber8")){
+			cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
+		}
+		else if (!strcmp (this_opt, "cyber16")){
+			cyberfb_default = cyberfb_predefined[CYBER16_DEFMODE].var;
+		}
 		else
 			get_video_mode(this_opt);
+
+	DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",cyberfb_default.xres,
+                                                           cyberfb_default.yres,
+		                                           cyberfb_default.bits_per_pixel);
 }
 
 
@@ -954,9 +1047,9 @@
 	fbhw->encode_var(&cyberfb_default, &par);
 
 	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);
+	cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
+	cyberfb_set_disp(-1, &fb_info);
+	do_install_cmap(0, &fb_info);
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, CyberSize>>10);
@@ -968,17 +1061,17 @@
 }
 
 
-static int Cyberfb_switch(int con)
+static int Cyberfb_switch(int con, struct fb_info *info)
 {
 	/* 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,
-			    fbhw->getcolreg);
+			    fbhw->getcolreg, info);
 
 	do_fb_set_var(&fb_display[con].var, 1);
 	currcon = con;
 	/* Install new colormap */
-	do_install_cmap(con);
+	do_install_cmap(con, info);
 	return(0);
 }
 
@@ -990,7 +1083,7 @@
  *    Since it's called by a kernel driver, no range checking is done.
  */
 
-static int Cyberfb_updatevar(int con)
+static int Cyberfb_updatevar(int con, struct fb_info *info)
 {
 	return(0);
 }
@@ -1000,7 +1093,7 @@
     *    Blank the display.
     */
 
-static void Cyberfb_blank(int blank)
+static void Cyberfb_blank(int blank, struct fb_info *info)
 {
 	fbhw->blank(blank);
 }
@@ -1014,14 +1107,73 @@
 {
 	int i;
 
-	for (i = 0; i < NUM_TOTAL_MODES; i++)
-		if (!strcmp(name, cyberfb_predefined[i].name))
+	for (i = 0; i < NUM_TOTAL_MODES; i++) {
+		if (!strcmp(name, cyberfb_predefined[i].name)) {
 			cyberfb_default = cyberfb_predefined[i].var;
 			return(i);
+		}
+	}
+	/* ++Andre: set cyberfb default mode */
+	cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
 	return(0);
 }
 
 
+/*
+ *    Text console acceleration
+ */
+
+static void fbcon_cyber8_bmove(struct display *p, int sy, int sx, int dy,
+			       int dx, int height, int width)
+{
+    sx *= 8; dx *= 8; width *= 8;
+    Cyber_BitBLT((u_short)sx, (u_short)(sy*p->fontheight), (u_short)dx,
+		 (u_short)(dy*p->fontheight), (u_short)width,
+		 (u_short)(height*p->fontheight), (u_short)S3_NEW);
+}
+
+static void fbcon_cyber8_clear(struct vc_data *conp, struct display *p, int sy,
+			       int sx, int height, int width)
+{
+    unsigned char bg;
+
+    sx *= 8; width *= 8;
+    bg = attr_bgcol_ec(p,conp);
+    Cyber_RectFill((u_short)sx,
+		   (u_short)(sy*p->fontheight),
+		   (u_short)width,
+		   (u_short)(height*p->fontheight),
+		   (u_short)S3_NEW,
+		   (u_short)bg);
+}
+
+static void fbcon_cyber8_putc(struct vc_data *conp, struct display *p, int c,
+			      int yy, int xx)
+{
+    Cyber_WaitBlit();
+    fbcon_cfb8_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_cyber8_putcs(struct vc_data *conp, struct display *p,
+			       const char *s, int count, int yy, int xx)
+{
+    Cyber_WaitBlit();
+    fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_cyber8_revc(struct display *p, int xx, int yy)
+{
+    Cyber_WaitBlit();
+    fbcon_cfb8_revc(p, xx, yy);
+}
+
+static struct display_switch fbcon_cyber8 = {
+   fbcon_cfb8_setup, fbcon_cyber8_bmove, fbcon_cyber8_clear, fbcon_cyber8_putc,
+   fbcon_cyber8_putcs, fbcon_cyber8_revc
+};
+
+
+
 #ifdef MODULE
 int init_module(void)
 {
@@ -1036,12 +1188,3 @@
 	/* TODO: clean up ... */
 }
 #endif /* MODULE */
-
-
-/*
- *  Visible symbols for modules
- */
-
-EXPORT_SYMBOL(Cyber_BitBLT);
-EXPORT_SYMBOL(Cyber_RectFill);
-EXPORT_SYMBOL(Cyber_WaitBlit);
--- m68k-2.1.85/drivers/video/fbcon-afb.h.orig	Sun Feb  8 22:35:56 1998
+++ m68k-2.1.85/drivers/video/fbcon-afb.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Amiga bitplanes (afb)
      */
 
-
-
 extern struct display_switch fbcon_afb;
 extern void fbcon_afb_setup(struct display *p);
 extern void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon-cfb16.c.orig	Sun Feb  8 22:35:51 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb16.c	Tue Feb 17 23:24:21 1998
@@ -46,7 +46,7 @@
 		       int height, int width)
 {
     int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
-    u_char *src, *dst;
+    u8 *src, *dst;
 
     if (sx == 0 && dx == 0 && width * 16 == bytes)
 	mymemmove(p->screen_base + dy * linesize,
@@ -74,7 +74,7 @@
 void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		       int height, int width)
 {
-    u_char *dest0, *dest;
+    u8 *dest0, *dest;
     int bytes = p->next_line, lines = height * p->fontheight, rows, i;
     u32 bgx;
 
@@ -109,7 +109,7 @@
 void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c, int yy,
 		      int xx)
 {
-    u_char *dest, *cdat;
+    u8 *dest, *cdat;
     int bytes = p->next_line, rows;
     u32 eorx, fgx, bgx;
 
@@ -125,7 +125,7 @@
     eorx = fgx ^ bgx;
 
     for (rows = p->fontheight ; rows-- ; dest += bytes) {
-	u_char bits = *cdat++;
+	u8 bits = *cdat++;
 	((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
 	((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
 	((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
@@ -136,7 +136,7 @@
 void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p, const char *s,
 		       int count, int yy, int xx)
 {
-    u_char *cdat, c, *dest, *dest0;
+    u8 *cdat, c, *dest, *dest0;
     int rows, bytes = p->next_line;
     u32 eorx, fgx, bgx;
 
@@ -151,7 +151,7 @@
 	cdat = p->fontdata + c * p->fontheight;
 
 	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
-	    u_char bits = *cdat++;
+	    u8 bits = *cdat++;
 	    ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
 	    ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
 	    ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
@@ -163,7 +163,7 @@
 
 void fbcon_cfb16_revc(struct display *p, int xx, int yy)
 {
-    u_char *dest;
+    u8 *dest;
     int bytes = p->next_line, rows;
 
     dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
--- m68k-2.1.85/drivers/video/fbcon-cfb16.h.orig	Sun Feb  8 22:35:56 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb16.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  16 bpp packed pixel (cfb16)
      */
 
-
-
 extern struct display_switch fbcon_cfb16;
 extern u16 fbcon_cfb16_cmap[16];
 extern void fbcon_cfb16_setup(struct display *p);
--- m68k-2.1.85/drivers/video/fbcon-cfb2.h.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb2.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  2 bpp packed pixel (cfb2)
      */
 
-
-
 extern struct display_switch fbcon_cfb2;
 extern void fbcon_cfb2_setup(struct display *p);
 extern void fbcon_cfb2_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon-cfb32.c.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb32.c	Tue Feb 17 23:24:21 1998
@@ -36,7 +36,7 @@
 		       int height, int width)
 {
     int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
-    u_char *src, *dst;
+    u8 *src, *dst;
 
     if (sx == 0 && dx == 0 && width * 32 == bytes)
 	mymemmove(p->screen_base + dy * linesize,
@@ -64,7 +64,7 @@
 void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		       int height, int width)
 {
-    u_char *dest0, *dest;
+    u8 *dest0, *dest;
     int bytes = p->next_line, lines = height * p->fontheight, rows, i;
     u32 bgx;
 
@@ -106,7 +106,7 @@
 void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c, int yy,
 		      int xx)
 {
-    u_char *dest, *cdat;
+    u8 *dest, *cdat;
     int bytes = p->next_line, rows;
     u32 eorx, fgx, bgx;
 
@@ -120,7 +120,7 @@
     eorx = fgx ^ bgx;
 
     for (rows = p->fontheight ; rows-- ; dest += bytes) {
-	u_char bits = *cdat++;
+	u8 bits = *cdat++;
 	((u32 *)dest)[0] = (-(bits >> 7) & eorx) ^ bgx;
 	((u32 *)dest)[1] = (-(bits >> 6 & 1) & eorx) ^ bgx;
 	((u32 *)dest)[2] = (-(bits >> 5 & 1) & eorx) ^ bgx;
@@ -135,7 +135,7 @@
 void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p, const char *s,
 		       int count, int yy, int xx)
 {
-    u_char *cdat, c, *dest, *dest0;
+    u8 *cdat, c, *dest, *dest0;
     int rows, bytes = p->next_line;
     u32 eorx, fgx, bgx;
 
@@ -148,7 +148,7 @@
 	cdat = p->fontdata + c * p->fontheight;
 
 	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
-	    u_char bits = *cdat++;
+	    u8 bits = *cdat++;
 	    ((u32 *)dest)[0] = (-(bits >> 7) & eorx) ^ bgx;
 	    ((u32 *)dest)[1] = (-(bits >> 6 & 1) & eorx) ^ bgx;
 	    ((u32 *)dest)[2] = (-(bits >> 5 & 1) & eorx) ^ bgx;
@@ -164,7 +164,7 @@
 
 void fbcon_cfb32_revc(struct display *p, int xx, int yy)
 {
-    u_char *dest;
+    u8 *dest;
     int bytes = p->next_line, rows;
 
     dest = p->screen_base + yy * p->fontheight * bytes + xx * 32;
--- m68k-2.1.85/drivers/video/fbcon-cfb32.h.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb32.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  32 bpp packed pixel (cfb32)
      */
 
-
-
 extern struct display_switch fbcon_cfb32;
 extern u32 fbcon_cfb32_cmap[16];
 extern void fbcon_cfb32_setup(struct display *p);
--- m68k-2.1.85/drivers/video/fbcon-cfb4.h.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb4.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  4 bpp packed pixel (cfb4)
      */
 
-
-
 extern struct display_switch fbcon_cfb4;
 extern void fbcon_cfb4_setup(struct display *p);
 extern void fbcon_cfb4_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon-cfb8.c.orig	Sun Feb  8 22:35:51 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb8.c	Tue Feb 17 23:24:21 1998
@@ -50,7 +50,7 @@
 		      int height, int width)
 {
     int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
-    u_char *src,*dst;
+    u8 *src,*dst;
 
     if (sx == 0 && dx == 0 && width * 8 == bytes)
 	mymemmove(p->screen_base + dy * linesize,
@@ -78,7 +78,7 @@
 void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		      int height, int width)
 {
-    u_char *dest0,*dest;
+    u8 *dest0,*dest;
     int bytes=p->next_line,lines=height * p->fontheight, rows, i;
     u32 bgx;
 
@@ -110,7 +110,7 @@
 void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
 		     int xx)
 {
-    u_char *dest,*cdat;
+    u8 *dest,*cdat;
     int bytes=p->next_line,rows;
     u32 eorx,fgx,bgx;
 
@@ -136,7 +136,7 @@
 void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p, const char *s,
 		      int count, int yy, int xx)
 {
-    u_char *cdat, c, *dest, *dest0;
+    u8 *cdat, c, *dest, *dest0;
     int rows,bytes=p->next_line;
     u32 eorx, fgx, bgx;
 
@@ -162,7 +162,7 @@
 
 void fbcon_cfb8_revc(struct display *p, int xx, int yy)
 {
-    u_char *dest;
+    u8 *dest;
     int bytes=p->next_line, rows;
 
     dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
--- m68k-2.1.85/drivers/video/fbcon-cfb8.h.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-cfb8.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  8 bpp packed pixel (cfb8)
      */
 
-
-
 extern struct display_switch fbcon_cfb8;
 extern void fbcon_cfb8_setup(struct display *p);
 extern void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon-ilbm.h.orig	Sun Feb  8 22:35:51 1998
+++ m68k-2.1.85/drivers/video/fbcon-ilbm.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Amiga interleaved bitplanes (ilbm)
      */
 
-
-
 extern struct display_switch fbcon_ilbm;
 extern void fbcon_ilbm_setup(struct display *p);
 extern void fbcon_ilbm_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon-iplan2p2.h.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-iplan2p2.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Atari interleaved bitplanes (2 planes) (iplan2p2)
      */
 
-
-
 extern struct display_switch fbcon_iplan2p2;
 extern void fbcon_iplan2p2_setup(struct display *p);
 extern void fbcon_iplan2p2_bmove(struct display *p, int sy, int sx, int dy,
--- m68k-2.1.85/drivers/video/fbcon-iplan2p4.h.orig	Sun Feb  8 22:35:57 1998
+++ m68k-2.1.85/drivers/video/fbcon-iplan2p4.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Atari interleaved bitplanes (4 planes) (iplan2p4)
      */
 
-
-
 extern struct display_switch fbcon_iplan2p4;
 extern void fbcon_iplan2p4_setup(struct display *p);
 extern void fbcon_iplan2p4_bmove(struct display *p, int sy, int sx, int dy,
--- m68k-2.1.85/drivers/video/fbcon-iplan2p8.h.orig	Sun Feb  8 22:35:58 1998
+++ m68k-2.1.85/drivers/video/fbcon-iplan2p8.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Atari interleaved bitplanes (8 planes) (iplan2p8)
      */
 
-
-
 extern struct display_switch fbcon_iplan2p8;
 extern void fbcon_iplan2p8_setup(struct display *p);
 extern void fbcon_iplan2p8_bmove(struct display *p, int sy, int sx, int dy,
--- m68k-2.1.85/drivers/video/fbcon-mac.h.orig	Sun Feb  8 22:35:58 1998
+++ m68k-2.1.85/drivers/video/fbcon-mac.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Mac variable bpp packed pixels (mac)
      */
 
-
-
 extern struct display_switch fbcon_mac;
 extern void fbcon_mac_setup(struct display *p);
 extern void fbcon_mac_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon-mfb.c.orig	Sun Feb  8 22:35:52 1998
+++ m68k-2.1.85/drivers/video/fbcon-mfb.c	Tue Feb 17 23:24:21 1998
@@ -36,7 +36,7 @@
 void fbcon_mfb_bmove(struct display *p, int sy, int sx, int dy, int dx,
 		     int height, int width)
 {
-    u_char *src, *dest;
+    u8 *src, *dest;
     u_int rows;
 
     if (sx == 0 && dx == 0 && width == p->next_line) {
@@ -65,7 +65,7 @@
 void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		     int height, int width)
 {
-    u_char *dest;
+    u8 *dest;
     u_int rows;
 
     dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
@@ -86,9 +86,9 @@
 void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c, int yy,
 		    int xx)
 {
-    u_char *dest, *cdat;
+    u8 *dest, *cdat;
     u_int rows, bold, revs, underl;
-    u_char d;
+    u8 d;
 
     c &= 0xff;
 
@@ -113,9 +113,9 @@
 void fbcon_mfb_putcs(struct vc_data *conp, struct display *p, const char *s,
 		     int count, int yy, int xx)
 {
-    u_char *dest, *dest0, *cdat;
+    u8 *dest, *dest0, *cdat;
     u_int rows, bold, revs, underl;
-    u_char c, d;
+    u8 c, d;
 
     dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
     bold = attr_bold(p,conp);
@@ -141,7 +141,7 @@
 
 void fbcon_mfb_revc(struct display *p, int xx, int yy)
 {
-    u_char *dest;
+    u8 *dest;
     u_int rows;
 
     dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
--- m68k-2.1.85/drivers/video/fbcon-mfb.h.orig	Sun Feb  8 22:35:58 1998
+++ m68k-2.1.85/drivers/video/fbcon-mfb.h	Tue Feb 17 23:24:21 1998
@@ -2,8 +2,6 @@
      *  Monochrome (mfb)
      */
 
-
-
 extern struct display_switch fbcon_mfb;
 extern void fbcon_mfb_setup(struct display *p);
 extern void fbcon_mfb_bmove(struct display *p, int sy, int sx, int dy, int dx,
--- m68k-2.1.85/drivers/video/fbcon.c.orig	Sun Feb  8 23:13:08 1998
+++ m68k-2.1.85/drivers/video/fbcon.c	Tue Feb 17 23:27:30 1998
@@ -880,6 +880,13 @@
 
     if (!p->can_soft_blank) {
 	if (blank) {
+#ifdef CONFIG_MAC
+	    if (MACH_IS_MAC)
+		mymemset(p->screen_base,
+			 p->var.xres_virtual*p->var.yres_virtual*
+			 p->var.bits_per_pixel>>3);
+	    else
+#endif
 	    if (p->visual == FB_VISUAL_MONO01)
 		mymemset(p->screen_base,
 			 p->var.xres_virtual*p->var.yres_virtual*
@@ -944,7 +951,7 @@
 	copy_from_user( name, data, MAX_FONT_NAME );
 	name[sizeof(name)-1] = 0;
 
-	if (!findsoftfont( name, &w, &h, (u_char **)&data ))
+	if (!findsoftfont( name, &w, &h, (u8 **)&data ))
 	    return( -ENOENT );
 	userspace = 0;
     } else if (w == 1) {
@@ -1031,7 +1038,7 @@
     int unit = conp->vc_num;
     struct display *p = &fb_display[unit];
     int i, j, k;
-    u_char val;
+    u8 val;
 
     if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked))
 	return(-EINVAL);
--- m68k-2.1.85/drivers/video/fonts.c.orig	Sun Feb  8 22:35:53 1998
+++ m68k-2.1.85/drivers/video/fonts.c	Tue Feb 17 23:24:21 1998
@@ -25,22 +25,22 @@
 /* VGA8x8 */
 extern char fontname_8x8[];
 extern int fontwidth_8x8, fontheight_8x8;
-extern u_char fontdata_8x8[];
+extern u8 fontdata_8x8[];
 
 /* VGA8x16 */
 extern char fontname_8x16[];
 extern int fontwidth_8x16, fontheight_8x16;
-extern u_char fontdata_8x16[];
+extern u8 fontdata_8x16[];
 
 /* PEARL8x8 */
 extern char fontname_pearl8x8[];
 extern int fontwidth_pearl8x8, fontheight_pearl8x8;
-extern u_char fontdata_pearl8x8[];
+extern u8 fontdata_pearl8x8[];
 
 /* VGA6x11 */
 extern char fontname_6x11[];
 extern int fontwidth_6x11, fontheight_6x11;
-extern u_char fontdata_6x11[];
+extern u8 fontdata_6x11[];
 
 
    /*
@@ -51,7 +51,7 @@
    char *name;
    int *width;
    int *height;
-   u_char *data;
+   u8 *data;
 };
 
 #define VGA8x8_IDX	0
@@ -74,7 +74,7 @@
     *    Find a font with a specific name
     */
 
-int findsoftfont(char *name, int *width, int *height, u_char *data[])
+int findsoftfont(char *name, int *width, int *height, u8 *data[])
 {
    unsigned int i;
 
@@ -97,7 +97,7 @@
     */
 
 void getdefaultfont(int xres, int yres, char *name[], int *width, int *height,
-                    u_char *data[])
+                    u8 *data[])
 {
     int i;
     
--- m68k-2.1.85/drivers/video/vgacon.c.orig	Sun Feb  8 22:35:55 1998
+++ m68k-2.1.85/drivers/video/vgacon.c	Tue Feb 17 23:24:21 1998
@@ -384,12 +384,12 @@
 
 static void vgacon_putc(struct vc_data *conp, int c, int ypos, int xpos)
 {
-    u_short *p;
+    u16 *p;
 
     if (console_blanked)
 	return;
 
-    p = (u_short *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
+    p = (u16 *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
     vga_writew(conp->vc_attr << 8 | c, p);
 }
 
@@ -397,13 +397,13 @@
 static void vgacon_putcs(struct vc_data *conp, const char *s, int count,
 			 int ypos, int xpos)
 {
-    u_short *p;
-    u_short sattr;
+    u16 *p;
+    u16 sattr;
 
     if (console_blanked)
 	return;
 
-    p = (u_short *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
+    p = (u16 *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
     sattr = conp->vc_attr << 8;
     while (count--)
 	vga_writew(sattr | *s++, p++);
--- m68k-2.1.85/drivers/video/virgefb.c.orig	Sun Feb  8 22:35:59 1998
+++ m68k-2.1.85/drivers/video/virgefb.c	Tue Feb 17 23:33:45 1998
@@ -35,6 +35,7 @@
 #include <asm/amigahw.h>
 
 #include "s3blit.h"
+#include "fbcon.h"
 #include "fbcon-cfb8.h"
 #include "fbcon-cfb16.h"
 
@@ -467,7 +468,7 @@
 	var->height = -1;
 	var->width = -1;
 
-	var->accel = FB_ACCEL_CYBERVISION3D;
+	var->accel = FB_ACCEL_S3VIRGE;
 	DPRINTK("accel CV64/3D\n");
 
 	var->vmode = FB_VMODE_NONINTERLACED;
--- m68k-2.1.85/drivers/video/atyfb.c.orig	Sun Feb  8 23:13:12 1998
+++ m68k-2.1.85/drivers/video/atyfb.c	Tue Feb 17 22:07:27 1998
@@ -35,7 +35,6 @@
 #include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/bios32.h>
 #include <linux/nvram.h>
 #include <linux/vc_ioctl.h>
 #include <asm/io.h>
@@ -57,8 +56,12 @@
 static char atyfb_name[16] = "ATY Mach64";
 
 struct atyfb_par {
-    int video_mode;
-    int color_mode;
+    int vmode;
+    int cmode;
+    u_int vxres;	/* virtual screen size */
+    u_int vyres;
+    int xoffset;	/* virtual screen position */
+    int yoffset;
 };
 
 
@@ -100,7 +103,10 @@
 #define CMODE_32		2	/* 32 (actually 24) bits/pixel */
 
 
-static struct atyfb_par default_par = { VMODE_NVRAM, CMODE_NVRAM };
+static int default_video_mode = VMODE_NVRAM;
+static int default_color_mode = CMODE_NVRAM;
+
+static struct atyfb_par default_par;
 static struct atyfb_par current_par;
 
 
@@ -219,9 +225,9 @@
 };
 
 static int aty_vram_reqd(const struct atyfb_par *par);
-static struct aty_regvals *get_aty_struct(const struct atyfb_par *par);
+static struct aty_regvals *get_aty_struct(int vmode);
 
-static unsigned char *frame_buffer;
+static unsigned long frame_buffer;
 
 static int total_vram;		/* total amount of video memory, bytes */
 static int chip_type;		/* what chip type was detected */
@@ -262,7 +268,8 @@
 	&aty_gx_reg_init_15,
 	NULL,
 	&aty_gx_reg_init_17,
-	NULL, NULL,
+	&aty_gx_reg_init_18,
+	NULL,
 	&aty_gx_reg_init_20
 };
 
@@ -351,8 +358,7 @@
 
 static inline int aty_vram_reqd(const struct atyfb_par *par)
 {
-    return vmode_attrs[par->video_mode-1].vres *
-	(vmode_attrs[par->video_mode-1].hres << par->color_mode);
+    return (par->vxres*par->vyres) << par->cmode;
 }
 
 extern inline unsigned aty_ld_le32(volatile unsigned long addr)
@@ -366,6 +372,7 @@
 extern inline void aty_st_le32(volatile unsigned long addr, unsigned val)
 {
     register unsigned long temp = ati_regbase;
+
     asm("stwbrx %0,%1,%2": : "r"(val), "r"(addr), "r"(temp):"memory");
 }
 
@@ -401,9 +408,9 @@
     aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN);
 }
 
-static struct aty_regvals *get_aty_struct(const struct atyfb_par *par)
+static struct aty_regvals *get_aty_struct(int vmode)
 {
-    int v = par->video_mode - 1;
+    int v = vmode - 1;
 
     switch (chip_type) {
 	case MACH64_GT_ID:
@@ -482,31 +489,31 @@
     aty_st_514(pDacProgTab->pixel_cntl_index, pDacProgTab->pixel_cntl_v1);
 }
 
-/* handle video scrollback; offset is in # of scanlines */
-static void ati_set_origin(const struct atyfb_par *par, unsigned short lines)
+static void set_off_pitch(const struct atyfb_par *par)
 {
-	int x = (vmode_attrs[par->video_mode-1].hres + 7) & 0xfff8;
-	int reg;
+    u32 pitch, offset;
 
-	reg = ((x >> 3) << 22) |	/* calculate pitch */
-	  ((lines * x * (1<<par->color_mode)) >> 3);
-
-	aty_st_le32(CRTC_OFF_PITCH, reg);
-	aty_st_le32(DST_OFF_PITCH, reg);
-	aty_st_le32(SRC_OFF_PITCH, reg);
+    pitch = par->vxres>>3;
+    offset = ((par->yoffset*par->vxres+par->xoffset)>>3)<<par->cmode;
+    aty_st_le32(CRTC_OFF_PITCH, pitch<<22 | offset);
+    if (chip_type == MACH64_GT_ID) {
+	/* Is this OK for other chips? */
+	aty_st_le32(DST_OFF_PITCH, pitch<<22 | offset);
+	aty_st_le32(SRC_OFF_PITCH, pitch<<22 | offset);
+    }
 }
 
 static void atyfb_set_par(struct atyfb_par *par)
 {
     int i, hres;
-    struct aty_regvals *init = get_aty_struct(par);
+    struct aty_regvals *init = get_aty_struct(par->vmode);
     int vram_type = aty_ld_le32(CONFIG_STAT0) & 7;
 
     if (init == 0)	/* paranoia, shouldn't get here */
-	panic("aty: display mode %d not supported", par->video_mode);
+	panic("aty: display mode %d not supported", par->vmode);
 
     current_par = *par;
-    hres = vmode_attrs[par->video_mode-1].hres;
+    hres = vmode_attrs[par->vmode-1].hres;
 
     /* clear FIFO errors */
     aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_HOST_ERR_ACK
@@ -550,7 +557,7 @@
 	    if (vram_type == 5) {
 		aty_st_pll(0, 0xcd);
 		aty_st_pll(PLL_MACRO_CNTL,
-			   par->video_mode >= VMODE_1024_768_60 ? 0xd3: 0xd5);
+			   par->vmode >= VMODE_1024_768_60 ? 0xd3: 0xd5);
 		aty_st_pll(PLL_REF_DIV, 0x21);
 		aty_st_pll(PLL_GEN_CNTL, 0x44);
 		aty_st_pll(MCLK_FB_DIV, 0xe8);
@@ -582,7 +589,7 @@
 	    }
 	    break;
 	default:
-	    RGB514_Program(par->color_mode);
+	    RGB514_Program(par->cmode);
 	    aty_WaitIdleEmpty();
 	    aty_st_514(0x06, 0x02);
 	    aty_st_514(0x10, 0x01);
@@ -599,7 +606,7 @@
     aty_WaitIdleEmpty();
 
     aty_st_le32(CRTC_H_TOTAL_DISP, init->crtc_h_tot_disp);
-    aty_st_le32(CRTC_H_SYNC_STRT_WID, init->crtc_h_sync_strt_wid[par->color_mode]);
+    aty_st_le32(CRTC_H_SYNC_STRT_WID, init->crtc_h_sync_strt_wid[par->cmode]);
     aty_st_le32(CRTC_V_TOTAL_DISP, init->crtc_v_tot_disp);
     aty_st_le32(CRTC_V_SYNC_STRT_WID, init->crtc_v_sync_strt_wid);
 
@@ -608,30 +615,26 @@
 
     aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0);
 
+    set_off_pitch(par);
+
     if (chip_type == MACH64_GT_ID) {
 	aty_st_le32(BUS_CNTL, 0x7b23a040);
 
-	/* we calculate this so we can use a scrollback buffer.
-	 * this should theoretically work with other ati's
-	 * OFF_PITCH == (((hres + 7) & 0xfff8) >> 3) << 22
-	 */
-	ati_set_origin(par, 0);
-
 	/* need to set DSP values !! assume sdram */
-	i = init->crtc_gen_cntl[0] - (0x100000 * par->color_mode);
+	i = init->crtc_gen_cntl[0] - (0x100000 * par->cmode);
 	if ( vram_type == 5 )
-	    i = init->crtc_gen_cntl[1] - (0x100000 * par->color_mode);
+	    i = init->crtc_gen_cntl[1] - (0x100000 * par->cmode);
 	aty_st_le32(DSP_CONFIG, i);
 
 	i = aty_ld_le32(MEM_CNTL) & MEM_SIZE_ALIAS;
 	if ( vram_type == 5 ) {
-	    i |= ((1 * par->color_mode) << 26) | 0x4215b0;
-	    aty_st_le32(DSP_ON_OFF,sgram_dsp[par->video_mode-1][par->color_mode]);
+	    i |= ((1 * par->cmode) << 26) | 0x4215b0;
+	    aty_st_le32(DSP_ON_OFF,sgram_dsp[par->vmode-1][par->cmode]);
 
 	//aty_st_le32(CLOCK_CNTL,8192);
 	} else {
-	    i |= ((1 * par->color_mode) << 26) | 0x300090;
-	    aty_st_le32(DSP_ON_OFF, init->mem_cntl[par->color_mode]);
+	    i |= ((1 * par->cmode) << 26) | 0x300090;
+	    aty_st_le32(DSP_ON_OFF, init->mem_cntl[par->cmode]);
 	}
 
 	aty_st_le32(MEM_CNTL, i);
@@ -640,7 +643,6 @@
 	/* if (total_vram > 0x400000)	
 	    i |= 0x538; this not been verified on > 4Megs!! */
     } else {
-	aty_st_le32(CRTC_OFF_PITCH, init->crtc_off_pitch);
 
 /* The magic constant below translates into:
 * 5   = No RDY delay, 1 wait st for mem write, increment during burst transfer
@@ -661,18 +663,18 @@
 
 	switch (total_vram) {
 	    case 0x00100000:
-		aty_st_le32(MEM_CNTL, vt_mem_cntl[0][par->color_mode]);
+		aty_st_le32(MEM_CNTL, vt_mem_cntl[0][par->cmode]);
 		break;
 	    case 0x00200000:
-		aty_st_le32(MEM_CNTL, vt_mem_cntl[1][par->color_mode]);
+		aty_st_le32(MEM_CNTL, vt_mem_cntl[1][par->cmode]);
 		break;
 	    case 0x00400000:
-		aty_st_le32(MEM_CNTL, vt_mem_cntl[2][par->color_mode]);
+		aty_st_le32(MEM_CNTL, vt_mem_cntl[2][par->cmode]);
 		break;
 	    default:
 		i = aty_ld_le32(MEM_CNTL) & 0x000F;
 		aty_st_le32(MEM_CNTL,
-			    (init->mem_cntl[par->color_mode] & 0xFFFFFFF0) | i);
+			    (init->mem_cntl[par->cmode] & 0xFFFFFFF0) | i);
 	}
     }
 /* These magic constants are harder to figure out
@@ -695,7 +697,7 @@
     aty_st_le32(DAC_CNTL, i);
     aty_st_8(DAC_MASK, 0xff);
 
-    switch (par->color_mode) {
+    switch (par->cmode) {
 	case CMODE_16:
 	    i = CRTC_PIX_WIDTH_15BPP; break;
 	/*case CMODE_24: */
@@ -709,24 +711,24 @@
     if (chip_type != MACH64_GT_ID) {
 	aty_st_le32(CRTC_INT_CNTL, 0x00000002);
 	aty_st_le32(GEN_TEST_CNTL, GUI_ENGINE_ENABLE | BLOCK_WRITE_ENABLE);	/* gui_en block_en */
-	i |= init->crtc_gen_cntl[par->color_mode];
+	i |= init->crtc_gen_cntl[par->cmode];
     }
     /* Gentlemen, start your crtc engine */
-    aty_st_le32(CRTC_GEN_CNTL, CRTC_EXT_DISP_EN | CRTC_EXT_EN | i);
+    aty_st_le32(CRTC_GEN_CNTL, CRTC_EXT_DISP_EN | CRTC_ENABLE | i);
 
 #ifdef CONFIG_FB_COMPAT_XPMAC
-    display_info.height = vmode_attrs[par->video_mode-1].vres;
-    display_info.width = vmode_attrs[par->video_mode-1].hres;
-    display_info.depth = 8<<par->color_mode;
-    display_info.pitch = vmode_attrs[par->video_mode-1].hres<<par->color_mode;
-    display_info.mode = par->video_mode;
+    display_info.height = vmode_attrs[par->vmode-1].vres;
+    display_info.width = vmode_attrs[par->vmode-1].hres;
+    display_info.depth = 8<<par->cmode;
+    display_info.pitch = par->vxres<<par->cmode;
+    display_info.mode = par->vmode;
     strcpy(display_info.name, atyfb_name);
-    display_info.fb_address = ((chip_type != MACH64_GT_ID) ?
-	(unsigned long) frame_buffer + init->offset[par->color_mode] :
-	(unsigned long) frame_buffer);
-    display_info.cmap_adr_address = (unsigned long) &aty_cmap_regs->windex;
-    display_info.cmap_data_address = (unsigned long) &aty_cmap_regs->lut;
-    display_info.disp_reg_address = ati_regbase;
+    display_info.fb_address =
+	iopa(((chip_type != MACH64_GT_ID) ?
+	     frame_buffer + init->offset[par->cmode] : frame_buffer));
+    display_info.cmap_adr_address = iopa((unsigned long)&aty_cmap_regs->windex);
+    display_info.cmap_data_address = iopa((unsigned long)&aty_cmap_regs->lut);
+    display_info.disp_reg_address = iopa(ati_regbase);
 #endif /* CONFIG_FB_COMPAT_XPMAC) */
 }
 
@@ -754,29 +756,33 @@
 
 
 static int encode_fix(struct fb_fix_screeninfo *fix,
-		       const struct atyfb_par *par)
+		      const struct atyfb_par *par)
 {
     struct aty_regvals *init;
 
     memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 
     strcpy(fix->id, atyfb_name);
-    init = get_aty_struct(par);
-    fix->smem_start = (char *)
-	((chip_type != MACH64_GT_ID) ?
-	    (unsigned long) frame_buffer + init->offset[par->color_mode] :
-	    (unsigned long) frame_buffer);
-    fix->smem_len = (unsigned long)total_vram-4096;	/* last page is MMIO */
-    fix->mmio_start = (char *)((unsigned long)ati_regbase & ~0xfff);
+    init = get_aty_struct(par->vmode);
+    /*
+     *  FIXME: This will cause problems on non-GT chips, because the frame
+     *  buffer must be aligned to a page
+     */
+    fix->smem_start = (char *)((chip_type != MACH64_GT_ID)
+	    ? frame_buffer + init->offset[par->cmode] : frame_buffer);
+    fix->smem_len = (u32)total_vram;
+    if (fix->smem_len > 0x7ff000)
+	fix->smem_len = 0x7ff000;	/* last page is MMIO */
+    fix->mmio_start = (char *)(ati_regbase & ~0xfff);
     fix->mmio_len = 4096;
     fix->type = FB_TYPE_PACKED_PIXELS;
     fix->type_aux = 0;
-    fix->line_length = vmode_attrs[par->video_mode-1].hres<<par->color_mode;
-    fix->visual = par->color_mode == CMODE_8 ? FB_VISUAL_PSEUDOCOLOR
-					     : FB_VISUAL_TRUECOLOR;
+    fix->line_length = par->vxres<<par->cmode;
+    fix->visual = par->cmode == CMODE_8 ? FB_VISUAL_PSEUDOCOLOR
+					: FB_VISUAL_TRUECOLOR;
     fix->ywrapstep = 0;
-    fix->xpanstep = 0;
-    fix->ypanstep = 0;
+    fix->xpanstep = 8;
+    fix->ypanstep = 1;
 
     return 0;
 }
@@ -792,39 +798,52 @@
 
     /* This should support more video modes */
 
-    /* No virtual screen yet */
-    if (var->xres_virtual > xres || var->yres_virtual > yres)
-	return -EINVAL;
-
     if (xres <= 512 && yres <= 384)
-	par->video_mode = VMODE_512_384_60;	/* 512x384, 60Hz */
+	par->vmode = VMODE_512_384_60;		/* 512x384, 60Hz */
     else if (xres <= 640 && yres <= 480)
-	par->video_mode = VMODE_640_480_67;	/* 640x480, 67Hz */
+	par->vmode = VMODE_640_480_67;		/* 640x480, 67Hz */
     else if (xres <= 640 && yres <= 870)
-	par->video_mode = VMODE_640_870_75P;	/* 640x870, 75Hz (portrait) */
+	par->vmode = VMODE_640_870_75P;		/* 640x870, 75Hz (portrait) */
     else if (xres <= 768 && yres <= 576)
-	par->video_mode = VMODE_768_576_50I;	/* 768x576, 50Hz (PAL full frame) */
+	par->vmode = VMODE_768_576_50I;		/* 768x576, 50Hz (PAL full frame) */
     else if (xres <= 800 && yres <= 600)
-	par->video_mode = VMODE_800_600_75;	/* 800x600, 75Hz */
+	par->vmode = VMODE_800_600_75;		/* 800x600, 75Hz */
     else if (xres <= 832 && yres <= 624)
-	par->video_mode = VMODE_832_624_75;	/* 832x624, 75Hz */
+	par->vmode = VMODE_832_624_75;		/* 832x624, 75Hz */
     else if (xres <= 1024 && yres <= 768)
-	par->video_mode = VMODE_1024_768_75;	/* 1024x768, 75Hz */
+	par->vmode = VMODE_1024_768_75;		/* 1024x768, 75Hz */
     else if (xres <= 1152 && yres <= 870)
-	par->video_mode = VMODE_1152_870_75;	/* 1152x870, 75Hz */
+	par->vmode = VMODE_1152_870_75;		/* 1152x870, 75Hz */
     else if (xres <= 1280 && yres <= 960)
-	par->video_mode = VMODE_1280_960_75;	/* 1280x960, 75Hz */
+	par->vmode = VMODE_1280_960_75;		/* 1280x960, 75Hz */
     else if (xres <= 1280 && yres <= 1024)
-	par->video_mode = VMODE_1280_1024_75;	/* 1280x1024, 75Hz */
+	par->vmode = VMODE_1280_1024_75;	/* 1280x1024, 75Hz */
+    else
+	return -EINVAL;
+
+    xres = vmode_attrs[par->vmode-1].hres;
+    yres = vmode_attrs[par->vmode-1].vres;
+
+    if (var->xres_virtual <= xres)
+	par->vxres = xres;
     else
+	par->vxres = (var->xres_virtual+7) & ~7;
+    if (var->yres_virtual <= yres)
+	par->vyres = yres;
+    else
+	par->vyres = var->yres_virtual;
+
+    par->xoffset = (var->xoffset+7) & ~7;
+    par->yoffset = var->yoffset;
+    if (par->xoffset+xres > par->vxres || par->yoffset+yres > par->vyres)
 	return -EINVAL;
 
     if (bpp <= 8)
-	par->color_mode = CMODE_8;
+	par->cmode = CMODE_8;
     else if (bpp <= 16)
-	par->color_mode = CMODE_16;
+	par->cmode = CMODE_16;
     else if (bpp <= 32)
-	par->color_mode = CMODE_32;
+	par->cmode = CMODE_32;
     else
 	return -EINVAL;
 
@@ -832,10 +851,10 @@
 	return -EINVAL;
 
     /* Check if we know about the wanted video mode */
-    init = get_aty_struct(par);
-    if (init == NULL || init->crtc_h_sync_strt_wid[par->color_mode] == 0 ||
+    init = get_aty_struct(par->vmode);
+    if (init == NULL || init->crtc_h_sync_strt_wid[par->cmode] == 0 ||
 	(chip_type != MACH64_GT_ID &&
-	 init->crtc_gen_cntl[par->color_mode] == 0) ||
+	 init->crtc_gen_cntl[par->cmode] == 0) ||
 	(chip_type == MACH64_GT_ID && (aty_ld_le32(CONFIG_STAT0) & 7) == 5 &&
 	 init->crtc_gen_cntl[1] == 0))
 	return -EINVAL;
@@ -848,12 +867,14 @@
 {
     memset(var, 0, sizeof(struct fb_var_screeninfo));
 
-    var->xres = var->xres_virtual = vmode_attrs[par->video_mode-1].hres;
-    var->yres = var->yres_virtual = vmode_attrs[par->video_mode-1].vres;
-    var->xoffset = 0;
-    var->yoffset = 0;
+    var->xres = vmode_attrs[par->vmode-1].hres;
+    var->yres = vmode_attrs[par->vmode-1].vres;
+    var->xres_virtual = par->vxres;
+    var->yres_virtual = par->vyres;
+    var->xoffset = par->xoffset;
+    var->yoffset = par->yoffset;
     var->grayscale = 0;
-    switch (par->color_mode) {
+    switch (par->cmode) {
 	case CMODE_8:
 	    var->bits_per_pixel = 8;
 	    var->red.offset = 0;
@@ -878,14 +899,14 @@
 	    break;
 	case CMODE_32:	/* RGB 888 */
 	    var->bits_per_pixel = 32;
-	    var->red.offset = 0;
+	    var->red.offset = 16;
 	    var->red.length = 8;
 	    var->green.offset = 8;
 	    var->green.length = 8;
-	    var->blue.offset = 16;
+	    var->blue.offset = 0;
 	    var->blue.length = 8;
-	    var->transp.offset = 0;
-	    var->transp.length = 0;
+	    var->transp.offset = 24;
+	    var->transp.length = 8;
 	    break;
     }
     var->red.msb_right = 0;
@@ -908,7 +929,7 @@
     var->pixclock = 1000000000/
 	(var->left_margin+var->xres+var->right_margin+var->hsync_len);
     var->pixclock *= 1000;
-    var->pixclock /= vmode_attrs[par->video_mode-1].vfreq*
+    var->pixclock /= vmode_attrs[par->vmode-1].vfreq*
 	 (var->upper_margin+var->yres+var->lower_margin+var->vsync_len);
     var->sync = 0;
 
@@ -916,6 +937,17 @@
 }
 
 
+static void init_par(struct atyfb_par *par, int vmode, int cmode)
+{
+    par->vmode = vmode;
+    par->cmode = cmode;
+    par->vxres = vmode_attrs[vmode-1].hres;
+    par->vyres = vmode_attrs[vmode-1].vres;
+    par->xoffset = 0;
+    par->yoffset = 0;
+}
+
+
     /*
      *  Get the Fixed Part of the Display
      */
@@ -994,7 +1026,7 @@
 	    display->line_length = fix.line_length;
 	    display->can_soft_blank = 1;
 	    display->inverse = 0;
-	    switch (par.color_mode) {
+	    switch (par.cmode) {
 		case CMODE_8:
 #if 1
 		    display->dispsw = &fbcon_cfb8;
@@ -1037,10 +1069,19 @@
 static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
 			     struct fb_info *info)
 {
-    if (var->xoffset || var->yoffset)
+    u32 xres, yres, xoffset, yoffset;
+    struct atyfb_par *par = &current_par;
+
+    xres = vmode_attrs[par->vmode-1].hres;
+    yres = vmode_attrs[par->vmode-1].vres;
+    xoffset = (var->xoffset+7) & ~7;
+    yoffset = var->yoffset;
+    if (xoffset+xres > par->vxres || yoffset+yres > par->vyres)
 	return -EINVAL;
-    else
-	return 0;
+    par->xoffset = xoffset;
+    par->yoffset = yoffset;
+    set_off_pitch(par);
+    return 0;
 }
 
     /*
@@ -1189,7 +1230,7 @@
     printk(" %x(%x)", dp->addrs[0].address, dp->addrs[0].size);
     printk(", intrs =");
     for (i = 0; i < dp->n_intrs; ++i)
-    printk(" %x", dp->intrs[i]);
+    printk(" %x", dp->intrs[i].line);
     printk("\nregbase: %x pci loc: %x:%x total_vram: %x cregs: %p\n",
 	   (int)ati_regbase, bus, devfn, total_vram, aty_cmap_regs);
 #endif
@@ -1199,55 +1240,60 @@
 
     /* use the big-endian aperture (??) */
     addr += 0x800000;
-    frame_buffer = ioremap(addr, 0x800000);
+    frame_buffer = (unsigned long)__ioremap(addr, 0x800000, _PAGE_WRITETHRU);
 
-    if (default_par.video_mode != -1) {
+    if (default_video_mode != -1) {
 	sense = read_aty_sense();
 	printk("monitor sense = %x\n", sense);
-	if (default_par.video_mode == VMODE_NVRAM) {
-	    default_par.video_mode = nvram_read_byte(NV_VMODE);
-	    init = get_aty_struct(&default_par);
-	    if (default_par.video_mode <= 0 ||
-		default_par.video_mode > VMODE_MAX || init == 0)
-		default_par.video_mode = VMODE_CHOOSE;
+	if (default_video_mode == VMODE_NVRAM) {
+	    default_video_mode = nvram_read_byte(NV_VMODE);
+	    init = get_aty_struct(default_video_mode);
+	    if (default_video_mode <= 0 ||
+		default_video_mode > VMODE_MAX || init == 0)
+		default_video_mode = VMODE_CHOOSE;
 	}
-	if (default_par.video_mode == VMODE_CHOOSE)
-	    default_par.video_mode = map_monitor_sense(sense);
+	if (default_video_mode == VMODE_CHOOSE)
+	    default_video_mode = map_monitor_sense(sense);
 
-	init = get_aty_struct(&default_par);
+	init = get_aty_struct(default_video_mode);
 	if (!init)
-	    default_par.video_mode = VMODE_640_480_60;
+	    default_video_mode = VMODE_640_480_60;
     }
 
     /*
      * Reduce the pixel size if we don't have enough VRAM.
      */
 
-    if (default_par.color_mode == CMODE_NVRAM)
-	default_par.color_mode = nvram_read_byte(NV_CMODE);
-    if (default_par.color_mode < CMODE_8 ||
-	default_par.color_mode > CMODE_32)
-	default_par.color_mode = CMODE_8;
+    if (default_color_mode == CMODE_NVRAM)
+	default_color_mode = nvram_read_byte(NV_CMODE);
+    if (default_color_mode < CMODE_8 ||
+	default_color_mode > CMODE_32)
+	default_color_mode = CMODE_8;
 
+    init_par(&default_par, default_video_mode, default_color_mode);
     while (aty_vram_reqd(&default_par) > total_vram) {
-	while (default_par.color_mode > CMODE_8 &&
-	       aty_vram_reqd(&default_par) > total_vram)
-	    --default_par.color_mode;
+	while (default_color_mode > CMODE_8 &&
+	       aty_vram_reqd(&default_par) > total_vram) {
+	    --default_color_mode;
+	    init_par(&default_par, default_video_mode, default_color_mode);
+	}
 	/*
 	 * adjust the video mode smaller if there still is not enough VRAM
 	 */
 	if (aty_vram_reqd(&default_par) > total_vram)
 	    do {
-		default_par.video_mode--;
-		init = get_aty_struct(&default_par);
+		default_video_mode--;
+		init_par(&default_par, default_video_mode, default_color_mode);
+		init = get_aty_struct(default_video_mode);
 	    } while ((init == 0) &&
-		     (default_par.video_mode > VMODE_640_480_60));
+		     (default_video_mode > VMODE_640_480_60));
     }
 
     if (chip_type == MACH64_GT_ID && (aty_ld_le32(CONFIG_STAT0) & 7) == 5
 	&& init->crtc_gen_cntl[1] == 0) {
-	    default_par.video_mode = VMODE_640_480_67;
-	    default_par.color_mode = CMODE_8;
+	    default_video_mode = VMODE_640_480_67;
+	    default_color_mode = CMODE_8;
+	    init_par(&default_par, default_video_mode, default_color_mode);
     }
 
     switch (chip_type) {
@@ -1312,20 +1358,20 @@
 	if (!strncmp(this_opt, "vmode:", 6)) {
 	    vmode = simple_strtoul(this_opt+6, NULL, 0);
 	    if (vmode > 0 && vmode <= VMODE_MAX)
-		default_par.video_mode = vmode;
+		default_video_mode = vmode;
 	} else if (!strncmp(this_opt, "cmode:", 6)) {
 	    depth = simple_strtoul(this_opt+6, NULL, 0);
 	    switch (depth) {
 		case 8:
-		    default_par.color_mode = CMODE_8;
+		    default_color_mode = CMODE_8;
 		    break;
 		case 15:
 		case 16:
-		    default_par.color_mode = CMODE_16;
+		    default_color_mode = CMODE_16;
 		    break;
 		case 24:
 		case 32:
-		    default_par.color_mode = CMODE_32;
+		    default_color_mode = CMODE_32;
 		    break;
 	    };
 	}
@@ -1355,7 +1401,8 @@
 
 static int atyfbcon_updatevar(int con, struct fb_info *info)
 {
-    /* Nothing */
+    current_par.yoffset = fb_display[con].var.yoffset;
+    set_off_pitch(&current_par);
     return 0;
 }
 
@@ -1421,7 +1468,7 @@
     aty_st_8(DAC_REGS + DAC_MASK, 0xff);
     eieio();
     scale = ((chip_type != MACH64_GX_ID) &&
-	     (current_par.color_mode == CMODE_16)) ? 3 : 0;
+	     (current_par.cmode == CMODE_16)) ? 3 : 0;
     aty_WaitQueue(4);
     aty_cmap_regs->windex = regno << scale;
     eieio();
@@ -1590,26 +1637,28 @@
     int err;
     struct fb_var_screeninfo var;
     struct atyfb_par par;
+    int vmode, cmode;
 
     if (mode->mode <= 0 || mode->mode > VMODE_MAX )
 	return -EINVAL;
-    par.video_mode = mode->mode;
+    vmode = mode->mode;
 
     switch (mode->depth) {
 	case 24:
 	case 32:
-	    par.color_mode = CMODE_32;
+	    cmode = CMODE_32;
 	    break;
 	case 16:
-	    par.color_mode = CMODE_16;
+	    cmode = CMODE_16;
 	    break;
 	case 8:
 	case 0:			/* (default) */
-	    par.color_mode = CMODE_8;
+	    cmode = CMODE_8;
 	    break;
 	default:
 	    return -EINVAL;
     }
+    init_par(&par, vmode, cmode);
     encode_var(&var, &par);
     if ((err = decode_var(&var, &par)))
 	return err;
--- m68k-2.1.85/drivers/video/offb.c.orig	Sun Feb  8 22:35:53 1998
+++ m68k-2.1.85/drivers/video/offb.c	Tue Feb 17 22:07:27 1998
@@ -278,7 +278,8 @@
 
 static const char *aty_names[] = {
     "ATY,mach64", "ATY,XCLAIM", "ATY,264VT", "ATY,mach64ii", "ATY,264GT-B", 
-    "ATY,mach64_3D_pcc", "ATY,XCLAIM3D", "ATY,XCLAIMVR", "ATY,RAGEII_M"
+    "ATY,mach64_3D_pcc", "ATY,XCLAIM3D", "ATY,XCLAIMVR", "ATY,RAGEII_M",
+    "ATY,mach64_3DU"
 };
 #endif /* CONFIG_FB_ATY */
 
@@ -370,15 +371,15 @@
 	    display_info.pitch = fix->line_length;
 	    display_info.mode = 0;
 	    strncpy(display_info.name, dp->name, sizeof(display_info.name));
-	    display_info.fb_address = (unsigned long)fix->smem_start;
+	    display_info.fb_address = iopa((unsigned long)fix->smem_start);
 	    display_info.cmap_adr_address = 0;
 	    display_info.cmap_data_address = 0;
 	    display_info.disp_reg_address = 0;
 	    /* XXX kludge for ati */
 	    if (strncmp(dp->name, "ATY,", 4) == 0) {
-		    display_info.disp_reg_address = address + 0x7ffc00;
-		    display_info.cmap_adr_address = address + 0x7ffcc0;
-		    display_info.cmap_data_address = address + 0x7ffcc1;
+		    display_info.disp_reg_address = iopa(address + 0x7ffc00);
+		    display_info.cmap_adr_address = iopa(address + 0x7ffcc0);
+		    display_info.cmap_data_address = iopa(address + 0x7ffcc1);
 	    }
 	}
 #endif /* CONFIG_FB_COMPAT_XPMAC) */
--- m68k-2.1.85/drivers/video/aty.h.orig	Sun Feb  8 22:35:55 1998
+++ m68k-2.1.85/drivers/video/aty.h	Mon Feb  2 17:36:31 1998
@@ -121,15 +121,15 @@
 #define DST_BRES_ERR		0x0124	/* Dword offset 0_49 */
 #define DST_BRES_INC		0x0128	/* Dword offset 0_4A */
 #define DST_BRES_DEC		0x012C	/* Dword offset 0_4B */
-#define DST_CNTL		0x0134	/* Dword offset 0_4C */
-#define DST_Y_X__ALIAS__	0x0138	/* Dword offset 0_4D */
-#define TRAIL_BRES_ERR		0x013C	/* Dword offset 0_4E */
-#define TRAIL_BRES_INC		0x0140	/* Dword offset 0_4F */
-#define TRAIL_BRES_DEC		0x0144	/* Dword offset 0_50 */
-#define LEAD_BRES_LNTH		0x0148	/* Dword offset 0_51 */
-#define Z_OFF_PITCH		0x014C	/* Dword offset 0_52 */
-#define Z_CNTL			0x0150	/* Dword offset 0_53 */
-#define ALPHA_TST_CNTL		0x0154	/* Dword offset 0_54 */
+#define DST_CNTL		0x0130	/* Dword offset 0_4C */
+#define DST_Y_X__ALIAS__	0x0134	/* Dword offset 0_4D */
+#define TRAIL_BRES_ERR		0x0138	/* Dword offset 0_4E */
+#define TRAIL_BRES_INC		0x013C	/* Dword offset 0_4F */
+#define TRAIL_BRES_DEC		0x0140	/* Dword offset 0_50 */
+#define LEAD_BRES_LNTH		0x0144	/* Dword offset 0_51 */
+#define Z_OFF_PITCH		0x0148	/* Dword offset 0_52 */
+#define Z_CNTL			0x014C	/* Dword offset 0_53 */
+#define ALPHA_TST_CNTL		0x0150	/* Dword offset 0_54 */
 #define SECONDARY_STW_EXP	0x0158	/* Dword offset 0_56 */
 #define SECONDARY_S_X_INC	0x015C	/* Dword offset 0_57 */
 #define SECONDARY_S_Y_INC	0x0160	/* Dword offset 0_58 */
@@ -462,8 +462,9 @@
 #define CRTC_HSYNC_DIS		0x00000004
 #define CRTC_VSYNC_DIS		0x00000008
 #define CRTC_CSYNC_EN		0x00000010
-#define CRTC_PIX_BY_2_EN	0x00000020
-#define CRTC_BLANK		0x00000040
+#define CRTC_PIX_BY_2_EN	0x00000020	/* unused on RAGE */
+#define CRTC_DISPLAY_DIS	0x00000040
+#define CRTC_VGA_XOVERSCAN	0x00000040
 
 #define CRTC_PIX_WIDTH_MASK	0x00000700
 #define CRTC_PIX_WIDTH_4BPP	0x00000100
@@ -478,8 +479,20 @@
 #define CRTC_PIX_ORDER_LSN_MSN	0x00000800
 
 #define CRTC_FIFO_LWM		0x000f0000
+
+#define VGA_128KAP_PAGING	0x00100000
+#define VFC_SYNC_TRISTATE	0x00200000
+#define CRTC_LOCK_REGS		0x00400000
+#define CRTC_SYNC_TRISTATE	0x00800000
+
 #define CRTC_EXT_DISP_EN	0x01000000
-#define CRTC_EXT_EN		0x02000000
+#define CRTC_ENABLE		0x02000000
+#define CRTC_DISP_REQ_ENB	0x04000000
+#define VGA_ATI_LINEAR		0x08000000
+#define CRTC_VSYNC_FALL_EDGE	0x10000000
+#define VGA_TEXT_132		0x20000000
+#define VGA_XCRT_CNT_EN		0x40000000
+#define VGA_CUR_B_TEST		0x80000000
 
 #define CRTC_CRNT_VLINE		0x07f00000
 #define CRTC_VBLANK		0x00000001
@@ -616,10 +629,12 @@
 #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 DRAM			1
+#define EDO			2
+#define PSEUDO_EDO		3
+#define SDRAM			4
+#define SGRAM			5
+#define WRAM			6
 
 #define DAC_INTERNAL		0x00
 #define DAC_IBMRGB514		0x01
--- m68k-2.1.85/drivers/video/ati-gx.h.orig	Sun Feb  8 22:35:55 1998
+++ m68k-2.1.85/drivers/video/ati-gx.h	Wed Jan 28 10:54:58 1998
@@ -1,64 +1,37 @@
-#if 0		/* not filled inaty_gt_reg_init yet */
-/* Register values for 1280x1024, 75Hz mode (20) */
+/* Register values for 1280x1024, 75Hz (WAS 60) mode (20) */
 static struct aty_regvals aty_gx_reg_init_20 = {
-	{ 0x10, 0x28, 0x3c },
-	{ },
-	{ }	/* pixel clock = 134.61MHz for V=74.81Hz */
-};
+   { 0x200, 0x200, 0x200 },
 
-/* Register values for 1280x960, 75Hz mode (19) */
-static struct aty_regvals aty_gx_reg_init_19 = {
-	{ 0x10, 0x28, 0x3c },
-	{ },
-	{ }	/* pixel clock = 126.01MHz for V=75.01 Hz */
-};
+    { 0x1200a5, 0x1200a3, 0x1200a3 },
+    { 0x30c0200, 0x30e0300, 0x30e0300 },
+    { 0x2, 0x3, 0x3 },
+
+    0x9f00d2, 0x3ff0429, 0x30400, 0x28100040,
+    { 0xd4, 0x9 }
+};     
 
 /* Register values for 1152x870, 75Hz mode (18) */
 static struct aty_regvals aty_gx_reg_init_18 = {
-	{ 0x10, 0x28, 0x50 },
-	{ },
-	{ }	/* pixel clock = 100.33MHz for V=75.31Hz */
-};
+    { 0x200, 0x200, 0x200 },
 
-/* Register values for 1024x768, 75Hz mode (17) */
-static struct aty_regvals aty_gx_reg_init_17 = {
-	{ 0x10, 0x28, 0x50 },
-	{ },
-	{ }	/* pixel clock = 79.55MHz for V=74.50Hz */
-};
+    { 0x300097, 0x300095, 0x300094 },
+    { 0x3090200, 0x30e0300, 0x30e0600 },
+    { 0x2, 0x3, 0x6 },
 
-/* Register values for 1024x768, 72Hz mode (15) */
-static struct aty_regvals aty_gx_reg_init_15 = {
-	{ 0x10, 0x28, 0x50 },
-	{ },
-	{ }	/* pixel clock = 78.12MHz for V=72.12Hz */
+    0x8f00b5, 0x3650392, 0x230368, 0x24100040,
+    { 0x53, 0x3 }
 };
 
-#endif
-
-
-/* Register values for 1280x1024, 60Hz mode (20) */
-static struct aty_regvals aty_gx_reg_init_20 = {
-   { 0, 0, 0 },
-
-    { 0x310086, 0x310084, 0x310084 },
-    { 0x3070200, 0x30e0300, 0x30e0300 },
-    { 0x2002312, 0x3002312, 0x3002312 },
-
-    0x7f00a5, 0x2ff0325, 0x260302, 0x20100000,
-    { 0x88, 0x7 }
-};     
-
 /* Register values for 1024x768, 75Hz mode (17) */
 static struct aty_regvals aty_gx_reg_init_17 = {
-    { 0, 0, 0 },
+    { 0x200, 0x200, 0x200 },
 
-    { 0xc0085, 0xc0083, 0xc0083 },
-    { 0x3070200, 0x30e0300, 0x30e0300 },
-    { 0x2002312, 0x3002312, 0x3002312 },
+    { 0x2c0087, 0x2c0085, 0x2c0084 },
+    { 0x3070200, 0x30e0300, 0x30e0600 },
+    { 0x2, 0x3, 0x6 },
 
-    0x7f00a3, 0x2ff031f, 0x30300, 0x20100000,
-    { 0x41, 0x3 }
+    0x7f00a5, 0x2ff0323, 0x230302, 0x20100000,
+    { 0x42, 0x3 }
 };
 
 /* Register values for 1024x768, 72Hz mode (15) */
@@ -87,14 +60,14 @@
 
 /* Register values for 832x624, 75Hz mode (13) */
 static struct aty_regvals aty_gx_reg_init_13 = {
-	{ 0x200, 0x200, 0x200 },
+    { 0x200, 0x200, 0x200 },
 
-	{ 0x28006f, 0x28006d, 0x28006c },
-	{ 0x3050200, 0x30b0300, 0x30e0600 },
-	{ 0x2002312, 0x3002312, 0x6002312 },
+    { 0x28006f, 0x28006d, 0x28006c },
+    { 0x3050200, 0x30b0300, 0x30e0600 },
+    { 0x2, 0x3, 0x6 },
 
-	0x67008f, 0x26f029a, 0x230270, 0x1a100040,
-        { 0x4f, 0x05 }
+    0x67008f, 0x26f029a, 0x230270, 0x1a100040,
+    { 0x4f, 0x5 }
 };
 
 #if 0		/* not filled in yet */
--- m68k-2.1.85/drivers/video/tgafb.c.orig	Sun Feb  8 23:13:10 1998
+++ m68k-2.1.85/drivers/video/tgafb.c	Mon Feb 16 22:39:50 1998
@@ -36,7 +36,6 @@
 #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>
@@ -456,22 +455,14 @@
 
 __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;
+    struct pci_dev *pdev;
 
-    status = pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA,
-				  0, &pci_bus, &pci_devfn);
-    if (status == PCIBIOS_DEVICE_NOT_FOUND)
+    pdev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL);
+    if (!pdev)
 	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;
+    tga_mem_base = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
 #ifdef DEBUG
     printk("tgafb_init: mem_base 0x%x\n", tga_mem_base);
 #endif /* DEBUG */

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

