Date: Wed, 1 Oct 1997 10:47:19 +0200 (CEST)
From: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
To: Linux/m68k <linux-m68k@lists.linux-m68k.org>
Subject: L68K: Patches for 2.1.57
Sender: owner-linux-m68k@phil.uni-sb.de


Here's a bunch of patches for 2.1.57:

  - Fixed a nasty bug (this drove me crazy...) in fbmem.c that made
    FBIOGET_VSCREENINFO always return invalid data. As a consequence, X didn't
    work.

  - Serial console (Jes, pleazzz). A machine without a serial console is no
    real computer but a toybox. It should work at least on m68k (Amiga), PPC
    and ix86.

  - Addition of mach64fb (from Bernd). Untested, but it does compile.

  - Addition of drivers/block/README.buddha

  - Removal of debug flag in the IDE probe code

  - Roman H's Penguin code (+ iplan2p? fixes)

  - Roman Z's amifb code (with some enhancements for roundup-compliance)

  - Fixed a typo that caused all Amigas to have Zorro III, which of course
    isn't true

  - Zorro II memory is now automatically removed from the memory list on
    machines that are Zorro III capable (i.e. A3000[T]/4000[T]). Thus you no
    longer need to twiddle with memfiles. For this I had to move a part of the
    memory initialization code (arch/m68k/kernel/config.c) after the machine
    specific code. Can someone please test this and report to the list?? I
    don't have Zorro II memory.

  - Fixed some typos, removed some obsolete comments, added some clarifications
    to Configure.help

Jes, should I send the IDE patches to Mark Lord/Gadi Oxman or will you do that?

--- m68k-2.1.57/init/main.c.orig	Mon Sep 15 22:50:52 1997
+++ m68k-2.1.57/init/main.c	Tue Sep 30 20:23:27 1997
@@ -86,6 +86,7 @@
 extern void panic_setup(char *str, int *ints);
 extern void bmouse_setup(char *str, int *ints);
 extern void msmouse_setup(char *str, int *ints);
+extern void console_setup(char *str, int *ints);
 #ifdef CONFIG_PRINTER
 extern void lp_setup(char *str, int *ints);
 #endif
@@ -249,15 +250,6 @@
 extern void ipc_init(void);
 #endif
 
-#if defined(__sparc__) || defined(CONFIG_SERIAL_CONSOLE)
-extern int serial_console;
-#ifdef CONFIG_SERIAL_CONSOLE
-extern void console_setup(char *str, int *ints);
-static char console_env[] = "CONSOLE=/dev/ttySx";
-static char *console_dev  = console_env + 8;
-#endif
-#endif
-
 /*
  * Boot command-line arguments
  */
@@ -348,6 +340,7 @@
 	{ "swap=", swap_setup },
 	{ "buff=", buff_setup },
 	{ "panic=", panic_setup },
+	{ "console=", console_setup },
 #ifdef CONFIG_VT
 	{ "no-scroll", no_scroll },
 #endif
@@ -833,16 +826,6 @@
 			argv_init[++args] = line;
 		}
 	}
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (serial_console)
-		console_env[17] = serial_console - 64 + '0';
-	else {
-		console_env[16] = '0';
-		console_env[17] = '\0';
-	}
-	if (envs < MAX_INIT_ENVS)
-		envp_init[++envs] = console_env;
-#endif
 	argv_init[args+1] = NULL;
 	envp_init[envs+1] = NULL;
 }
@@ -1019,7 +1002,7 @@
 
 	close(0);close(1);close(2);
 	setsid();
-	(void) open("/dev/tty1",O_RDWR,0);
+	(void) open("/dev/console",O_RDWR,0);
 	(void) dup(0);
 	(void) dup(0);
 	return execve(shell, argv, envp_init);
@@ -1103,8 +1086,8 @@
 
 	setup(1);
 	
-	if (open("/dev/console",O_RDWR,0) < 0)
-		printk("Unable to open an initial console.\n");
+	if (open("/dev/console", O_RDWR, 0) < 0)
+		printk("Warning: unable to open an initial console.\n");
 
 	(void) dup(0);
 	(void) dup(0);
--- m68k-2.1.57/kernel/printk.c.orig	Thu Sep 25 19:35:12 1997
+++ m68k-2.1.57/kernel/printk.c	Tue Sep 30 20:23:27 1997
@@ -53,6 +53,46 @@
 static char log_buf[LOG_BUF_LEN];
 static unsigned long log_start = 0;
 static unsigned long logged_chars = 0;
+struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
+static int selected_console = 0;
+
+/*
+ *	Setup a list of consoles. Called from init/main.c
+ */
+__initfunc(void console_setup(char *str, int *ints))
+{
+	char *s;
+	int i;
+	struct console_cmdline *c;
+
+	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+		;
+	if (i == MAX_CMDLINECONSOLES)
+		return;
+	c = &console_cmdline[i];
+	selected_console = 1;
+
+	if (str[0] >= '0' && str[0] <= '9') {
+		strcpy(c->name, "ttyS");
+		strncpy(c->name + 4, str, sizeof(c->name) - 5);
+	} else
+		strncpy(c->name, str, sizeof(c->name) - 1);
+	if ((c->options = strchr(str, ',')) != NULL)
+		*(c->options++) = 0;
+#ifdef __sparc__
+	if (strcmp(str, "ttya"))
+		strcpy(c->name, "ttyS0");
+	if (strcmp(str, "ttyb"))
+		strcpy(c->name, "ttyS1");
+#endif
+
+	for(s = c->name; *s; s++)
+		if (*s >= '0' && *s <= '9')
+			break;
+	c->index = simple_strtoul(s, NULL, 10);
+	*s = 0;
+}
+
 
 /*
  * Commands to sys_syslog:
@@ -222,7 +262,7 @@
 		if (msg_level < console_loglevel && console_drivers) {
 			struct console *c = console_drivers;
 			while(c) {
-				if (c->write)
+				if ((c->flags & CON_ENABLED) && c->write)
 					c->write(msg, p - msg + line_feed);
 				c = c->next;
 			}
@@ -239,8 +279,9 @@
 {
 	struct console *c = console_drivers;
 	int len = strlen(s);
+
 	while(c) {
-		if (c->write)
+		if ((c->flags & CON_ENABLED) && c->write)
 			c->write(s, len);
 		c = c->next;
 	}
@@ -250,7 +291,7 @@
 {
 	struct console *c = console_drivers;
 	while(c) {
-		if (c->unblank)
+		if ((c->flags & CON_ENABLED) && c->unblank)
 			c->unblank();
 		c = c->next;
 	}
@@ -262,7 +303,7 @@
  * print any messages that were printed by the kernel before the
  * console driver was initialized.
  */
-__initfunc(void register_console(struct console * console))
+void register_console(struct console * console)
 {
 	int	i,j,len;
 	int	p = log_start;
@@ -270,9 +311,43 @@
 	signed char msg_level = -1;
 	char	*q;
 
-	console->next = console_drivers;
-	console_drivers = console;
+	/*
+	 *	See if we want to use this console driver.
+	 */
+	if (selected_console == 0) {
+		console->flags |= CON_ENABLED | CON_FIRST;
+		selected_console = 1;
+		if (console->setup)
+			console->setup(NULL);
+	}
+	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
+		if (strcmp(console_cmdline[i].name, console->name) != 0)
+			continue;
+		console->flags |= CON_ENABLED;
+		console->index = console_cmdline[i].index;
+		if (i == 0)
+			console->flags |= CON_FIRST;
+		if (console->setup)
+			console->setup(console_cmdline[i].options);
+		break;
+	}
+
+	/*
+	 *	Put this console in the list - keep the
+	 *	preferred driver at the head of the list.
+	 */
+	if ((console->flags & CON_FIRST) || console_drivers == NULL) {
+		console->next = console_drivers;
+		console_drivers = console;
+	} else {
+		console->next = console_drivers->next;
+		console_drivers->next = console;
+	}
+	if ((console->flags & CON_PRINTBUFFER) == 0) return;
 
+	/*
+	 *	Print out buffered log messages.
+	 */
 	for (i=0,j=0; i < log_size; i++) {
 		buf[j++] = log_buf[p];
 		p++; p &= LOG_BUF_LEN-1;
--- m68k-2.1.57/include/linux/console.h.orig	Mon Sep 29 20:28:35 1997
+++ m68k-2.1.57/include/linux/console.h	Tue Sep 30 20:23:27 1997
@@ -62,36 +62,39 @@
 struct tty_struct;
 int tioclinux(struct tty_struct *tty, unsigned long arg);
 
-/* The interface for /dev/console(s) and printk output */
-
-struct console
+/*
+ *	Array of consoles built from command line options (console=)
+ */
+struct console_cmdline
 {
-	/*
-	 * This function should not return before the string is written.
-	 */
-	void (*write)(const char*, unsigned);
-
-        /* To unblank the console in case of panic */
-        void (*unblank)(void);
+	char name[8];				/* Name of the driver	    */
+	int index;				/* Minor dev. to use	    */
+	char *options;				/* Options for the driver   */
+};
+#define MAX_CMDLINECONSOLES 8
+extern struct console_cmdline console_list[MAX_CMDLINECONSOLES];
 
-	/*
-         * Only the console that was registered last with wait_key !=
-	 * NULL will be used. This blocks until there is a character
-	 * to give back, it does not schedule.
-         */
-	void (*wait_key)(void);
+/*
+ *	The interface for a console, or any other device that
+ *	wants to capture console messages (printer driver?)
+ */
 
-	/*
-	 * Return the device to use when opening /dev/console. Only the
-	 * last registered console will do.
-	 */
-	int (*device)(void);
+#define CON_PRINTBUFFER	(1)
+#define CON_FIRST	(2)
+#define CON_ENABLED	(4)
 
-	/* 
-	 * For a linked list of consoles for multiple output. Any console
-         * not at the head of the list is used only for output.
-	 */
-	struct console *next;
+struct console
+{
+	char name[8];		/* Name of the driver, eg tty, ttyS, ttyR   */
+	void (*write)(const char*, unsigned);	/* Write string - blocking. */
+	int (*read)(const char*, unsigned);	/* Read string - blocking.  */
+	kdev_t (*device)(struct console *);	/* Return maj/min device    */
+	int (*wait_key)(void);	/* Wait for keypress			    */
+        void (*unblank)(void);	/* To unblank the console in case of panic  */
+	void (*setup)(char *);	/* Initialize speed etc.		    */
+	short flags;		/* CON_XXX defined above.		    */
+	short index;		/* ttyS0, ttyS1, ..			    */
+	struct console *next;	/* Next. Only the first one used for input  */
 };
 
 extern void register_console(struct console *);
--- m68k-2.1.57/include/linux/fb.h.orig	Mon Sep 29 20:39:25 1997
+++ m68k-2.1.57/include/linux/fb.h	Tue Sep 30 20:31:55 1997
@@ -74,6 +74,7 @@
 #define FB_ACCEL_AMIGABLITT	2	/* Amiga Blitter                */
 #define FB_ACCEL_CYBERVISION	3	/* Cybervision64 (S3 Trio64)    */
 #define FB_ACCEL_RETINAZ3	4	/* RetinaZ3 (NCR77C32BLT)       */
+#define FB_ACCEL_MACH64		6	/* ATI Mach 64			*/
 
 #define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active	*/
 #define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
--- m68k-2.1.57/include/linux/tty_driver.h.orig	Mon Sep 29 20:38:18 1997
+++ m68k-2.1.57/include/linux/tty_driver.h	Tue Sep 30 20:30:42 1997
@@ -194,10 +194,12 @@
 #define TTY_DRIVER_TYPE_SERIAL		0x0003
 #define TTY_DRIVER_TYPE_PTY		0x0004
 #define TTY_DRIVER_TYPE_SCC		0x0005	/* scc driver */
+#define TTY_DRIVER_TYPE_SYSCONS		0x0006
 
 /* system subtypes (magic, used by tty_io.c) */
 #define SYSTEM_TYPE_TTY			0x0001
 #define SYSTEM_TYPE_CONSOLE		0x0002
+#define SYSTEM_TYPE_SYSCONS		0x0003
 
 /* pty subtypes (magic, used by tty_io.c) */
 #define PTY_TYPE_MASTER			0x0001
--- m68k-2.1.57/drivers/block/README.buddha.orig	Tue Sep 30 20:25:47 1997
+++ m68k-2.1.57/drivers/block/README.buddha	Tue Sep 30 20:26:06 1997
@@ -0,0 +1,210 @@
+
+The Amiga Buddha and Catweasel IDE Driver (part of ide.c) was written by
+Geert Uytterhoeven based on the following specifications:
+
+------------------------------------------------------------------------
+
+Register map of the Buddha IDE controller and the
+Buddha-part of the Catweasel Zorro-II version
+
+The Autoconfiguration has been implemented just as Commodore
+described  in  their  manuals, no tricks have been used (for
+example leaving some address lines out of the equations...).
+If you want to configure the board yourself (for example let
+a  Linux  kernel  configure the card), look at the Commodore
+Docs.  Reading the nibbles should give this information:
+
+Vendor number: 4626 ($1212)
+product number: 0 (42 for Catweasel Z-II)
+Serial number: 0
+Rom-vector: $1000
+
+The  card  should be a Z-II board, size 64K, not for freemem
+list, Rom-Vektor is valid, no second Autoconfig-board on the
+same card, no space preferrence, supports "Shutup_forever".
+
+Setting  the  base address should be done in two steps, just
+as  the Amiga Kickstart does:  The lower nibble of the 8-Bit
+address is written to $4a, then the whole Byte is written to
+$48, while it doesn't matter how often you're writing to $4a
+as  long as $48 is not touched.  After $48 has been written,
+the  whole card disappears from $e8 and is mapped to the new
+addrress just written.  Make shure $4a is written befor $48,
+otherwise your chance is only 1:16 to find the board :-).
+
+The local memory-map is even active when mapped to $e8:
+
+$0-$7e		Autokonfig-space, see Z-II docs.
+
+$80-$7fd	reserved
+
+$7fe		Speed-select Register: Read & Write
+		(description see further down)
+
+$800-$8ff	IDE-Select 0 (Port 0, Register set 0)
+
+$900-$9ff	IDE-Select 1 (Port 0, Register set 1)
+
+$a00-$aff	IDE-Select 2 (Port 1, Register set 0)
+
+$b00-$bff	IDE-Select 3 (Port 1, Register set 1)
+
+$c00-$cff	IDE-Select 4 (Port 2, Register set 0,
+                          Catweasel only!)
+
+$d00-$dff	IDE-Select 5 (Port 3, Register set 1,
+			      Catweasel only!)
+
+$e00-$eff	local expansion port, on Catweasel Z-II the 
+		Catweasel registers are also mapped here.
+		Never touch, use multidisk.device!
+		
+$f00		read only, Byte-access: Bit 7 shows the 
+		level of the IRQ-line of IDE port 0. 
+
+$f01-$f3f	mirror of $f00
+
+$f40		read only, Byte-access: Bit 7 shows the 
+		level of the IRQ-line of IDE port 1. 
+
+$f41-$f7f	mirror of $f40
+
+$f80		read only, Byte-access: Bit 7 shows the 
+		level of the IRQ-line of IDE port 2. 
+		(Catweasel only!)
+
+$f81-$fbf	mirror of $f80
+
+$fc0		write-only: Writing any value to this
+		register enables IRQs to be passed from the 
+		IDE ports to the Zorro bus. This mechanism 
+		has been implemented to be compatible with 
+		harddisks that are either defective or have
+		a buggy firmware and pull the IRQ line up 
+		while starting up. If interrupts would 
+		always be passed to the bus, the computer 
+		might not start up. Once enabled, this flag 
+		can not be disabled again. The level of the 
+		flag can not be determined by software 
+		(what for? Write to me if it's necessary!).
+
+$fc1-$fff	mirror of $fc0
+
+$1000-$ffff	Buddha-Rom with offset $1000 in the rom
+		chip. The addresses $0 to $fff of the rom 
+		chip cannot be read. Rom is Byte-wide and
+		mapped to even addresses.
+
+The  IDE ports issue an INT2.  You can read the level of the
+IRQ-lines  of  the  IDE-ports by reading from the three (two
+for  Buddha-only)  registers  $f00, $f40 and $f80.  This way
+more  than one I/O request can be handled and you can easily
+determine  what  driver  has  to serve the INT2.  Buddha and
+Catweasel  expansion  boards  can issue an INT6.  A seperate
+memory  map  is available for the I/O module and the sysop's
+I/O module.
+
+The IDE ports are fed by the address lines A2 to A4, just as
+the  Amiga  1200  and  Amiga  4000  IDE ports are.  This way
+existing  drivers  can be easily ported to Buddha.  A move.l
+polls  two  words  out of the same address of IDE port since
+every  word  is  mirrored  once.  movem is not possible, but
+it's  not  necessary  either,  because  you can only speedup
+68000  systems  with  this  technique.   A 68020 system with
+fastmem is faster with move.l.
+
+If you're using the mirrored registers of the IDE-ports with
+A6=1,  the Buddha doesn't care about the speed that you have
+selected  in  the  speed  register (see further down).  With
+A6=1  (for example $840 for port 0, register set 0), a 780ns
+access  is being made.  These registers should be used for a
+command   access   to  the  harddisk/CD-Rom,  since  command
+accesses  are Byte-wide and have to be made slower according
+to the ATA-X3T9 manual.
+
+Now  for the speed-register:  The register is byte-wide, and
+only  the  upper  three  bits are used (Bits 7 to 5).  Bit 4
+must  always  be set to 1 to be compatible with later Buddha
+versions  (if  I'll  ever  update this one).  I presume that
+I'll  never use the lower four bits, but they have to be set
+to 1 by definition.
+  The  values in this table have to be shifted 5 bits to the
+left and or'd with $1f (this sets the lower 5 bits).
+
+All  the timings have in common:  Select and IOR/IOW rise at
+the  same  time.   IOR  and  IOW have a propagation delay of
+about  30ns  to  the clocks on the Zorro bus, that's why the
+values  are no multiple of 71.  One clock-cycle is 71ns long
+(exactly 70,5 at 14,18 Mhz on PAL systems).
+
+value 0 (Default after reset)
+
+497ns Select (7 clock cycles) , IOR/IOW after 172ns (2 clock cycles)
+(same timing as the Amiga 1200 does on it's IDE port without
+accelerator card)
+
+value 1
+
+639ns Select (9 clock cycles), IOR/IOW after 243ns (3 clock cycles)
+
+value 2
+
+781ns Select (11 clock cycles), IOR/IOW after 314ns (4 clock cycles)
+
+value 3
+
+355ns Select (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
+
+value 4
+
+355ns Select (5 clock cycles), IOR/IOW after 172ns (2 clock cycles)
+
+value 5
+
+355ns Select (5 clock cycles), IOR/IOW after 243ns (3 clock cycles)
+
+value 6
+
+1065ns Select (15 clock cycles), IOR/IOW after 314ns (4 clock cycles)
+
+value 7
+
+355ns Select, (5 clock cycles), IOR/IOW after 101ns (1 clock cycle)
+
+When accessing IDE registers with A6=1 (for example $84x),
+the timing will always be mode 0 8-bit compatible, no matter
+what you have selected in the speed register:
+
+781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive. 
+
+All  the  timings with a very short select-signal (the 355ns
+fast  accesses)  depend  on the accelerator card used in the
+system:  Sometimes two more clock cycles are inserted by the
+bus  interface,  making  the  whole access 497ns long.  This
+doesn't  affect  the  reliability  of the controller nor the
+performance  of  the  card,  since  this doesn't happen very
+often.
+
+All  the  timings  are  calculated  and  only  confirmed  by
+measurements  that allowed me to count the clock cycles.  If
+the  system  is clocked by an oscillator other than 28,37516
+Mhz  (for  example  the  NTSC-frequency  28,63636 Mhz), each
+clock  cycle is shortened to a bit less than 70ns (not worth
+mentioning).   You  could think of a small performance boost
+by  overclocking  the  system,  but  you would either need a
+multisync  monitor,  or  a  graphics card, and your internal
+diskdrive would go crazy, that's why you shouldn't tune your
+Amiga this way.
+
+Giving  you  the  possibility  to  write  software  that  is
+compatible  with both the Buddha and the Catweasel Z-II, The
+Buddha  acts  just  like  a  Catweasel  Z-II  with no device
+connected  to  the  third  IDE-port.   The IRQ-register $f80
+always  shows a "no IRQ here" on the Buddha, and accesses to
+the  third  IDE  port  are  going into data's Nirwana on the
+Buddha.
+
+			    Jens Schönfeld february 19th, 1997
+					updated may 27th, 1997
+			     eMail: sysop@nostlgic.tng.oche.de
+
--- m68k-2.1.57/drivers/block/ide-probe.c.orig	Mon Sep 29 20:19:27 1997
+++ m68k-2.1.57/drivers/block/ide-probe.c	Tue Sep 30 20:23:20 1997
@@ -68,8 +68,6 @@
 
 #include "ide.h"
 
-#define DEBUG
-
 static inline void do_identify (ide_drive_t *drive, byte cmd)
 {
 	int bswap = 1;
--- m68k-2.1.57/drivers/char/console.c.orig	Thu Sep 11 22:30:57 1997
+++ m68k-2.1.57/drivers/char/console.c	Tue Sep 30 20:44:52 1997
@@ -158,6 +158,7 @@
 extern void compute_shiftstate(void);
 extern void reset_palette(int currcons);
 extern void set_palette(void);
+extern int con_is_present(void);
 extern unsigned long con_type_init(unsigned long, const char **);
 extern void con_type_init_finish(void);
 extern int set_get_cmap(unsigned char *, int);
@@ -1885,16 +1886,24 @@
 	printing = 0;
 }
 
-static int vt_console_device(void)
+static kdev_t vt_console_device(struct console *c)
 {
-	return MKDEV(TTY_MAJOR, fg_console + 1);
+	return MKDEV(TTY_MAJOR, c->index ? c->index : fg_console + 1);
 }
 
-extern void keyboard_wait_for_keypress(void);
+extern int keyboard_wait_for_keypress(void);
 
 struct console vt_console_driver = {
-	vt_console_print, do_unblank_screen,
-        keyboard_wait_for_keypress, vt_console_device
+	"tty",
+	vt_console_print,
+	NULL,
+	vt_console_device,
+	keyboard_wait_for_keypress,
+	do_unblank_screen,
+	NULL,
+	CON_PRINTBUFFER,
+	0,
+	NULL
 };
 #endif
 
@@ -1983,6 +1992,9 @@
  *
  * Reads the information preserved by setup.s to determine the current display
  * type and sets everything accordingly.
+ *
+ * FIXME: return early if we don't _have_ a video card installed.
+ *
  */
 __initfunc(unsigned long con_init(unsigned long kmem_start))
 {
@@ -2117,7 +2129,7 @@
 	 * within the bus probing code... :-(
 	 */
 #ifdef CONFIG_VT_CONSOLE
-	if (video_type != VIDEO_TYPE_TGAC)
+	if (video_type != VIDEO_TYPE_TGAC && con_is_present())
 		register_console(&vt_console_driver);
 #endif
 
--- m68k-2.1.57/drivers/char/Config.in.orig	Thu Sep 11 22:30:58 1997
+++ m68k-2.1.57/drivers/char/Config.in	Tue Sep 30 20:23:20 1997
@@ -6,7 +6,7 @@
 
 bool 'Virtual terminal' CONFIG_VT
 if [ "$CONFIG_VT" = "y" ]; then
-  bool 'Console on virtual terminal' CONFIG_VT_CONSOLE
+  bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
 fi
 tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
 bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED
@@ -15,7 +15,7 @@
    bool '   Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ
    bool '   Support special multiport boards' CONFIG_SERIAL_MULTIPORT
    bool '   Support the Bell Technologies HUB6 card' CONFIG_HUB6
-   bool '   Console on serial port' CONFIG_SERIAL_CONSOLE
+   bool '   Support for serial port console' CONFIG_SERIAL_CONSOLE
 fi
 bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD
 if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then
--- m68k-2.1.57/drivers/char/m68kserial.c.orig	Mon Sep 15 22:50:44 1997
+++ m68k-2.1.57/drivers/char/m68kserial.c	Tue Sep 30 20:23:20 1997
@@ -74,6 +74,9 @@
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #endif
+#ifdef CONFIG_SERIAL_CONSOLE
+#include <linux/console.h>
+#endif
 
 #include <asm/setup.h>
 #include <asm/system.h>
@@ -135,6 +138,10 @@
 static struct tty_struct *serial_table[NR_PORTS];
 static struct termios *serial_termios[NR_PORTS];
 static struct termios *serial_termios_locked[NR_PORTS];
+#ifdef CONFIG_SERIAL_CONSOLE
+static struct console sercons;
+static int serial_console_cflag;
+#endif
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
@@ -1282,6 +1289,13 @@
 			*tty->termios = info->callout_termios;
 		info->sw->change_speed(info);
 	}
+#ifdef CONFIG_SERIAL_CONSOLE
+	if (serial_console_cflag && sercons.index == line) {
+		tty->termios->c_cflag = serial_console_cflag;
+		serial_console_cflag = 0;
+		info->sw->change_speed(info);
+	}
+#endif
 
 	info->session = current->session;
 	info->pgrp = current->pgrp;
@@ -1375,6 +1389,18 @@
 
 	init_bh(SERIAL_BH, do_serial_bh);
 
+#ifdef CONFIG_SERIAL_CONSOLE
+	/*
+	 *	The interrupt of the serial console port
+	 *	can't be shared.
+	 */
+	if (sercons.flags & CON_FIRST) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+			    rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
 	show_serial_version();
 
 	/* Initialize the tty_driver structure */
@@ -1614,3 +1640,119 @@
 		printk("SERIAL: failed to unregister callout driver\n");
 }
 #endif /* MODULE */
+
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+
+static kdev_t serial_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity.
+ */
+__initfunc(static void serial_console_setup(char *options))
+{
+	char *s;
+	int baud = 0, bits, parity;
+	int cflag = CREAD | HUPCL | CLOCAL;
+
+	bits = 8;
+	parity = 'n';
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s - '0';
+	}
+
+	/* Now construct a cflag setting. */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+
+	serial_console_cflag = cflag;
+}
+
+static struct console sercons = {
+	"ttyS",
+	NULL,			/* filled in by serial_console_init */
+	NULL,
+	serial_console_device,
+	NULL,			/* filled in by serial_console_init */
+	NULL,
+	serial_console_setup,
+	CON_PRINTBUFFER,
+	0,
+	NULL
+};
+
+extern void amiga_serial_console_write(const char *s, unsigned int count);
+extern int amiga_serial_console_wait_key(void);
+extern void amiga_init_serial_console(struct async_struct *info, int cflag);
+
+/*
+ * This is here to set the speed etc. for a non-initialized
+ * line. We have no termios struct yet, so we just use "cflag".
+ */
+long serial_console_init(long kmem_start, long kmem_end)
+{
+	/* Currently this supports the Amiga builtin port only */
+	if (MACH_IS_AMIGA && sercons.index == 0) {
+		sercons.write = amiga_serial_console_write;
+		sercons.wait_key = amiga_serial_console_wait_key;
+		register_console(&sercons);
+		/* no initialization yet */
+		/* amiga_init_serial_console(rs_table+sercons.index, */
+		/*			     serial_console_cflag); */
+	}
+	return kmem_start;
+}
+#endif
--- m68k-2.1.57/drivers/char/n_tty.c.orig	Thu Sep 25 19:35:09 1997
+++ m68k-2.1.57/drivers/char/n_tty.c	Tue Sep 30 20:23:20 1997
@@ -40,6 +40,7 @@
 #include <asm/bitops.h>
 
 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
+#define SYSCONS_DEV  MKDEV(TTYAUX_MAJOR,1)
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
@@ -855,6 +856,7 @@
 	   check of the logic of this change. -- jlc */
 	/* don't stop on /dev/console */
 	if (file->f_dentry->d_inode->i_rdev != CONSOLE_DEV &&
+	    file->f_dentry->d_inode->i_rdev != SYSCONS_DEV &&
 	    current->tty == tty) {
 		if (tty->pgrp <= 0)
 			printk("read_chan: tty->pgrp <= 0!\n");
@@ -1013,7 +1015,8 @@
 	int retval = 0;
 
 	/* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
-	if (L_TOSTOP(tty) && file->f_dentry->d_inode->i_rdev != CONSOLE_DEV) {
+	if (L_TOSTOP(tty) && file->f_dentry->d_inode->i_rdev != CONSOLE_DEV &&
+	    file->f_dentry->d_inode->i_rdev != SYSCONS_DEV) {
 		retval = tty_check_change(tty);
 		if (retval)
 			return retval;
--- m68k-2.1.57/drivers/char/serial.c.orig	Thu Sep 25 19:35:10 1997
+++ m68k-2.1.57/drivers/char/serial.c	Tue Sep 30 20:23:20 1997
@@ -46,6 +46,9 @@
 #include <linux/mm.h>
 #include <linux/malloc.h>
 #include <linux/init.h>
+#ifdef CONFIG_SERIAL_CONSOLE
+#include <linux/console.h>
+#endif
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -149,6 +152,10 @@
 static volatile int rs_irq_triggered;
 static volatile int rs_triggered;
 static int rs_wild_int_mask;
+#ifdef CONFIG_SERIAL_CONSOLE
+static struct console sercons;
+static int serial_console_cflag;
+#endif
 
 static void autoconfig(struct serial_state * info);
 static void change_speed(struct async_struct *info);
@@ -2833,7 +2840,13 @@
 			*tty->termios = info->state->callout_termios;
 		change_speed(info);
 	}
-
+#ifdef CONFIG_SERIAL_CONSOLE
+	if (serial_console_cflag && sercons.index == line) {
+		tty->termios->c_cflag = serial_console_cflag;
+		serial_console_cflag = 0;
+		change_speed(info);
+	}
+#endif
 	info->session = current->session;
 	info->pgrp = current->pgrp;
 
@@ -3277,7 +3290,18 @@
 		       sizeof(struct rs_multiport_struct));
 #endif
 	}
-	
+#ifdef CONFIG_SERIAL_CONSOLE
+	/*
+	 *	The interrupt of the serial console port
+	 *	can't be shared.
+	 */
+	if (sercons.flags & CON_FIRST) {
+		for(i = 0; i < NR_PORTS; i++)
+			if (i != sercons.index &&
+			    rs_table[i].irq == rs_table[sercons.index].irq)
+				rs_table[i].irq = 0;
+	}
+#endif
 	show_serial_version();
 
 	/* Initialize the tty_driver structure */
@@ -3479,23 +3503,17 @@
  */
 #ifdef CONFIG_SERIAL_CONSOLE
 
-#include <linux/console.h>
-
-/*
- * this defines the index into rs_table for the port to use
- */
-#ifndef CONFIG_SERIAL_CONSOLE_PORT
-#define CONFIG_SERIAL_CONSOLE_PORT	0
-#endif
-
 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
 
 /* Wait for transmitter & holding register to empty */
 static inline void wait_for_xmitr(struct serial_state *ser)
 {
 	int lsr;
+	unsigned int tmout = 1000000;
+
 	do {
 		lsr = inb(ser->port + UART_LSR);
+		if (--tmout == 0) break;
 	} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
 }
 
@@ -3509,7 +3527,7 @@
 	int ier;
 	unsigned i;
 
-	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+	ser = rs_table + sercons.index;
 	/*
 	 * First save the IER then disable the interrupts
 	 */
@@ -3543,14 +3561,14 @@
 /*
  * Receive character from the serial port
  */
-static void serial_console_wait_key(void)
+static int serial_console_wait_key(void)
 {
 	struct serial_state *ser;
 	int ier;
 	int lsr;
 	int c;
 
-	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+	ser = rs_table + sercons.index;
 
 	/*
 	 * First save the IER then disable the interrupts so
@@ -3567,37 +3585,142 @@
 
 	/* Restore the interrupts */
 	outb(ier, ser->port + UART_IER);
+
+	return c;
 }
 
-static int serial_console_device(void)
+static kdev_t serial_console_device(struct console *c)
 {
-	return MKDEV(TTYAUX_MAJOR, 64 + CONFIG_SERIAL_CONSOLE_PORT);
+	return MKDEV(TTY_MAJOR, 64 + c->index);
 }
 
+/*
+ *	Setup initial baud/bits/parity.
+ */
+__initfunc(static void serial_console_setup(char *options))
+{
+	char *s;
+	int baud = 0, bits, parity;
+	int cflag = CREAD | HUPCL | CLOCAL;
+
+	bits = 8;
+	parity = 'n';
+
+	if (options) {
+		baud = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) parity = *s++;
+		if (*s) bits   = *s - '0';
+	}
+
+	/* Now construct a cflag setting. */
+	switch(baud) {
+		case 1200:
+			cflag |= B1200;
+			break;
+		case 2400:
+			cflag |= B2400;
+			break;
+		case 4800:
+			cflag |= B4800;
+			break;
+		case 19200:
+			cflag |= B19200;
+			break;
+		case 38400:
+			cflag |= B38400;
+			break;
+		case 57600:
+			cflag |= B57600;
+			break;
+		case 9600:
+		default:
+			cflag |= B9600;
+			break;
+	}
+	switch(bits) {
+		case 7:
+			cflag |= CS7;
+			break;
+		default:
+		case 8:
+			cflag |= CS8;
+			break;
+	}
+	switch(parity) {
+		case 'o': case 'O':
+			cflag |= PARODD;
+			break;
+		case 'e': case 'E':
+			cflag |= PARENB;
+			break;
+	}
+
+	serial_console_cflag = cflag;
+}
+
+static struct console sercons = {
+	"ttyS",
+	serial_console_write,
+	NULL,
+	serial_console_device,
+	serial_console_wait_key,
+	NULL,
+	serial_console_setup,
+	CON_PRINTBUFFER,
+	0,
+	NULL
+};
+
+/*
+ * This is here to set the speed etc. for a non-initialized
+ * line. We have no termios struct yet, so we just use "cflag".
+ */
 long serial_console_init(long kmem_start, long kmem_end)
 {
-	static struct console console = {
-		serial_console_write, 0,
-                serial_console_wait_key, serial_console_device
-	};
+	unsigned cval;
+	int	i;
+	int	quot = 0;
 	struct serial_state *ser;
+	
+	register_console(&sercons);
+	ser = rs_table + sercons.index;
+
+	i = serial_console_cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i == 1 || i == 2) i += 15;
+	}
+	/* We do not support baudrates of 0. */
+	if (!baud_table[i]) i = 13; /* 9600 */
+	quot = BASE_BAUD / baud_table[i];
+
+	/* byte size and parity */
+	cval = serial_console_cflag & (CSIZE | CSTOPB);
+#if defined(__powerpc__) || defined(__alpha__)
+	cval >>= 8;
+#else /* !__powerpc__ && !__alpha__ */
+	cval >>= 4;
+#endif /* !__powerpc__ && !__alpha__ */
+	if (serial_console_cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(serial_console_cflag & PARODD))
+		cval |= UART_LCR_EPAR;
 
-	ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT;
+	/* Disable UART interrupts. */
+	outb(0, ser->port + UART_IER);
 
-	/* Disable all interrupts, it works in polled mode */
-	outb(0x00, ser->port + UART_IER); 
+	/* Set DTR and RTS high. */
+	outb(UART_MCR_DTR | UART_MCR_RTS, ser->port + UART_MCR);
 
-	/*
-	 * now do hardwired init
-	 */
-	outb(0x03, ser->port + UART_LCR); /* No parity, 8 data bits, 1 stop */
-	outb(0x83, ser->port + UART_LCR); /* Access divisor latch */
-	outb(0x00, ser->port + UART_DLM); /* 9600 baud */
-	outb(0x0c, ser->port + UART_DLL);
-	outb(0x03, ser->port + UART_LCR); /* Done with divisor */
+	/* And set speed. */
+	outb(cval | UART_LCR_DLAB, ser->port + UART_LCR);	/* set DLAB */
+	outb(quot & 0xff, ser->port + UART_DLL);	/* LS of divisor */
+	outb(quot >> 8, ser->port + UART_DLM);		/* MS of divisor */
+	outb(cval, ser->port + UART_LCR);		/* reset DLAB */
 
-	register_console(&console);
 	return kmem_start;
 }
-
 #endif
--- m68k-2.1.57/drivers/char/tga.c.orig	Thu Sep 11 22:30:58 1997
+++ m68k-2.1.57/drivers/char/tga.c	Tue Sep 30 20:23:20 1997
@@ -443,6 +443,19 @@
 {
 }
 
+
+/*
+ *	See if we have a TGA card.
+ */
+__initfunc(int con_is_present())
+{
+	int status;
+
+	status = pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA,
+				      0, &pci_bus, &pci_devfn);
+	return (status == PCIBIOS_DEVICE_NOT_FOUND) ? 0 : 1;
+}
+
 /*
  * video init code, called from within the PCI bus probing code;
  * when TGA console is configured, at the end of the probing code,
--- m68k-2.1.57/drivers/char/tty_io.c.orig	Mon Sep 29 20:19:28 1997
+++ m68k-2.1.57/drivers/char/tty_io.c	Tue Sep 30 20:23:20 1997
@@ -90,6 +90,7 @@
 
 #define CONSOLE_DEV MKDEV(TTY_MAJOR,0)
 #define TTY_DEV MKDEV(TTYAUX_MAJOR,0)
+#define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1)
 
 #undef TTY_DEBUG_HANGUP
 
@@ -376,7 +377,8 @@
 			continue;
 		if (!filp->f_dentry->d_inode)
 			continue;
-		if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV)
+		if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
+		    filp->f_dentry->d_inode->i_rdev == SYSCONS_DEV)
 			continue;
 		if (filp->f_op != &tty_fops)
 			continue;
@@ -626,7 +628,12 @@
 	int is_console;
 	struct tty_struct * tty;
 
-	is_console = (inode->i_rdev == CONSOLE_DEV);
+	/*
+	 *	For now, we redirect writes from /dev/console as
+	 *	well as /dev/tty0.
+	 */
+	is_console = (inode->i_rdev == SYSCONS_DEV ||
+			inode->i_rdev == CONSOLE_DEV);
 
 	if (is_console && redirect)
 		tty = redirect;
@@ -1177,13 +1184,20 @@
 		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
 		/* noctty = 1; */
 	}
+#ifdef CONFIG_VT
 	if (device == CONSOLE_DEV) {
+		extern int fg_console;
+		device = MKDEV(TTY_MAJOR, fg_console + 1);
+		noctty = 1;
+	}
+#endif
+	if (device == SYSCONS_DEV) {
 		struct console *c = console_drivers;
 		while(c && !c->device)
 			c = c->next;
 		if (!c)
                         return -ENODEV;
-                device = c->device();
+                device = c->device(c);
 		noctty = 1;
 	}
 	minor = MINOR(device);
@@ -1364,7 +1378,8 @@
 
 static int tioccons(struct tty_struct *tty, struct tty_struct *real_tty)
 {
-	if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) {
+	if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE ||
+	    tty->driver.type == TTY_DRIVER_TYPE_SYSCONS) {
 		if (!suser())
 			return -EPERM;
 		redirect = NULL;
@@ -1768,16 +1783,17 @@
 	 * set up the console device so that later boot sequences can 
 	 * inform about problems etc..
 	 */
-#ifdef CONFIG_SERIAL_CONSOLE
-	kmem_start = serial_console_init(kmem_start, kmem_end);
-#endif
 #ifdef CONFIG_VT
 	kmem_start = con_init(kmem_start);
 #endif
+#ifdef CONFIG_SERIAL_CONSOLE
+	kmem_start = serial_console_init(kmem_start, kmem_end);
+#endif
 	return kmem_start;
 }
 
-static struct tty_driver dev_tty_driver, dev_console_driver;
+static struct tty_driver dev_tty_driver, dev_console_driver,
+	dev_syscons_driver;
 
 /*
  * Ok, now we can initialize the rest of the tty devices and can count
@@ -1808,17 +1824,28 @@
 	if (tty_register_driver(&dev_tty_driver))
 		panic("Couldn't register /dev/tty driver\n");
 
+	dev_syscons_driver = dev_tty_driver;
+	dev_syscons_driver.driver_name = "/dev/console";
+	dev_syscons_driver.name = dev_syscons_driver.driver_name + 5;
+	dev_syscons_driver.major = TTYAUX_MAJOR;
+	dev_syscons_driver.minor_start = 1;
+	dev_syscons_driver.type = TTY_DRIVER_TYPE_SYSTEM;
+	dev_syscons_driver.subtype = SYSTEM_TYPE_SYSCONS;
+
+	if (tty_register_driver(&dev_syscons_driver))
+		panic("Couldn't register /dev/console driver\n");
+
+#ifdef CONFIG_VT
 	dev_console_driver = dev_tty_driver;
-	dev_console_driver.driver_name = "/dev/console";
+	dev_console_driver.driver_name = "/dev/tty0";
 	dev_console_driver.name = dev_console_driver.driver_name + 5;
 	dev_console_driver.major = TTY_MAJOR;
 	dev_console_driver.type = TTY_DRIVER_TYPE_SYSTEM;
 	dev_console_driver.subtype = SYSTEM_TYPE_CONSOLE;
 
 	if (tty_register_driver(&dev_console_driver))
-		panic("Couldn't register /dev/console driver\n");
+		panic("Couldn't register /dev/tty0 driver\n");
 
-#ifdef CONFIG_VT
 	kbd_init();
 #endif
 #ifdef CONFIG_ESPSERIAL  /* init ESP before rs, so rs doesn't see the port */
--- m68k-2.1.57/drivers/char/vga.c.orig	Thu Sep 11 22:30:58 1997
+++ m68k-2.1.57/drivers/char/vga.c	Tue Sep 30 20:23:20 1997
@@ -150,7 +150,33 @@
 	if (deccm) {
 		write_vga(14, (pos - video_mem_base)>>1);
 	} else
-		hide_cursor();
+		hide_cursor(currcons);
+}
+
+__initfunc(int con_is_present(void))
+{
+	unsigned short saved;
+	unsigned short *p;
+
+	/*
+	 *	Find out if there is a graphics card present.
+	 *	Are there smarter methods around?
+	 */
+	p = (unsigned short *)(((ORIG_VIDEO_MODE == 7) ? 0xb0000 : 0xb8000) +
+			       + VGA_OFFSET);
+	saved = scr_readw(p);
+	scr_writew(0xAA55, p);
+	if (scr_readw(p) != 0xAA55) {
+		scr_writew(saved, p);
+		return 0;
+	}
+	scr_writew(0x55AA, p);
+	if (scr_readw(p) != 0x55AA) {
+		scr_writew(saved, p);
+		return 0;
+	}
+	scr_writew(saved, p);
+	return 1;
 }
 
 __initfunc(unsigned long
--- m68k-2.1.57/drivers/video/Config.in.orig	Mon Sep 29 20:19:29 1997
+++ m68k-2.1.57/drivers/video/Config.in	Tue Sep 30 20:23:20 1997
@@ -21,7 +21,7 @@
   fi
   if [ "$CONFIG_ATARI" = "y" ]; then
     bool 'Atari native chipset support' CONFIG_FB_ATARI
-#    tristate 'Mach64 Frame Buffer support' CONFIG_FB_MACH64
+    tristate 'Mach64 Frame Buffer support' CONFIG_FB_MACH64
   fi 
   tristate 'Virtual Frame Buffer support' CONFIG_FB_VIRTUAL
 
@@ -37,6 +37,7 @@
     tristate '16 bpp packed pixel support' CONFIG_FBCON_CFB16
     tristate 'Cybervision support (accelerated)' CONFIG_FBCON_CYBER
     tristate 'RetinaZ3 support (accelerated)' CONFIG_FBCON_RETINAZ3
+    tristate 'Mach64 support (accelerated)' CONFIG_FBCON_MACH64
   else
     if [ "$CONFIG_FB_AMIGA" != "n" -o "$CONFIG_FB_ATARI" != "n" -o \
 	 "$CONFIG_FB_CYBER" != "n" -o "$CONFIG_FB_RETINAZ3" != "n" -o \
@@ -61,6 +62,9 @@
     fi
     if [ "$CONFIG_FB_RETINAZ3" = "y" -o "$CONFIG_FB_RETINAZ3" = "m" ]; then
       define_bool CONFIG_FBCON_RETINAZ3 y
+    fi
+    if [ "$CONFIG_FB_MACH64" = "y" -o "$CONFIG_FB_MACH64" = "m" ]; then
+      define_bool CONFIG_FBCON_MACH64 y
     fi
   fi
 
--- m68k-2.1.57/drivers/video/amifb.c.orig	Tue Sep 30 20:27:52 1997
+++ m68k-2.1.57/drivers/video/amifb.c	Tue Sep 30 22:47:44 1997
@@ -59,7 +59,6 @@
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <asm/setup.h>
-#include <asm/linux_logo.h>
 
 #define DEBUG
 
@@ -94,6 +93,12 @@
 #  define IS_AGA (1)
 #endif
 
+#ifdef DEBUG
+#  define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
 /*******************************************************************************
 
 
@@ -1710,72 +1715,6 @@
 }
 
 
-#ifndef MODULE
-__initfunc(static int amifb_show_logo(void))
-{
-    struct amiga_fb_par *par = &currentpar;
-    int x1, x2, y, i, m, colorshift;
-    u_char *fb = (u_char *)videomemory, *p, s, t;
-
-    if (IS_AGA)
-	colorshift = 0;
-    else if (par->clk_shift == TAG_SHRES)
-	colorshift = 6;
-    else
-	colorshift = 4;
-    if (par->bpp == 8) {
-	/* 256 colors */
-	for (i = 0; i < LINUX_LOGO_COLORS; i++)
-	    ami_setcolreg(32+i, linux_logo_red[i]>>colorshift,
-	    		  linux_logo_green[i]>>colorshift,
-	    		  linux_logo_blue[i]>>colorshift, 0);
-	for (y = 0; y < 80; y++)
-	    for (x1 = 0; x1 < 10; x1++) {
-		p = fb+y*par->next_line+x1;
-		for (m = 1; m < 256; m <<= 1, p += par->next_plane) {
-		    t = 0;
-		    for (s = 0x80, x2 = 0; s; s >>= 1, x2++)
-			if (linux_logo[(y*10+x1)*8+x2] & m)
-			    t |= s;
-		    *p = t;
-		}
-	    }
-    } else if (par->bpp >= 4) {
-	/* 16 colors */
-	for (i = 0; i < 16; i++)
-	    ami_setcolreg(par->bpp == 4 ? i : 16+i,
-	    		  linux_logo16_red[i]>>colorshift,
-	    		  linux_logo16_green[i]>>colorshift,
-	    		  linux_logo16_blue[i]>>colorshift, 0);
-	for (y = 0; y < 80; y++) {
-	    for (x1 = 0; x1 < 10; x1++) {
-		p = fb+y*par->next_line+x1;
-		for (m = 1; m < 16; m <<= 1, p += par->next_plane) {
-		    t = 0;
-		    for (s = 0x80, x2 = 0; s; s >>= 1, x2++) {
-			if ((linux_logo16[(y*10+x1)*4+x2]>>4) & m)
-			    t |= s;
-			s >>= 1;
-			if (linux_logo16[(y*10+x1)*4+x2] & m)
-			    t |= s;
-		    }
-		    *p = t;
-		}
-	    }
-	    for (i = 4; i < par->bpp; i++)
-		memset(&fb[y*par->next_line+i*par->next_plane],
-		       i == 4 ? 0xff : 0x00, 10);
-	}
-    } else {
-	/* monochrome */
-	for (y = 0; y < 80; y++)
-	    memcpy(&fb[y*par->next_line], &linux_logo_bw[y*10], 10);
-    }
-    return(80/fb_display[0].fontheight+1);
-}
-#endif /* MODULE */
-
-
 	/*
 	 * Initialisation
 	 */
@@ -1958,11 +1897,6 @@
 	/* TODO: This driver cannot be unloaded yet */
 	MOD_INC_USE_COUNT;
 
-#ifndef MODULE
-	if (!console_show_logo)
-	    console_show_logo = amifb_show_logo;
-#endif
-
 	return mem_start;
 }
 
@@ -2259,11 +2193,13 @@
 	 * Find a matching Pixel Clock
 	 */
 
-	for (clk_shift = TAG_SHRES; clk_shift < TAG_LORES; clk_shift++)
+	for (clk_shift = TAG_SHRES; clk_shift <= TAG_LORES; clk_shift++)
 		if (var->pixclock <= pixclock[clk_shift])
 			break;
-	if (clk_shift >= TAG_LORES)
+	if (clk_shift > TAG_LORES) {
+		DPRINTK("pixclock too high\n");
 		return -EINVAL;
+	}
 	par->clk_shift = clk_shift;
 
 	/*
@@ -2281,14 +2217,27 @@
 
 	par->bpp = var->bits_per_pixel;
 	if (!var->nonstd) {
-		if (par->bpp <= 0 || par->bpp > maxdepth[clk_shift])
+		if (par->bpp < 1)
+			par->bpp = 1;
+		if (par->bpp > maxdepth[clk_shift]) {
+			DPRINTK("invalid bpp\n");
 			return -EINVAL;
+		}
 	} else if (var->nonstd == FB_NONSTD_HAM) {
-		if (par->bpp != 6)
-			if (par->bpp != 8 || !IS_AGA)
+		if (par->bpp < 6)
+			par->bpp = 6;
+		if (par->bpp != 6) {
+			if (par->bpp < 8)
+				par->bpp = 8;
+			if (par->bpp != 8 || !IS_AGA) {
+				DPRINTK("invalid bpp for ham mode\n");
 				return -EINVAL;
-	} else
+			}
+		}
+	} else {
+		DPRINTK("unknown nonstd mode\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing
@@ -2304,11 +2253,14 @@
 			line_shift = 1;
 			break;
 		case FB_VMODE_DOUBLE:
-			if (!IS_AGA)
+			if (!IS_AGA) {
+				DPRINTK("double mode only possible with aga\n");
 				return -EINVAL;
+			}
 			line_shift = 2;
 			break;
 		default:
+			DPRINTK("unknown video mode\n");
 			return -EINVAL;
 			break;
 	}
@@ -2333,11 +2285,19 @@
 			par->diwstop_h += mod4(var->hsync_len);
 		else
 			par->diwstop_h = down4(par->diwstop_h);
+
 		par->diwstrt_h = par->diwstop_h - xres_n;
 		par->diwstop_v = par->vtotal-((var->lower_margin-var->vsync_len)<<line_shift);
 		par->diwstrt_v = par->diwstop_v - yres_n;
-		if (par->diwstop_h >= par->htotal+8 || par->diwstop_v > par->vtotal)
+		if (par->diwstop_h >= par->htotal+8) {
+			DPRINTK("invalid diwstop_h\n");
+			return -EINVAL;
+		}
+		if (par->diwstop_v > par->vtotal) {
+			DPRINTK("invaild diwstop_v\n");
 			return -EINVAL;
+		}
+
 		if (!IS_OCS) {
 			/* Initialize sync with some reasonable values for pwrsave */
 			par->hsstrt = 160;
@@ -2352,12 +2312,18 @@
 		}
 		if (par->vtotal > (PAL_VTOTAL+NTSC_VTOTAL)/2) {
 			/* PAL video mode */
-			if (par->htotal != PAL_HTOTAL)
+			if (par->htotal != PAL_HTOTAL) {
+				DPRINTK("htotal invalid for pal\n");
 				return -EINVAL;
-			if (par->diwstrt_h < PAL_DIWSTRT_H)
+			}
+			if (par->diwstrt_h < PAL_DIWSTRT_H) {
+				DPRINTK("diwstrt_h too low for pal\n");
 				return -EINVAL;
-			if (par->diwstrt_v < PAL_DIWSTRT_V)
+			}
+			if (par->diwstrt_v < PAL_DIWSTRT_V) {
+				DPRINTK("diwstrt_v too low for pal\n");
 				return -EINVAL;
+			}
 			hrate = 15625;
 			vrate = 50;
 			if (!IS_OCS) {
@@ -2367,19 +2333,27 @@
 			           AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
 				par->beamcon0 = BMC0_PAL;
 				par->hsstop = 1;
-			} else if (amiga_vblank != 50)
+			} else if (amiga_vblank != 50) {
+				DPRINTK("pal not supported by this chipset\n");
 				return -EINVAL;
+			}
 		} else {
 			/* NTSC video mode
 			 * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK
 			 * and NTSC activated, so than better let diwstop_h <= 1812
 			 */
-			if (par->htotal != NTSC_HTOTAL)
+			if (par->htotal != NTSC_HTOTAL) {
+				DPRINTK("htotal invalid for ntsc\n");
 				return -EINVAL;
-			if (par->diwstrt_h < NTSC_DIWSTRT_H)
+			}
+			if (par->diwstrt_h < NTSC_DIWSTRT_H) {
+				DPRINTK("diwstrt_h too low for ntsc\n");
 				return -EINVAL;
-			if (par->diwstrt_v < NTSC_DIWSTRT_V)
+			}
+			if (par->diwstrt_v < NTSC_DIWSTRT_V) {
+				DPRINTK("diwstrt_v too low for ntsc\n");
 				return -EINVAL;
+			}
 			hrate = 15750;
 			vrate = 60;
 			if (!IS_OCS) {
@@ -2389,13 +2363,17 @@
 			           AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
 				par->beamcon0 = 0;
 				par->hsstop = 1;
-			} else if (amiga_vblank != 60)
+			} else if (amiga_vblank != 60) {
+				DPRINTK("ntsc not supported by this chipset\n");
 				return -EINVAL;
+			}
 		}
 		if (IS_OCS) {
 			if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 ||
-			    par->diwstrt_v >=  512 || par->diwstop_v <  256)
+			    par->diwstrt_v >=  512 || par->diwstop_v <  256) {
+				DPRINTK("invalid position for display on ocs\n");
 				return -EINVAL;
+			}
 		}
 	} else if (!IS_OCS) {
 		/* Programmable video mode */
@@ -2418,8 +2396,14 @@
 		par->diwstrt_v = par->diwstop_v - yres_n;
 		par->vbstop = par->diwstrt_v - 2;
 		par->vbstrt = par->diwstop_v - 2;
-		if (par->vtotal > 2048 || par->htotal > 2048)
+		if (par->vtotal > 2048) {
+			DPRINTK("vtotal too high\n");
+			return -EINVAL;
+		}
+		if (par->htotal > 2048) {
+			DPRINTK("htotal too high\n");
 			return -EINVAL;
+		}
 		par->bplcon3 |= BPC3_EXTBLKEN;
 		par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
 		                BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
@@ -2433,8 +2417,10 @@
 		hrate = (amiga_masterclock+par->htotal/2)/par->htotal;
 		vrate = div2(par->vtotal) * par->htotal;
 		vrate = (amiga_masterclock+vrate/2)/vrate;
-	} else
+	} else {
+		DPRINTK("only broadcast modes possible for ocs\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * Checking the DMA timing
@@ -2450,8 +2436,10 @@
 
 	fsize = ((maxfmode+clk_shift <= 1) ? fconst : 64);
 	fstrt = downx(fconst, par->diwstrt_h-4) - fsize;
-	if (fstrt < min_fstrt)
+	if (fstrt < min_fstrt) {
+		DPRINTK("fetch start too low\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * smallest window start value where smooth scrolling is possible
@@ -2469,8 +2457,10 @@
 		par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
 
 	fsize = upx(fconst, xres_n);
-	if (fstrt + fsize > maxfetchstop)
+	if (fstrt + fsize > maxfetchstop) {
+		DPRINTK("fetch stop too high\n");
 		return -EINVAL;
+	}
 
 	if (maxfmode + clk_shift <= 1) {
 		fsize = up64(xres_n + fconst - 1);
@@ -2478,8 +2468,10 @@
 			par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
 
 		fsize = up64(xres_n);
-		if (min_fstrt + fsize - 64 > maxfetchstop)
+		if (min_fstrt + fsize - 64 > maxfetchstop) {
+			DPRINTK("fetch size too high\n");
 			return -EINVAL;
+		}
 
 		fsize -= 64;
 	} else
@@ -2499,13 +2491,17 @@
 	if (amifb_ilbm) {
 		par->next_plane = div8(upx(16<<maxfmode, par->vxres));
 		par->next_line = par->bpp*par->next_plane;
-		if (par->next_line * par->vyres > videomemorysize)
+		if (par->next_line * par->vyres > videomemorysize) {
+			DPRINTK("too few video mem\n");
 			return -EINVAL;
+		}
 	} else {
 		par->next_line = div8(upx(16<<maxfmode, par->vxres));
 		par->next_plane = par->vyres*par->next_line;
-		if (par->next_plane * par->bpp > videomemorysize)
+		if (par->next_plane * par->bpp > videomemorysize) {
+			DPRINTK("too few video mem\n");
 			return -EINVAL;
+		}
 	}
 
 	/*
@@ -2555,8 +2551,10 @@
 	par->crsr.spot_x = par->crsr.spot_y = 0;
 	par->crsr.height = par->crsr.width = 0;
 
-	if (hrate < hfmin || hrate > hfmax || vrate < vfmin || vrate > vfmax)
+	if (hrate < hfmin || hrate > hfmax || vrate < vfmin || vrate > vfmax) {
+		DPRINTK("mode doesn't fit for monitor\n");
 		return -EINVAL;
+	}
 
 	return 0;
 }
--- m68k-2.1.57/drivers/video/fbcon-iplan2p2.c.orig	Mon Sep 15 22:50:48 1997
+++ m68k-2.1.57/drivers/video/fbcon-iplan2p2.c	Tue Sep 30 20:23:20 1997
@@ -188,7 +188,7 @@
 	return -EINVAL;
 
     p->next_line = p->var.xres_virtual>>2;
-    p->next_plane = 0;
+    p->next_plane = 2;
     MOD_INC_USE_COUNT;
     return 0;
 }
--- m68k-2.1.57/drivers/video/fbcon-iplan2p4.c.orig	Mon Sep 15 22:50:48 1997
+++ m68k-2.1.57/drivers/video/fbcon-iplan2p4.c	Tue Sep 30 20:23:20 1997
@@ -207,7 +207,7 @@
 	return -EINVAL;
 
     p->next_line = p->var.xres_virtual>>1;
-    p->next_plane = 0;
+    p->next_plane = 2;
     MOD_INC_USE_COUNT;
     return 0;
 }
--- m68k-2.1.57/drivers/video/fbcon-iplan2p8.c.orig	Mon Sep 15 22:50:48 1997
+++ m68k-2.1.57/drivers/video/fbcon-iplan2p8.c	Tue Sep 30 20:23:20 1997
@@ -256,7 +256,7 @@
 	return -EINVAL;
 
     p->next_line = p->var.xres_virtual;
-    p->next_plane = 0;
+    p->next_plane = 2;
     MOD_INC_USE_COUNT;
     return 0;
 }
--- m68k-2.1.57/drivers/video/fbcon-mach64.c.orig	Tue Sep 30 20:25:47 1997
+++ m68k-2.1.57/drivers/video/fbcon-mach64.c	Tue Sep 30 20:37:35 1997
@@ -0,0 +1,516 @@
+/*
+ *  linux/drivers/video/fbcon-mach64.c -- Low level frame buffer operations for 
+ *					  Ati Mach64 (accelerated)
+ *
+ *	Created 20 Jun 1997 by Bernd Harries
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/fb.h>
+
+#include "fbcon.h"
+#include "mach64fb.h"
+
+/*============================================================================*/
+/* Defines */
+
+#define  _USE_HW_ACCEL_BLT_
+#define  _USE_HW_ACCEL_FILL_
+
+
+#ifdef  BHA_DEBUG
+
+#define  FuncId       if(mach64_debug & 0x00000100) printk
+#define  FuncDone     if(mach64_debug & 0x00000200) printk
+#define  CFuncId      if(mach64_debug & 0x00000400) printk
+#define  CFuncDone    if(mach64_debug & 0x00000800) printk
+
+
+/* Busy */
+#define  Bprint       if(mach64_debug & 0x01000000) printk
+/* Debug */
+#define  Dprint       if(mach64_debug & 0x00800000) printk
+
+/* Message */
+#define  Mprint       if(mach64_debug & 0x00004000) printk
+/* Info */
+#define  Iprint       if(mach64_debug & 0x00008000) printk
+/* Warn */
+#define  Wprint       if(mach64_debug & 0x00010000) printk
+/* Error */
+#define  Eprint       if(mach64_debug & 0x00020000) printk
+/* Fatal */
+#define  Fprint       if(mach64_debug & 0x00040000) printk
+/* Panic */
+#define  Pprint       if(mach64_debug & 0x00040000) printk
+
+#else
+
+#define  FuncId
+#define  FuncDone
+#define  CFuncId
+#define  CFuncDone
+
+#endif  /* BHA_DEBUG*/
+
+/*============================================================================*/
+/* Types */
+
+/*============================================================================*/
+/* Extern Functions*/
+
+
+
+/*============================================================================*/
+/* Intern Functions*/
+
+    /*
+     *  Prototypes
+     */
+
+int fbcon_init_mach64(void);
+
+static int open_mach64(struct display *p);
+static void release_mach64(void);
+static void bmove_mach64(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static void clear_mach64(struct vc_data *conp, struct display *p, int sy,
+		       int sx, int height, int width);
+static void putc_mach64(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_mach64(struct vc_data *conp, struct display *p,
+		       const char *s, int count, int yy, int xx);
+static void rev_char_mach64(struct display *p, int xx, int yy);
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Intern Variables */
+
+/*--------------------------------------------------------------------------*/
+/* BSS */
+
+/*--------------------------------------------------------------------------*/
+/* Data */
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch    dispsw_mach64 = 
+{
+  open_mach64,
+  release_mach64,
+  bmove_mach64,
+  clear_mach64,
+  putc_mach64,
+  putcs_mach64,
+  rev_char_mach64
+};
+
+
+    /*
+     *  8 bpp packed pixels => 4 pixel / 32 Bit => 1/2 FontByte 
+     */
+
+static u_int nibbletab_mach64[16] = 
+{
+  0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+  0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+  0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+  0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
+};
+
+static  unsigned int    mach64_debug = 0x018FCF00;
+
+/*============================================================================*/
+/*============================================================================*/
+/* Functions */
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+open_mach64(struct display * p)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("open_mach64($%08lX) : ", p);
+  if(p->type != FB_TYPE_PACKED_PIXELS || p->var.accel != FB_ACCEL_MACH64)
+  {
+    FuncDone(" Fail! \n");
+    return -EINVAL;  /* This driver can only do Mach64 boards! */
+  }
+  /*endif*/
+
+  p->next_line = (p->var.xres_virtual * p->var.bits_per_pixel) >> 3;
+  p->next_plane = 0;
+  MOD_INC_USE_COUNT;
+
+  FuncDone(" Match! \n");
+  return 0;
+}
+/*endproc open_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+release_mach64(void)
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("release_mach64() \n");
+    MOD_DEC_USE_COUNT;
+}
+/*endproc release_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+bmove_mach64(struct display * p,
+  int sy,
+  int sx,
+  int dy,
+  int dx,
+  int height,
+  int width)
+
+/*--------------------------------------------------------------------------*/
+{
+  u_char * src, * dst;
+  int                           bytes = p->next_line,
+                                linesize = bytes * p->fontheight,
+                                rows;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("bmove_mach64($%04X, $%04X, $%04X, $%04X) \n",
+    sy, sx, dy, dx, height, width);
+
+#ifdef _USE_HW_ACCEL_BLT_
+
+  Mach64_BitBLT(
+    (sx << 3),
+    (sy * p->fontheight),
+    (dx << 3),
+    (dy * p->fontheight),
+    (width << 3),
+    (height * p->fontheight),
+    3);                 /*  MIX_SRC); see XGCValues GCFunction = GXCopy */
+
+#else
+
+  if(sx == 0 && dx == 0 && width * 8 == bytes)   /* full stride */
+
+    mymemmove(p->screen_base + dy * linesize,
+      p->screen_base + sy * linesize,
+      height * linesize);
+
+  else if (dy < sy || (dy == sy && dx < sx))
+  {
+    src = p->screen_base + sy * linesize + sx * 8;
+    dst = p->screen_base + dy * linesize + dx * 8;
+    for (rows = height * p->fontheight ; rows-- ;)
+    {
+      mymemmove(dst, src, (width << 3));
+      src += bytes;
+      dst += bytes;
+    }
+    /*next rows*/
+  }
+  else
+  {
+    src = p->screen_base + (sy+height) * linesize + sx * 8 - bytes;
+    dst = p->screen_base + (dy+height) * linesize + dx * 8 - bytes;
+    for(rows = height * p->fontheight ; rows-- ;)
+    {
+      mymemmove(dst, src, (width << 3));
+      src -= bytes;
+      dst -= bytes;
+    }
+    /*next rows*/
+  }
+  /*endif*/
+
+#endif  /* _USE_HW_ACCEL_BLT_ */
+
+  return;
+}
+/*endproc bmove_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+clear_mach64(struct vc_data * conp,
+  struct display * p,
+  int sy,                       /* in Characters von oben */
+  int sx,
+  int height,                   /* in Characters */
+  int width)                    /* in Characters */
+
+/*--------------------------------------------------------------------------*/
+{
+  register u_int *              dest;
+  register u_int                bgx;
+  register int                  i;
+
+  u_char *                      dest0;
+
+  int                           bytes_p_line = p->next_line,
+                                lines_w = height * p->fontheight,
+                                rows;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("clear_mach64($%04X, $%04X, $%04X, $%04X) \n",
+    sy, sx, height, width);
+
+  bgx = attr_bgcol_ec(p, conp);
+  bgx |= (bgx << 8);
+  bgx |= (bgx << 16);
+
+#ifdef _USE_HW_ACCEL_FILL_
+
+  Mach64_RectFill(
+    (sx << 3),
+    (sy * p->fontheight),
+    (width << 3),
+    (height * p->fontheight),
+    3,                            /* MIX_SRC, see XGCValues GCFunction  */
+    bgx);
+
+#else
+
+  dest0 = p->screen_base + sy * p->fontheight * bytes_p_line + sx * 8;
+  if(sx == 0 && (width << 3) == bytes_p_line)     /* full stride */
+  {
+    lines_w *= width;
+    dest = (u_int*)dest0;
+    for(i = 0 ; i < lines_w ; i++)
+    {
+      *dest++ = bgx;          /* clears 4 pixels == half Char */
+      *dest++ = bgx;
+    }
+  }
+  else                                     /* only part of the width */
+  {
+    for(rows = lines_w; rows-- ; dest0 += bytes_p_line)
+    {
+      dest = (u_int*)dest0;
+      for(i = 0 ; i < width ; i++)
+      {
+        *dest++ = bgx;        /* clears 4 pixels */
+        *dest++ = bgx;
+      }
+      /*next i*/
+    }
+  }
+  /*endif*/
+
+#endif  /* _USE_HW_ACCEL_FILL_ */
+
+  return;
+}
+/*endproc clear_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+putc_mach64(struct vc_data * conp,
+  struct display * p,
+  int c,                   /* ASCII */
+  int yy,                  /* Text column */
+  int xx)                  /* Text row */
+
+/*--------------------------------------------------------------------------*/
+{
+  register u_char *             dest_p;
+  register u_char *             cdat_p;
+  register u_char               cdat;
+  register u_int                eorx, fgx, bgx;
+  int                           bytes = p->next_line; /*must be multiple of 4*/
+  int                           rows;
+
+  /*--------------------------------------------------------------------------*/
+  c &= 0xFF;
+
+  dest_p = p->screen_base + yy * p->fontheight * bytes + (xx << 3);
+  cdat_p = p->fontdata + c * p->fontheight;
+
+  fgx=attr_fgcol(p, conp);
+  bgx=attr_bgcol(p,conp);
+
+  fgx |= (fgx << 8);
+  fgx |= (fgx << 16);
+  bgx |= (bgx << 8);
+  bgx |= (bgx << 16);
+  eorx = fgx ^ bgx;
+
+  /* Mach64_WaitBlit(); */    /* We will have to sync with HW Blit */
+  for(rows = p->fontheight ; rows-- ; dest_p += bytes) /* byte* add = natural */
+  {
+    cdat = *cdat_p++;
+    *((u_int*)dest_p) = (nibbletab_mach64[cdat >> 4] & eorx) ^ bgx;
+    ((u_int *)dest_p)[1] = (nibbletab_mach64[cdat & 0xF] & eorx) ^ bgx;
+  }
+  /*next row*/
+
+  return;
+}
+/*endproc putc_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+putcs_mach64(struct vc_data * conp,
+  struct display * p,
+  const char * s,
+  int count,
+  int yy,
+  int xx)
+
+/*--------------------------------------------------------------------------*/
+{
+  register u_char *             dest_p;
+  register u_char *             cdat_p;
+  register u_char               cdat;
+  register u_int                eorx, fgx, bgx;
+  u_char *                      dest0;
+  int                           bytes = p->next_line; /*must be multiple of 4*/
+  int                           rows;
+  u_char                        c;
+
+  /*--------------------------------------------------------------------------*/
+
+  dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+  fgx=attr_fgcol(p,conp);
+  bgx=attr_bgcol(p,conp);
+
+  fgx |= (fgx << 8);
+  fgx |= (fgx << 16);
+  bgx |= (bgx << 8);
+  bgx |= (bgx << 16);
+  eorx = fgx ^ bgx;
+
+  /* Mach64_WaitBlit(); */    /* We will have to sync with HW Blit */
+  while(count--)        /* character count 8 x h */
+  {
+    c = *s++;
+    cdat_p = p->fontdata + c * p->fontheight;
+
+    for(rows = p->fontheight, dest_p = dest0; rows-- ; dest_p += bytes)
+    {
+      cdat = *cdat_p++;
+      *((u_int*)dest_p) = (nibbletab_mach64[cdat >> 4] & eorx) ^ bgx;
+      ((u_int *)dest_p)[1] = (nibbletab_mach64[cdat & 0xF] & eorx) ^ bgx;
+    }
+    /*next rows*/
+    dest0 += 8;
+  }
+  /*endwhile*/
+
+  return;
+}
+/*endproc putcs_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+rev_char_mach64(struct display *p, int xx, int yy)
+
+/*--------------------------------------------------------------------------*/
+{
+    u_char *dest;
+    int bytes=p->next_line, rows;
+
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	((u_long *)dest)[0] ^= 0x0f0f0f0f;
+	((u_long *)dest)[1] ^= 0x0f0f0f0f;
+    }
+}
+/*endproc rev_char_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef MODULE
+int 
+init_module(void)
+#else
+int 
+fbcon_init_mach64(void)
+#endif
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("fbcon_init_mach64() \n");
+  /* We want to be added to the list of accelerated drivers */
+  return(fbcon_register_driver(&dispsw_mach64, 1));
+}
+/*endproc fbcon_init_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef MODULE
+void 
+cleanup_module(void)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("cleanup_module() \n");
+    fbcon_unregister_driver(&dispsw_mach64);
+}
+/*endproc cleanup_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+#endif /* MODULE */
+/*============================================================================*/
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+  static char
+  rcs_id_c[] =
+    "@(#) Linux-m68k: 1997 08 16 12:39:32 BHA: fbcon-mach64.c ";
+
+/*============================================================================*/
--- m68k-2.1.57/drivers/video/fbcon.c.orig	Mon Sep 15 22:50:48 1997
+++ m68k-2.1.57/drivers/video/fbcon.c	Tue Sep 30 20:23:23 1997
@@ -42,10 +42,10 @@
  *
  *	  o cyber	 CyberVision64 packed pixels (accelerated)
  *	  o retz3	 Retina Z3 packed pixels (accelerated)
+ *	  o mach64	 ATI Mach 64 packed pixels (accelerated)
  *
  *  To do:
  *
- *    - Get rid of the m68k specific inline assembler
  *    - Implement 16 plane mode (iplan2p16)
  *    - Add support for 24/32 bit packed pixels (cfb{24,32})
  *    - Hardware cursor
@@ -71,6 +71,7 @@
 #include <linux/fb.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
+#include <linux/init.h>
 #ifdef CONFIG_KERNELD
 #include <linux/kerneld.h>
 #endif
@@ -88,6 +89,7 @@
 #ifdef CONFIG_ATARI
 #include <asm/atariints.h>
 #endif
+#include <asm/linux_logo.h>
 
 #include "fbcon.h"
 
@@ -154,7 +156,6 @@
 static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
 static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data);
 static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
-
 int fbcon_register_driver(struct display_switch *dispsw, int is_accel);
 int fbcon_unregister_driver(struct display_switch *dispsw);
 
@@ -182,6 +183,7 @@
 static void request_driver(struct display *disp, int is_accel);
 #endif
 static struct display_switch *fbcon_get_driver(struct display *disp);
+static int fbcon_show_logo(void);
 
 
 /*
@@ -220,11 +222,14 @@
 #ifdef CONFIG_FBCON_RETINAZ3
 extern int fbcon_init_retz3(void);
 #endif
+#ifdef CONFIG_FBCON_MACH64
+extern int fbcon_init_mach64(void);
+#endif
 
 extern int num_registered_fb;
 
-static unsigned long fbcon_startup(unsigned long kmem_start,
-				   const char **display_desc)
+__initfunc(static unsigned long fbcon_startup(unsigned long kmem_start,
+					      const char **display_desc))
 {
     int irqres = 1;
 
@@ -273,6 +278,9 @@
 #ifdef CONFIG_FBCON_CYBER
     fbcon_init_cyber();
 #endif
+#ifdef CONFIG_FBCON_MACH64
+    fbcon_init_mach64();
+#endif
 
     *display_desc = "frame buffer device";
 
@@ -294,6 +302,9 @@
     if (irqres)
 	panic("fbcon_startup: Couldn't add vblank interrupt");
 
+    if (!console_show_logo)
+	console_show_logo = fbcon_show_logo;
+
     return kmem_start;
 }
 
@@ -987,6 +998,199 @@
 	palette_cmap.len = 16;
     return(p->fb_info->setcmap(&palette_cmap, unit));
 }
+
+
+
+#define LOGO_H			80
+#define LOGO_W			80
+#define LOGO_LINE	(LOGO_W/8)
+
+__initfunc(static int fbcon_show_logo( void ))
+{
+    struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
+    int depth = p->var.bits_per_pixel;
+    int line = p->next_line;
+    unsigned char *fb = p->screen_base;
+    unsigned char *logo;
+    unsigned char *dst, *src;
+    int i, j, n, x1, y1;
+    int logo_depth, done = 0;
+	
+    /* Set colors if visual is PSEUDOCOLOR and we have enough colors */
+    if (p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 4) {
+	int first_col = depth >= 8 ? 32 : depth > 4 ? 16 : 0;
+	int num_cols = depth >= 8 ? LINUX_LOGO_COLORS : 16;
+	unsigned char *red, *green, *blue;
+	int old_cmap_len;
+	
+	if (depth >= 8) {
+	    red   = linux_logo_red;
+	    green = linux_logo_green;
+	    blue  = linux_logo_blue;
+	}
+	else {
+	    red   = linux_logo16_red;
+	    green = linux_logo16_green;
+	    blue  = linux_logo16_blue;
+	}
+
+	/* dirty trick to avoid setcmap calling kmalloc which isn't
+	 * initialized yet... */
+	old_cmap_len = fb_display[fg_console].cmap.len;
+	fb_display[fg_console].cmap.len = 1 << depth;
+	
+	for( i = 0; i < num_cols; i += n ) {
+	    n = num_cols - i;
+	    if (n > 16)
+		/* palette_cmap provides space for only 16 colors at once */
+		n = 16;
+	    palette_cmap.start = first_col + i;
+	    palette_cmap.len   = n;
+	    for( j = 0; j < n; ++j ) {
+		palette_cmap.red[j]   = (red[i+j] << 8) | red[i+j];
+		palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];
+		palette_cmap.blue[j]  = (blue[i+j] << 8) | blue[i+j];
+	    }
+	    p->fb_info->setcmap( &palette_cmap, fg_console );
+	}
+	fb_display[fg_console].cmap.len = old_cmap_len;
+    }
+
+    if (depth >= 8) {
+	logo = linux_logo;
+	logo_depth = 8;
+    }
+    else if (depth >= 4) {
+	logo = linux_logo16;
+	logo_depth = 4;
+    }
+    else {
+	logo = linux_logo_bw;
+	logo_depth = 1;
+    }
+
+#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CYBER) || \
+    defined(CONFIG_FBCON_RETINAZ3)
+    if ((depth % 8 == 0) && (p->visual == FB_VISUAL_TRUECOLOR ||
+			     p->visual == FB_VISUAL_DIRECTCOLOR)) {
+	/* Modes without color mapping, needs special data transformation... */
+	unsigned long val;		/* max. depth 32! */
+	int bdepth = depth/8;
+	unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
+	unsigned char redmask, greenmask, bluemask;
+	int redshift, greenshift, blueshift;
+		
+	/* Bug: Doesn't obey msb_right ... (who needs that?) */
+	redmask   = mask[p->var.red.length   < 8 ? p->var.red.length   : 8];
+	greenmask = mask[p->var.green.length < 8 ? p->var.green.length : 8];
+	bluemask  = mask[p->var.blue.length  < 8 ? p->var.blue.length  : 8];
+	redshift   = p->var.red.offset   - (8-p->var.red.length);
+	greenshift = p->var.green.offset - (8-p->var.green.length);
+	blueshift  = p->var.blue.offset  - (8-p->var.blue.length);
+
+	src = logo;
+	for( y1 = 0; y1 < LOGO_H; y1++ ) {
+	    dst = fb + y1*line;
+	    for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
+		val = ((linux_logo_red[*src]   & redmask)   << redshift) |
+		      ((linux_logo_green[*src] & greenmask) << greenshift) |
+		      ((linux_logo_blue[*src]  & bluemask)  << blueshift);
+		for( i = 0; i < bdepth; ++i )
+		    *dst++ = val >> (i*8);
+	    }
+	}
+		
+	done = 1;
+    }
+#endif
+#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CYBER) || \
+    defined(CONFIG_FBCON_RETINAZ3)
+    if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {
+	/* depth 8 or more, packed, with color registers */
+		
+	src = logo;
+	for( y1 = 0; y1 < LOGO_H; y1++ ) {
+	    dst = fb + y1*line;
+	    for( x1 = 0; x1 < LOGO_W; x1++ ) {
+		*dst++ = *src++;
+	    }
+	}
+
+	done = 1;
+    }
+#endif
+#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
+    defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
+    defined(CONFIG_FBCON_IPLAN2P8)
+    if (depth >= 2 && (p->type == FB_TYPE_PLANES ||
+		       p->type == FB_TYPE_INTERLEAVED_PLANES)) {
+	/* planes (normal or interleaved), with color registers */
+	int bit;
+	unsigned char val, mask;
+	int plane = p->next_plane;
+
+	/* for support of Atari interleaved planes */
+#define MAP_X(x)	(plane > line ? x : (x & ~1)*depth + (x & 1))
+	/* extract a bit from the source image */
+#define	BIT(p,pix,bit)	(p[pix*logo_depth/8] & \
+			 (1 << ((8-((pix*logo_depth)&7)-logo_depth) + bit)))
+		
+	src = logo;
+	for( y1 = 0; y1 < LOGO_H; y1++ ) {
+	    for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) {
+		dst = fb + y1*line + MAP_X(x1);
+		for( bit = 0; bit < logo_depth; bit++ ) {
+		    val = 0;
+		    for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {
+			if (BIT( src, i, bit ))
+			    val |= mask;
+		    }
+		    *dst = val;
+		    dst += plane;
+		}
+	    }
+	}
+	
+	/* fill remaining planes
+	 * special case for logo_depth == 4: we used color registers 16..31,
+	 * so fill plane 4 with 1 bits instead of 0 */
+	if (depth > logo_depth) {
+	    for( y1 = 0; y1 < LOGO_H; y1++ ) {
+		for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
+		    dst = fb + y1*line + MAP_X(x1) + logo_depth*plane;
+		    for( i = logo_depth; i < depth; i++, dst += plane )
+			*dst = (i == logo_depth && logo_depth == 4)
+			       ? 0xff : 0x00;
+		}
+	    }
+	}
+	
+	done = 1;
+    }
+#endif
+#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_AFB) || \
+    defined(CONFIG_FBCON_ILBM)
+    if (depth == 1) {
+	/* monochrome */
+	unsigned char inverse = p->inverse ? 0x00 : 0xff;
+
+	/* can't use simply memcpy because need to apply inverse */
+	for( y1 = 0; y1 < LOGO_H; y1++ ) {
+	    src = logo + y1*LOGO_LINE;
+	    dst = fb + y1*line;
+	    for( x1 = 0; x1 < LOGO_LINE; ++x1 )
+		*dst++ = *src++ ^ inverse;
+	}
+
+	done = 1;
+    }
+#endif
+    /* Modes not yet supported: packed pixels with depth != 8 (does such a
+     * thing exist in reality?) */
+
+    return( done ? LOGO_H/p->fontheight + 1 : 0 );
+}
+
 
 
 /*
--- m68k-2.1.57/drivers/video/fonts.c.orig	Mon Sep 15 22:50:48 1997
+++ m68k-2.1.57/drivers/video/fonts.c	Tue Sep 30 20:23:23 1997
@@ -1,6 +1,5 @@
-
 /*
- * arch/m68k/console/fonts.c -- `Soft' font definitions
+ * linux/drivers/video/fonts.c -- `Soft' font definitions
  *
  *    Created 1995 by Geert Uytterhoeven
  *
--- m68k-2.1.57/drivers/video/mach64fb.h.orig	Tue Sep 30 20:25:47 1997
+++ m68k-2.1.57/drivers/video/mach64fb.h	Tue Sep 30 20:36:26 1997
@@ -0,0 +1,46 @@
+
+
+#ifndef _MACH64FB_H_LOADED_
+#define _MACH64FB_H_LOADED_
+
+
+   /*
+    *    Accelerated Functions used by the low level console driver
+    */
+
+void Mach64_WaitQueue(u_short fifo);
+
+void Mach64_WaitBlit(void);
+
+void 
+Mach64_BitBLT(
+  int srcx,
+  int srcy,
+  int destx,
+  int desty,
+  u_int width,
+  u_int height,
+  u_short mode);
+
+
+void 
+Mach64_RectFill(
+  int     xpos,
+  int     ypos,
+  u_int   width,
+  u_int   height,
+  u_int   mode,
+  u_int   fcolor);
+
+void Mach64_MoveCursor(u_short xpos, u_short ypos);
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define MACH64FB_H_ID \
+  "@(#) Linux-m68k: 1997 07 27 00:08:18 BHA: mach64fb.h "
+
+/*============================================================================*/
+
+#endif /* _MACH64FB_H_LOADED_ */
--- m68k-2.1.57/drivers/video/retz3fb.c.orig	Mon Sep 29 20:19:30 1997
+++ m68k-2.1.57/drivers/video/retz3fb.c	Tue Sep 30 20:23:26 1997
@@ -37,7 +37,6 @@
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
-#include <asm/linux_logo.h>
 
 #include "retz3fb.h"
 
@@ -1479,36 +1478,6 @@
 }
 
 
-#ifndef MODULE
-__initfunc(static int retz3_show_logo(void))
-{
-	struct retz3_fb_par *par = &current_par;
-	short i;
-	unsigned int next_line;
-	unsigned char *p = (unsigned char *)z3_fbmem;
-
-	next_line = (par->xres_vir * par->bpp / 8);
-
-	if (par->bpp == 8) {
-		for (i = 0; i < LINUX_LOGO_COLORS; i++) {
-			retz3_setcolreg(32 + i,
-					linux_logo_red[i],
-					linux_logo_green[i],
-					linux_logo_blue[i],
-					0);
-		}
-#if 0
-		(*fbinfo [0].loadcmap)(&fbinfo [0], 0, linux_logo_colors + 32);
-#endif
-		for (i = 0; i < 80; i++, p += next_line){
-			memcpy (p, linux_logo + 80 * i, 80);
-		}
-	}
-
-	return(80/fb_display[0].fontheight + 1);
-}
-#endif
-
 /*
  *    Initialization
  */
@@ -1581,10 +1550,6 @@
 	/* TODO: This driver cannot be unloaded yet */
 	MOD_INC_USE_COUNT;
 
-#ifndef MODULE
-	if (!console_show_logo)
-		console_show_logo = retz3_show_logo;
-#endif
 	return mem_start;
 }
 
--- m68k-2.1.57/drivers/video/mach64regs.h.orig	Tue Sep 30 20:25:47 1997
+++ m68k-2.1.57/drivers/video/mach64regs.h	Tue Sep 30 20:26:39 1997
@@ -0,0 +1,662 @@
+
+#ifndef MACH64REGS_H
+#define MACH64REGS_H
+
+/*
+#include "compiler.h"
+*/
+
+/* NON-GUI IO MAPPED Registers */
+
+extern unsigned ioCONFIG_CHIP_ID;
+extern unsigned ioCONFIG_CNTL;
+extern unsigned ioSCRATCH_REG0;
+extern unsigned ioSCRATCH_REG1;
+extern unsigned ioCONFIG_STAT0;
+extern unsigned ioMEM_CNTL;
+extern unsigned ioDAC_REGS;
+extern unsigned ioDAC_CNTL;
+extern unsigned ioGEN_TEST_CNTL;
+extern unsigned ioCLOCK_CNTL;
+extern unsigned ioCRTC_GEN_CNTL;
+
+/* NON-GUI sparse IO register offsets */
+
+#define sioCONFIG_CHIP_ID	0x1B
+#define sioCONFIG_CNTL		0x1A
+#define sioSCRATCH_REG0		0x10
+#define sioSCRATCH_REG1		0x11
+#define sioCONFIG_STAT0		0x1C
+#define sioMEM_CNTL		0x14
+#define sioDAC_REGS		0x17
+#define sioDAC_CNTL		0x18
+#define sioGEN_TEST_CNTL 	0x19
+#define sioCLOCK_CNTL	 	0x12
+#define sioCRTC_GEN_CNTL 	0x07
+
+/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
+
+#define CRTC_H_TOTAL_DISP       0x0000  /* Dword offset 00 */
+#define CRTC_H_SYNC_STRT_WID    0x0004  /* Dword offset 01 */
+#define CRTC_V_TOTAL_DISP       0x0008  /* Dword offset 02 */
+#define CRTC_V_SYNC_STRT_WID    0x000C  /* Dword offset 03 */
+#define CRTC_VLINE_CRNT_VLINE   0x0010  /* Dword offset 04 */
+#define CRTC_OFF_PITCH          0x0014  /* Dword offset 05 */
+#define CRTC_INT_CNTL           0x0018  /* Dword offset 06 */
+#define CRTC_GEN_CNTL           0x001C  /* Dword offset 07 */
+
+#define OVR_CLR                 0x0040  /* Dword offset 10 */
+#define OVR_WID_LEFT_RIGHT      0x0044  /* Dword offset 11 */
+#define OVR_WID_TOP_BOTTOM      0x0048  /* Dword offset 12 */
+
+#define CUR_CLR0                0x0060  /* Dword offset 18 */
+#define CUR_CLR1                0x0064  /* Dword offset 19 */
+#define CUR_OFFSET              0x0068  /* Dword offset 1A */
+#define CUR_HORZ_VERT_POSN      0x006C  /* Dword offset 1B */
+#define CUR_HORZ_VERT_OFF       0x0070  /* Dword offset 1C */
+
+#define SCRATCH_REG0            0x0080  /* Dword offset 20 */
+#define SCRATCH_REG1            0x0084  /* Dword offset 21 */
+
+#define CLOCK_CNTL              0x0090  /* Dword offset 24 */
+
+#define BUS_CNTL                0x00A0  /* Dword offset 28 */
+
+#define MEM_CNTL                0x00B0  /* Dword offset 2C */
+
+#define MEM_VGA_WP_SEL          0x00B4  /* Dword offset 2D */
+#define MEM_VGA_RP_SEL          0x00B8  /* Dword offset 2E */
+
+#define DAC_REGS                0x00C0  /* Dword offset 30 */
+#define DAC_W_INDEX             0x00C0  /* Dword offset 30 */
+#define DAC_DATA                0x00C1  /* Dword offset 30 */
+#define DAC_MASK                0x00C2  /* Dword offset 30 */
+#define DAC_R_INDEX             0x00C3  /* Dword offset 30 */
+#define DAC_CNTL                0x00C4  /* Dword offset 31 */
+
+#define GEN_TEST_CNTL           0x00D0  /* Dword offset 34 */
+
+#define CONFIG_CNTL		0x00DC	/* Dword offset 37 (CT, ET, VT) */
+#define CONFIG_CHIP_ID          0x00E0  /* Dword offset 38 */
+#define CONFIG_STAT0            0x00E4  /* Dword offset 39 */
+#define CONFIG_STAT1            0x00E8  /* Dword offset 3A */
+
+
+/* GUI MEMORY MAPPED Registers */
+
+#define DST_OFF_PITCH           0x0100  /* Dword offset 40 */
+#define DST_X                   0x0104  /* Dword offset 41 */
+#define DST_Y                   0x0108  /* Dword offset 42 */
+#define DST_Y_X                 0x010C  /* Dword offset 43 */
+#define DST_WIDTH               0x0110  /* Dword offset 44 */
+#define DST_HEIGHT              0x0114  /* Dword offset 45 */
+#define DST_HEIGHT_WIDTH        0x0118  /* Dword offset 46 */
+#define DST_X_WIDTH             0x011C  /* Dword offset 47 */
+#define DST_BRES_LNTH           0x0120  /* Dword offset 48 */
+#define DST_BRES_ERR            0x0124  /* Dword offset 49 */
+#define DST_BRES_INC            0x0128  /* Dword offset 4A */
+#define DST_BRES_DEC            0x012C  /* Dword offset 4B */
+#define DST_CNTL                0x0130  /* Dword offset 4C */
+
+#define SRC_OFF_PITCH           0x0180  /* Dword offset 60 */
+#define SRC_X                   0x0184  /* Dword offset 61 */
+#define SRC_Y                   0x0188  /* Dword offset 62 */
+#define SRC_Y_X                 0x018C  /* Dword offset 63 */
+#define SRC_WIDTH1              0x0190  /* Dword offset 64 */
+#define SRC_HEIGHT1             0x0194  /* Dword offset 65 */
+#define SRC_HEIGHT1_WIDTH1      0x0198  /* Dword offset 66 */
+#define SRC_X_START             0x019C  /* Dword offset 67 */
+#define SRC_Y_START             0x01A0  /* Dword offset 68 */
+#define SRC_Y_X_START           0x01A4  /* Dword offset 69 */
+#define SRC_WIDTH2              0x01A8  /* Dword offset 6A */
+#define SRC_HEIGHT2             0x01AC  /* Dword offset 6B */
+#define SRC_HEIGHT2_WIDTH2      0x01B0  /* Dword offset 6C */
+#define SRC_CNTL                0x01B4  /* Dword offset 6D */
+
+#define HOST_DATA0              0x0200  /* Dword offset 80 */
+#define HOST_DATA1              0x0204  /* Dword offset 81 */
+#define HOST_DATA2              0x0208  /* Dword offset 82 */
+#define HOST_DATA3              0x020C  /* Dword offset 83 */
+#define HOST_DATA4              0x0210  /* Dword offset 84 */
+#define HOST_DATA5              0x0214  /* Dword offset 85 */
+#define HOST_DATA6              0x0218  /* Dword offset 86 */
+#define HOST_DATA7              0x021C  /* Dword offset 87 */
+#define HOST_DATA8              0x0220  /* Dword offset 88 */
+#define HOST_DATA9              0x0224  /* Dword offset 89 */
+#define HOST_DATAA              0x0228  /* Dword offset 8A */
+#define HOST_DATAB              0x022C  /* Dword offset 8B */
+#define HOST_DATAC              0x0230  /* Dword offset 8C */
+#define HOST_DATAD              0x0234  /* Dword offset 8D */
+#define HOST_DATAE              0x0238  /* Dword offset 8E */
+#define HOST_DATAF              0x023C  /* Dword offset 8F */
+#define HOST_CNTL               0x0240  /* Dword offset 90 */
+
+#define PAT_REG0                0x0280  /* Dword offset A0 */
+#define PAT_REG1                0x0284  /* Dword offset A1 */
+#define PAT_CNTL                0x0288  /* Dword offset A2 */
+
+#define SC_LEFT                 0x02A0  /* Dword offset A8 */
+#define SC_RIGHT                0x02A4  /* Dword offset A9 */
+#define SC_LEFT_RIGHT           0x02A8  /* Dword offset AA */
+#define SC_TOP                  0x02AC  /* Dword offset AB */
+#define SC_BOTTOM               0x02B0  /* Dword offset AC */
+#define SC_TOP_BOTTOM           0x02B4  /* Dword offset AD */
+
+#define DP_BKGD_CLR             0x02C0  /* Dword offset B0 */
+#define DP_FRGD_CLR             0x02C4  /* Dword offset B1 */
+#define DP_WRITE_MASK           0x02C8  /* Dword offset B2 */
+#define DP_CHAIN_MASK           0x02CC  /* Dword offset B3 */
+#define DP_PIX_WIDTH            0x02D0  /* Dword offset B4 */
+#define DP_MIX                  0x02D4  /* Dword offset B5 */
+#define DP_SRC                  0x02D8  /* Dword offset B6 */
+
+#define CLR_CMP_CLR             0x0300  /* Dword offset C0 */
+#define CLR_CMP_MASK            0x0304  /* Dword offset C1 */
+#define CLR_CMP_CNTL            0x0308  /* Dword offset C2 */
+
+#define FIFO_STAT               0x0310  /* Dword offset C4 */
+
+#define CONTEXT_MASK            0x0320  /* Dword offset C8 */
+#define CONTEXT_LOAD_CNTL       0x032C  /* Dword offset CB */
+
+#define GUI_TRAJ_CNTL           0x0330  /* Dword offset CC */
+#define GUI_STAT                0x0338  /* Dword offset CE */
+
+
+/* CRTC control values */
+
+#define CRTC_H_SYNC_NEG		0x00200000
+#define CRTC_V_SYNC_NEG		0x00200000
+
+#define CRTC_DBL_SCAN_EN	0x00000001
+#define CRTC_INTERLACE_EN	0x00000002
+#define CRTC_HSYNC_DIS		0x00000004
+#define CRTC_VSYNC_DIS		0x00000008
+#define CRTC_CSYNC_EN		0x00000010
+#define CRTC_PIX_BY_2_EN	0x00000020
+
+#define CRTC_PIX_WIDTH		0x00000700
+#define CRTC_PIX_WIDTH_4BPP	0x00000100
+#define CRTC_PIX_WIDTH_8BPP	0x00000200
+#define CRTC_PIX_WIDTH_15BPP	0x00000300
+#define CRTC_PIX_WIDTH_16BPP	0x00000400
+#define CRTC_PIX_WIDTH_24BPP	0x00000500
+#define CRTC_PIX_WIDTH_32BPP	0x00000600
+
+#define CRTC_BYTE_PIX_ORDER	0x00000800
+#define CRTC_PIX_ORDER_MSN_LSN	0x00000000
+#define CRTC_PIX_ORDER_LSN_MSN	0x00000800
+
+#define CRTC_FIFO_LWM		0x000f0000
+#define CRTC_EXT_DISP_EN	0x01000000
+#define CRTC_EXT_EN		0x02000000
+
+#define CRTC_CRNT_VLINE		0x07f00000
+#define CRTC_VBLANK		0x00000001
+
+/* DAC control values */
+
+#define DAC_EXT_SEL_RS2		0x01
+#define DAC_EXT_SEL_RS3		0x02
+#define DAC_8BIT_EN		0x00000100
+#define DAC_PIX_DLY_MASK	0x00000600
+#define DAC_PIX_DLY_0NS		0x00000000
+#define DAC_PIX_DLY_2NS		0x00000200
+#define DAC_PIX_DLY_4NS		0x00000400
+#define DAC_BLANK_ADJ_MASK	0x00001800
+#define DAC_BLANK_ADJ_0		0x00000000
+#define DAC_BLANK_ADJ_1		0x00000800
+#define DAC_BLANK_ADJ_2		0x00001000
+
+
+/* Mix control values */
+
+#define MIX_NOT_DST                     0x0000
+#define MIX_0                           0x0001
+#define MIX_1                           0x0002
+#define MIX_DST                         0x0003
+#define MIX_NOT_SRC                     0x0004
+#define MIX_XOR                         0x0005
+#define MIX_XNOR                        0x0006
+#define MIX_SRC                         0x0007
+#define MIX_NAND                        0x0008
+#define MIX_NOT_SRC_OR_DST              0x0009
+#define MIX_SRC_OR_NOT_DST              0x000a
+#define MIX_OR                          0x000b
+#define MIX_AND                         0x000c
+#define MIX_SRC_AND_NOT_DST             0x000d
+#define MIX_NOT_SRC_AND_DST             0x000e
+#define MIX_NOR                         0x000f
+
+/* Maximum engine dimensions */
+#define ENGINE_MIN_X        0
+#define ENGINE_MIN_Y        0
+#define ENGINE_MAX_X        4095
+#define ENGINE_MAX_Y        16383
+
+/* Mach64 engine bit constants - these are typically ORed together */
+
+/* BUS_CNTL register constants */
+#define BUS_FIFO_ERR_ACK        0x00200000
+#define BUS_HOST_ERR_ACK        0x00800000
+
+/* GEN_TEST_CNTL register constants */
+#define GEN_OVR_OUTPUT_EN       0x20
+#define HWCURSOR_ENABLE         0x80
+#define GUI_ENGINE_ENABLE       0x100
+#define BLOCK_WRITE_ENABLE      0x200
+
+/* CLOCK_CNTL register constants */
+#define CLOCK_SEL		0x0f
+#define CLOCK_DIV		0x30
+#define CLOCK_DIV1		0x00
+#define CLOCK_DIV2		0x10
+#define CLOCK_DIV4		0x20
+#define CLOCK_STROBE		0x40
+#define PLL_WR_EN		0x02
+
+/* PLL registers */
+#define PLL_MACRO_CNTL		0x01
+#define PLL_REF_DIV		0x02
+#define PLL_GEN_CNTL		0x03
+#define MCLK_FB_DIV		0x04
+#define PLL_VCLK_CNTL		0x05
+#define VCLK_POST_DIV		0x06
+#define VCLK0_FB_DIV		0x07
+#define VCLK1_FB_DIV		0x08
+#define VCLK2_FB_DIV		0x09
+#define VCLK3_FB_DIV		0x0A
+#define PLL_XCLK_CNTL		0x0B
+#define PLL_TEST_CTRL		0x0E
+#define PLL_TEST_COUNT		0x0F
+
+/* Fields in PLL registers */
+#define PLL_PC_GAIN		0x07
+#define PLL_VC_GAIN		0x18
+#define PLL_DUTY_CYC		0xE0
+#define PLL_OVERRIDE		0x01
+#define PLL_MCLK_RST		0x02
+#define OSC_EN			0x04
+#define EXT_CLK_EN		0x08
+#define MCLK_SRC_SEL		0x70
+#define EXT_CLK_CNTL		0x80
+#define VCLK_SRC_SEL		0x03
+#define PLL_VCLK_RST		0x04
+#define VCLK_INVERT		0x08
+#define VCLK0_POST		0x03
+#define VCLK1_POST		0x0C
+#define VCLK2_POST		0x30
+#define VCLK3_POST		0xC0
+
+/* CONFIG_CNTL register constants */
+#define APERTURE_4M_ENABLE      1
+#define APERTURE_8M_ENABLE      2
+#define VGA_APERTURE_ENABLE     4
+
+/* CONFIG_STAT0 register constants (GX, CX) */
+#define CFG_BUS_TYPE		0x00000007
+#define CFG_MEM_TYPE		0x00000038
+#define CFG_INIT_DAC_TYPE	0x00000e00
+
+/* CONFIG_STAT0 register constants (CT, ET, VT) */
+#define CFG_MEM_TYPE_xT		0x00000007
+
+#define ISA			0
+#define EISA			1
+#define LOCAL_BUS		6
+#define PCI			7
+
+/* Memory types for GX, CX */
+#define DRAMx4			0
+#define VRAMx16			1
+#define VRAMx16ssr		2
+#define DRAMx16			3
+#define GraphicsDRAMx16		4
+#define EnhancedVRAMx16		5
+#define EnhancedVRAMx16ssr	6
+
+/* Memory types for CT, ET, VT, GT */
+#define DRAM			0
+#define EDO_DRAM		1
+#define PSEUDO_EDO		2
+#define SDRAM			3
+
+#define DAC_INTERNAL		0x00
+#define DAC_IBMRGB514		0x01
+#define DAC_ATI68875		0x02
+#define DAC_TVP3026_A		0x72
+#define DAC_BT476		0x03
+#define DAC_BT481		0x04
+#define DAC_ATT20C491		0x14
+#define DAC_SC15026		0x24
+#define DAC_MU9C1880		0x34
+#define DAC_IMSG174		0x44
+#define DAC_ATI68860_B		0x05
+#define DAC_ATI68860_C		0x15
+#define DAC_TVP3026_B		0x75
+#define DAC_STG1700		0x06
+#define DAC_ATT498		0x16
+#define DAC_STG1702		0x07
+#define DAC_SC15021		0x17
+#define DAC_ATT21C498		0x27
+#define DAC_STG1703		0x37
+#define DAC_CH8398		0x47
+#define DAC_ATT20C408		0x57
+
+#define CLK_ATI18818_0		0
+#define CLK_ATI18818_1		1
+#define CLK_STG1703		2
+#define CLK_CH8398		3
+#define CLK_INTERNAL		4
+#define CLK_ATT20C408		5
+#define CLK_IBMRGB514		6
+
+/* MEM_CNTL register constants */
+#define MEM_SIZE_ALIAS		0x00000007
+#define MEM_SIZE_512K		0x00000000
+#define MEM_SIZE_1M		0x00000001
+#define MEM_SIZE_2M		0x00000002
+#define MEM_SIZE_4M		0x00000003
+#define MEM_SIZE_6M		0x00000004
+#define MEM_SIZE_8M		0x00000005
+#define MEM_SIZE_ALIAS_GTB	0x0000000F
+#define MEM_SIZE_2M_GTB		0x00000003
+#define MEM_SIZE_4M_GTB		0x00000007
+#define MEM_SIZE_6M_GTB		0x00000009
+#define MEM_SIZE_8M_GTB		0x0000000B
+#define MEM_BNDRY               0x00030000
+#define MEM_BNDRY_0K            0x00000000
+#define MEM_BNDRY_256K          0x00010000
+#define MEM_BNDRY_512K          0x00020000
+#define MEM_BNDRY_1M            0x00030000
+#define MEM_BNDRY_EN            0x00040000
+
+/* ATI PCI constants */
+#define PCI_ATI_VENDOR_ID	0x1002
+#define PCI_MACH64_GX		0x4758
+#define PCI_MACH64_CX		0x4358
+#define PCI_MACH64_CT		0x4354
+#define PCI_MACH64_ET		0x4554
+#define PCI_MACH64_VT		0x5654
+#define PCI_MACH64_GT		0x4754
+
+/* CONFIG_CHIP_ID register constants */
+#define CFG_CHIP_TYPE		0x0000FFFF
+#define CFG_CHIP_CLASS		0x00FF0000
+#define CFG_CHIP_REV		0xFF000000
+#define CFG_CHIP_VERSION	0x07000000
+#define CFG_CHIP_FOUNDRY	0x38000000
+#define CFG_CHIP_REVISION	0xC0000000
+
+/* Chip IDs read from CONFIG_CHIP_ID */
+#define MACH64_GX_ID		0xD7
+#define MACH64_CX_ID		0x57
+#define MACH64_CT_ID		0x4354
+#define MACH64_ET_ID		0x4554
+#define MACH64_VT_ID		0x5654
+#define MACH64_GT_ID		0x4754
+
+/* Mach64 chip types */
+#define MACH64_UNKNOWN		0
+#define MACH64_GX		1
+#define MACH64_CX		2
+#define MACH64_CT		3
+#define MACH64_ET		4
+#define MACH64_VT		5
+#define MACH64_GT		6
+
+/* DST_CNTL register constants */
+#define DST_X_RIGHT_TO_LEFT     0
+#define DST_X_LEFT_TO_RIGHT     1
+#define DST_Y_BOTTOM_TO_TOP     0
+#define DST_Y_TOP_TO_BOTTOM     2
+#define DST_X_MAJOR             0
+#define DST_Y_MAJOR             4
+#define DST_X_TILE              8
+#define DST_Y_TILE              0x10
+#define DST_LAST_PEL            0x20
+#define DST_POLYGON_ENABLE      0x40
+#define DST_24_ROTATION_ENABLE  0x80
+
+/* SRC_CNTL register constants */
+#define SRC_PATTERN_ENABLE      1
+#define SRC_ROTATION_ENABLE     2
+#define SRC_LINEAR_ENABLE       4
+#define SRC_BYTE_ALIGN          8
+#define SRC_LINE_X_RIGHT_TO_LEFT 0
+#define SRC_LINE_X_LEFT_TO_RIGHT 0x10
+
+/* HOST_CNTL register constants */
+#define HOST_BYTE_ALIGN         1
+
+/* GUI_TRAJ_CNTL register constants */
+#define PAT_MONO_8x8_ENABLE     0x01000000
+#define PAT_CLR_4x2_ENABLE      0x02000000
+#define PAT_CLR_8x1_ENABLE      0x04000000
+
+/* DP_CHAIN_MASK register constants */
+#define DP_CHAIN_4BPP		0x8888
+#define DP_CHAIN_7BPP		0xD2D2
+#define DP_CHAIN_8BPP		0x8080
+#define DP_CHAIN_8BPP_RGB	0x9292
+#define DP_CHAIN_15BPP		0x4210
+#define DP_CHAIN_16BPP		0x8410
+#define DP_CHAIN_24BPP		0x8080
+#define DP_CHAIN_32BPP		0x8080
+
+/* DP_PIX_WIDTH register constants */
+#define DST_1BPP                0
+#define DST_4BPP                1
+#define DST_8BPP                2
+#define DST_15BPP               3
+#define DST_16BPP               4
+#define DST_32BPP               6
+#define SRC_1BPP                0
+#define SRC_4BPP                0x100
+#define SRC_8BPP                0x200
+#define SRC_15BPP               0x300
+#define SRC_16BPP               0x400
+#define SRC_32BPP               0x600
+#define HOST_1BPP               0
+#define HOST_4BPP               0x10000
+#define HOST_8BPP               0x20000
+#define HOST_15BPP              0x30000
+#define HOST_16BPP              0x40000
+#define HOST_32BPP              0x60000
+#define BYTE_ORDER_MSB_TO_LSB   0
+#define BYTE_ORDER_LSB_TO_MSB   0x1000000
+
+/* DP_MIX register constants */
+#define BKGD_MIX_NOT_D              0
+#define BKGD_MIX_ZERO               1
+#define BKGD_MIX_ONE                2
+#define BKGD_MIX_D                  3
+#define BKGD_MIX_NOT_S              4
+#define BKGD_MIX_D_XOR_S            5
+#define BKGD_MIX_NOT_D_XOR_S        6
+#define BKGD_MIX_S                  7
+#define BKGD_MIX_NOT_D_OR_NOT_S     8
+#define BKGD_MIX_D_OR_NOT_S         9
+#define BKGD_MIX_NOT_D_OR_S         10
+#define BKGD_MIX_D_OR_S             11
+#define BKGD_MIX_D_AND_S            12
+#define BKGD_MIX_NOT_D_AND_S        13
+#define BKGD_MIX_D_AND_NOT_S        14
+#define BKGD_MIX_NOT_D_AND_NOT_S    15
+#define BKGD_MIX_D_PLUS_S_DIV2      0x17
+#define FRGD_MIX_NOT_D              0
+#define FRGD_MIX_ZERO               0x10000
+#define FRGD_MIX_ONE                0x20000
+#define FRGD_MIX_D                  0x30000
+#define FRGD_MIX_NOT_S              0x40000
+#define FRGD_MIX_D_XOR_S            0x50000
+#define FRGD_MIX_NOT_D_XOR_S        0x60000
+#define FRGD_MIX_S                  0x70000
+#define FRGD_MIX_NOT_D_OR_NOT_S     0x80000
+#define FRGD_MIX_D_OR_NOT_S         0x90000
+#define FRGD_MIX_NOT_D_OR_S         0xa0000
+#define FRGD_MIX_D_OR_S             0xb0000
+#define FRGD_MIX_D_AND_S            0xc0000
+#define FRGD_MIX_NOT_D_AND_S        0xd0000
+#define FRGD_MIX_D_AND_NOT_S        0xe0000
+#define FRGD_MIX_NOT_D_AND_NOT_S    0xf0000
+#define FRGD_MIX_D_PLUS_S_DIV2      0x170000
+
+/* DP_SRC register constants */
+#define BKGD_SRC_BKGD_CLR           0
+#define BKGD_SRC_FRGD_CLR           1
+#define BKGD_SRC_HOST               2
+#define BKGD_SRC_BLIT               3
+#define BKGD_SRC_PATTERN            4
+#define FRGD_SRC_BKGD_CLR           0
+#define FRGD_SRC_FRGD_CLR           0x100
+#define FRGD_SRC_HOST               0x200
+#define FRGD_SRC_BLIT               0x300
+#define FRGD_SRC_PATTERN            0x400
+#define MONO_SRC_ONE                0
+#define MONO_SRC_PATTERN            0x10000
+#define MONO_SRC_HOST               0x20000
+#define MONO_SRC_BLIT               0x30000
+
+/* CLR_CMP_CNTL register constants */
+#define COMPARE_FALSE               0
+#define COMPARE_TRUE                1
+#define COMPARE_NOT_EQUAL           4
+#define COMPARE_EQUAL               5
+#define COMPARE_DESTINATION         0
+#define COMPARE_SOURCE              0x1000000
+
+/* FIFO_STAT register constants */
+#define FIFO_ERR                    0x80000000
+
+/* CONTEXT_LOAD_CNTL constants */
+#define CONTEXT_NO_LOAD             0
+#define CONTEXT_LOAD                0x10000
+#define CONTEXT_LOAD_AND_DO_FILL    0x20000
+#define CONTEXT_LOAD_AND_DO_LINE    0x30000
+#define CONTEXT_EXECUTE             0
+#define CONTEXT_CMD_DISABLE         0x80000000
+
+/* GUI_STAT register constants */
+#define ENGINE_IDLE                 0
+#define ENGINE_BUSY                 1
+#define SCISSOR_LEFT_FLAG           0x10
+#define SCISSOR_RIGHT_FLAG          0x20
+#define SCISSOR_TOP_FLAG            0x40
+#define SCISSOR_BOTTOM_FLAG         0x80
+
+/* ATI VGA Extended Regsiters */
+#define sioATIEXT	0x1ce
+#define bioATIEXT	0x3ce
+extern unsigned ATIExtReg;
+#define ATI2E		0xae
+#define ATI32		0xb2
+#define ATI36		0xb6
+
+/* VGA Graphics Controller Registers */
+#define VGAGRA		0x3ce
+#define GRA06		0x06
+
+/* VGA Seququencer Registers */
+#define VGASEQ		0x3c4
+#define SEQ02		0x02
+#define SEQ04		0x04
+
+#define MACH64_MAX_X	ENGINE_MAX_X
+#define MACH64_MAX_Y	ENGINE_MAX_Y
+
+#define INC_X           0x0020
+#define INC_Y           0x0080
+
+#define RGB16_555               0x0000
+#define RGB16_565               0x0040
+#define RGB16_655               0x0080
+#define RGB16_664               0x00c0
+
+#define POLY_TEXT_TYPE          0x0001
+#define IMAGE_TEXT_TYPE         0x0002
+#define TEXT_TYPE_8_BIT         0x0004
+#define TEXT_TYPE_16_BIT        0x0008
+#define POLY_TEXT_TYPE_8        (POLY_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define IMAGE_TEXT_TYPE_8       (IMAGE_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define POLY_TEXT_TYPE_16       (POLY_TEXT_TYPE | TEXT_TYPE_16_BIT)
+#define IMAGE_TEXT_TYPE_16      (IMAGE_TEXT_TYPE | TEXT_TYPE_16_BIT)
+
+#define MACH64_NUM_CLOCKS	16
+#define MACH64_NUM_FREQS	50
+
+typedef struct {
+    unsigned char h_disp;
+    unsigned char dacmask;
+    unsigned char ram_req;
+    unsigned char max_dot_clock;
+    unsigned char color_depth;
+} mach64FreqRec;
+
+typedef struct {
+    unsigned char r, g, b;
+} LUTENTRY;
+
+typedef struct {
+    unsigned long h_total_disp, h_sync_strt_wid;
+    unsigned long v_total_disp, v_sync_strt_wid;
+    unsigned long crtc_gen_cntl;
+    unsigned long color_depth;
+    unsigned long clock_cntl;
+    unsigned long dot_clock;
+    unsigned long fifo_v1;
+} mach64CRTCRegRec, *mach64CRTCRegPtr;
+
+
+/* Wait until "v" queue entries are free */
+#define WaitQueue(v)  \
+{ \
+  int   __cntr = 0;      \
+  while((regr(FIFO_STAT) & 0xffff) > ((unsigned short)(0x8000 >> (v))))  \
+  { \
+    if(__cntr++ > 500000)    \
+    { \
+      Eprint(" Timeout Waiting for FIFO. \n"); \
+    } \
+  } \
+}
+
+/* Wait until GP is idle and queue is empty */
+#define WaitIdleEmpty() \
+{  \
+  int   __cntr = 0;      \
+  WaitQueue(16); \
+  while ((regr(GUI_STAT) & 1) != 0) \
+  { \
+    if(__cntr++ > 500000)    \
+    { \
+      Eprint(" Timeout Waiting for BLT engine. \n"); \
+    } \
+  } \
+}
+
+#define SKIP_2(_v) ((((_v)<<1)&0xfff8)|((_v)&0x3)|(((_v)&0x80)>>5))
+
+#define MACH64_BIT_BLT(_srcx, _srcy, _dstx, _dsty, _w, _h, _dir) \
+{ \
+    WaitQueue(5); \
+    regw(SRC_Y_X, (((_srcx) << 16) | ((_srcy) & 0x0000ffff))); \
+    regw(SRC_WIDTH1, (_w)); \
+    regw(DST_CNTL, (_dir)); \
+    regw(DST_Y_X, (((_dstx) << 16) | ((_dsty) & 0x0000ffff))); \
+    regw(DST_HEIGHT_WIDTH, (((_w) << 16) | ((_h) & 0x0000ffff))); \
+}
+
+#ifndef NULL
+#define NULL    0
+#endif
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define MACH64REGS_H_ID \
+  "@(#) Linux-m68k: 1997 08 16 20:48:18 BHA: mach64regs.h "
+
+/*============================================================================*/
+
+#endif /* MACH64REGS_H */
--- m68k-2.1.57/drivers/video/mach64fb.c.orig	Tue Sep 30 19:59:39 1997
+++ m68k-2.1.57/drivers/video/mach64fb.c	Tue Sep 30 20:38:49 1997
@@ -0,0 +1,2525 @@
+/*
+ * linux/drivers/video/mach64fb.c -- Low level implementation of the
+ *                                   ATI Mach64 frame buffer device
+ *
+ *    Copyright (C) 1997 Bernd Harries
+ *
+ *
+ * This file is based on the Amiga frame buffer device (amifb.c):
+ *
+ *    Copyright (C) 1995 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.
+ */
+
+/*============================================================================*/
+/* Includes */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/zorro.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+
+#include "mach64regs.h"
+
+#include "mach64fb.h"
+
+
+unsigned long Mach64_fb_init(unsigned long mem_start);
+void Mach64_video_setup(char *options, int *ints);
+
+
+/*============================================================================*/
+/* Defines */
+
+#define _NOT_MAP_768K_IO_
+
+#define _MAP_GUIREGS_0BFC00_
+
+
+#define _NOT_DUMP_IO_REGS_
+
+#define _NOT_DUMP_GUIREGS_0BFC00_
+
+#define _NOT_DUMP_GUIREGS_3FFC00_
+
+#define _NOT_DUMP_KMAP_RANGE_
+
+
+#ifdef MULTI_MACH
+
+#define MACH_MAX 8
+
+#define DECLARE_STATIC_UINT08___MN_  static unsigned char          m64_num;
+#define DECLARE_UINT08___MN_         unsigned char m64_num;
+#define ARG_UINT08___MN_             unsigned char m64_num
+#define ADD_ARG_UINT08___MN_         , unsigned char m64_num
+
+#define _ARRAY_       [MACH_MAX]
+#define __MN__        [m64_num]
+#define _MN_           m64_num
+#define _INC_MN_       m64_num++
+#define _ARG_MN_       m64_num
+#define _ADD_ARG_MN_   , m64_num
+
+#else      /*---------------------*/
+
+#define DECLARE_STATIC_UINT08___MN_
+#define DECLARE_UINT08___MN_
+#define ARG_UINT08___MN_           void
+#define ADD_ARG_UINT08___MN_
+
+#define _ARRAY_    
+#define __MN__         
+#define _MN_           0
+#define _INC_MN_       
+#define _ARG_MN_       
+#define _ADD_ARG_MN_   
+
+#endif     /* MULTI_MACH */
+
+/*--------------------------------------------------------------------------*/
+  
+#define MACH_MAX 8
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+#define  FuncId       if(mach64fb_debug & 0x00000100) printk
+#define  FuncDone     if(mach64fb_debug & 0x00000200) printk
+#define  CFuncId      if(mach64fb_debug & 0x00000400) printk
+#define  CFuncDone    if(mach64fb_debug & 0x00000800) printk
+#define  OFuncId      if(mach64fb_debug & 0x00001000) printk
+#define  OFuncDone    if(mach64fb_debug & 0x00002000) printk
+
+
+/* Busy */
+#define  Bprint       if(mach64fb_debug & 0x01000000) printk
+/* Debug */
+#define  Dprint       if(mach64fb_debug & 0x00800000) printk
+
+/* Message */
+#define  Mprint       if(mach64fb_debug & 0x00004000) printk
+/* Info */
+#define  Iprint       if(mach64fb_debug & 0x00008000) printk
+/* Warn */
+#define  Wprint       if(mach64fb_debug & 0x00010000) printk
+/* Error */
+#define  Eprint       if(mach64fb_debug & 0x00020000) printk
+/* Fatal */
+#define  Fprint       if(mach64fb_debug & 0x00040000) printk
+/* Panic */
+#define  Pprint       if(mach64fb_debug & 0x00080000) printk
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef __alpha__
+/*
+ * on the Alpha, there are "write buffers" that hold data to be written
+ *  to memory; the data is *not* necessarily flushed to memory immediately.
+ * so, we use a "memory barrier" instruction to force the flush of these
+ *  buffers, so that writing to the memory-mapped Mach64 registers *will*
+ *  take place immediately.
+ */
+
+#define barrier() __asm__ __volatile__("mb": : :"memory")
+
+#else /* __alpha__ */
+
+/*
+#define barrier()
+*/
+
+#endif /* __alpha__ */
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef _MAP_768K_IO_
+
+#define OUTB(port,val) \
+  *((unsigned volatile char *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )) = (val)
+
+#define INB(port) \
+  (*((unsigned volatile char *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )))
+
+/*
+#define OUTL(port,val) \
+  *((unsigned volatile int *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )) = (val)
+
+#define INL(port) \
+  (*((unsigned volatile int *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )))
+*/
+
+#else
+
+#define OUTB(port,val) \
+  *((unsigned volatile char *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+#define INB(port) \
+  (*((unsigned volatile char *) ((port) + virt_vgaiobase __MN__  )))
+
+/*
+#define OUTL(port,val) \
+  *((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+#define INL(port) \
+  (*((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )))
+*/
+
+#endif  /* _MAP_768K_IO_ */
+
+#define DACDelay                    \
+  do {                              \
+    unsigned char tmp = INB(0x3da); \
+    tmp = INB(0x3da);               \
+  } while (0)
+
+/*============================================================================*/
+
+/*
+#define regwr(port, val) \
+  *((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+
+#define regrd(port) \
+  (*((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )))
+*/
+
+/*============================================================================*/
+/* Types */
+
+struct mach64_fb_par
+{
+   int xres;
+   int yres;
+   int bpp;
+};
+
+/*============================================================================*/
+/* Extern Functions*/
+
+
+
+/*============================================================================*/
+/* Intern Functions*/
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Interface to the low level console driver exported with fb_info
+    */
+
+static int  Mach64fb_switch(int con);
+static int  Mach64fb_updatevar(int con);
+static void Mach64fb_blank(int blank);
+static int  Mach64fb_setcmap(struct fb_cmap * cmap, int con);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Interface fb_ops used by the world exported with fb_info.fb_ops
+    */
+
+static int M64_op_open(int fbidx);
+static int M64_op_release(int fbidx);
+static int M64_op_get_fix(struct fb_fix_screeninfo * fix, int con);
+static int M64_op_get_var(struct fb_var_screeninfo * var, int con);
+static int M64_op_set_var(struct fb_var_screeninfo * var, int con);
+static int M64_op_get_cmap(struct fb_cmap * cmap, int kspc, int con);
+static int M64_op_set_cmap(struct fb_cmap * cmap, int kspc, int con);
+static int M64_op_pan_display(struct fb_var_screeninfo * var, int con);
+
+static int 
+M64_op_ioctl(
+  struct inode * inode,
+  struct file *file,
+  u_int cmd,
+  u_long arg,
+  int con);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *   Internal Routines
+    */
+
+static int 
+do_fb_set_var(struct fb_var_screeninfo * var, int isactive);
+
+static void 
+do_install_cmap(int con);
+
+static void 
+Mach64_fb_set_disp(int con);
+
+static int 
+get_video_mode(const char * name);
+
+static int 
+store_video_par(char* videopar  ADD_ARG_UINT08___MN_ );
+
+static char * 
+strtoke(char * s,const char * ct);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *   Hardware Specific Routines
+    */
+
+static int 
+M64_hw_init( ARG_UINT08___MN_ );
+
+static int 
+M64_hw_encode_fix(struct fb_fix_screeninfo * fix, struct mach64_fb_par * par);
+
+static int 
+M64_hw_decode_var(struct fb_var_screeninfo * var, struct mach64_fb_par * par);
+
+static int 
+M64_hw_encode_var(struct fb_var_screeninfo * var, struct mach64_fb_par * par);
+
+static void 
+M64_hw_get_par(struct mach64_fb_par * par);
+
+static void 
+M64_hw_set_par(struct mach64_fb_par * par);
+
+static int 
+M64_hw_getcolreg(
+  u_int regno,
+  u_int * red,
+  u_int * green,
+  u_int * blue,
+  u_int * transp);
+
+static int 
+M64_hw_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp);
+
+static void 
+M64_hw_blank(int blank);
+
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Intern Variables */
+
+/*--------------------------------------------------------------------------*/
+/* BSS */
+
+
+static unsigned long            phys_vmembase _ARRAY_ ;
+static unsigned long            phys_size _ARRAY_ ;
+static unsigned long            phys_vgaiobase _ARRAY_ ;
+static unsigned long            phys_guiregbase _ARRAY_ ;
+
+static unsigned long            virt_vmembase _ARRAY_ ;
+static unsigned long            virt_size _ARRAY_ ;
+static unsigned long            virt_vgaiobase _ARRAY_ ;
+static unsigned long            virt_guiregbase _ARRAY_ ;
+
+static unsigned int             mach64_xres _ARRAY_ ;
+static unsigned int             mach64_yres _ARRAY_ ;
+static unsigned int             mach64_depth _ARRAY_ ;
+
+
+static struct mach64_fb_par     current_par _ARRAY_ ;
+static struct display           m_disp _ARRAY_ ;
+static struct fb_info           fb_info _ARRAY_ ;
+
+static u_short                  mach64_colormap  _ARRAY_ [256][4];
+
+static u_int                    mach64_key;
+static u_int                    mach64_bitspercol _ARRAY_ ;
+
+static int                      currcon;
+
+
+static u_short                  mach64_inverse _ARRAY_ ;
+static short int                mach64_pmode _ARRAY_ ;
+static short int                mach64_mode _ARRAY_ ;   /* 0..31 */
+static short int                mach64_use_accel _ARRAY_ ;
+static char                     current_par_valid _ARRAY_ ;
+
+static unsigned char            mach64_count;
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Switch for Chipset Independency
+    */
+
+static struct fb_hwswitch
+{
+
+  /* Initialisation */
+
+  int (*init)( ARG_UINT08___MN_ );
+
+  /* Display Control */
+
+  int (*encode_fix)(struct fb_fix_screeninfo * fix, struct mach64_fb_par * par);
+  int (*decode_var)(struct fb_var_screeninfo * var, struct mach64_fb_par * par);
+  int (*encode_var)(struct fb_var_screeninfo * var, struct mach64_fb_par * par);
+  void (*get_par)(struct mach64_fb_par * par );
+  void (*set_par)(struct mach64_fb_par * par );
+  int (*getcolreg)(u_int regno, u_int * red, u_int * green, u_int * blue,
+    u_int * transp);
+  int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
+    u_int transp);
+  void (*blank)(int blank);
+  void (*set_screen_base)( unsigned long s_base );
+  int  (*pan_display)( struct fb_var_screeninfo * var);
+} 
+* fbhws_ptr;
+
+
+/*--------------------------------------------------------------------------*/
+/* Data */
+
+
+/* -------------- local Interfaces to hardware functions ---------------- */
+
+/* see XGCValues GCFunction */
+int 
+mach64alu[16] =
+{
+    MIX_0,
+    MIX_AND,
+    MIX_SRC_AND_NOT_DST,
+    MIX_SRC,
+    MIX_NOT_SRC_AND_DST,
+    MIX_DST,
+    MIX_XOR,
+    MIX_OR,
+    MIX_NOR,
+    MIX_XNOR,
+    MIX_NOT_DST,
+    MIX_SRC_OR_NOT_DST,
+    MIX_NOT_SRC,
+    MIX_NOT_SRC_OR_DST,
+    MIX_NAND,
+    MIX_1
+};
+
+static struct fb_hwswitch 
+mach64_switch = 
+{
+  M64_hw_init,
+  M64_hw_encode_fix,
+  M64_hw_decode_var,
+  M64_hw_encode_var,
+  NULL,                    /* M64_hw_get_par, */
+  NULL,                    /* M64_hw_set_par, */
+  M64_hw_getcolreg,
+  M64_hw_setcolreg,
+  M64_hw_blank,
+  NULL,
+  NULL
+};
+
+/* ------ Interfaces to hardware functions to export with fb_info  ------ */
+
+static struct fb_ops 
+mach64_fb_ops =
+{
+  M64_op_open,
+  M64_op_release,
+  M64_op_get_fix,
+  M64_op_get_var,
+  M64_op_set_var,
+  M64_op_get_cmap,
+  M64_op_set_cmap,
+  M64_op_pan_display,
+  M64_op_ioctl
+};
+
+static  unsigned int    mach64fb_debug = 0x018FCF00;
+
+   /*
+    *    Frame Buffer Name
+    */
+
+static char     mach64_fb_name[16] = "ATI Mach64 ";
+
+
+   /*
+    *    Ati Mach64 Graphics Board
+    */
+
+#define M64_8_WIDTH 1152
+#define M64_8_HEIGHT 912
+#define M64_8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+
+#define M64_16_WIDTH 800
+#define M64_16_HEIGHT 600
+#define M64_16_PIXCLOCK 25000   /* ++Geert: Just a guess */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Predefined Video Mode Names
+    */
+/*--------------------------------------------------------------------------*/
+
+static char *                   fb_var_names[] =
+{
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   "autodetect",
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   "Mach64_8",            /* Mach64 8 bpp */
+   "Mach64_16",           /* Mach64 16 bpp */
+
+   /*
+    *    Dummy Video Modes
+    */
+
+   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+   "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
+   "dummy", "dummy", "dummy", "dummy",
+
+   /*
+    *    User Defined Video Modes
+    *
+    *    This doesn't work yet!!
+    */
+
+   "user0", "user1", "user2", "user3", "user4", "user5", "user6", "user7"
+};
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Predefined Video Mode Definitions
+    */
+/*--------------------------------------------------------------------------*/
+
+static struct fb_var_screeninfo mach64_fb_predefined[] = 
+{
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   { 0, },
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   {
+      /* Cybervision 8 bpp */
+      M64_8_WIDTH, M64_8_HEIGHT, M64_8_WIDTH, M64_8_HEIGHT, 0, 0, 8, 0,
+      {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+      0, 0, -1, -1, FB_ACCEL_NONE, M64_8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+   }, {
+      /* Cybervision 16 bpp */
+      M64_16_WIDTH, M64_16_HEIGHT, M64_16_WIDTH, M64_16_HEIGHT, 0, 0, 16, 0,
+      {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+      0, 0, -1, -1, FB_ACCEL_NONE, M64_16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+   },
+
+   /*
+    *    Dummy Video Modes
+    */
+
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, },
+   { 0, }, { 0, },
+
+   /*
+    *    User Defined Video Modes
+    */
+
+   { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }
+};
+
+
+#define NUM_TOTAL_MODES    arraysize(mach64_fb_predefined)
+#define NUM_PREDEF_MODES   (3)
+
+
+   /*
+    *    Some default modes
+    */
+
+#define M64_8_DEFMODE     (1)
+#define M64_16_DEFMODE    (2)
+
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Functions */
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*============================================================================*/
+
+__inline__ void 
+regwr(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regrd(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwrb(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+
+#ifdef _MAP_768K_IO_
+
+__inline__ void
+OUTL(unsigned int port, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + 0x00080000 + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+INL(unsigned int port)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + 0x00080000 + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regw(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regr(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwB(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+#else
+
+__inline__ void 
+OUTL(unsigned int port, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+INL(unsigned int port)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+
+
+__inline__ void 
+regw(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regr(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwB(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+#endif  /* _MAP_768K_IO_ */
+
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_open(int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_open(%02d) \n", fbidx);
+  /*
+   * Nothing, only a usage count for the moment
+   */
+
+  MOD_INC_USE_COUNT;
+
+  return(0);
+}
+/*endproc M64_op_open() */
+
+/*============================================================================*/
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_release(int fbidx)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("M64_op_release() \n");
+  MOD_DEC_USE_COUNT;
+  return(0);
+}
+/*endproc M64_op_release() */
+
+/*============================================================================*/
+
+
+/* -------------------- Hardware specific routines ------------------------ */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Initialization
+    *
+    *    Set the default video mode for this chipset. If a video mode was
+    *    specified on the command line, it will override the default mode.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_init( ARG_UINT08___MN_ )
+
+/*--------------------------------------------------------------------------*/
+{
+  struct fb_var_screeninfo *    var_ptr = &mach64_fb_predefined[0];
+  struct mach64_fb_par          dummy_par;
+
+  unsigned long                 board_addr;
+  u_int *                       u32_ptr;
+  u_int                         read_val;
+  int                           n;
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("M64_hw_init() \n");
+
+  if(mach64_mode __MN__   == -1)
+  {
+    mach64_mode __MN__   = M64_8_DEFMODE;
+  }
+  /*endif*/
+
+  board_addr = virt_vmembase __MN__  ;
+  for (i = 0; i < 256; i++)
+  {
+    mach64_colormap  __MN__  [i][0] = i;
+    mach64_colormap  __MN__  [i][1] = i;
+    mach64_colormap  __MN__  [i][2] = i;
+    mach64_colormap  __MN__  [i][3] = 0;
+  }
+
+#ifdef _DUMP_IO_REGS_
+  u32_ptr = (u_int *)(0x000002EC + virt_vgaiobase __MN__ );
+  n = 0;
+  while(n < 0x20)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    u32_ptr += 0x0400;
+  }
+  /*endwhile*/
+  Dprint("\n" );
+#endif
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+  read_val = regr(GEN_TEST_CNTL);
+  if(0)
+  {
+    regw(GEN_TEST_CNTL, read_val | 0x0200);
+  }
+  else
+  {
+    regw(GEN_TEST_CNTL, read_val & ~0x0200);
+  }
+  /*endif*/
+
+  WaitQueue(13);
+  regw(SRC_OFF_PITCH, (mach64_xres __MN__  << 19));
+  regw(DST_OFF_PITCH, (mach64_xres __MN__  << 19));
+  regw(SC_LEFT_RIGHT, (mach64_xres __MN__  -1) << 16);
+  regw(SC_TOP_BOTTOM, (mach64_yres __MN__  -1) << 16);
+
+  regw(DP_BKGD_CLR, 0x00000000);
+  regw(DP_FRGD_CLR, 0x00000001);
+
+  regw(DP_WRITE_MASK, 0x000000FF  /* pGC->planemask */ );
+  regw(DP_PIX_WIDTH, BYTE_ORDER_MSB_TO_LSB | HOST_8BPP | SRC_8BPP | DST_8BPP);
+  regw(DP_MIX, FRGD_MIX_S | BKGD_MIX_D);
+  regw(DP_SRC, FRGD_SRC_BLIT | BKGD_SRC_BKGD_CLR);
+
+  regw(CLR_CMP_CNTL, 0x00000000);
+  regw(CLR_CMP_CLR, 0x00000000);
+
+  regw(GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+
+
+#ifdef  _DUMP_GUIREGS_0BFC00_
+
+#ifdef _MAP_768K_IO_
+  u32_ptr = (u_int *)(0x0003FC00 + virt_vgaiobase __MN__ );
+#else
+  u32_ptr = (u_int *)(0x0000FC00 + virt_guiregbase __MN__ );
+#endif
+  n = 0;
+  while(n < 0x100)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    u32_ptr += 4;
+  }
+  /*endwhile*/
+  Dprint("\n" );
+#endif
+
+#ifdef  _DUMP_GUIREGS_3FFC00_
+  u32_ptr = (u_int *)(0x003FFC00 + virt_vmembase __MN__ );
+  n = 0;
+  while(n < 0x100)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    u32_ptr += 4;
+  }
+  /*endwhile*/
+
+  Dprint("\n" );
+#endif
+
+
+
+  dummy_par.xres = mach64_xres __MN__  ;
+  dummy_par.yres = mach64_yres __MN__  ;
+  dummy_par.bpp = mach64_depth __MN__  ;
+  M64_hw_encode_var(var_ptr, &dummy_par);
+
+  mach64fb_debug = 0x018FC100;
+
+  M64_hw_setcolreg (255, 56, 100, 160, 0);
+  M64_hw_setcolreg (254, 0, 0, 0, 0);
+
+  FuncDone("M64_hw_init() done.\n");
+  return(1);    /* detected_mode */
+}
+/*endproc M64_hw_init() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    This function should fill in the `fix' structure based on the
+    *    values in the `par' structure.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_encode_fix(struct fb_fix_screeninfo * fix, struct mach64_fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_encode_fix() \n");
+
+  strcpy(fix->id, mach64_fb_name);
+  fix->id[15] =  _MN_ ;
+  fix->smem_start = (caddr_t) virt_vmembase __MN__  ;
+
+  /* aufrunden */
+  fix->smem_len = (phys_size __MN__   + PAGE_SIZE - 0x00200001) & PAGE_MASK;
+
+  if(mach64_depth __MN__   == 1)
+  {
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    /* The letters 'n' and 'i' in the "video=Mach64:" stand
+     * for "normal" and "inverted", rsp., in the monochrome case */
+    fix->visual =
+      (mach64_pmode __MN__   == FB_TYPE_INTERLEAVED_PLANES ||
+      mach64_pmode __MN__   == FB_TYPE_PACKED_PIXELS) ?
+      FB_VISUAL_MONO10 : FB_VISUAL_MONO01;
+  }
+  else   /* depth > 1 */
+  {
+    switch(mach64_pmode __MN__  )
+    {
+      /* All visuals are STATIC, because we don't know how to change
+       * colors :-(
+       */
+      case -1:              /* truecolor */
+        fix->type = FB_TYPE_PACKED_PIXELS;
+        fix->visual = FB_VISUAL_TRUECOLOR;
+        break;
+      case FB_TYPE_PACKED_PIXELS:
+        fix->type = FB_TYPE_PACKED_PIXELS;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+      case FB_TYPE_PLANES:
+        fix->type = FB_TYPE_PLANES;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+      case FB_TYPE_INTERLEAVED_PLANES:
+        fix->type = FB_TYPE_INTERLEAVED_PLANES;
+        fix->type_aux = 2;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+    }
+    /*endswitch*/
+  }
+  /*endif*/
+  fix->xpanstep = 0;
+  fix->ypanstep = 0;
+  fix->ywrapstep = 0;
+  fix->line_length = 0;
+
+  for(i = 0; i < arraysize(fix->reserved); i++)
+    fix->reserved[i] = 0;
+
+  CFuncId("M64_hw_encode_fix() done. \n");
+  return(0);
+}
+/*endproc _encode_fix() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the video params out of `var'. If a value doesn't fit, round
+    *    it up, if it's too big, return -EINVAL.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_decode_var(struct fb_var_screeninfo * var, struct mach64_fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_decode_var() \n");
+
+  par->xres = var->xres;
+  par->yres = var->yres;
+  par->bpp = var->bits_per_pixel;
+
+  return(0);
+}
+/*endproc _decode_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Fill the `var' structure based on the values in `par' and maybe
+    *    other values read out of the hardware.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_encode_var(struct fb_var_screeninfo * var, struct mach64_fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_encode_var() \n");
+
+  var->xres = par->xres;
+  var->yres = par->yres;
+  var->xres_virtual = par->xres;
+  var->yres_virtual = par->yres;
+  var->xoffset = 0;
+  var->yoffset = 0;
+
+  var->bits_per_pixel = par->bpp;
+  var->grayscale = 0;
+
+  if(par->bpp == 8)
+  {
+    var->red.offset = 0;
+    var->red.length =
+      (virt_vgaiobase __MN__   ? mach64_bitspercol __MN__  : 0);
+    var->red.msb_right = 0;
+    var->blue = var->green = var->red;
+  }
+  else
+  {
+    var->red.offset = 11;
+    var->red.length = 5;
+    var->red.msb_right = 0;
+    var->green.offset = 5;
+    var->green.length = 6;
+    var->green.msb_right = 0;
+    var->blue.offset = 0;
+    var->blue.length = 5;
+    var->blue.msb_right = 0;
+  }
+  var->transp.offset = 0;
+  var->transp.length = 0;
+  var->transp.msb_right = 0;
+
+  var->nonstd = 0;
+  var->activate = 0;
+
+  var->height = -1;
+  var->width = -1;
+  var->accel = mach64_use_accel __MN__  ;
+  var->vmode = FB_VMODE_NONINTERLACED;
+
+  /* Dummy values */
+
+  if (par->bpp == 8)
+    var->pixclock = M64_8_PIXCLOCK;
+  else
+    var->pixclock = M64_16_PIXCLOCK;
+  var->sync = 0;
+  var->left_margin = 64;
+  var->right_margin = 96;
+  var->upper_margin = 35;
+  var->lower_margin = 12;
+  var->hsync_len = 112;
+  var->vsync_len = 2;
+
+  for(i = 0; i < arraysize(var->reserved); i++)
+    var->reserved[i] = 0;
+
+  return(0);
+}
+/*endproc _encode_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Set a single color register. The values supplied are already
+    *    rounded down to the hardware's capabilities (according to the
+    *    entries in the var structure). Return != 0 for invalid regno.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_setcolreg(u_int regno,
+  u_int red,
+  u_int green,
+  u_int blue,
+  u_int transp)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  unsigned short                colmask;
+  unsigned short                colshift;
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_hw_setcolreg(%02X) \n", regno);
+
+  if(regno > 255)  return (1);
+  mach64_colormap  __MN__  [regno][0] = red;
+  mach64_colormap  __MN__  [regno][1] = green;
+  mach64_colormap  __MN__  [regno][2] = blue;
+  mach64_colormap  __MN__  [regno][3] = transp;
+
+  if(! phys_vgaiobase)  return 1;
+
+  colmask = (1 << mach64_bitspercol __MN__  ) - 1;
+  colshift = 8 - mach64_bitspercol __MN__  ;
+
+  OUTB(0x3c8, regno);
+  DACDelay;
+  OUTB(0x3c9, (red >> colshift) & colmask);
+  DACDelay;
+  OUTB(0x3c9, (green >> colshift) & colmask);
+  DACDelay;
+  OUTB(0x3c9, (blue >> colshift) & colmask);
+  DACDelay;
+
+  return (0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Read a single color register and split it into
+    *    colors/transparent. Return != 0 for invalid regno.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_getcolreg(u_int regno,
+  u_int * red,
+  u_int * green,
+  u_int * blue,
+  u_int * transp)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_hw_getcolreg() \n");
+
+  if(regno >= 256)  return (1);
+
+  *red    = mach64_colormap  __MN__  [regno][0];
+  *green  = mach64_colormap  __MN__  [regno][1];
+  *blue   = mach64_colormap  __MN__  [regno][2];
+  *transp = mach64_colormap  __MN__  [regno][3];
+
+  /*
+  OUTB(0x3c7, regno);
+  DACDelay;
+  *red = INB(0x3c9) & colmask;
+  DACDelay;
+  *green = INB(0x3c9) & colmask;
+  DACDelay;
+  *blue = INB(0x3c9) & colmask;
+  DACDelay;
+  */
+	    
+  return (0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    (Un)Blank the screen: Set all colors = RGB 000 or back
+    */
+/*--------------------------------------------------------------------------*/
+
+void 
+M64_hw_blank(int blank)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int regno;
+
+  unsigned short                colmask;
+  unsigned short                colshift;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_blank() \n");
+
+  if(blank)
+  {
+    for(regno = 0; regno < 256; regno++)
+    {
+      OUTB(0x3c8, regno);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+
+    }
+    /*nexxt regno*/
+  }
+  else
+  {
+    colmask = (1 << mach64_bitspercol __MN__  ) - 1;
+    colshift = 8 - mach64_bitspercol __MN__  ;
+    for (regno = 0; regno < 256; regno++)
+    {
+      OUTB(0x3c8, regno);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][0] >> colshift) & colmask);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][1] >> colshift) & colmask);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][2] >> colshift) & colmask);
+    }
+    /*nexxt regno*/
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We are waiting for "fifo" FIFO-slots empty
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_WaitQueue (u_short fifo)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_WaitQueue() \n");
+
+  WaitQueue(16);
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We are waiting for Hardware (Graphics Engine) not busy
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_WaitBlit (void)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_WaitBlit() \n");
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * BitBLT - Through the Plane
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_BitBLT (
+  int     xSrc,
+  int     ySrc,
+  int     xDst,
+  int     yDst,
+  u_int   wSrc,
+  u_int   hSrc,
+  u_short mode)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  u_int                         direction;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("BB(%03X,%03X,%03X,%03X,%03X,%03X,%X) ",
+    xSrc, ySrc, xDst, yDst, wSrc, hSrc, mode);
+  /* Set drawing direction */
+  /* -Y, X maj, -X (default) */
+
+#if 1
+
+  direction = 0;
+
+  if(ySrc < yDst)
+  {
+    yDst += hSrc - 1;
+    ySrc += hSrc - 1;
+  }
+  else
+  {
+    direction |= DST_Y_TOP_TO_BOTTOM;
+  }
+  /*endif*/
+  if(xSrc < xDst)
+  {
+    xDst += wSrc - 1;
+    xSrc += wSrc - 1;
+  }
+  else
+  {
+    direction |= DST_X_LEFT_TO_RIGHT;
+  }
+  /*endif*/
+
+
+  WaitQueue(4);
+  regw(DP_WRITE_MASK, 0x000000FF          /* pGC->planemask */ );
+  regw(DP_MIX, (mach64alu[mode] << 16) |  MIX_DST);
+  regw(DP_SRC, FRGD_SRC_BLIT);
+
+  regw(GUI_TRAJ_CNTL, direction);
+
+/*
+  MACH64_BIT_BLT(xSrc, ySrc, xDst, yDst, wSrc, hSrc, direction);
+*/
+    WaitQueue(4);
+    regw(SRC_Y_X, (((xSrc) << 16) | (ySrc) ));
+    regw(SRC_WIDTH1, (wSrc));
+    regw(DST_Y_X, (((xDst) << 16) | (yDst) ));
+    regw(DST_HEIGHT_WIDTH, (((wSrc) << 16) | (hSrc) ));
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+  /*
+   * Make sure that the destination trajectory is correctly set
+   * for subsequent calls.  MACH64_BIT_BLT is the only function that
+   * currently changes the destination trajectory from L->R and T->B.
+   */
+  regw(DST_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+
+#endif
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * Rectangle Fill Solid
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_RectFill(
+  int     x,
+  int     y,
+  u_int   wSrc,
+  u_int   hSrc,
+  u_int   mode,
+  u_int   color)
+
+/*--------------------------------------------------------------------------*/
+{
+
+#if 1
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("RF(%03X,%03X,%03X,%03X,%X) ",
+    x, y, wSrc, hSrc, mode);
+
+  WaitQueue(5);
+  regw(DP_FRGD_CLR, color              /* pGC->fgPixel */ );
+  regw(DP_WRITE_MASK, 0x000000FF       /* pGC->planemask */ );
+  regw(DP_MIX, (mach64alu[mode] << 16) | MIX_DST);
+  regw(DP_SRC, FRGD_SRC_FRGD_CLR);
+
+  regw(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+  if ((wSrc > 0) && (hSrc > 0))
+  {
+    /* Bprint("q\n"); */
+    WaitQueue(2);
+    regw(DST_Y_X, (((u_int)x << 16) | ((u_int)y & 0x0000ffff)));
+    regw(DST_HEIGHT_WIDTH, (((u_int)wSrc << 16) | hSrc));
+  }
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+#endif
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * Move cursor to x, y
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_MoveCursor (u_short x, u_short y)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_MoveCursor() \n");
+
+
+  return;
+}
+/*endproc Mach64_MoveCursor()*/
+
+/*============================================================================*/
+
+
+/* -------------------- Generic routines ------------------------------------ */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Fill the hardware's `par' structure.
+    */
+/*--------------------------------------------------------------------------*/
+
+static void 
+M64_hw_get_par(struct mach64_fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_get_par() \n");
+  if(current_par_valid __MN__  )
+  {
+    *par = current_par __MN__  ;
+  }
+  else    /* use a default, initialize */
+  {
+    fbhws_ptr->decode_var(
+      &mach64_fb_predefined[mach64_mode __MN__  ],
+      par);
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+M64_hw_set_par(struct mach64_fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_set_par() \n");
+  current_par __MN__   = *par;
+  current_par_valid __MN__   = 1;
+
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+do_fb_set_var(struct fb_var_screeninfo * var, int isactive)
+
+/*--------------------------------------------------------------------------*/
+{
+  int                           err, activate;
+  struct mach64_fb_par          par;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("do_fb_set_var() \n");
+  if((err = fbhws_ptr->decode_var(var, &par)))
+    return(err);
+  activate = var->activate;
+  if((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+  {
+    M64_hw_set_par(&par);
+  }
+  /*endif*/
+  fbhws_ptr->encode_var(var, &par);
+  var->activate = activate;
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+do_install_cmap(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("do_install_cmap() \n");
+
+  if(con != currcon)  return;
+
+  if(fb_display[con].cmap.len)
+  {
+    fb_set_cmap(&fb_display[con].cmap,
+      &fb_display[con].var,
+      1,
+      fbhws_ptr->setcolreg);
+  }
+  else
+  {
+    fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+      &fb_display[con].var,
+      1,
+      fbhws_ptr->setcolreg);
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the Fixed Part of the Display
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_fix(struct fb_fix_screeninfo * fix, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+  struct mach64_fb_par          par;
+  int                           status = 0;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_get_fix() \n");
+  if (con == -1)
+  {
+    M64_hw_get_par(&par);
+  }
+  else
+  {
+    status = fbhws_ptr->decode_var(&fb_display[con].var, &par);
+  }
+  /*endif*/
+  return(status ? status : fbhws_ptr->encode_fix(fix, &par));
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the User Defined Part of the Display
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_var(struct fb_var_screeninfo *var, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+  struct mach64_fb_par          par;
+  int                           status = 0;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_get_var() \n");
+  if(con == -1)
+  {
+    M64_hw_get_par(&par);
+    status = fbhws_ptr->encode_var(var, &par);
+  }
+  else
+  {
+    *var = fb_display[con].var;
+  }
+  /*endif*/
+  return(status);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+Mach64_fb_set_disp(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  struct display *              disp_p;
+  struct fb_fix_screeninfo      fix;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_fb_set_disp() \n");
+
+  if(con >= 0)
+    disp_p = &fb_display[con];
+  else
+    disp_p = &m_disp __MN__  ;  	/* used during initialization */
+
+  M64_op_get_fix(&fix, con);
+
+  if(con == -1)  con = 0;
+
+  disp_p->screen_base = (u_char *)fix.smem_start;
+  disp_p->visual = fix.visual;
+  disp_p->type = fix.type;
+  disp_p->type_aux = fix.type_aux;
+  disp_p->ypanstep = fix.ypanstep;
+  disp_p->ywrapstep = fix.ywrapstep;
+  disp_p->line_length = fix.line_length;
+  if(fix.visual != FB_VISUAL_PSEUDOCOLOR && fix.visual != FB_VISUAL_DIRECTCOLOR)
+  {
+    disp_p->can_soft_blank = 0;                   /* aus atari_ */
+  }
+  else
+  {
+    disp_p->can_soft_blank = 1;
+  }
+  /*endif*/
+
+  disp_p->can_soft_blank = 1;                       /* aus Cyber_ */
+  disp_p->inverse = mach64_inverse __MN__  ;
+
+  return;
+}
+/*endproc Mach64_fb_set_disp() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+  /*
+   *    Set the User Defined Part of the Display
+   */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_set_var(struct fb_var_screeninfo * var, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int       err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_set_var() \n");
+
+  if((err = do_fb_set_var(var, con == currcon)))
+    return(err);
+  if((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+  {
+    oldxres = fb_display[con].var.xres;
+    oldyres = fb_display[con].var.yres;
+    oldvxres = fb_display[con].var.xres_virtual;
+    oldvyres = fb_display[con].var.yres_virtual;
+    oldbpp = fb_display[con].var.bits_per_pixel;
+    fb_display[con].var = *var;
+    if(oldxres != var->xres || oldyres != var->yres ||
+      oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+      oldbpp != var->bits_per_pixel)
+    {
+      Mach64_fb_set_disp(con);
+      (*fb_info __MN__  .changevar)(con);
+      fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
+      do_install_cmap(con);
+    }
+  }
+  /*endif*/
+  var->activate = 0;
+
+  return(0);
+}
+/*endproc M64_op_set_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the Colormap
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_cmap(struct fb_cmap * cmap, int kspc, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_get_cmap() \n");
+
+  if(con == currcon) /* current console? */
+  {
+    return(fb_get_cmap(cmap, &fb_display[con].var, kspc, fbhws_ptr->getcolreg));
+  }
+  else if(fb_display[con].cmap.len) /* non default colormap? */
+  {
+    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+  }
+  else
+  {
+    fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+      cmap, kspc ? 0 : 2);
+  }
+  /*endif*/
+
+  return(0);
+}
+/*endproc M64_op_get_cmap() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Set the Colormap
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_set_cmap(struct fb_cmap * cmap, int kspc, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+  int err;
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_set_cmap() \n");
+
+  if (!fb_display[con].cmap.len)       /* no colormap allocated? */
+  {
+    err = fb_alloc_cmap(&fb_display[con].cmap,
+      1 << fb_display[con].var.bits_per_pixel,
+      0);
+    if(err)
+    {
+      return(err);
+    }
+    /*endif*/
+  }
+  /*endif*/
+  if(con == currcon)              /* current console? */
+  {
+    return(fb_set_cmap(cmap, &fb_display[con].var, kspc, fbhws_ptr->setcolreg));
+  }
+  else
+  {
+    fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+  }
+  /*endif*/
+
+  return(0);
+}
+/*endproc M64_op_set_cmap() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Pan or Wrap the Display
+    *
+    *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_pan_display(struct fb_var_screeninfo *var, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_pan_display() \n");
+
+  return(-EINVAL);
+}
+/*endproc M64_op_pan_display() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Mach 64 Frame Buffer Specific ioctls
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_ioctl(
+  struct inode * inode,
+  struct file *  file,
+  u_int          cmd,
+  u_long         arg,
+  int            con)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_ioctl($%08X %d) \n", cmd, con);
+  switch (cmd)
+  {
+
+#ifdef FBCMD_GET_CURRENTPAR
+    case FBCMD_GET_CURRENTPAR:
+    {
+      if (copy_to_user((void *)arg, (void *)&current_par __MN__  ,
+         sizeof(struct mach64_fb_par)))
+        return -EFAULT;
+      return 0;
+    }
+    /*endcase*/
+#endif
+
+#ifdef FBCMD_SET_CURRENTPAR
+    case FBCMD_SET_CURRENTPAR:
+    {
+
+      if (copy_from_user((void *)&current_par __MN__  , (void *)arg,
+        sizeof(struct mach64_fb_par)))
+        return -EFAULT;
+      M64_hw_set_par(&current_par __MN__  );
+      return 0;
+    }
+    /*endcase*/
+#endif
+
+  }
+  /*endswitch*/
+  return(-EINVAL);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+int 
+Mach64_probe(void)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("Mach64_probe() \n");
+  mach64_key = 0;
+  return(mach64_key);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+__initfunc(
+void 
+Mach64_video_setup(char * options, int * ints)
+)
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  char *        this_opt;
+  char          mach64_str[80];
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("Mach64_video_setup() '%s'\n", options);
+
+  fb_info __MN__  .fontname[0] = '\0';
+
+  if(!options || !*options)  return;
+
+  for(this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
+  {
+    if (!strcmp(this_opt, "inverse"))
+    {
+      mach64_inverse __MN__   = 1;
+      fb_invert_cmaps();
+    }
+    else if (!strncmp(this_opt, "font:", 5))
+    {
+      strcpy(fb_info __MN__  .fontname, this_opt + 5);
+    }
+    else if (!strncmp(this_opt,"Mach64:", 7))
+    {
+      strncpy(mach64_str, this_opt + 7, 80);
+      store_video_par(mach64_str  _ADD_ARG_MN_ );
+      _INC_MN_ ;
+      mach64_count =  _MN_ ;
+    }
+    else
+    {
+      mach64_mode __MN__   = get_video_mode(this_opt);
+    }
+    /*endif*/
+  }
+  /*next this_opt*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+store_video_par(char* video_str ADD_ARG_UINT08___MN_ )
+
+/*--------------------------------------------------------------------------*/
+{
+  char *                        p;
+  unsigned  long                sm_addr, sm_size;
+
+  int                           xres, yres, depth;
+  short int                     pmode;
+  short int                     use_accel;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("store_video_par(%d) \n",  _MN_ );
+  /* Format is: <xres>;<yres>;<depth>;<plane organ.>;
+   *            <screen mem addr>
+   *        [;<screen mem length>[;<vgaiobase>[;<colorreg-type>]]]
+   */
+
+  use_accel = 0;
+  if (!(p = strtoke(video_str, ";")) || !*p)  goto mach64_invalid;
+  xres = simple_strtoul(p, NULL, 10);
+  if (xres <= 0)  goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  yres = simple_strtoul(p, NULL, 10);
+  if (yres <= 0) goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  depth = simple_strtoul(p, NULL, 10);
+  if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
+      depth != 16 && depth != 24)  goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  if (*p == 'i')
+    pmode = FB_TYPE_INTERLEAVED_PLANES;
+  else if (*p == 'p')
+    pmode = FB_TYPE_PACKED_PIXELS;
+  else if (*p == 'n')
+    pmode = FB_TYPE_PLANES;
+  else if (*p == 't')
+    pmode = -1; /* true color */
+  else
+    goto mach64_invalid;
+
+
+  if (!(p = strtoke(NULL, ";")) ||!*p)  goto mach64_invalid;
+  sm_addr = simple_strtoul(p, NULL, 0);
+
+  if (!(p = strtoke(NULL, ";")) ||!*p)
+    sm_size = xres * yres * depth / 8;
+  else
+    sm_size = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+    phys_vgaiobase __MN__   = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+  {
+    mach64_bitspercol __MN__   = simple_strtoul(p, NULL, 0);
+    if (mach64_bitspercol __MN__   > 8)
+      mach64_bitspercol __MN__   = 8;
+    else if (mach64_bitspercol __MN__   < 1)
+      mach64_bitspercol __MN__   = 1;
+  }
+  /*endif*/
+
+  if ((p = strtoke(NULL, ";")) && *p)
+    phys_guiregbase __MN__   = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+  {
+    if(*p == 'a')  use_accel = FB_ACCEL_MACH64;
+  
+  }
+  /*endif*/
+
+  mach64_xres __MN__    = xres;
+  mach64_yres __MN__    = yres;
+  mach64_depth __MN__   = depth;
+  mach64_pmode __MN__   = pmode;
+  mach64_use_accel __MN__   = use_accel;
+  phys_vmembase __MN__   = sm_addr;
+  phys_size __MN__    = sm_size;
+
+  return(0);
+
+  /*--------------------------------------------------------------------------*/
+  mach64_invalid:
+
+  phys_vmembase __MN__   = 0;
+
+  return(-1);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/* a strtok which returns empty strings, too */
+
+/*--------------------------------------------------------------------------*/
+
+static char * 
+strtoke(char * s, const char * ct)
+
+/*--------------------------------------------------------------------------*/
+{
+  static char    *ssave = NULL;
+  char          *sbegin, *send;
+  
+  /*--------------------------------------------------------------------------*/
+  sbegin  = s ? s : ssave;
+  if (!sbegin) {
+    return NULL;
+  }
+  if (*sbegin == '\0') {
+    ssave = NULL;
+    return NULL;
+  }
+  send = strpbrk(sbegin, ct);
+  if (send && *send != '\0')
+    *send++ = '\0';
+  ssave = send;
+  return sbegin;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Initialization
+    */
+/*--------------------------------------------------------------------------*/
+
+__initfunc(
+unsigned long
+Mach64_fb_init(unsigned long mem_start)
+)
+/*--------------------------------------------------------------------------*/
+{
+  static unsigned long          virt_dummy;
+  static u_char                 fb_init_count;
+  DECLARE_STATIC_UINT08___MN_
+
+  struct mach64_fb_par          par;
+  int                           err;
+  DECLARE_UINT08___MN_
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("Mach64_fb_init($%08lX) \n", mem_start);
+
+  /*
+  _MN_ = fb_init_count;
+  */
+  if(phys_vmembase __MN__   == 0)  return mem_start;
+
+  fb_init_count++;
+
+  fbhws_ptr = &mach64_switch;
+
+  /* Map the video memory (physical address given) to somewhere
+   * in the kernel address space.
+   */
+  mem_start = (mem_start + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+  virt_vmembase __MN__   = kernel_map(
+    phys_vmembase __MN__  ,
+    phys_size __MN__  ,
+#ifdef  _OHNE_HW_ACCEL_
+    KERNELMAP_NO_COPYBACK,    /* must be changed if hardware blit */
+#else
+    KERNELMAP_NOCACHE_SER,
+#endif
+    &mem_start);
+
+#ifdef  _MAP_GUIREGS_0BFC00_
+    
+  if(phys_guiregbase __MN__  )
+  {
+    virt_guiregbase __MN__   = kernel_map(
+      phys_guiregbase __MN__  ,
+      0x10000,                           /* 64 K */
+      KERNELMAP_NOCACHE_SER,
+      &mem_start);
+  }
+  /*endif*/
+
+#endif
+
+  if(phys_vgaiobase __MN__  )
+  {
+/*
+    phys_guiregbase __MN__   = phys_vgaiobase __MN__  - 0x00100000 + 0x000B0000;
+*/
+
+#ifdef _MAP_768K_IO_
+
+    virt_vgaiobase __MN__   = kernel_map(
+      phys_vgaiobase __MN__  - 0x00080000,
+      0x0C0000,                          /* 768 K */
+      KERNELMAP_NOCACHE_SER,
+      &mem_start);
+
+#else
+
+    if(phys_guiregbase __MN__  )
+    {
+      virt_vgaiobase __MN__   = kernel_map(
+        phys_vgaiobase __MN__  ,
+        0x10000,                           /* 64 K */
+        KERNELMAP_NOCACHE_SER,
+        &mem_start);
+    }
+    else
+    {
+      virt_vgaiobase __MN__   = 0x00080000 + kernel_map(
+        phys_vgaiobase __MN__  - 0x00080000,
+        0x0C0000,                          /* 768 K */
+        KERNELMAP_NOCACHE_SER,
+        &mem_start);
+
+      Dprint(" faking virt_guiregbase to virt_vgaiobase - 0x00050000 \n");
+      virt_guiregbase __MN__   = virt_vgaiobase __MN__  - 0x00050000;
+    }
+    /*endif*/
+
+#endif  /* _MAP_768K_IO_ */
+  }
+  /*endif*/
+
+  Dprint(" phys_guiregbase=$%08lX virt_dummy=$%08lX\n",
+    phys_guiregbase __MN__  ,
+    virt_dummy);
+
+    
+#ifdef  _DUMP_KMAP_RANGE_
+  dump_kmap_range();
+#endif
+
+
+  virt_size __MN__   = phys_size __MN__   & PAGE_MASK;  /* abrunden */
+  virt_size __MN__   = (phys_size __MN__  - 0x00200000) & PAGE_MASK;  /* abrunden */
+
+  Dprint(" PAGE_MASK=$%08lX phys_size=$%08lX \n", PAGE_MASK, phys_size __MN__ );
+  /*
+  memset((char *) virt_vmembase __MN__  , 0, virt_size __MN__  );
+  */
+
+  strcpy(fb_info __MN__  .modename, mach64_fb_name);
+  fb_info __MN__  .changevar = NULL;
+  fb_info __MN__  .node = -1;
+  fb_info __MN__  .fbops = &mach64_fb_ops;
+  fb_info __MN__  .fbvar_num = NUM_TOTAL_MODES;
+  fb_info __MN__  .fbvar = mach64_fb_predefined;
+  fb_info __MN__  .disp = &m_disp __MN__  ;
+  fb_info __MN__  .switch_con = &Mach64fb_switch;
+  fb_info __MN__  .updatevar = &Mach64fb_updatevar;
+  fb_info __MN__  .blank = &Mach64fb_blank;
+  fb_info __MN__  .setcmap = &Mach64fb_setcmap;
+  strcat(fb_info __MN__  .modename, fb_var_names[mach64_mode __MN__  ]);
+  fb_info __MN__  .modename[39] =  _MN_ ;
+
+  err = register_framebuffer(&fb_info __MN__  );
+  if(err < 0)
+  {
+    Eprint(" Cannot register frame buffer() \n" );
+    return mem_start;
+  }
+  /*endif*/
+
+  fbhws_ptr->init( _ARG_MN_ );
+  fbhws_ptr->decode_var(&mach64_fb_predefined[mach64_mode __MN__  ], &par);
+  fbhws_ptr->encode_var(&mach64_fb_predefined[0], &par); /* store resolution */
+
+  do_fb_set_var(&mach64_fb_predefined[0], 1);
+
+  M64_op_get_var(&m_disp __MN__  .var, -1);  /* fill in m_disp.var */
+  Mach64_fb_set_disp(-1);                    /* fill in the rest of m_disp  */
+
+  Iprint(" Determined %dx%d, depth %d $%08lX MEM @ $%08lX IO @ $%08lX $%08lX\n",
+    m_disp __MN__  .var.xres,
+    m_disp __MN__  .var.yres,
+    m_disp __MN__  .var.bits_per_pixel,
+    phys_size __MN__  ,
+    phys_vmembase __MN__  ,
+    phys_vgaiobase __MN__  ,
+    phys_guiregbase __MN__  );
+  do_install_cmap(0);
+
+  Iprint(
+    " %s FB device %d, using %ldK of video MEM @ $%08lX IO @ $%08lX $%08lX\n",
+    fb_info __MN__  .modename,
+     _MN_ ,
+    virt_size __MN__   >> 10,
+    virt_vmembase __MN__  ,
+    virt_vgaiobase __MN__  ,
+    virt_guiregbase __MN__  );
+
+  _INC_MN_ ;
+
+  return mem_start;
+}
+/*endproc Mach64_fb_init() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+Mach64fb_switch(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_switch(%d) \n", con);
+  /* Do we have to save the colormap? */
+  if (fb_display[currcon].cmap.len)
+  {
+    fb_get_cmap(&fb_display[currcon].cmap,
+      &fb_display[currcon].var,
+      1,
+      fbhws_ptr->getcolreg);
+  }
+  /*endif*/
+  do_fb_set_var(&fb_display[con].var, 1);
+  currcon = con;
+  /* Install new colormap */
+  do_install_cmap(con);
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Update the `var' structure (called by fbcon.c)
+    *
+    *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+    *    Since it's called by a kernel driver, no range checking is done.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+Mach64fb_updatevar(int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_updatevar() \n");
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Blank the display.
+    */
+/*--------------------------------------------------------------------------*/
+
+static void 
+Mach64fb_blank(int blank)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_blank() \n");
+  fbhws_ptr->blank(blank);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Set the colormap
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+Mach64fb_setcmap(struct fb_cmap *cmap, int con)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_setcmap() \n");
+  return(M64_op_set_cmap(cmap, 1, con));
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get a Video Mode
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+get_video_mode(const char * name)
+
+/*--------------------------------------------------------------------------*/
+{
+  int i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("get_video_mode(%s) \n", name);
+
+  for (i = 1; i < NUM_PREDEF_MODES; i++)
+  {
+    if (!strcmp(name, fb_var_names[i]))  return(i);
+  }
+  /*next i*/
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+  static char
+  rcs_id_c[] =
+    "@(#) Linux-m68k: 1997 08 27 00:49:00 BHA: mach64fb.c ";
+
+  static char
+  rcs_id_h[] = MACH64FB_H_ID;
+
+  static char
+  rcs_id_regs_h[] = MACH64REGS_H_ID;
+
+/*============================================================================*/
--- m68k-2.1.57/arch/m68k/amiga/config.c.orig	Mon Sep 29 20:19:25 1997
+++ m68k-2.1.57/arch/m68k/amiga/config.c	Tue Sep 30 20:23:15 1997
@@ -75,18 +75,15 @@
 extern void amiga_floppy_setup(char *, int *);
 #endif
 static void amiga_reset (void);
-static void amiga_wait_key(void);
 extern struct consw fb_con;
 extern void zorro_init(void);
 extern void amiga_init_sound(void);
 static void amiga_savekmsg_init(void);
 static void amiga_mem_console_write(const char *b, unsigned int count);
-static void amiga_serial_console_write(const char *s, unsigned int count);
+void amiga_serial_console_write(const char *s, unsigned int count);
 static void amiga_debug_init(void);
 
-static struct console amiga_console_driver = {
-    NULL, NULL, amiga_wait_key
-};
+static struct console amiga_console_driver;
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static char amiga_sysrq_xlate[128] =
@@ -156,10 +153,10 @@
 }
 
     /*
-     *  Setup the Amiga configuration info
+     *  Identify builtin hardware
      */
 
-__initfunc(void config_amiga(void))
+__initfunc(static void amiga_identify(void))
 {
   /* Fill in some default values, if necessary */
   if (amiga_eclock == 0)
@@ -167,8 +164,6 @@
 
   memset(&amiga_hw_present, 0, sizeof(amiga_hw_present));
 
-  amiga_debug_init();
-
   printk("Amiga hardware found: ");
   if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO)
     printk("[%s] ", amiga_models[amiga_model-AMI_500]);
@@ -311,11 +306,21 @@
   AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC ");
   AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK ");
   AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA ");
-  if (AMIGAHW_SET(ZORRO))
-    printk("ZORRO%s ", AMIGAHW_SET(ZORRO3) ? "3" : "");
+  if (AMIGAHW_PRESENT(ZORRO))
+    printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : "");
   printk("\n");
 
 #undef AMIGAHW_ANNOUNCE
+}
+
+    /*
+     *  Setup the Amiga configuration info
+     */
+
+__initfunc(void config_amiga(void))
+{
+  amiga_debug_init();
+  amiga_identify();
 
   mach_sched_init      = amiga_sched_init;
   mach_keyb_init       = amiga_keyb_init;
@@ -371,6 +376,27 @@
   /* ensure that the DMA master bit is set */
   custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
 
+  /* don't use Z2 RAM as system memory on Z3 capable machines */
+  if (AMIGAHW_PRESENT(ZORRO3)) {
+    int i, j;
+    unsigned long z2mem = 0;
+    for (i = 0; i < m68k_num_memory; i++)
+      if (m68k_memory[i].addr < 16*1024*1024) {
+	if (i == 0) {
+	  /* don't cut off the branch we're sitting on */
+	  printk("Warning: kernel runs in Zorro II memory\n");
+	  continue;
+	}
+	z2mem += m68k_memory[i].size;
+	m68k_num_memory--;
+	for (j = i; j < m68k_num_memory; j++)
+	  m68k_memory[j] = m68k_memory[j+1];
+      }
+    if (z2mem)
+      printk("%ldK of Zorro II memory will not be used as system memory\n",
+	     z2mem>>10);
+  }
+
   /* initialize chipram allocator */
   amiga_chip_init ();
 
@@ -384,8 +410,6 @@
 		  register_console(&amiga_console_driver);
 	  }
 
-  /* It must _not_ be initialized here as the chip mem is not yet free. */
-
   /* our beloved beeper */
   if (AMIGAHW_PRESENT(AMI_AUDIO))
 	  amiga_init_sound();
@@ -620,32 +644,6 @@
 	return 0;
 }
 
-static void amiga_wait_key (void)
-{
-    int i;
-
-    while (1) {
-	while (ciaa.pra & 0x40);
-
-	/* debounce */
-	for (i = 0; i < 1000; i++);
-
-	if (!(ciaa.pra & 0x40))
-	    break;
-    }
-
-    /* wait for button up */
-    while (1) {
-	while (!(ciaa.pra & 0x40));
-
-	/* debounce */
-	for (i = 0; i < 1000; i++);
-
-	if (ciaa.pra & 0x40)
-	    break;
-    }
-}
-
 void dbprintf(const char *fmt , ...)
 {
 	static char buf[1024];
@@ -771,7 +769,7 @@
 	;
 }
 
-static void amiga_serial_console_write(const char *s, unsigned int count)
+void amiga_serial_console_write(const char *s, unsigned int count)
 {
     while (count--) {
 	if (*s == '\n')
@@ -786,16 +784,24 @@
     amiga_serial_console_write(s, strlen(s));
 }
 
+int amiga_serial_console_wait_key(void)
+{
+    int ch;
+
+    while (!(custom.intreqr & IF_RBF))
+	barrier();
+    ch = custom.serdatr & 0xff;
+    /* clear the interrupt, so that another character can be read */
+    custom.intreq = IF_RBF;
+    return ch;
+}
+
 void amiga_serial_gets(char *s, int len)
 {
     int ch, cnt = 0;
 
     while (1) {
-	while (!(custom.intreqr & IF_RBF))
-	    barrier();
-	ch = custom.serdatr & 0xff;
-	/* clear the interrupt, so that another character can be read */
-	custom.intreq = IF_RBF;
+	ch = amiga_serial_console_wait_key();
 
 	/* Check for backspace. */
 	if (ch == 8 || ch == 127) {
--- m68k-2.1.57/arch/m68k/kernel/console.c.orig	Mon Sep 15 22:50:42 1997
+++ m68k-2.1.57/arch/m68k/kernel/console.c	Tue Sep 30 20:50:28 1997
@@ -165,6 +165,7 @@
 extern void compute_shiftstate(void);
 extern void reset_palette(int currcons);
 extern void set_palette(void);
+extern int con_is_present(void);
 void poke_blanked_console(void);
 void do_blank_screen(int);
 
@@ -2221,16 +2222,24 @@
    printing = 0;
 }
 
-static int vt_console_device(void)
+static kdev_t vt_console_device(struct console *c)
 {
-	return MKDEV(TTY_MAJOR, fg_console + 1);
+	return MKDEV(TTY_MAJOR, c->index ? c->index : fg_console + 1);
 }
 
-extern void keyboard_wait_for_keypress(void);
+extern int keyboard_wait_for_keypress(void);
 
 struct console vt_console_driver = {
-	vt_console_print, do_unblank_screen,
-        keyboard_wait_for_keypress, vt_console_device
+	"tty",
+	vt_console_print,
+	NULL,
+	vt_console_device,
+	keyboard_wait_for_keypress,
+	do_unblank_screen,
+	NULL,
+	CON_PRINTBUFFER,
+	0,
+	NULL
 };
 #endif
 
@@ -2320,6 +2329,7 @@
 	const char *display_desc = "????";
 	unsigned int currcons = 0;
 	extern int serial_debug;
+	extern int num_registered_fb;
 
 	memset(&console_driver, 0, sizeof(struct tty_driver));
 	console_driver.magic = TTY_DRIVER_MAGIC;
@@ -2395,8 +2405,10 @@
 	printable = 1;
 
 	/* If "serdebug" cmd line option was present, don't register for printk */
-	if (!serial_debug)
+#ifdef CONFIG_VT_CONSOLE
+	if (!serial_debug && num_registered_fb)
 		register_console(&vt_console_driver);
+#endif
 	printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
 		can_do_color ? "colour":"mono",
 		display_desc,
--- m68k-2.1.57/arch/m68k/kernel/setup.c.orig	Mon Sep 29 20:19:26 1997
+++ m68k-2.1.57/arch/m68k/kernel/setup.c	Tue Sep 30 20:23:16 1997
@@ -151,7 +151,6 @@
 __initfunc(void setup_arch(char **cmdline_p, unsigned long * memory_start_p,
 			   unsigned long * memory_end_p))
 {
-	unsigned long memory_start, memory_end;
 	extern int _etext, _edata, _end;
 	int i;
 	char *p, *q;
@@ -172,12 +171,6 @@
 		asm __volatile__ ("frestore %0" : : "m" (zero));
 	}
 
-	memory_start = availmem;
-	memory_end = 0;
-
-	for (i = 0; i < m68k_num_memory; i++)
-		memory_end += m68k_memory[i].size & MASK_256K;
-
 	init_task.mm->start_code = 0;
 	init_task.mm->end_code = (unsigned long) &_etext;
 	init_task.mm->end_data = (unsigned long) &_edata;
@@ -210,9 +203,6 @@
 	    }
 	}
 
-	*memory_start_p = memory_start;
-	*memory_end_p = memory_end;
-
 	switch (m68k_machtype) {
 #ifdef CONFIG_AMIGA
 	    case MACH_AMIGA:
@@ -249,6 +239,11 @@
 		initrd_end = initrd_start + m68k_ramdisk.size;
 	}
 #endif
+
+	*memory_start_p = availmem;
+	*memory_end_p = 0;
+	for (i = 0; i < m68k_num_memory; i++)
+		*memory_end_p += m68k_memory[i].size & MASK_256K;
 }
 
 int get_cpuinfo(char * buffer)
--- m68k-2.1.57/arch/m68k/mm/init.c.orig	Thu Sep 11 22:31:00 1997
+++ m68k-2.1.57/arch/m68k/mm/init.c	Tue Sep 30 20:23:16 1997
@@ -293,8 +293,6 @@
 /*
  * paging_init() continues the virtual memory environment setup which
  * was begun by the code in arch/head.S.
- * The parameters are pointers to where to stick the starting and ending
- * addresses  of available kernel virtual memory.
  */
 __initfunc(unsigned long paging_init(unsigned long start_mem,
 				     unsigned long end_mem))
--- m68k-2.1.57/arch/m68k/config.in.orig	Mon Sep 15 22:50:42 1997
+++ m68k-2.1.57/arch/m68k/config.in	Tue Sep 30 20:23:15 1997
@@ -226,7 +226,9 @@
 comment 'Character devices'
 
 define_bool CONFIG_VT y
-define_bool CONFIG_VT_CONSOLE y
+if [ "$CONFIG_VT" = "y" ]; then
+  bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
+fi
 define_bool CONFIG_FB_CONSOLE y
 
 if [ "$CONFIG_ATARI" = "y" ]; then
@@ -263,7 +265,7 @@
 if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
      "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
      "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" ]; then
-  bool 'Serial console support' CONFIG_SERIAL_CONSOLE
+  bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
 fi
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
--- m68k-2.1.57/Documentation/Configure.help.orig	Mon Sep 29 20:19:24 1997
+++ m68k-2.1.57/Documentation/Configure.help	Tue Sep 30 20:23:15 1997
@@ -369,9 +369,9 @@
   I/O speeds to be set as well.  See the Documentation/ide.txt and
   ali14xx.c files for more info.
 
-Amiga Gayle IDE interface support
+Amiga builtin Gayle IDE interface support
 CONFIG_BLK_DEV_GAYLE
-  This is the IDE driver for the builtin IDE interface on some Amigas
+  This is the IDE driver for the builtin IDE interface on some Amiga
   models.  It supports both the `A1200 style' (used in A600 and A1200)
   and `A4000 style' (used in A4000 and A4000T) of the Gayle IDE
   interface.
@@ -386,7 +386,7 @@
   Say Y if you have a Falcon and want to use IDE devices (hard disks,
   CD-ROM drives, etc.) that are connected to the builtin IDE interface.
 
-Buddha/Catweasel IDE interface support (EXPERIMENTAL)
+Amiga Buddha/Catweasel IDE interface support (EXPERIMENTAL)
 CONFIG_BLK_DEV_BUDDHA
   This is the IDE driver for the IDE interfaces on the Buddha and
   Catweasel expansion boards.  It supports up to two interfaces on the
@@ -4545,11 +4545,10 @@
 
 Console on virtual terminal
 CONFIG_VT_CONSOLE
-  If you enable this option, all kernel messages will be sent to the
-  device /dev/tty which corresponds to the virtual terminal you have
-  visible on your display. You should say N here only if you have some
-  other console device, in which case you probably want to say Y to
-  "Console on serial port", below. If unsure, say N.
+  If you enable this option, by default all kernel messages will be sent
+  to the device /dev/tty0 which corresponds to the virtual terminal you
+  have visible on your display. You should say Y here unless you only
+  want to have the kernel messages output on a serial port.
 
 Software generated cursor
 CONFIG_SOFTCURSOR
@@ -4578,15 +4577,12 @@
 
 Console on serial port
 CONFIG_SERIAL_CONSOLE
-  If you enable this option, all kernel messages will be sent to the
-  device /dev/ttyS0 which corresponds to a serial port; this could be
-  useful if you attached a terminal or printer to that port. (You can
-  change the number of the serial port used from 0 to something else
-  by setting the variable CONFIG_SERIAL_CONSOLE_PORT.) You can use
-  this option in combination with the option "Console on virtual
-  terminal" above, in which case you get the output on both the serial
-  port and on your display. Most people say N here so that they can
-  use the serial port for modem, mouse or some other device.
+  If you enable this option, it is possible to use a serial port as the
+  console. By default still the virtual console will be used at the
+  system console but you can alter that using a kernel command line
+  option. If you don't have a VGA card installed the kernel will
+  automatically use /dev/ttyS0 as system console if this option is
+  enabled.
 
 Comtrol Rocketport support
 CONFIG_ROCKETPORT
--- m68k-2.1.57/Documentation/serial-console.txt.orig	Thu Sep 11 22:31:00 1997
+++ m68k-2.1.57/Documentation/serial-console.txt	Tue Sep 30 20:23:15 1997
@@ -1,48 +1,65 @@
                        Linux Serial Console
 
-These examples are valid if you want to use /dev/ttyS1 (COM2)
-as the serial console. Replace as needed.
+It is possible to specify multiple devices for console output. You can
+define a new kernel command line option to select which device(s) to
+use for console output.
 
-1. Tell LILO to use the serial port.
+The format of this option is:
+
+	console=device,options
+
+	device:		tty0 for the foreground virtual console
+			ttyX for any other virtual console
+			ttySx for a serial port
+
+	options:	depend on the driver. For the serial port this
+			defines the baudrate/parity/bits of the port,
+			in the format BBBBPN, where BBBB is the speed,
+			P is parity (n/o/e), and N is bits. Default is
+			9600n8.
+
+You can specify multiple console= options on the kernel command line.
+Output will appear on all of them. The first device will be used when
+you open /dev/console. So, for example:
+
+	console=tty0 console=ttyS1,9600
+
+defines that opening /dev/console will get you the current foreground
+virtual console, and kernel messages will appear on both the VGA
+console and the 2nd serial port (ttyS1 or COM2) at 9600 baud.
+
+If no console device is specified, the first device found capable of
+acting as a system console will be used. At this time, the system
+first looks for a VGA card and then for a serial port. So if you don't
+have a VGA card in your system the first serial port will automatically
+become the console.
+
+You will need to create a new device to use /dev/console. The official
+/dev/console is now character device 5,1.
+
+Here's an example that will use /dev/ttyS1 (COM2) as the console.
+Replace the sample values as needed.
+
+1. Create /dev/console (real console) and /dev/tty0 (master virtual
+   console):
+
+   cd /dev
+   rm -f console tty0
+   mknod -m 622 console c 5 1
+   mknod -m 622 tty0 c 4 0
+
+2. LILO can also take input from a serial device. This is a very
+   useful option. To tell LILO to use the serial port:
    In lilo.conf (global section): 
 
    serial  = 1,9600n8 (ttyS1, 9600 bd, no parity, 8 bits)
 
-2. Adjust to kernel flags for the new kernel,
+3. Adjust to kernel flags for the new kernel,
    again in lilo.conf (kernel section)
 
-   append = "console=1,9600,n8" 
-
-   (Note the extra comma needed if you want to supply parity/framing 
-   information.)
-
-3. Link /dev/console to the serial port.
+   append = "console=ttyS1,9600" 
 
-   Your probably want to save your old /dev/console (the "master" virtual
-   console). Check if it is a symbolic link first. If not, `mv' it to
-   `/dev/tty0':
-
-   ls -l /dev/console
-   mv /dev/console /dev/tty0
-
-   Now link the serial port you are going to use as the console to
-   /dev/console, for example ttyS1:
-
-   ln -s /dev/ttyS1 /dev/console
-
-   On some systems you might want to edit your bootup scripts to make sure
-   they don't reset this arrangement on boot. (On Debian, check
-   /etc/rc.boot/console and /etc/default/console). You probably also want
-   to put a getty on either /dev/console or /dev/ttyS1.
-
-4. Init and /dev/console.
-   Sysvinit will open /dev/console on boot. If this does not point
-   to the serial console device, the startup messages will be printed
-   to the wrong device. The kernel also passes the environment variable
-   "CONSOLE" to the init program. sysvinit-2.64 reckognizes this, and
-   opens that device instead. Boot scripts as mentioned in (3) can
-   also check this variable to see what device the system console is.
-   If CONSOLE is not set you can assume the console is /dev/tty0.
+4. Init and /etc/ioctl.save
 
    Sysvinit remembers its stty settings in a file in /etc, called
    `/etc/ioctl.save'. REMOVE THIS FILE before using the serial
@@ -51,28 +68,19 @@
 
 5. /dev/console and X
    Programs that want to do something with the virtual console usually
-   open /dev/console. XF86 does this, and probably SVGALIB as well.
-   IMO this is wrong; they should open /dev/tty0.
-   I have binary patched /usr/bin/X11/XF86_SVGA to use "tty0"
-   instead of "console".
-
-6. Notes.
-
-   If you compile the next little program, you will be able
-   to really "halt" the system. It will enter a little
-   monitor :)
-
-   main() { reboot(0xfee1dead, 672274793, 0xCDEF0123); }
-
-   This is just a call to the new "halt" function that later
-   kernels have. This is included the "halt" command of
-   the recent sysvinit versions.
-
-   The monitor will also be entered at a kernel panic, or
-   when you press "break". That last function does not
-   work at the moment I think, but it would be useful for
-   kernel debugging.  You don't have alt-scrollock on a serial
-   console to find out the current EIP...
+   open /dev/console. If you have created the new /dev/console device,
+   and your console is NOT the virtual console some programs will fail.
+   Those are programs that want to access the VT interface, and use
+   /dev/console instead of /dev/tty0. Some of those programs are:
+
+   Xfree86, svgalib, gpm, SVGATextMode
+
+   I have binary patched the above mentioned programs to use "tty0"
+   instead of "console".  This will be reported to the maintainers of
+   said programs.
+
+   Note that if you boot without a console= option (or with
+   console=/dev/tty0), /dev/console is the same as /dev/tty0. In that
+   case everything will still work.
 
-Miquel van Smoorenburg <miquels@cistron.nl>, 21-Jun-1996
-Stephen C. Tweedie <sct@dcs.ed.ac.uk>, 23-Dec-1996
+Miquel van Smoorenburg <miquels@cistron.nl>, 15-Jun-1997
--- m68k-2.1.57/drivers/char/fbmem.c.orig	Mon Sep 29 20:19:28 1997
+++ m68k-2.1.57/drivers/char/fbmem.c	Tue Sep 30 23:41:50 1997
@@ -78,6 +78,9 @@
 #ifdef CONFIG_FB_VIRTUAL
 	{ "vfb", virtual_fb_init, vfb_video_setup },
 #endif
+#ifdef CONFIG_FB_MACH64
+	{ "mach64", Mach64_fb_init, Mach64_video_setup },
+#endif
 #ifdef CONFIG_GSP_RESOLVER
 	/* Not a real frame buffer device... */
 	{ "resolver", NULL, resolver_video_setup },
@@ -86,7 +89,7 @@
 
 #define NUM_FB_DRIVERS	(sizeof(fb_drivers)/sizeof(*fb_drivers))
 
-static fb_init_func *pref_init_funcs[FB_MAX];
+static unsigned long (*pref_init_funcs[FB_MAX])(unsigned long);
 static int num_pref_init_funcs __initdata = 0;
 
 
@@ -227,10 +230,10 @@
 	case FBIOGET_VSCREENINFO:
 		fbidx=GET_FB_IDX(inode->i_rdev);
 		vidx=GET_FB_VAR_IDX(inode->i_rdev);
-		if (! vidx) /* ask device driver for current */
+		if (! vidx) { /* ask device driver for current */
 			if ((i = fb->fb_get_var(&var, PROC_CONSOLE())))
 				return i;
-		else
+		} else
 			var=registered_fb[fbidx]->fbvar[vidx-1];
 		return copy_to_user((void *) arg, &var,
 				    sizeof(var)) ? -EFAULT : 0;

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

