Date: Fri, 9 Jan 1998 10:16:28 +0100 (CET)
From: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
To: Ola Nystrom <ola@utel.pp.se>
cc: linux-m68k@lists.linux-m68k.org
Subject: Re: L68K: 2.1.77 is out
In-Reply-To: <Pine.LNX.3.96.980109091322.2236A-100000@ola.utel.pp.se>
Sender: owner-linux-m68k@phil.uni-sb.de

On Fri, 9 Jan 1998, Ola Nystrom wrote:
> On Thu, 8 Jan 1998, Jes Sorensen wrote:
> > 2.1.77 is out - you know where to find it.
> 
> Hmm, where did the Cybervision64/3D support go? I thought I saw that in
> Geerts last (huge) posting..

Here it is, combined with some other things:

  - Unified console driver
  - Frame buffer device updates (incl. Mac by Michael Schmitz et al.)
  - Hyperbolic heartbeat (Roman Hodek)
  - New Amiga floppy driver (Jörg Dorchain)
  - Don't waste time swapping bytes (Andreas Schwab)

Note that this patch isn't tested. While Morpheus already had won, the linker
complained about the missing ide_ack_intr() function, so I couldn't boot 2.1.77
yet.

I forgot to mention yesterday that skeletonfb.c should become a skeleton for
new frame buffer devices, but you may already have guessed so.

diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/Documentation/Configure.help m68k-2.1.77/Documentation/Configure.help
--- /usr/src/m68k-2.1.77/Documentation/Configure.help	Thu Jan  8 22:04:53 1998
+++ m68k-2.1.77/Documentation/Configure.help	Fri Jan  9 01:19:23 1998
@@ -7710,6 +7710,12 @@
   module called pms.o ( = code which can be inserted in and removed
   from the running kernel whenever you want). If you want to compile
   it as a module, say M here and read Documentation/modules.txt.
+Unified console driver (EXPERIMENTAL)
+CONFIG_ABSTRACT_CONSOLE
+  Say Y if you want to use the unified console driver that supports all kinds
+  of consoles: VGA text, frame buffer based graphics, ...
+  Please read http://www.cs.kuleuven.ac.be/~geert/Console/ first before saying
+  Y here. Normal users say N.
 
 # need an empty line after last entry, for sed script in Configure.
 
@@ -7838,36 +7844,18 @@
 # LocalWords:  zorro CAPI AVMB capi avmb VP SYN syncookies EM em pc Ethertalk
 # LocalWords:  Dayna DL Daynatalk LT PhoneNET ATB Daystar queueing CMDS SCBs ls
 # LocalWords:  SCB STATS Thinnet ThunderLAN TLAN Netelligent NetFlex tlan james
-# LocalWords:  caldera Preload dcache Preloading slowdowns schoebel uni NBD nbd
-# LocalWords:  stuttgart rdist TRANS hostnames mango jukeboxes ESS userland PD
+# LocalWords:  caldera Preload dcache Preloading slowdowns schoebel uni
+# LocalWords:  stuttgart rdist TRANS hostnames mango jukeboxes ESS
 # LocalWords:  hardlinked NAMETRANS env mtab fstab umount nologin runlevel gid
 # LocalWords:  transname filespace adm Nodename hostname uname Kernelname bootp
 # LocalWords:  KERNNAME kname ktype kernelname Kerneltype KERNTYPE Alt SCB's RX
 # LocalWords:  dataless kerneltype SYSNAME Netbeui Comtrol Rocketport palmtop
 # LocalWords:  nvram SYSRQ SysRq PrintScreen sysrq NVRAMs NvRAM Shortwave RTTY
 # LocalWords:  HFMODEM shortwave Sitor Amtor Pactor GTOR hfmodem hayes TX TMOUT
-# LocalWords:  IDEPCI IDEDMA idedma PDC pdc TRM trm raidtools luthien nuclecu
-# LocalWords:  unam mx miguel koobera uic EMUL solaris pp ieee lpsg co DMAs TOS
-# LocalWords:  BLDCONFIG preloading jumperless BOOTINIT modutils multipath GRE
-# LocalWords:  misconfigured autoconfiguration IPGRE ICMP tracert ipautofw PIM
-# LocalWords:  netis rlynch autofw ipportfw monmouth ipsubs portforwarding pimd
-# LocalWords:  portfw PIMSM netweb usc pim pf EUI aggregatable PB decapsulate
-# LocalWords:  ipddp Decapsulation DECAP bool HAMRADIO WAN's tcpdump af CD's tx
-# LocalWords:  ethertap multisession PPC MMIO GDT GDTH ICP gdth hamradio LAN's
-# LocalWords:  lmh weejock AIMSlab RadioTrack RTRACK HZP OptoSCC TRX rx TRXECHO
-# LocalWords:  DMASCC paccomm dmascc addr cfg oevsv oe kib picpar FDX baudrate
-# LocalWords:  baudrates fdx HDX hdx PSK kanren frforum QoS SCHED CBQ SCH sched
-# LocalWords:  sch cbq CSZ Shenker Zhang csz SFQ sfq TBF tbf PFIFO fifo PRIO RW
-# LocalWords:  prio Micom xIO dwmw rimi OMIRR omirr omirrd unicode ntfs cmu
-# LocalWords:  Braam braam Schmidt's freiburg nls codepages codepage Romanian
-# LocalWords:  Slovak Slovenian Sorbian Nordic iso Catalan Faeroese Galician SZ
-# LocalWords:  Valencian Slovene Esperanto Estonian Latvian Byelorussian KOI mt
-# LocalWords:  charset Inuit Greenlandic Sami Lappish koi SOFTCURSOR softcursor
-# LocalWords:  Specialix specialix DTR RTS RTSCTS cycladesZ Exabyte ftape's
-# LocalWords:  Iomega's LBFM claus ZFTAPE VFS zftape zft William's lzrw DFLT kb
-# LocalWords:  MTSETBLK MTIOCTOP qft setblk zftape's tar's afio's setdrvbuffer
-# LocalWords:  Procfs Exabyte's THR FCD sysvinit init PSC pscwdt VMIDI Euro SAB
-# LocalWords:  Mostek Fastlane PowerMac PReP PMAC PowerPC Macintoshes Starmax
-# LocalWords:  PowerStack Starmaxes MCOMMON DEVICETREE ATY IMS IMSTT videodev
-# LocalWords:  BT Hauppauge STB bttv Quickcam BW BWQCAM bw qcam Mediavision PMS
-# LocalWords:  pms
+# LocalWords:  QIC TR CONFIG FTAPE Iomega CMS FC FDC Exabyte Iomega's DFLT
+# LocalWords:  tapedrive THR FCD IRQ DMA SZ PCI ftape README txt HOWTO
+# LocalWords:  http www rwth aachen LBFM claus FAQ mt ZFTAPE VFS
+# LocalWords:  zftape zft William's lzrw kerneld BLK zftape's tar's
+# LocalWords:  afio's MTSETBLK MTIOCTOP dev qft setblk BLKSZ NR
+# LocalWords:  setdrvbuffer kb NUMBUFFERS Procfs PROC FS proc resp STD
+# LocalWords:  Alt LocalWords
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/arch/m68k/kernel/Makefile m68k-2.1.77/arch/m68k/kernel/Makefile
--- /usr/src/m68k-2.1.77/arch/m68k/kernel/Makefile	Wed Dec 17 22:56:41 1997
+++ m68k-2.1.77/arch/m68k/kernel/Makefile	Fri Jan  9 01:19:23 1998
@@ -14,9 +14,6 @@
 O_TARGET := kernel.o
 O_OBJS := entry.o process.o traps.o ints.o signal.o ptrace.o \
 	  setup.o sys_m68k.o time.o
-ifdef CONFIG_VT
-O_OBJS += console.o
-endif
 OX_OBJS := m68k_ksyms.o
 
 ifdef CONFIG_KGDB
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/arch/m68k/kernel/console.c m68k-2.1.77/arch/m68k/kernel/console.c
--- /usr/src/m68k-2.1.77/arch/m68k/kernel/console.c	Thu Jan  8 22:04:54 1998
+++ m68k-2.1.77/arch/m68k/kernel/console.c	Fri Jan  9 01:19:23 1998
@@ -1,2781 +0,0 @@
-/*
- *  linux/drivers/char/console.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-/*
- *	console.c
- *
- * This module exports the console io functions:
- *
- *     'void do_keyboard_interrupt(void)'
- *
- *     'int vc_allocate(unsigned int console)'
- *     'int vc_cons_allocated(unsigned int console)'
- *     'int vc_resize(unsigned long lines, unsigned long cols)'
- *     'int vc_resize_con(unsigned long lines, unsigned long cols,
- *			  unsigned int currcons)'
- *     'void vc_disallocate(unsigned int currcons)'
- *
- *     'unsigned long con_init(unsigned long)'
- *     'int con_open(struct tty_struct *tty, struct file * filp)'
- *     'void con_write(struct tty_struct * tty)'
- *     'void vt_console_print(const char * b)'
- *     'void update_screen(int new_console)'
- *
- *     'void do_blank_screen(int)'
- *     'void do_unblank_screen(void)'
- *     'void poke_blanked_console(void)'
- *
- *     'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
- *     'void complement_pos(int currcons, int offset)'
- *     'void invert_screen(int currcons, int offset, int count, int shift)'
- *
- *     'void scrollback(int lines)'
- *     'void scrollfront(int lines)'
- *
- *     'int con_get_font(char *)' 
- *     'int con_set_font(char *)'
- * 
- *     'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
- *     'int mouse_reporting(void)'
- *
- *     'unsigned long get_video_num_lines(unsigned int console)'
- *     'unsigned long get_video_num_columns(unsigned int console)'
- *     'unsigned long get_video_size_row(unsigned int console)'
- *
- * Hopefully this will be a rather complete VT102 implementation.
- *
- * Beeping thanks to John T Kohl.
- *
- * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
- *   Chars, and VT100 enhancements by Peter MacDonald.
- *
- * Copy and paste function by Andrew Haylett,
- *   some enhancements by Alessandro Rubini.
- *
- * User definable mapping table and font loading by Eugene G. Crosser,
- * <crosser@pccross.msk.su>
- *
- * Code to check for different video-cards mostly by Galen Hunt,
- * <g-hunt@ee.utah.edu>
- *
- * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
- * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
- *
- * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
- * Resizing of consoles, aeb, 940926
- *
- * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
- * <poe@daimi.aau.dk>
- *
- * 680x0 LINUX support by Arno Griffioen (arno@usn.nl)
- *
- * 9-Apr-94:  Arno Griffioen: fixed scrolling and delete-char bug.
- *            Scrolling code moved to amicon.c
- *
- * 18-Apr-94: David Carter [carter@cs.bris.ac.uk]. 680x0 LINUX modified 
- *            Integrated support for new low level driver `amicon_ocs.c'
- *
- */
-
-#define BLANK 0x0020
-#define CAN_LOAD_EGA_FONTS    /* undefine if the user must not do this */
-
-/* A bitmap for codes <32. A bit of 1 indicates that the code
- * corresponding to that bit number invokes some special action
- * (such as cursor movement) and should not be displayed as a
- * glyph unless the disp_ctrl mode is explicitly enabled.
- */
-#define CTRL_ACTION 0x0d00ff81
-#define CTRL_ALWAYS 0x0800f501	/* Cannot be overridden by disp_ctrl */
-
-/*
- * Here is the default bell parameters: 750HZ, 1/8th of a second
- */
-#define DEFAULT_BELL_PITCH	750
-#define DEFAULT_BELL_DURATION	(HZ/8)
-
-/*
- *  NOTE!!! We sometimes disable and enable interrupts for a short while
- * (to put a word in video IO), but this will work even for keyboard
- * interrupts. We know interrupts aren't enabled when getting a keyboard
- * interrupt, as we use trap-gates. Hopefully all is well.
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/console.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/console.h>
-#include <linux/kd.h>
-#include <linux/malloc.h>
-#include <linux/major.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#define INCLUDE_LINUX_LOGO_DATA
-#include <asm/linux_logo.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/consolemap.h>
-#include <linux/selection.h>
-#include <linux/console_struct.h>
-
-
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
-struct tty_driver console_driver;
-static int console_refcount;
-static struct tty_struct *console_table[MAX_NR_CONSOLES];
-static struct termios *console_termios[MAX_NR_CONSOLES];
-static struct termios *console_termios_locked[MAX_NR_CONSOLES];
-
-static void vc_init(unsigned int console, int do_clear);
-
-static void update_attr(int currcons);
-static void gotoxy(int currcons, int new_x, int new_y);
-static void save_cur(int currcons);
-static void blank_screen(void);
-static void unblank_screen(void);
-static int con_open(struct tty_struct *, struct file *);
-extern void change_console(unsigned int);
-static inline void set_cursor(int currcons);
-static void reset_terminal(int currcons, int do_clear);
-extern void reset_vc(unsigned int new_console);
-extern void vt_init(void);
-static void set_vesa_blanking(unsigned long arg);
-extern void vesa_blank(void);
-extern void vesa_unblank(void);
-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);
-
-#if 0
-/* Make sure there are no references left to this variables.  */
-unsigned long	video_num_lines;
-unsigned long	video_num_columns;
-unsigned long	video_size_row;
-#endif
-
-static int printable = 0;			/* Is console ready for printing? */
-unsigned long video_font_height;	/* Height of current screen font */
-unsigned long video_scan_lines;		/* Number of scan lines on screen */
-unsigned long default_font_height;      /* Height of default screen font */
-int	      video_mode_512ch = 0;	/* 512-character mode */
-static unsigned short console_charmask = 0x0ff;
-
-static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
-struct vc vc_cons [MAX_NR_CONSOLES];
-
-/* used by kbd_bh - set by keyboard_interrupt */
-       int do_poke_blanked_console = 0;
-       int console_blanked = 0;
-static int blankinterval = 10*60*HZ;
-static int vesa_off_interval = 0;
-static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
-
-/*
- * fg_console is the current virtual console,
- * last_console is the last used one,
- * want_console is the console we want to switch to,
- * kmsg_redirect is the console for kernel messages,
- */
-int fg_console = 0;
-int last_console = 0;
-int want_console = -1;
-int kmsg_redirect = 0;
-
-struct consw *conswitchp;
-
-#define cols            (vc_cons[currcons].d->vc_cols)
-#define rows            (vc_cons[currcons].d->vc_rows)
-#define size_row        (vc_cons[currcons].d->vc_size_row)
-#define screenbuf_size	(vc_cons[currcons].d->vc_screenbuf_size)
-#define cons_num	(vc_cons[currcons].d->vc_num)
-#define origin		(vc_cons[currcons].d->vc_origin)
-#define scr_end		(vc_cons[currcons].d->vc_scr_end)
-#define pos		(vc_cons[currcons].d->vc_pos)
-#define top		(vc_cons[currcons].d->vc_top)
-#define bottom		(vc_cons[currcons].d->vc_bottom)
-#define x		(vc_cons[currcons].d->vc_x)
-#define y		(vc_cons[currcons].d->vc_y)
-#define vc_state	(vc_cons[currcons].d->vc_state)
-#define npar		(vc_cons[currcons].d->vc_npar)
-#define par		(vc_cons[currcons].d->vc_par)
-#define ques		(vc_cons[currcons].d->vc_ques)
-#define attr		(vc_cons[currcons].d->vc_attr)
-#define saved_x		(vc_cons[currcons].d->vc_saved_x)
-#define saved_y		(vc_cons[currcons].d->vc_saved_y)
-#define translate	(vc_cons[currcons].d->vc_translate)
-#define G0_charset	(vc_cons[currcons].d->vc_G0_charset)
-#define G1_charset	(vc_cons[currcons].d->vc_G1_charset)
-#define saved_G0	(vc_cons[currcons].d->vc_saved_G0)
-#define saved_G1	(vc_cons[currcons].d->vc_saved_G1)
-#define utf		(vc_cons[currcons].d->vc_utf)
-#define utf_count	(vc_cons[currcons].d->vc_utf_count)
-#define utf_char	(vc_cons[currcons].d->vc_utf_char)
-#define video_mem_start	(vc_cons[currcons].d->vc_video_mem_start)
-#define video_mem_end	(vc_cons[currcons].d->vc_video_mem_end)
-#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)	
-#define disp_ctrl	(vc_cons[currcons].d->vc_disp_ctrl)
-#define toggle_meta	(vc_cons[currcons].d->vc_toggle_meta)
-#define decscnm		(vc_cons[currcons].d->vc_decscnm)
-#define decom		(vc_cons[currcons].d->vc_decom)
-#define decawm		(vc_cons[currcons].d->vc_decawm)
-#define deccm		(vc_cons[currcons].d->vc_deccm)
-#define decim		(vc_cons[currcons].d->vc_decim)
-#define deccolm	 	(vc_cons[currcons].d->vc_deccolm)
-#define need_wrap	(vc_cons[currcons].d->vc_need_wrap)
-#define has_scrolled	(vc_cons[currcons].d->vc_has_scrolled)
-#define kmalloced	(vc_cons[currcons].d->vc_kmalloced)
-#define report_mouse	(vc_cons[currcons].d->vc_report_mouse)
-#define can_do_color	(vc_cons[currcons].d->vc_can_do_color)
-#define color		(vc_cons[currcons].d->vc_color)
-#define s_color		(vc_cons[currcons].d->vc_s_color)
-#define def_color	(vc_cons[currcons].d->vc_def_color)
-#define	foreground	(color & 0x0f)
-#define background	(color & 0xf0)
-#define charset		(vc_cons[currcons].d->vc_charset)
-#define s_charset	(vc_cons[currcons].d->vc_s_charset)
-#define	intensity	(vc_cons[currcons].d->vc_intensity)
-#define	underline	(vc_cons[currcons].d->vc_underline)
-#define	blink		(vc_cons[currcons].d->vc_blink)
-#define	reverse		(vc_cons[currcons].d->vc_reverse)
-#define	s_intensity	(vc_cons[currcons].d->vc_s_intensity)
-#define	s_underline	(vc_cons[currcons].d->vc_s_underline)
-#define	s_blink		(vc_cons[currcons].d->vc_s_blink)
-#define	s_reverse	(vc_cons[currcons].d->vc_s_reverse)
-#define	ulcolor		(vc_cons[currcons].d->vc_ulcolor)
-#define	halfcolor	(vc_cons[currcons].d->vc_halfcolor)
-#define tab_stop	(vc_cons[currcons].d->vc_tab_stop)
-#define palette		(vc_cons[currcons].d->vc_palette)
-#define bell_pitch	(vc_cons[currcons].d->vc_bell_pitch)
-#define bell_duration	(vc_cons[currcons].d->vc_bell_duration)
-#define sw		(vc_cons[currcons].d->vc_sw)
-
-#define vcmode		(vt_cons[currcons]->vc_mode)
-#if 0 /* XXX */
-#define	vtmode		(vt_cons[currcons]->vt_mode)
-#define	vtpid		(vt_cons[currcons]->vt_pid)
-#define	vtnewvt		(vt_cons[currcons]->vt_newvt)
-#endif
-
-int vc_cons_allocated(unsigned int i)
-{
-	return (i < MAX_NR_CONSOLES && vc_cons[i].d);
-}
-
-int vc_allocate(unsigned int currcons)		/* return 0 on success */
-{
-	if (currcons >= MAX_NR_CONSOLES)
-	  return -ENODEV;
-	if (!vc_cons[currcons].d) {
-	    long p, q;
-
-	    /* prevent users from taking too much memory */
-	    if (currcons >= MAX_NR_USER_CONSOLES && !suser())
-	      return -EPERM;
-
-	    /* due to the granularity of kmalloc, we waste some memory here */
-	    /* the alloc is done in two steps, to optimize the common situation
-	       of a 25x80 console (structsize=216, screenbuf_size=4000) */
-	    p = (long) kmalloc(structsize, GFP_KERNEL);
-	    if (!p)
-		return -ENOMEM;
-	    vc_cons[currcons].d = (struct vc_data *) p;
-	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
-
-	    /* ++Geert: sw->con_init determines console size */
-	    sw = conswitchp;
-	    cons_num = currcons;
-	    sw->con_init (vc_cons[currcons].d);
-	    size_row = cols<<1;
-	    screenbuf_size = rows*size_row;
-
-	    q = (long) kmalloc(screenbuf_size, GFP_KERNEL);
-	    if (!q) {
-		kfree_s((char *) p, structsize);
-		vc_cons[currcons].d = NULL;
-		return -ENOMEM;
-	    }
-	    vc_scrbuf[currcons] = (unsigned short *) q;
-	    kmalloced = 1;
-	    vc_init (currcons, 1);
-	}
-	return 0;
-}
-
-/*
- * Change # of rows and columns (0 means the size of fg_console)
- * [this is to be used together with some user program
- * like resize that changes the hardware videomode]
- */
-int vc_resize(unsigned long lines, unsigned long columns)
-{
-	unsigned long cc, ll, ss, sr;
-	unsigned long occ, oll, oss, osr;
-	unsigned short *p;
-	unsigned int currcons = fg_console, i;
-	unsigned short *newscreens[MAX_NR_CONSOLES];
-	long ol, nl, rlth, rrem;
-
-	cc = (columns ? columns : cols);
-	ll = (lines ? lines : rows);
-	sr = cc << 1;
-	ss = sr * ll;
-
-	/*
-	 * Some earlier version had all consoles of potentially
-	 * different sizes, but that was really messy.
-	 * So now we only change if there is room for all consoles
-	 * of the same size.
-	 */
-	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
-	    if (!vc_cons_allocated(currcons))
-	      newscreens[currcons] = 0;
-	    else {
-		p = (unsigned short *) kmalloc(ss, GFP_USER);
-		if (!p) {
-		    for (i = 0; i< currcons; i++)
-		      if (newscreens[i])
-			kfree_s(newscreens[i], ss);
-		    return -ENOMEM;
-		}
-		newscreens[currcons] = p;
-	    }
-	}
-
-#if 0 /* XXX */
-	get_scrmem(fg_console);
-#endif
-
-	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
-	    if (!vc_cons_allocated(currcons))
-	      continue;
-
-	    oll = rows;
-	    occ = cols;
-	    osr = size_row;
-	    oss = screenbuf_size;
-
-	    rows = ll;
-	    cols = cc;
-	    size_row = sr;
-	    screenbuf_size = ss;
-
-	    rlth = MIN(osr, sr);
-	    rrem = sr - rlth;
-	    ol = origin;
-	    nl = (long) newscreens[currcons];
-	    if (ll < oll)
-	      ol += (oll - ll) * osr;
-
-	    update_attr(currcons);
-	    while (ol < scr_end) {
-		/* ++Geert: TODO: Because the attributes have different meanings
-                   on monochrome and color, they should really be converted if
-                   can_do_color changes... */
-		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
-		if (rrem)
-		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
-		ol += osr;
-		nl += sr;
-	    }
-
-	    if (kmalloced)
-	      kfree_s(vc_scrbuf[currcons], oss);
-	    vc_scrbuf[currcons] = newscreens[currcons];
-	    kmalloced = 1;
-	    screenbuf_size = ss;
-
-	    origin = (long) video_mem_start = vc_scrbuf[currcons];
-	    scr_end = video_mem_end = ((long) video_mem_start) + ss;
-
-	    if (scr_end > nl)
-	      memsetw((void *) nl, video_erase_char, scr_end - nl);
-
-	    /* do part of a reset_terminal() */
-	    top = 0;
-	    bottom = rows;
-	    gotoxy(currcons, x, y);
-	    save_cur(currcons);
-	}
-
-#if 0 /* XXX */
-	set_scrmem(fg_console, 0);
-	set_origin(fg_console);
-#endif /* XXX */
-	/* don't update in graphics mode */
-	if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
-	    update_screen(fg_console);
-
-	set_cursor(fg_console);
-
-	return 0;
-}
-
-/*
- * ++Geert: Change # of rows and columns for one specific console.
- * Of course it's not messy to have all consoles of potentially different sizes,
- * except on PCish hardware :-)
- *
- * This is called by the low level console driver (arch/m68k/console/fbcon.c or
- * arch/m68k/console/txtcon.c)
- */
-void vc_resize_con(unsigned long lines, unsigned long columns,
-		   unsigned int currcons)
-{
-	unsigned long cc, ll, ss, sr;
-	unsigned long occ, oll, oss, osr;
-	unsigned short *newscreen;
-	long ol, nl, rlth, rrem;
-	struct winsize ws;
-
-	if (!columns || !lines || currcons >= MAX_NR_CONSOLES)
-	    return;
-
-	cc = columns;
-	ll = lines;
-	sr = cc << 1;
-	ss = sr * ll;
-
-	if (!vc_cons_allocated(currcons))
-	    newscreen = 0;
-	else if (!(newscreen = (unsigned short *) kmalloc(ss, GFP_USER)))
-	    return;
-
-	if (vc_cons_allocated(currcons)) {
-	    oll = rows;
-	    occ = cols;
-	    osr = size_row;
-	    oss = screenbuf_size;
-
-	    rows = ll;
-	    cols = cc;
-	    size_row = sr;
-	    screenbuf_size = ss;
-
-	    rlth = MIN(osr, sr);
-	    rrem = sr - rlth;
-	    ol = origin;
-	    nl = (long) newscreen;
-	    if (ll < oll)
-	      ol += (oll - ll) * osr;
-
-	    update_attr(currcons);
-	    while (ol < scr_end) {
-		/* ++Geert: TODO: Because the attributes have different meanings
-                   on monochrome and color, they should really be converted if
-                   can_do_color changes... */
-		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
-		if (rrem)
-		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
-		ol += osr;
-		nl += sr;
-	    }
-
-	    if (kmalloced)
-	      kfree_s(vc_scrbuf[currcons], oss);
-	    vc_scrbuf[currcons] = newscreen;
-	    kmalloced = 1;
-	    screenbuf_size = ss;
-
-	    origin = (long) video_mem_start = vc_scrbuf[currcons];
-	    scr_end = video_mem_end = ((long)video_mem_start) + ss;
-
-	    if (scr_end > nl)
-	      memsetw((void *) nl, video_erase_char, scr_end - nl);
-
-	    /* do part of a reset_terminal() */
-	    top = 0;
-	    bottom = rows;
-	    gotoxy(currcons, x, y);
-	    save_cur(currcons);
-
-	    ws.ws_row = rows;
-	    ws.ws_col = cols;
-	    if (memcmp(&ws, &console_table[currcons]->winsize, sizeof (struct winsize)) &&
-	        console_table[currcons]->pgrp > 0)
-		kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
-	    console_table[currcons]->winsize = ws;
-	}
-
-	/* don't update in graphics mode */
-	if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
-	    update_screen(fg_console);
-}
-
-void vc_disallocate(unsigned int currcons)
-{
-	if (vc_cons_allocated(currcons)) {
-	    if (kmalloced)
-	      kfree_s(vc_scrbuf[currcons], screenbuf_size);
-	    if (currcons >= MIN_NR_CONSOLES)
-	      kfree_s(vc_cons[currcons].d, structsize);
-	    vc_cons[currcons].d = 0;
-	}
-}
-
-
-#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
-#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
-#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
-
-#define decarm		VC_REPEAT
-#define decckm		VC_CKMODE
-#define kbdapplic	VC_APPLIC
-#define lnm		VC_CRLF
-
-/*
- * this is what the terminal answers to a ESC-Z or csi0c query.
- */
-#define VT100ID "\033[?1;2c"
-#define VT102ID "\033[?6c"
-
-static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
-				       8,12,10,14, 9,13,11,15 };
-
-/* the default colour table, for VGA+ colour systems */
-int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
-    0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
-int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
-    0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
-int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
-    0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
-
-/*
- * gotoxy() must verify all boundaries, because the arguments
- * might also be negative. If the given position is out of
- * bounds, the cursor is placed at the nearest margin.
- */
-static void gotoxy(int currcons, int new_x, int new_y)
-{
-	int min_y, max_y;
-
-	if (new_x < 0)
-		x = 0;
-	else
-		if (new_x >= cols)
-			x = cols - 1;
-		else
-			x = new_x;
- 	if (decom) {
-		min_y = top;
-		max_y = bottom;
-	} else {
-		min_y = 0;
-		max_y = rows;
-	}
-	if (new_y < min_y)
-		y = min_y;
-	else if (new_y >= max_y)
-		y = max_y - 1;
-	else
-		y = new_y;
-	pos = video_mem_start + y * cols + x;
-	need_wrap = 0;
-}
-
-/* for absolute user moves, when decom is set */
-static void gotoxay(int currcons, int new_x, int new_y)
-{
-	gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
-}
-
-static void hide_cursor(int currcons)
-{
-	sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
-	return;
-}
-
-static void set_cursor(int currcons)
-{
-	if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
-		return;
-	if (deccm)
-		sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
-	else
-		hide_cursor(currcons);
-	return;
-}
-
-void no_scroll(char *str, int *ints)
-{
-  /*
-   * no_scroll currently does nothing on the m68k.
-   */
-}
-
-/*
- * Arno:
- * Why do we need these? The keyboard code doesn't seem to do anything
- * with them either...
- */
-void scrollfront(int l)
-{
-	return;
-}
-
-void scrollback(int l)
-{
-	return;
-}
-
-static void scrup(int currcons, unsigned int t, unsigned int b, int nr)
-{
-	unsigned short *p;
-	int i;
-
-	if (b > rows || t >= b)
-		return;
-
-	memmove (video_mem_start + t * cols,
-		 video_mem_start + (t + nr) * cols,
-		 (b - t - nr) * cols * 2);
-
-	p = video_mem_start + (b - nr) * cols;
-	for (i = nr * cols; i > 0; i--)
-		*p++ = video_erase_char;
-
-	if (currcons != fg_console)
-		return;
-/*
- * Arno:
- * Scrolling has now been moved to amicon.c where it should have
- * been all along.
- */
-	sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
-
-	return;
-	
-}
-
-static void scrdown(int currcons, unsigned int t, unsigned int b,
-		    int nr)
-{
-	unsigned short *p;
-	int i;
-
-	if (b > rows || t >= b)
-		return;
-
-	memmove (video_mem_start + (t + nr) * cols,
-		 video_mem_start + t * cols,
-		 (b - t - nr) * cols * 2);
-
-	p = video_mem_start + t * cols;
-	for (i = nr * cols; i > 0; i--)
-	  *p++ = video_erase_char;
-
-	if (currcons != fg_console)
-	  return;
-/*
- * Arno:
- * Scrolling has now been moved to amicon.c where it should have
- * been all along.
- */
-	sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
-
-	return;
-}
-
-static void lf(int currcons)
-{
-    	/* don't scroll if above bottom of scrolling region, or
-	 * if below scrolling region
-	 */
-    	if (y+1 == bottom)
-		scrup(currcons,top,bottom, 1);
-	else if (y < rows-1) {
-	    	y++;
-		pos += cols;
-	}
-	need_wrap = 0;
-}
-
-static void ri(int currcons)
-{
-    	/* don't scroll if below top of scrolling region, or
-	 * if above scrolling region
-	 */
-	if (y == top)
-		scrdown(currcons,top,bottom, 1);
-	else if (y > 0) {
-		y--;
-		pos -= cols;
-	}
-	need_wrap = 0;
-}
-
-static inline void cr(int currcons)
-{
-	pos -= x;
-	need_wrap = x = 0;
-}
-
-static inline void bs(int currcons)
-{
-	if (x) {
-		pos--;
-		x--;
-		need_wrap = 0;
-	}
-}
-
-static inline void del(int currcons)
-{
-	/* ignored */
-}
-
-static void csi_J(int currcons, int vpar)
-{
-	unsigned long count;
-	unsigned short *start;
-
-	switch (vpar) {
-		case 0:	/* erase from cursor to end of display */
-			count = (video_mem_start
-				 + cols * rows
-				 - pos);
-			start = pos;
-			if (currcons != fg_console)
-			  break;
-			/* 680x0 do in two stages */
-			sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
-			sw->con_clear(vc_cons[currcons].d,y+1,0,rows-y-1, cols);
-			break;
-		case 1:	/* erase from start to cursor */
-			count = pos - video_mem_start + 1;
-			start = video_mem_start;
-			if (currcons != fg_console)
-			  break;
-			/* 680x0 do in two stages */
-			sw->con_clear(vc_cons[currcons].d,0,0,y, cols);
-			sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
-			break;
-		case 2: /* erase whole display */
-			count = cols * rows;
-			start = video_mem_start;
-			if (currcons != fg_console)
-			  break;
-			sw->con_clear(vc_cons[currcons].d,0,0,rows, cols);
-			break;
-		default:
-			return;
-	}
-	while (count-- > 0)
-	  *start++ = video_erase_char;
-	need_wrap = 0;
-}
-
-static void csi_K(int currcons, int vpar)
-{
-	unsigned long count;
-	unsigned short *start;
-
-	switch (vpar) {
-		case 0:	/* erase from cursor to end of line */
-			count = cols - x;
-			start = pos;
-			if (currcons != fg_console)
-			  break;
-			sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
-			break;
-		case 1:	/* erase from start of line to cursor */
-			start = pos - x;
-			count = x + 1;
-			if (currcons != fg_console)
-			  break;
-			sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
-			break;
-		case 2: /* erase whole line */
-			start = pos - x;
-			count = cols;
-			if (currcons != fg_console)
-			  break;
-			sw->con_clear(vc_cons[currcons].d,y,0,1,cols);
-			break;
-		default:
-			return;
-	}
-	while (count-- > 0)
-	  *start++ = video_erase_char;
-	need_wrap = 0;
-}
-
-static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
-{					  /* not vt100? */
-	unsigned long count;
-	unsigned short * start;
-
-	if (!vpar)
-		vpar++;
-
-	start = pos;
-	count = (vpar > cols-x) ? (cols-x) : vpar;
-
-	if (currcons == fg_console)
-		sw->con_clear(vc_cons[currcons].d,y,x,1,count);
-
-	while (count-- > 0)
-		*start++ = video_erase_char;
-	need_wrap = 0;
-}
-
-/*
- * Arno: 
- * On 680x0 attributes are currently not used. This piece of code
- * seems hardware independent, but uses the EGA/VGA way of representing
- * attributes. 
- * TODO: modify for 680x0 and add attribute processing to putc code.
- *
- * ++roman: I completely changed the attribute format for monochrome
- * mode (!can_do_color). The formerly used MDA (monochrome display
- * adapter) format didn't allow the combination of certain effects.
- * Now the attribute is just a bit vector:
- *  Bit 0..1: intensity (0..2)
- *  Bit 2   : underline
- *  Bit 3   : reverse
- *  Bit 7   : blink
- */
-static void update_attr(int currcons)
-{
-	if (!can_do_color) {
-		/* Special treatment for monochrome */
-		attr = intensity |
-			(underline ? 4 : 0) |
-			((reverse ^ decscnm) ? 8 : 0) |
-			(blink ? 0x80 : 0);
-		video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
-		return;
-	}
-
-	attr = color;
-	if (underline)
-		attr = (attr & 0xf0) | ulcolor;
-	else if (intensity == 0)
-		attr = (attr & 0xf0) | halfcolor;
-	if (reverse ^ decscnm)
-		attr = reverse_video_char(attr);
-	if (blink)
-		attr ^= 0x80;
-	if (intensity == 2)
-		attr ^= 0x08;
-	if (decscnm)
-		video_erase_char = (reverse_video_char(color) << 8) | ' ';
-	else
-		video_erase_char = (color << 8) | ' ';
-}
-
-static void default_attr(int currcons)
-{
-	intensity = 1;
-	underline = 0;
-	reverse = 0;
-	blink = 0;
-	color = def_color;
-}
-
-static void csi_m(int currcons)
-{
-	int i;
-
-	for (i=0;i<=npar;i++)
-		switch (par[i]) {
-			case 0:	/* all attributes off */
-				default_attr(currcons);
-				break;
-			case 1:
-				intensity = 2;
-				break;
-			case 2:
-				intensity = 0;
-				break;
-			case 4:
-				underline = 1;
-				break;
-			case 5:
-				blink = 1;
-				break;
-			case 7:
-				reverse = 1;
-				break;
-			case 10: /* ANSI X3.64-1979 (SCO-ish?)
-				  * Select primary font, don't display
-				  * control chars if defined, don't set
-				  * bit 8 on output.
-				  */
-				translate = set_translate(charset == 0
-						? G0_charset
-						: G1_charset);
-				disp_ctrl = 0;
-				toggle_meta = 0;
-				break;
-			case 11: /* ANSI X3.64-1979 (SCO-ish?)
-				  * Select first alternate font, let's
-				  * chars < 32 be displayed as ROM chars.
-				  */
-				translate = set_translate(IBMPC_MAP);
-				disp_ctrl = 1;
-				toggle_meta = 0;
-				break;
-			case 12: /* ANSI X3.64-1979 (SCO-ish?)
-				  * Select second alternate font, toggle
-				  * high bit before displaying as ROM char.
-				  */
-				translate = set_translate(IBMPC_MAP);
-				disp_ctrl = 1;
-				toggle_meta = 1;
-				break;
-			case 21:
-			case 22:
-				intensity = 1;
-				break;
-			case 24:
-				underline = 0;
-				break;
-			case 25:
-				blink = 0;
-				break;
-			case 27:
-				reverse = 0;
-				break;
-			case 38: /* ANSI X3.64-1979 (SCO-ish?)
-				  * Enables underscore, white foreground
-				  * with white underscore (Linux - use
-				  * default foreground).
-				  */
-				color = (def_color & 0x0f) | background;
-				underline = 1;
-				break;
-			case 39: /* ANSI X3.64-1979 (SCO-ish?)
-				  * Disable underline option.
-				  * Reset colour to default? It did this
-				  * before...
-				  */
-				color = (def_color & 0x0f) | background;
-				underline = 0;
-				break;
-			case 49:
-				color = (def_color & 0xf0) | foreground;
-				break;
-			default:
-				if (par[i] >= 30 && par[i] <= 37)
-					color = color_table[par[i]-30]
-						| background; 
-				else if (par[i] >= 40 && par[i] <= 47)
-					color = (color_table[par[i]-40]<<4)
-						| foreground;
-				break;
-		}
-	update_attr(currcons);
-}
-
-static void respond_string(const char * p, struct tty_struct * tty)
-{
-	while (*p) {
-		tty_insert_flip_char(tty, *p, 0);
-		p++;
-	}
-	tty_schedule_flip(tty);
-}
-
-static inline void cursor_report(int currcons, struct tty_struct * tty)
-{
-	char buf[40];
-
-	sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
-	respond_string(buf, tty);
-}
-
-static inline void status_report(struct tty_struct * tty)
-{
-	respond_string("\033[0n", tty);	/* Terminal ok */
-}
-
-static inline void respond_ID(struct tty_struct * tty)
-{
-	respond_string(VT102ID, tty);
-}
-
-void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
-{
-	char buf[8];
-
-	sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
-		(char)('!' + mry));
-	respond_string(buf, tty);
-}
-
-/* invoked via ioctl(TIOCLINUX) and through set_selection */
-int mouse_reporting(void)
-{
-	int currcons = fg_console;
-
-	return report_mouse;
-}
-
-int tioclinux(struct tty_struct *tty, unsigned long arg)
-{
-	char type, data;
-
-	if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
-		return -EINVAL;
-	if (current->tty != tty && !suser())
-		return -EPERM;
-	if (get_user(type, (char *)arg))
-		return -EFAULT;
-	switch (type)
-	{
-		case 2:
-			return set_selection(arg, tty, 1);
-		case 3:
-			return paste_selection(tty);
-		case 4:
-			do_unblank_screen();
-			return 0;
-		case 5:
-			return sel_loadlut(arg);
-		case 6:
-			
-	/*
-	 * Make it possible to react to Shift+Mousebutton.
-	 * Note that 'shift_state' is an undocumented
-	 * kernel-internal variable; programs not closely
-	 * related to the kernel should not use this.
-	 */
-	 		data = shift_state;
-			return put_user(data, (char *) arg);
-		case 7:
-			data = mouse_reporting();
-			return put_user(data, (char *) arg);
-		case 10:
-			set_vesa_blanking(arg);
-			return 0;
-		case 11:	/* set kmsg redirect */
-			if (!suser())
-				return -EPERM;
-			if (get_user(data, (char *)arg+1))
-					return -EFAULT;
-			kmsg_redirect = data;
-			return 0;
-		case 12:	/* get fg_console */
-			return fg_console;
-	}
-	return -EINVAL;
-}
-
-static inline unsigned short *screenpos(int currcons, int offset, int viewed)
-{
-	unsigned short *p = (unsigned short *)(origin + offset);
-#if 0
-	if (viewed && currcons == fg_console)
-		p -= (__real_origin - __origin);
-#endif
-	return p;
-}
-
-/* Note: inverting the screen twice should revert to the original state */
-void invert_screen(int currcons, int offset, int count, int viewed)
-{
-	unsigned short *p;
-	unsigned short xx, yy, oldattr;
-
-	count /= 2;
-	p = screenpos(currcons, offset, viewed);
-	xx = (offset >> 1) % cols;
-	yy = (offset >> 1) / cols;
-	oldattr = attr;
-	if (can_do_color)
-		while (count--) {
-			unsigned short old = scr_readw(p);
-			unsigned short new = reverse_video_short(old);
-			scr_writew(new, p);
-			p++;
-			if (currcons != fg_console)
-				continue;
-			attr = new >> 8;
-			sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
-			if (++xx == cols)
-				xx = 0, ++yy;
-		}
-	else
-		while (count--) {
-			unsigned short old = scr_readw(p);
-			unsigned short new = old ^ 0x800;
-			scr_writew(new, p);
-			p++;
-			if (currcons != fg_console)
-				continue;
-			attr = new >> 8;
-			sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
-			if (++xx == cols)
-				xx = 0, ++yy;
-		}
-	attr = oldattr;
-}
-
-/* used by selection: complement pointer position */
-void complement_pos(int currcons, int offset)
-{
-	static unsigned short *p = NULL;
-	static unsigned short old = 0;
-	static unsigned short oldx = 0, oldy = 0;
-	unsigned short new, oldattr;
-
-	oldattr = attr;
-	if (p) {
-		scr_writew(old, p);
-		if (currcons == fg_console) {
-			attr = old >> 8;
-			sw->con_putc(vc_cons[currcons].d, old & 0xff, oldy, oldx);
-			attr = oldattr;
-		}
-	}
-	if (offset == -1)
-		p = NULL;
-	else {
-		p = screenpos(currcons, offset, 1);
-		old = scr_readw(p);
-		oldx = (offset >> 1) % cols;
-		oldy = (offset >> 1) / cols;
-		if (can_do_color)
-			new = old ^ 0x7700;
-		else
-			new = old ^ 0x800;
-		scr_writew(new, p);
-		if (currcons == fg_console) {
-			attr = new >> 8;
-			sw->con_putc(vc_cons[currcons].d, new & 0xff, oldy, oldx);
-			attr = oldattr;
-		}
-	}
-}
-
-/* used by selection */
-unsigned short screen_word(int currcons, int offset, int viewed)
-{
-	return scr_readw(screenpos(currcons, offset, viewed));
-}
-
-/* used by selection - convert a screen word to a glyph number */
-int scrw2glyph(unsigned short scr_word)
-{
-	return ( video_mode_512ch )
-		? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
-		: scr_word & 0x00ff;
-}
-
-/* used by vcs - note the word offset */
-unsigned short *screen_pos(int currcons, int w_offset, int viewed)
-{
-	return screenpos(currcons, 2 * w_offset, viewed);
-}
-
-void getconsxy(int currcons, char *p)
-{
-	p[0] = x;
-	p[1] = y;
-}
-
-void putconsxy(int currcons, char *p)
-{
-	gotoxy(currcons, p[0], p[1]);
-	set_cursor(currcons);
-}
-
-static void set_mode(int currcons, int on_off)
-{
-	int i;
-
-	for (i=0; i<=npar; i++)
-		if (ques) switch(par[i]) {	/* DEC private modes set/reset */
-			case 1:			/* Cursor keys send ^[Ox/^[[x */
-				if (on_off)
-					set_kbd(decckm);
-				else
-					clr_kbd(decckm);
-				break;
-			case 3:	/* 80/132 mode switch unimplemented */
-				deccolm = on_off;
-#if 0
-				(void) vc_resize(rows, deccolm ? 132 : 80);
-				/* this alone does not suffice; some user mode
-				   utility has to change the hardware regs */
-#endif
-				break;
-			case 5:			/* Inverted screen on/off */
-				if (decscnm != on_off) {
-					decscnm = on_off;
-					invert_screen(currcons, 0, screenbuf_size, 0);
-					update_attr(currcons);
-				}
-				break;
-			case 6:			/* Origin relative/absolute */
-				decom = on_off;
-				gotoxay(currcons,0,0);
-				break;
-			case 7:			/* Autowrap on/off */
-				decawm = on_off;
-				break;
-			case 8:			/* Autorepeat on/off */
-				if (on_off)
-					set_kbd(decarm);
-				else
-					clr_kbd(decarm);
-				break;
-			case 9:
-				report_mouse = on_off ? 1 : 0;
-				break;
-			case 25:		/* Cursor on/off */
-				deccm = on_off;
-				set_cursor(currcons);
-				break;
-			case 1000:
-				report_mouse = on_off ? 2 : 0;
-				break;
-		} else switch(par[i]) {		/* ANSI modes set/reset */
-			case 3:			/* Monitor (display ctrls) */
-				disp_ctrl = on_off;
-				break;
-			case 4:			/* Insert Mode on/off */
-				decim = on_off;
-				break;
-			case 20:		/* Lf, Enter == CrLf/Lf */
-				if (on_off)
-					set_kbd(lnm);
-				else
-					clr_kbd(lnm);
-				break;
-		}
-}
-
-static void setterm_command(int currcons)
-{
-	switch(par[0]) {
-		case 1:	/* set color for underline mode */
-			if (can_do_color && par[1] < 16) {
-				ulcolor = color_table[par[1]];
-				if (underline)
-					update_attr(currcons);
-			}
-			break;
-		case 2:	/* set color for half intensity mode */
-			if (can_do_color && par[1] < 16) {
-				halfcolor = color_table[par[1]];
-				if (intensity == 0)
-					update_attr(currcons);
-			}
-			break;
-		case 8:	/* store colors as defaults */
-			def_color = attr;
-			default_attr(currcons);
-			update_attr(currcons);
-			break;
-		case 9:	/* set blanking interval */
-			blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
-			poke_blanked_console();
-			break;
-		case 10: /* set bell frequency in Hz */
-			if (npar >= 1)
-				bell_pitch = par[1];
-			else
-				bell_pitch = DEFAULT_BELL_PITCH;
-			break;
-		case 11: /* set bell duration in msec */
-			if (npar >= 1)
-				bell_duration = (par[1] < 2000) ?
-					par[1]*HZ/1000 : 0;
-			else
-				bell_duration = DEFAULT_BELL_DURATION;
-			break;
-		case 12: /* bring specified console to the front */
-			if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
-				update_screen(par[1]-1);
-			break;
-		case 13: /* unblank the screen */
-			unblank_screen();
-			break;
-		case 14: /* set vesa powerdown interval */
-			vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
-			break;
-	}
-}
-
-static inline void insert_char(int currcons)
-{
-	int i;
-	unsigned short *p = pos;
-
-	for (i = cols - x - 2; i >= 0; i--)
-		p[i + 1] = p[i];
-	*pos = video_erase_char;
-	need_wrap = 0;
-
-	if (currcons != fg_console)
-		return;
-
-	/* Arno:
-	 * Move the remainder of the line (-1 character) one spot to the right
-	 */
-	sw->con_bmove(vc_cons[currcons].d,y,x,y,x+1,1,(cols-x-1));
-	/*
-	 * Print the erase char on the current position
-	 */
-	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x);
-}
-
-static void csi_at(int currcons, unsigned int nr)
-{
-	int i;
-	unsigned short *p;
-
-	if (nr > cols - x)
-		nr = cols - x;
-	else if (!nr)
-		nr = 1;
-
-	p = pos + cols - x - nr;
-	while (--p >= pos)
-		p[nr] = *p;
-	for (i = 0; i < nr; i++)
-		*++p = video_erase_char;
-	need_wrap = 0;
-
-	if (currcons != fg_console)
-		return;
-
-	sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
-		       1, cols - x - nr);
-	while (nr--)
-		sw->con_putc (vc_cons[currcons].d,
-			      video_erase_char & 0x00ff, y, x + nr);
-}
-
-static void csi_L(int currcons, unsigned int nr)
-{
-	if (nr > rows)
-		nr = rows;
-	else if (!nr)
-		nr = 1;
-	scrdown (currcons, y, bottom, nr);
-	need_wrap = 0;
-}
-
-static void csi_P(int currcons, unsigned int nr)
-{
-	int i;
-	unsigned short *p, *end;
-
-	if (nr > cols - x)
-		nr = cols - x;
-	else if (!nr)
-		nr = 1;
-
-	p = pos;
-	end = pos + cols - x - nr;
-	while (p < end)
-	  *p = p[nr], p++;
-	for (i = 0; i < nr; i++)
-	  *p++ = video_erase_char;
-	need_wrap = 0;
-
-	if (currcons != fg_console)
-	  return;
-
-	sw->con_bmove (vc_cons[currcons].d, y, x + nr, y, x,
-		       1, cols - x - nr);
-
-	while (nr--)
-	  sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
-			y, cols - 1 - nr);
-}
-
-static void csi_M(int currcons, unsigned int nr)
-{
-	if (nr > rows)
-		nr = rows;
-	else if (!nr)
-		nr=1;
-	scrup (currcons, y, bottom, nr);
-	need_wrap = 0;
-}
-
-static void save_cur(int currcons)
-{
-	saved_x		= x;
-	saved_y		= y;
-	s_intensity	= intensity;
-	s_underline	= underline;
-	s_blink		= blink;
-	s_reverse	= reverse;
-	s_charset	= charset;
-	s_color		= color;
-	saved_G0	= G0_charset;
-	saved_G1	= G1_charset;
-}
-
-static void restore_cur(int currcons)
-{
-	gotoxy(currcons,saved_x,saved_y);
-	intensity	= s_intensity;
-	underline	= s_underline;
-	blink		= s_blink;
-	reverse		= s_reverse;
-	charset		= s_charset;
-	color		= s_color;
-	G0_charset	= saved_G0;
-	G1_charset	= saved_G1;
-	translate	= set_translate(charset ? G1_charset : G0_charset);
-	update_attr(currcons);
-	need_wrap = 0;
-}
-
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
-	EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
-	ESpalette };
-
-static void reset_terminal(int currcons, int do_clear)
-{
-	top		= 0;
-	bottom		= rows;
-	vc_state	= ESnormal;
-	ques		= 0;
-	translate	= set_translate(LAT1_MAP);
-	G0_charset	= LAT1_MAP;
-	G1_charset	= GRAF_MAP;
-	charset		= 0;
-	need_wrap	= 0;
-	report_mouse	= 0;
-	utf             = 0;
-	utf_count       = 0;
-
-	disp_ctrl	= 0;
-	toggle_meta	= 0;
-
-	decscnm		= 0;
-	decom		= 0;
-	decawm		= 1;
-	deccm		= 1;
-	decim		= 0;
-
-	set_kbd(decarm);
-	clr_kbd(decckm);
-	clr_kbd(kbdapplic);
-	clr_kbd(lnm);
-	kbd_table[currcons].lockstate = 0;
-	kbd_table[currcons].slockstate = 0;
-	kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
-	kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
-	set_leds();
-
-	default_attr(currcons);
-	update_attr(currcons);
-
-	tab_stop[0]	= 0x01010100;
-	tab_stop[1]	=
-	tab_stop[2]	=
-	tab_stop[3]	=
-	tab_stop[4]	= 0x01010101;
-
-	bell_pitch = DEFAULT_BELL_PITCH;
-	bell_duration = DEFAULT_BELL_DURATION;
-
-	gotoxy(currcons,0,0);
-	save_cur(currcons);
-	if (do_clear)
-	    csi_J(currcons,2);
-}
-
-/*
- * Turn the Scroll-Lock LED on when the tty is stopped
- */
-static void con_stop(struct tty_struct *tty)
-{
-	int console_num;
-	if (!tty)
-		return;
-	console_num = MINOR(tty->device) - (tty->driver.minor_start);
-	if (!vc_cons_allocated(console_num))
-		return;
-	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
-	set_leds();
-}
-
-/*
- * Turn the Scroll-Lock LED off when the console is started
- */
-static void con_start(struct tty_struct *tty)
-{
-	int console_num;
-	if (!tty)
-		return;
-	console_num = MINOR(tty->device) - (tty->driver.minor_start);
-	if (!vc_cons_allocated(console_num))
-		return;
-	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
-	set_leds();
-}
-
-static void con_flush_chars(struct tty_struct *tty)
-{
-	unsigned int currcons;
-	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
-
-	currcons = vt->vc_num;
-	if (vcmode != KD_GRAPHICS)
-		set_cursor(currcons);
-}	
-
-static int do_con_write(struct tty_struct * tty, int from_user,
-			const unsigned char *buf, int count)
-{
-	int c, tc, ok, n = 0;
-	unsigned int currcons;
-	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
-
-	currcons = vt->vc_num;
-	if (!vc_cons_allocated(currcons)) {
-		/* could this happen? */
-		static int error = 0;
-		if (!error) {
-			error = 1;
-			printk("con_write: tty %d not allocated\n", currcons+1);
-		}
-		return 0;
-	}
-
-	/* undraw cursor first */
-	if (currcons == fg_console)
-		hide_cursor(currcons);
-	
-	/* clear the selection */
-	if (currcons == sel_cons)
-		clear_selection();
-
-        disable_bh(CONSOLE_BH);
-	while (count) {
-		enable_bh(CONSOLE_BH);
-		if (from_user)
-			get_user(c, buf);
-		else
-			c = *buf;
-		buf++; n++; count--;
-		disable_bh(CONSOLE_BH);
-
-		if (utf) {
-		    /* Combine UTF-8 into Unicode */
-		    /* Incomplete characters silently ignored */
-		    if(c > 0x7f) {   
-			if (utf_count > 0 && (c & 0xc0) == 0x80) {
-				utf_char = (utf_char << 6) | (c & 0x3f);
-				utf_count--;
-				if (utf_count == 0)
-				    tc = c = utf_char;
-				else continue;
-			} else {
-				if ((c & 0xe0) == 0xc0) {
-				    utf_count = 1;
-				    utf_char = (c & 0x1f);
-				} else if ((c & 0xf0) == 0xe0) {
-				    utf_count = 2;
-				    utf_char = (c & 0x0f);
-				} else if ((c & 0xf8) == 0xf0) {
-				    utf_count = 3;
-				    utf_char = (c & 0x07);
-				} else if ((c & 0xfc) == 0xf8) {
-				    utf_count = 4;
-				    utf_char = (c & 0x03);
-				} else if ((c & 0xfe) == 0xfc) {
-				    utf_count = 5;
-				    utf_char = (c & 0x01);
-				} else
-				    utf_count = 0;
-				continue;
-			}
-		    } else {
-			tc = c;
-			utf_count = 0;
-		    }
-		} else {	/* no utf */
-		    tc = translate[toggle_meta ? (c|0x80) : c];
-		}
-
-                /* If the original code was a control character we
-                 * only allow a glyph to be displayed if the code is
-                 * not normally used (such as for cursor movement) or
-                 * if the disp_ctrl mode has been explicitly enabled.
-                 * Certain characters (as given by the CTRL_ALWAYS
-                 * bitmap) are always displayed as control characters,
-                 * as the console would be pretty useless without
-                 * them; to display an arbitrary font position use the
-                 * direct-to-font zone in UTF-8 mode.
-                 */
-                ok = tc && (c >= 32 ||
-                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS
-                                         : CTRL_ACTION) >> c) & 1)))
-                        && (c != 127 || disp_ctrl)
-			&& (c != 128+27);
-
-		if (vc_state == ESnormal && ok) {
-			/* Now try to find out how to display it */
-			tc = conv_uni_to_pc(tc);
-			if ( tc == -4 ) {
-                                /* If we got -4 (not found) then see if we have
-                                   defined a replacement character (U+FFFD) */
-                                tc = conv_uni_to_pc(0xfffd);
-                        } else if ( tc == -3 ) {
-                                /* Bad hash table -- hope for the best */
-                                tc = c;
-                        }
-			if (tc & ~console_charmask)
-				continue; /* Conversion failed */
-
-			if (need_wrap) {
-				cr(currcons);
-				lf(currcons);
-			}
-
-#if 1 /* XXX */
-                        /* DPC: 1994-04-12
-                         *   Speed up overstrike mode, using new putcs.
-                         *
-                         * P.S. I hate 8 spaces per tab! Use Emacs!
-			 */
-			
-			/* Only use this for the foreground console,
-			   where we really draw the chars */
-
-			if (count > 2 &&
-			    !decim && !utf && currcons == fg_console) { 
-				static char putcs_buf[256];
-				char   *p     = putcs_buf;
-				int putcs_count  = 1;
-				ushort nextx  = x + 1;
-
-				*p++ = tc;
-				*pos++ = tc | (attr << 8);
-
-				if (nextx == cols) {
-					sw->con_putc(vc_cons[currcons].d,
-						     *putcs_buf, y, x);
-					pos--;
-					need_wrap = decawm;
-					continue;
-				}
-				
-				while (count)
-				{
-					enable_bh(CONSOLE_BH);
-					if (from_user)
-						get_user(c, buf);
-					else
-						c = *buf;
-					disable_bh(CONSOLE_BH);
-					tc = translate[toggle_meta ? (c|0x80) : c];
-					if (!tc ||
-					    !(c >= 32
-					      || !(((disp_ctrl ? CTRL_ALWAYS
-						   : CTRL_ACTION) >> c) & 1)))
-					  break;
-					tc = conv_uni_to_pc(tc);
-					if (tc == -4)
-					  tc = conv_uni_to_pc(0xfffd);
-					else if (tc == -3)
-					  tc = c;
-
-					buf++; n++; count--;
-					if (tc & ~console_charmask)
-					  continue; /* Conversion failed */
-
-					*p++ = tc;
-					*pos++ = tc | (attr << 8);
-					++putcs_count;
-					++nextx;
-					if (nextx == cols || 
-					    putcs_count == sizeof (putcs_buf))
-						break;
-				}
-				
-				sw->con_putcs(vc_cons[currcons].d,
-					      putcs_buf, putcs_count, y, x);
-				if (nextx == cols) {
-					pos--;
-					x         = cols-1;
-					need_wrap = decawm;
-				} else
-					x += putcs_count;
-				continue;
-                        }
-			
-                        /* DPC: End of putcs support */
-#endif
-			
-			if (decim)
-				insert_char(currcons);
-			*pos = (attr << 8) + tc;
-			if (currcons == fg_console)
-				sw->con_putc(vc_cons[currcons].d,tc,y,x);
-			if (x == cols - 1)
-				need_wrap = decawm;
-			else {
-				pos++;
-				x++;
-			}
-			continue;
-		}
-
-		/*
-		 *  Control characters can be used in the _middle_
-		 *  of an escape sequence.
-		 */
-		switch (c) {
-		    case 0:
-			continue;
-		    case 7:
-			if (bell_duration)
-			    kd_mksound(bell_pitch, bell_duration);
-			continue;
-		    case 8:
-			bs(currcons);
-			continue;
-		    case 9:
-			pos -= x;
-			while (x < cols - 1) {
-				x++;
-				if (tab_stop[x >> 5] & (1 << (x & 31)))
-					break;
-			}
-			pos += x;
-			continue;
-		    case 10: case 11: case 12:
-			lf(currcons);
-			if (!is_kbd(lnm))
-				continue;
-		    case 13:
-			cr(currcons);
-			continue;
-  			case 14:
-			charset = 1;
-			translate = set_translate(G1_charset);
-			disp_ctrl = 1;
-			continue;
-		    case 15:
-			charset = 0;
-			translate = set_translate(G0_charset);
-			disp_ctrl = 0;
-			continue;
-		    case 24: case 26:
-			vc_state = ESnormal;
-			continue;
-		    case 27:
-			vc_state = ESesc;
-			continue;
-		    case 127:
-			del(currcons);
-			continue;
-		    case 128+27:
-			vc_state = ESsquare;
-			continue;
-		}
-		switch(vc_state) {
-		    case ESesc:
-			vc_state = ESnormal;
-			switch (c) {
-			    case '[':
-				vc_state = ESsquare;
-				continue;
-			    case ']':
-				vc_state = ESnonstd;
-				continue;
-			    case '%':
-				vc_state = ESpercent;
-				continue;
-			    case 'E':
-				cr(currcons);
-				lf(currcons);
-				continue;
-			    case 'M':
-				ri(currcons);
-				continue;
-			    case 'D':
-				lf(currcons);
-				continue;
-			    case 'H':
-				tab_stop[x >> 5] |= (1 << (x & 31));
-				continue;
-			    case 'Z':
-				respond_ID(tty);
-				continue;
-			    case '7':
-				save_cur(currcons);
-				continue;
-			    case '8':
-				restore_cur(currcons);
-				continue;
-			    case '(':
-				vc_state = ESsetG0;
-				continue;
-			    case ')':
-				vc_state = ESsetG1;
-				continue;
-			    case '#':
-				vc_state = EShash;
-				continue;
-			    case 'c':
-				reset_terminal(currcons,1);
-				continue;
-			    case '>':  /* Numeric keypad */
-				clr_kbd(kbdapplic);
-				continue;
-			    case '=':  /* Appl. keypad */
-				set_kbd(kbdapplic);
-				continue;
-			}	
-			continue;
-		    case ESnonstd:
-			if (c=='P') {   /* palette escape sequence */
-			    for (npar=0; npar<NPAR; npar++)
-				par[npar] = 0 ;
-			    npar = 0 ;
-			    vc_state = ESpalette;
-			    continue;
-			} else if (c=='R') {   /* reset palette */
-			    reset_palette (currcons);
-			    vc_state = ESnormal;
-			} else
-			    vc_state = ESnormal;
-			continue;
-		case ESpalette:
-			if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
-			    par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
-			    if (npar==7) {
-				int i = par[0]*3, j = 1;
-				palette[i] = 16*par[j++];
-				palette[i++] += par[j++];
-				palette[i] = 16*par[j++];
-				palette[i++] += par[j++];
-				palette[i] = 16*par[j++];
-				palette[i] += par[j];
-				set_palette() ;
-				vc_state = ESnormal;
-			    }
-			} else
-			    vc_state = ESnormal;
-			continue;
-		    case ESsquare:
-			for(npar = 0 ; npar < NPAR ; npar++)
-				par[npar] = 0;
-			npar = 0;
-			vc_state = ESgetpars;
-			if (c == '[') { /* Function key */
-				vc_state=ESfunckey;
-				continue;
-			}
-			ques = (c=='?');
-			if (ques)
-				continue;
-		    case ESgetpars:
-			if (c==';' && npar<NPAR-1) {
-				npar++;
-				continue;
-			} else if (c>='0' && c<='9') {
-				par[npar] *= 10;
-				par[npar] += c-'0';
-				continue;
-			} else vc_state=ESgotpars;
-		    case ESgotpars:
-			vc_state = ESnormal;
-			switch(c) {
-			    case 'h':
-				set_mode(currcons,1);
-				continue;
-			    case 'l':
-				set_mode(currcons,0);
-				continue;
-			    case 'n':
-				if (!ques)
-					if (par[0] == 5)
-						status_report(tty);
-					else if (par[0] == 6)
-						cursor_report(currcons,tty);
-				continue;
-			}
-			if (ques) {
-				ques = 0;
-				continue;
-			}
-			switch(c) {
-			    case 'G': case '`':
-				if (par[0]) par[0]--;
-				gotoxy(currcons,par[0],y);
-				continue;
-			    case 'A':
-				if (!par[0]) par[0]++;
-				gotoxy(currcons,x,y-par[0]);
-				continue;
-			    case 'B': case 'e':
-				if (!par[0]) par[0]++;
-				gotoxy(currcons,x,y+par[0]);
-				continue;
-			    case 'C': case 'a':
-				if (!par[0]) par[0]++;
-				gotoxy(currcons,x+par[0],y);
-				continue;
-			    case 'D':
-				if (!par[0]) par[0]++;
-				gotoxy(currcons,x-par[0],y);
-				continue;
-			    case 'E':
-				if (!par[0]) par[0]++;
-				gotoxy(currcons,0,y+par[0]);
-				continue;
-			    case 'F':
-				if (!par[0]) par[0]++;
-				gotoxy(currcons,0,y-par[0]);
-				continue;
-			    case 'd':
-				if (par[0]) par[0]--;
-				gotoxay(currcons,x,par[0]);
-				continue;
-			    case 'H': case 'f':
-				if (par[0]) par[0]--;
-				if (par[1]) par[1]--;
-				gotoxay(currcons,par[1],par[0]);
-				continue;
-			    case 'J':
-				csi_J(currcons,par[0]);
-				continue;
-			    case 'K':
-				csi_K(currcons,par[0]);
-				continue;
-			    case 'L':
-				csi_L(currcons,par[0]);
-				continue;
-			    case 'M':
-				csi_M(currcons,par[0]);
-				continue;
-			    case 'P':
-				csi_P(currcons,par[0]);
-				continue;
-			    case 'c':
-				if (!par[0])
-					respond_ID(tty);
-				continue;
-			    case 'g':
-				if (!par[0])
-					tab_stop[x >> 5] &= ~(1 << (x & 31));
-				else if (par[0] == 3) {
-					tab_stop[0] =
-						tab_stop[1] =
-							tab_stop[2] =
-								tab_stop[3] =
-									tab_stop[4] = 0;
-				}
-				continue;
-			    case 'm':
-				csi_m(currcons);
-				continue;
-			    case 'q': /* DECLL - but only 3 leds */
-				/* map 0,1,2,3 to 0,1,2,4 */
-				if (par[0] < 4)
-					setledstate(kbd_table + currcons,
-						    (par[0] < 3) ? par[0] : 4);
-				continue;
-			    case 'r':
-				if (!par[0])
-					par[0]++;
-				if (!par[1])
-					par[1] = rows;
-				/* Minimum allowed region is 2 lines */
-				if (par[0] < par[1] &&
-				    par[1] <= rows) {
-					top=par[0]-1;
-					bottom=par[1];
-					gotoxay(currcons,0,0);
-				}
-				continue;
-			    case 's':
-				save_cur(currcons);
-				continue;
-			    case 'u':
-				restore_cur(currcons);
-				continue;
-			    case 'X':
-				csi_X(currcons, par[0]);
-				continue;
-			    case '@':
-				csi_at(currcons,par[0]);
-				continue;
-			    case ']': /* setterm functions */
-				setterm_command(currcons);
-				continue;
-			}
-			continue;
-		    case ESpercent:
-			vc_state = ESnormal;
-			switch (c) {
-			    case '@':  /* defined in ISO 2022 */
-				utf = 0;
-				continue;
-			    case 'G':  /* prelim official escape code */
-			    case '8':  /* retained for compatibility */
-				utf = 1;
-				continue;
-			}
-			continue;
-		    case ESfunckey:
-			vc_state = ESnormal;
-			continue;
-		    case EShash:
-			vc_state = ESnormal;
-			if (c == '8') {
-				/* DEC screen alignment test. kludge :-) */
-				video_erase_char =
-					(video_erase_char & 0xff00) | 'E';
-				/* Arno:
-				 * Doesn't work, because csi_J(c,2)
-				 * calls con_clear and doesn't print
-				 * the erase char..
-				 */
-				csi_J(currcons, 2);
-				video_erase_char =
-					(video_erase_char & 0xff00) | ' ';
-			}
-			continue;
-		    case ESsetG0:
-			if (c == '0')
-				G0_charset = GRAF_MAP;
-			else if (c == 'B')
-				G0_charset = LAT1_MAP;
-			else if (c == 'U')
-				G0_charset = IBMPC_MAP;
-			else if (c == 'K')
-				G0_charset = USER_MAP;
-			if (charset == 0)
-				translate = set_translate(G0_charset);
-			vc_state = ESnormal;
-			continue;
-		    case ESsetG1:
-			if (c == '0')
-				G1_charset = GRAF_MAP;
-			else if (c == 'B')
-				G1_charset = LAT1_MAP;
-			else if (c == 'U')
-				G1_charset = IBMPC_MAP;
-			else if (c == 'K')
-				G1_charset = USER_MAP;
-			if (charset == 1)
-				translate = set_translate(G1_charset);
-			vc_state = ESnormal;
-			continue;
-		    default:
-			vc_state = ESnormal;
-		}
-	}
-	enable_bh(CONSOLE_BH);
-	return n;
-}
-
-static int con_write(struct tty_struct * tty, int from_user,
-		     const unsigned char *buf, int count)
-{
-	int	retval;
-	
-	retval = do_con_write(tty, from_user, buf, count);
-	con_flush_chars(tty);
-	
-	return retval;
-}
-
-static void con_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	do_con_write(tty, 0, &ch, 1);
-}
-
-static int con_write_room(struct tty_struct *tty)
-{
-	if (tty->stopped)
-		return 0;
-	return 4096;		/* No limit, really; we're not buffering */
-}
-
-static int con_chars_in_buffer(struct tty_struct *tty)
-{
-	return 0;		/* we're not buffering */
-}
-
-void poke_blanked_console(void)
-{
-	timer_active &= ~(1<<BLANK_TIMER);
-	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
-		return;
-	if (console_blanked) {
-		timer_table[BLANK_TIMER].fn = unblank_screen;
-		timer_table[BLANK_TIMER].expires = 0;
-		timer_active |= 1<<BLANK_TIMER;
-	} else if (blankinterval) {
-		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
-		timer_active |= 1<<BLANK_TIMER;
-	}
-}
-
-/* DPC: New version of console_print using putcs */
-
-#ifdef CONFIG_VT_CONSOLE
-void vt_console_print(struct console *co, const char * b, unsigned count)
-{
-   int currcons = fg_console;
-   unsigned char c;
-   const char *start = b;
-   ushort cnt        = 0;
-   ushort myx        = x;
-   static int printing = 0;
-
-   if (!printable || printing)
-	   return;	 /* console not yet initialized */
-   printing = 1;
-
-   if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
-	   currcons = kmsg_redirect - 1;
-
-   if (!vc_cons_allocated(currcons)) {
-	   /* impossible */
-	   printk("vt_console_print: tty %d not allocated ??\n", currcons+1);
-	   printing = 0;
-	   return;
-   }
-
-   /* undraw cursor first */
-   hide_cursor(currcons);
-
-   /* Contrived structure to try to emulate original need_wrap behaviour
-    * Problems caused when we have need_wrap set on '\n' character */
-
-   while (count-- > 0) {
-	   c = *(b++);
-	   if (c == 10 || c == 13 || c == 8 || need_wrap) {
-			if ((cnt = b - start - 1) > 0) {
-				sw->con_putcs(vc_cons[currcons].d,
-					      start, cnt, y, x);
-				x += cnt;
-				if (need_wrap)
-					x--;
-		   }
-
-		   if (c == 8) {	/* backspace */
-			   bs(currcons);
-			   start = b;
-			   myx = x;
-			   continue;
-		   }
-		   if (c != 13)
-			   lf(currcons);
-		   cr(currcons);
-
-		   if (c == 10 || c == 13) {
-			   start = b; myx = x; continue;
-		   }
-
-		   start = b-1; myx = x;
-	   }
-
-	   *pos = c | (attr << 8);
-	   if (myx == cols - 1) {
-		   need_wrap = 1;
-		   continue;
-	   }
-	   pos++;
-	   myx++;
-   }
-
-   if ((cnt = b - start) > 0) {
-	   sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);
-	   x += cnt;
-	   if (x == cols){
-		   x--;
-		   need_wrap = 1;
-	   }
-   }
-   
-   set_cursor(currcons);
-   poke_blanked_console();
-   printing = 0;
-}
-
-static kdev_t vt_console_device(struct console *c)
-{
-	return MKDEV(TTY_MAJOR, c->index ? c->index : fg_console + 1);
-}
-
-extern int keyboard_wait_for_keypress(struct console *);
-
-struct console vt_console_driver = {
-	"tty",
-	vt_console_print,
-	NULL,
-	vt_console_device,
-	keyboard_wait_for_keypress,
-	do_unblank_screen,
-	NULL,
-	CON_PRINTBUFFER,
-	-1,
-	0,
-	NULL
-};
-#endif
-
-/*
- * con_throttle and con_unthrottle are only used for
- * paste_selection(), which has to stuff in a large number of
- * characters...
- */
-static void con_throttle(struct tty_struct *tty)
-{
-}
-
-static void con_unthrottle(struct tty_struct *tty)
-{
-	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
-
-	wake_up_interruptible(&vt->paste_wait);
-}
-
-static void vc_init(unsigned int currcons, int do_clear)
-{
-	long base = (long) vc_scrbuf[currcons];
-
-	pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
-	scr_end = base + screenbuf_size;
-	video_mem_end = base + screenbuf_size;
-	reset_vc(currcons);
-	def_color       = 0x07;   /* white */
-	ulcolor		= 0x0f;   /* bold white */
-	halfcolor       = 0x08;   /* grey */
-	vt_cons[currcons]->paste_wait = 0;
-	reset_terminal(currcons, do_clear);
-}
-
-/*
- * This is the console switching bottom half handler.
- *
- * Doing console switching in a bottom half handler allows
- * us to do the switches asynchronously (needed when we want
- * to switch due to a keyboard interrupt), while still giving
- * us the option to easily disable it to avoid races when we
- * need to write to the console.
- */
-static void console_bh(void)
-{
-	if (want_console >= 0) {
-		if (want_console != fg_console) {
-			change_console(want_console);
-			/* we only changed when the console had already
-			   been allocated - a new console is not created
-			   in an interrupt routine */
-		}
-		want_console = -1;
-	}
-	if (do_poke_blanked_console) { /* do not unblank for a LED change */
-		do_poke_blanked_console = 0;
-		poke_blanked_console();
-	}
-}
-
-int (*console_show_logo)(void) __initdata = NULL;
-
-__initfunc(void con_init_finish(void))
-{
-	char q[2] = { 0, 1 };
-
-	if (console_show_logo)
-		q[1] += console_show_logo();
-	conswitchp->con_putcs(vc_cons[fg_console].d, linux_logo_banner,
-			      sizeof(linux_logo_banner)-1, q[1]-1, q[0]);
-	putconsxy(0, q);
-}
-
-
-/*
- *  unsigned long con_init(unsigned long);
- *
- * This routine initializes console interrupts, and does nothing
- * else. If you want the screen to clear, call tty_write with
- * the appropriate escape-sequence.
- *
- * Reads the information preserved by setup.s to determine the current display
- * type and sets everything accordingly.
- */
-__initfunc(unsigned long con_init(unsigned long kmem_start))
-{
-	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;
-	console_driver.name = "tty";
-	console_driver.name_base = 1;
-	console_driver.major = TTY_MAJOR;
-	console_driver.minor_start = 1;
-	console_driver.num = MAX_NR_CONSOLES;
-	console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
-	console_driver.init_termios = tty_std_termios;
-	console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
-	console_driver.refcount = &console_refcount;
-	console_driver.table = console_table;
-	console_driver.termios = console_termios;
-	console_driver.termios_locked = console_termios_locked;
-
-	console_driver.open = con_open;
-	console_driver.write = con_write;
-	console_driver.write_room = con_write_room;
-	console_driver.put_char = con_put_char;
-	console_driver.flush_chars = con_flush_chars;
-	console_driver.chars_in_buffer = con_chars_in_buffer;
-	console_driver.ioctl = vt_ioctl;
-	console_driver.stop = con_stop;
-	console_driver.start = con_start;
-	console_driver.throttle = con_throttle;
-	console_driver.unthrottle = con_unthrottle;
-	
-	if (tty_register_driver(&console_driver))
-		panic("Couldn't register console driver\n");
-
-	kmem_start = conswitchp->con_startup (kmem_start, &display_desc);
-
-	timer_table[BLANK_TIMER].fn = blank_screen;
-	timer_table[BLANK_TIMER].expires = 0;
-	if (blankinterval) {
-		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
-		timer_active |= 1<<BLANK_TIMER;
-	}
-
-	/* Due to kmalloc roundup allocating statically is more efficient -
-	   so provide MIN_NR_CONSOLES for people with very little memory */
-	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
-		vc_cons[currcons].d = (struct vc_data *) kmem_start;
-		kmem_start += sizeof(struct vc_data);
-		vt_cons[currcons] = (struct vt_struct *) kmem_start;
-		kmem_start += sizeof(struct vt_struct);
-
-		/* ++Geert: sw->con_init determines console size */
-		sw = conswitchp;
-		cons_num = currcons;
-
-		sw->con_init (vc_cons[currcons].d);
-		size_row = cols<<1;
-		screenbuf_size = rows*size_row;
-
-		vc_scrbuf[currcons] = (unsigned short *) kmem_start;
-		kmem_start += screenbuf_size;
-		kmalloced = 0;
-		vc_init(currcons, currcons);
-	}
-
-	currcons = fg_console = 0;
-
-	gotoxy(currcons,0,0);
-	csi_J(currcons, 0);
-	printable = 1;
-	update_screen(fg_console);
-
-	con_init_finish();
-
-	sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
-	printable = 1;
-
-	/* If "serdebug" cmd line option was present, don't register for printk */
-#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,
-		cols,rows,
-		MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
-
-	init_bh(CONSOLE_BH, console_bh);
-	return kmem_start;
-}
-
-void vesa_powerdown_screen(void)
-{
-	int currcons = fg_console;
-
-	timer_active &= ~(1<<BLANK_TIMER);
-	timer_table[BLANK_TIMER].fn = unblank_screen;
-
-	/* Power down if currently suspended (1 or 2),
-	 * suspend if currently blanked (0),
-	 * else do nothing (i.e. already powered down (3)).
-	 * Called only if powerdown features are allowed.
-	 */
-	switch (vesa_blank_mode) {
-	case 0:
-		sw->con_blank(2);
-		break;
-	case 1:
-	case 2:
-		sw->con_blank(4);
-		break;
-	}
-}
-
-void do_blank_screen(int nopowersave)
-{
-	int currcons;
-
-	if (console_blanked)
-		return;
-
-	if (!vc_cons_allocated(fg_console)) {
-		/* impossible */
-		printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
-		return;
-	}
-
-	/* don't blank graphics */
-	if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
-		if (vesa_off_interval && !nopowersave) {
-			timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
-			timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
-			timer_active |= (1<<BLANK_TIMER);
-		} else {
-			timer_active &= ~(1<<BLANK_TIMER);
-			timer_table[BLANK_TIMER].fn = unblank_screen;
-		}
-
-		/* try not to lose information by blanking,
-		   and not to waste memory */
-		currcons = fg_console;
-		has_scrolled = 0;
-		sw->con_blank(1);
-		if (!nopowersave)
-			sw->con_blank(vesa_blank_mode + 1);
-	}
-	else
-		hide_cursor(fg_console);
- 	console_blanked = fg_console + 1;
-}
-
-void do_unblank_screen(void)
-{
-	int currcons;
-
-	if (!console_blanked)
-		return;
-	if (!vc_cons_allocated(fg_console)) {
-		/* impossible */
-		printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
-		return;
-	}
-	timer_table[BLANK_TIMER].fn = blank_screen;
-	if (blankinterval) {
-		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
-		timer_active |= 1<<BLANK_TIMER;
-	}
-
-	currcons = fg_console;
-  	console_blanked = 0;
-	if (sw->con_blank (0))
-		/* Low-level driver cannot restore -> do it ourselves */
-	  	update_screen( fg_console );
-	set_cursor (fg_console);
-}
-
-void update_screen(int new_console)
-{
-	int currcons = fg_console;
-	int xx, yy, startx, attr_save;
-	char buf[256], *bufp;
-	unsigned short *p;
-	static int lock = 0;
-
-	if (/* new_console == fg_console || */ lock)
-		return;
-	if (!vc_cons_allocated(new_console)) {
-		/* strange ... */
-		printk("update_screen: tty %d not allocated ??\n", new_console+1);
-		return;
-	}
-	lock = 1;
-
-	clear_selection();
-
-	currcons = fg_console = new_console;
-	sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
-	sw->con_switch (vc_cons[new_console].d);
-	/* Update the screen contents */
-	p = video_mem_start;
-	attr_save = attr;
-	for (yy = 0; yy < rows; yy++)
-	  {
-	    bufp = buf;
-	    for (startx = xx = 0; xx < cols; xx++)
-	      {
-		if (attr != ((*p >> 8) & 0xff))
-		  {
-		    if (bufp > buf)
-		      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
-				     yy, startx);
-		    startx = xx;
-		    bufp = buf;
-		    attr = (*p >> 8) & 0xff;
-		  }
-		*bufp++ = *p++;
-		if (bufp == buf + sizeof (buf))
-		  {
-		    sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
-				   yy, startx);
-		    startx = xx + 1;
-		    bufp = buf;
-		  }
-	      }
-	    if (bufp > buf)
-	      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
-			     yy, startx);
-	  }
-	set_cursor (currcons);
-	attr = attr_save;
-	set_leds();
-	compute_shiftstate();
-	lock = 0;
-}
-
-/*
- * If a blank_screen is due to a timer, then a power save is allowed.
- * If it is related to console_switching, then avoid vesa_blank().
- */
-static void blank_screen(void)
-{
-	do_blank_screen(0);
-}
-
-static void unblank_screen(void)
-{
-	do_unblank_screen();
-}
-
-/*
- * Allocate the console screen memory.
- */
-static int con_open(struct tty_struct *tty, struct file * filp)
-{
-	unsigned int currcons;
-	int i;
-
-	currcons = MINOR(tty->device) - tty->driver.minor_start;
-	
-	i = vc_allocate(currcons);
-	if (i)
-		return i;
-
-	vt_cons[currcons]->vc_num = currcons;
-	tty->driver_data = vt_cons[currcons];
-	
-	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
-		tty->winsize.ws_row = rows;
-		tty->winsize.ws_col = cols;
- 	}
-
-	return 0;
-}
-
-/*
- * PIO_FONT support.
- *
- * Currently we only support 8 pixels wide fonts, at a maximum height
- * of 32 pixels. Userspace fontdata is stored with 32 bytes reserved
- * for each character which is kinda wasty, but this is done in order
- * to maintain compatibility with the EGA/VGA fonts. It is upto the
- * actual low-level console-driver convert data into its favorite
- * format (maybe we should add a `fontoffset' field to the `display'
- * structure so we wont have to convert the fontdata all the time.
- * /Jes
- */
-
-#define cmapsz 8192
-
-static int set_get_font(char * arg, int set, int ch512)
-{
-#ifdef CAN_LOAD_EGA_FONTS
-	int i, unit, size;
-	char *charmap;
-
-	if (!arg)
-		return -EINVAL;
-
-
-	size = ch512 ? 2*cmapsz : cmapsz;
-
-	charmap = (char *)kmalloc(size, GFP_USER);
-
-	if (set){
-		if (copy_from_user(charmap, arg, size)) {
-			kfree(charmap);
-			return -EFAULT;
-		}
-
-		for (unit = 32; unit > 0; unit--)
-			for (i = 0; i < (ch512 ? 512 : 256); i++)
-				if (charmap[32*i+unit-1])
-					goto nonzero;
-	nonzero:
-		i = conswitchp->con_set_font(vc_cons[fg_console].d, 8,
-					     unit, charmap);
-	}else{
-		memset(charmap, 0, size);
-		i = conswitchp->con_get_font(vc_cons[fg_console].d,
-					     &unit, &unit, charmap);
-		if (i == 0 && copy_to_user(arg, charmap, size))
-			i = -EFAULT;
-	}
-	kfree(charmap);
-
-	return i;
-#else
-	return -EINVAL;
-#endif
-}
-
-/*
- * Load palette into the EGA/VGA DAC registers. arg points to a colour
- * map, 3 bytes per colour, 16 colours, range from 0 to 255.
- */
-
-static int set_get_cmap(unsigned char *arg, int set)
-{
-	int i, j, k;
-
-	for (i = 0; i < 16; i++)
-		if (set) {
-			get_user(default_red[i], arg++);
-			get_user(default_grn[i], arg++);
-			get_user(default_blu[i], arg++);
-		} else {
-			put_user(default_red[i], arg++);
-			put_user(default_grn[i], arg++);
-			put_user(default_blu[i], arg++);
-		}
-	if (set) {
-		for (i = 0; i < MAX_NR_CONSOLES; i++)
-			if (vc_cons_allocated(i))
-				for (j = k = 0; j < 16; j++) {
-					vc_cons[i].d->vc_palette[k++] =
-						default_red[j];
-					vc_cons[i].d->vc_palette[k++] =
-						default_grn[j];
-					vc_cons[i].d->vc_palette[k++] =
-						default_blu[j];
-				}
-		set_palette();
-	}
-	return 0;
-}
-
-int con_set_cmap (unsigned char *arg)
-{
-	return set_get_cmap (arg, 1);
-}
-
-int con_get_cmap (unsigned char *arg)
-{
-	return set_get_cmap (arg, 0);
-}
-
-void reset_palette(int currcons)
-{
-	int j, k;
-	for (j = k = 0; j < 16; j++) {
-		palette[k++] = default_red[j];
-		palette[k++] = default_grn[j];
-		palette[k++] = default_blu[j];
-	}
-	set_palette() ;
-}
-
-void set_palette(void)
-{
-	if (vt_cons[fg_console]->vc_mode != KD_GRAPHICS)
-		conswitchp->con_set_palette(vc_cons[fg_console].d, color_table);
-}
-
-/*
- * Load font into the EGA/VGA character generator. arg points to a 8192
- * byte map, 32 bytes per character. Only first H of them are used for
- * 8xH fonts (0 < H <= 32).
- */
-
-int con_set_font (char *arg, int ch512)
-{
-	int i;
-
-	i = set_get_font (arg,1,ch512);
-  	if ( !i ) {
-		hashtable_contents_valid = 0;
-      		video_mode_512ch = ch512;
-      		console_charmask = ch512 ? 0x1ff : 0x0ff;
-	}
-	return i;
-}
-
-int con_get_font (char *arg)
-{
-	return set_get_font (arg,0,video_mode_512ch);
-}
-
-/*
- * Adjust the screen to fit a font of a certain height
- *
- * Returns < 0 for error, 0 if nothing changed, and the number
- * of lines on the adjusted console if changed.
- */
-int con_adjust_height(unsigned long fontheight)
-{
-	return -EINVAL;
-}
-
-static void set_vesa_blanking(unsigned long arg)
-{
-	char *argp = (char *)arg + 1;
-	unsigned int mode;
-	get_user(mode, argp);
-	vesa_blank_mode = (mode < 4) ? mode : 0;
-}
-
-unsigned long get_video_num_lines(unsigned int currcons)
-{
-	return(rows);
-}
-
-unsigned long get_video_num_columns(unsigned int currcons)
-{
-	return(cols);
-}
-
-unsigned long get_video_size_row(unsigned int currcons)
-{
-	return(size_row);
-}
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/arch/m68k/kernel/time.c m68k-2.1.77/arch/m68k/kernel/time.c
--- /usr/src/m68k-2.1.77/arch/m68k/kernel/time.c	Thu Jan  8 22:04:54 1998
+++ m68k-2.1.77/arch/m68k/kernel/time.c	Fri Jan  9 01:19:23 1998
@@ -7,7 +7,6 @@
  * Most of the stuff is located in the machine specific files.
  */
 
-#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -78,18 +77,24 @@
 	   for debugging -- based on the version for PReP by Cort */
 	/* acts like an actual heart beat -- ie thump-thump-pause... */
 	if (mach_heartbeat) {
-	    switch(kstat.interrupts[mach_heartbeat_irq] % 101) {
-	      case 0:
-	      case 20:
+	    static unsigned cnt = 0, period = 0, dist = 0;
+
+	    if (cnt == 0 || cnt == dist)
 		mach_heartbeat( 1 );
-		break;
-	      case 7:
-	      case 27:
+	    else if (cnt == 7 || cnt == dist+7)
 		mach_heartbeat( 0 );
-		break;
+
+	    if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
 	    }
 	}
-#endif
+#endif /* CONFIG_HEARTBEAT */
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/block/amiflop.c m68k-2.1.77/drivers/block/amiflop.c
--- /usr/src/m68k-2.1.77/drivers/block/amiflop.c	Wed Dec 17 22:56:42 1997
+++ m68k-2.1.77/drivers/block/amiflop.c	Fri Jan  9 01:25:38 1998
@@ -45,6 +45,12 @@
  *    major/minor handling that came with kdev_t. It seems to work for
  *    the time being, but I can't guarantee that it will stay like
  *    that when we start using 16 (24?) bit minors.
+ *
+ * restructured jan 1997 by Joerg Dorchain
+ * - Fixed Bug accessing multiple disks
+ * - some code cleanup
+ * - added trackbuffer for each drive to speed things up
+ * - fixed some race conditions (who finds the next may send it to me ;-)
  */
 
 #ifdef MODULE
@@ -61,7 +67,7 @@
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/string.h>
-#include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 
 #include <asm/setup.h>
@@ -82,16 +88,6 @@
 #define IOCTL_RAW_TRACK 0x5254524B  /* 'RTRK' */
 #endif
 
-/* prototypes */
-
-static int amiga_read(int,unsigned char *, unsigned long, int);
-static void amiga_write(int, unsigned long, unsigned char *, int);
-static int dos_read(int, unsigned char *, unsigned long, int);
-static void dos_write(int, unsigned long, unsigned char *,int);
-static ushort dos_crc(void *, int, int, int);
-static void fd_probe(int);
-
-
 /*
  *  Defines
  */
@@ -107,6 +103,11 @@
 #define FD_NOTACTIVE	3	/* unit is not active */
 #define FD_NOTREADY	4	/* unit is not ready (motor not on/no disk) */
 
+#define MFM_NOSYNC	1
+#define MFM_HEADER	2
+#define MFM_DATA	3
+#define MFM_TRACK	4
+
 /*
  *  Floppy ID values
  */
@@ -115,8 +116,9 @@
 #define FD_HD_3 	0x55555555  /* high-density 3.5" (1760K) drive */
 #define FD_DD_5 	0xaaaaaaaa  /* double-density 5.25" (440K) drive */
 
-static int fd_def_df0 = 0;     /* default for df0 if it doesn't identify */
+static long int fd_def_df0 = 0;     /* default for df0 if it doesn't identify */
 
+MODULE_PARM(fd_def_fd0,"l");
 
 /*
  *  Macros
@@ -147,26 +149,34 @@
 static int floppy_blocksizes[256]={0,};
 /* hardsector size assumed to be 512 */
 
+static int amiga_read(int), dos_read(int);
+static void amiga_write(int), dos_write(int);
 static struct fd_data_type data_types[] = {
   { "Amiga", 11 , amiga_read, amiga_write},
   { "MS-Dos", 9, dos_read, dos_write}
 };
 
 /* current info on each unit */
-static struct amiga_floppy_struct unit[FD_MAX_UNITS];
+static struct amiga_floppy_struct unit[FD_MAX_UNITS] = {{ 0,}};
 
-static struct timer_list flush_track_timer;
+static struct timer_list flush_track_timer[FD_MAX_UNITS];
 static struct timer_list post_write_timer;
 static struct timer_list motor_on_timer;
 static struct timer_list motor_off_timer[FD_MAX_UNITS];
 static int on_attempts;
 
-/* track buffer */
-static int lastdrive = -1;
-static int savedtrack = -1;
+/* Synchronization of FDC access */
+/* request loop (trackbuffer) */
+static volatile int fdc_busy = -1;
+static volatile int fdc_nested = 0;
+static struct wait_queue *fdc_wait = NULL;
+ 
+static struct wait_queue *motor_wait = NULL;
+
+static volatile int selected = -1;	/* currently selected drive */
+
 static int writepending = 0;
 static int writefromint = 0;
-static unsigned char trackdata[MAX_SECTORS * 512];
 static char *raw_buf;
 
 #define RAW_BUF_SIZE 30000  /* size of raw disk data */
@@ -177,21 +187,8 @@
  * request.
  */
 static volatile char block_flag = 0;
-static volatile int selected = 0;
 static struct wait_queue *wait_fd_block = NULL;
 
-/* Synchronization of FDC access */
-/* request loop (trackbuffer) */
-static volatile int fdc_busy = -1;
-static volatile int fdc_nested = 0;
-static struct wait_queue *fdc_wait = NULL;
-/* hardware */
-static volatile int hw_busy = -1;
-static volatile int hw_nested = 0;
-static struct wait_queue *hw_wait = NULL;
- 
-static struct wait_queue *motor_wait = NULL;
-
 /* MS-Dos MFM Coding tables (should go quick and easy) */
 static unsigned char mfmencode[16]={
   0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15,
@@ -211,13 +208,6 @@
  */
 #define MAX_ERRORS 12
 
-/*
- * The driver is trying to determine the correct media format
- * while probing is set. rw_interrupt() clears it after a
- * successful access.
- */
-static int probing = 0;
-
 /* Prevent "aliased" accesses. */
 static int fd_ref[4] = { 0,0,0,0 };
 static int fd_device[4] = { 0,0,0,0 };
@@ -231,61 +221,15 @@
 /* Current error count. */
 #define CURRENT_ERRORS (CURRENT->errors)
 
-static void get_fdc(int drive)
-{
-unsigned long flags;
 
-       drive &= 3;
-       save_flags(flags);
-       cli();
-       if (fdc_busy != drive)
-         while (!(fdc_busy < 0))
-           sleep_on(&fdc_wait);
-       fdc_busy = drive;
-       fdc_nested++;
-       restore_flags(flags);
-}
 
-static inline void rel_fdc(void)
-{
-#ifdef DEBUG
-       if (fdc_nested == 0)
-         printk("fd: unmatched rel_fdc\n");
-#endif
-       fdc_nested--;
-       if (fdc_nested == 0) {
-         fdc_busy = -1;
-         wake_up(&fdc_wait);
-       }
-}
-
-static void get_hw(int drive)
-{
-unsigned long flags;
-
-       drive &= 3;
-       save_flags(flags);
-       cli();
-       if (hw_busy != drive)
-         while (!(hw_busy < 0))
-           sleep_on(&hw_wait);
-       hw_busy = drive;
-       hw_nested++;
-       restore_flags(flags);
-}
+/*
+ * Here come the actual hardware access and helper functions.
+ * They are not reentrant and single threaded because all drives
+ * share the same hardware and the same trackbuffer.
+ */
 
-static inline void rel_hw(void)
-{
-#ifdef DEBUG
-       if (hw_nested == 0)
-         printk("fd: unmatched hw_rel\n");
-#endif
-       hw_nested--;
-       if (hw_nested == 0) {
-         hw_busy = -1;
-         wake_up(&hw_wait);
-       }
-}
+/* Milliseconds timer */
 
 static void ms_isr(int irq, void *dummy, struct pt_regs *fp)
 {
@@ -314,53 +258,102 @@
   }
 }
 
-/*
- * Functions
- */
-/*======================================================================
-  Turn off the motor of the given drive.  Unit must already be active.
-  Returns standard floppy error code.
-======================================================================*/
-static void fd_motor_off(unsigned long drive)
+/* Hardware semaphore */
+
+/* returns true when we would get the semaphore */
+static inline int try_fdc(int drive)
+{
+	drive &= 3;
+	return ((fdc_busy < 0) || (fdc_busy == drive));
+}
+
+static void get_fdc(int drive)
+{
+unsigned long flags;
+
+       drive &= 3;
+#ifdef DEBUG
+       printk("get_fdc: drive %d  fdc_busy %d  fdc_nested %d\n",drive,fdc_busy,fdc_nested);
+#endif
+       save_flags(flags);
+       cli();
+       while (!try_fdc(drive))
+	       sleep_on(&fdc_wait);
+       fdc_busy = drive;
+       fdc_nested++;
+       restore_flags(flags);
+}
+
+static inline void rel_fdc(void)
+{
+#ifdef DEBUG
+       if (fdc_nested == 0)
+         printk("fd: unmatched rel_fdc\n");
+       printk("rel_fdc: fdc_busy %d fdc_nested %d\n",fdc_busy,fdc_nested);
+#endif
+       fdc_nested--;
+       if (fdc_nested == 0) {
+         fdc_busy = -1;
+         wake_up(&fdc_wait);
+       }
+}
+
+static void fd_select (int drive)
 {
-	unsigned long flags;
 	unsigned char prb = ~0;
 
 	drive&=3;
-	get_hw(drive);
-	save_flags(flags);
-	cli();
+#ifdef DEBUG
+printk("selecting %d\n",drive);
+#endif
+	if (drive == selected)
+		return;
+	get_fdc(drive);
+	selected = drive;
 
 	if (unit[drive].track % 2 != 0)
 		prb &= ~DSKSIDE;
+	if (unit[drive].motor == 1)
+		prb &= ~DSKMOTOR;
 	ciab.prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
 	ciab.prb = prb;
 	prb &= ~SELMASK(drive);
 	ciab.prb = prb;
-	udelay (1);
+	rel_fdc();
+}
+
+static void fd_deselect (int drive)
+{
+	unsigned char prb;
+	unsigned long flags;
+
+	drive&=3;
+#ifdef DEBUG
+printk("deselecting %d\n",drive);
+#endif
+	if (drive != selected) {
+		printk(KERN_WARNING "Deselecting drive %d while %d was selected!\n",drive,selected);
+		return;
+	}
+
+	get_fdc(drive);
+	save_flags (flags);
+	sti();
+
+	selected = -1;
+
+	prb = ciab.prb;
 	prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
 	ciab.prb = prb;
-	selected = -1;
-	unit[drive].motor = 0;
 
-	rel_hw();
-#ifdef MODULE
-/*
-this is the last interrupt for any drive access, happens after
-release. So we have to wait until now to decrease the use count.
-*/
-       if (fd_ref[drive] == 0)
-         MOD_DEC_USE_COUNT;
-#endif
-	restore_flags(flags);
+	restore_flags (flags);
+	rel_fdc();
+
 }
 
 static void motor_on_callback(unsigned long nr)
 {
-  nr &= 3;
-
 	if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
-		unit[nr].motor = 1;
 		wake_up (&motor_wait);
 	} else {
 		motor_on_timer.expires = jiffies + HZ/10;
@@ -368,39 +361,25 @@
 	}
 }
 
-static int motor_on(int nr)
+static int fd_motor_on(int nr)
 {
-	unsigned long flags;
-	unsigned char prb = ~0;
-
 	nr &= 3;
-	get_hw(nr);
-	save_flags (flags);
-	cli();
+
 	del_timer(motor_off_timer + nr);
 
 	if (!unit[nr].motor) {
+		unit[nr].motor = 1;
+		fd_select(nr);
+
 		del_timer(&motor_on_timer);
 		motor_on_timer.data = nr;
 		motor_on_timer.expires = jiffies + HZ/2;
 		add_timer(&motor_on_timer);
-		on_attempts = 10;
 
-
-		prb &= ~DSKMOTOR;
-		if (unit[nr].track % 2 != 0)
-			prb &= ~DSKSIDE;
-		ciab.prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
-		ciab.prb = prb;
-		prb &= ~SELMASK(nr);
-		ciab.prb = prb;
-		selected = nr;
-
-		while (!unit[nr].motor)
-			sleep_on (&motor_wait);
+		on_attempts = 10;
+		sleep_on (&motor_wait);
+		fd_deselect(nr);
 	}
-	rel_hw();
-	restore_flags(flags);
 
 	if (on_attempts == 0) {
 		on_attempts = -1;
@@ -416,72 +395,58 @@
 	return 1;
 }
 
-static void floppy_off (unsigned int nr)
-{
-	nr&=3;
-	del_timer(motor_off_timer+nr);
-	motor_off_timer[nr].expires = jiffies + 3*HZ;
-	add_timer(motor_off_timer+nr);
-}
-
-static void fd_select (int drive)
+static void fd_motor_off(unsigned long drive)
 {
-	unsigned char prb = ~0;
+long calledfromint;
+#ifdef MODULE
+long decusecount;
 
+	decusecount = drive &0x40000000;
+#endif
+	calledfromint = drive & 0x80000000;
 	drive&=3;
-	if (drive == selected)
+	if (calledfromint && !try_fdc(drive)) {
+		/* We would be blocked in an interrupt, so try again later */
+		motor_off_timer[drive].expires = jiffies + 1;
+		add_timer(motor_off_timer + drive);
 		return;
-	get_hw(drive);
-	selected = drive;
+	}
+	unit[drive].motor = 0;
+	fd_select(drive);
+	udelay (1);
+	fd_deselect(drive);
 
-	if (unit[drive].track % 2 != 0)
-		prb &= ~DSKSIDE;
-	if (unit[drive].motor == 1)
-		prb &= ~DSKMOTOR;
-	ciab.prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
-	ciab.prb = prb;
-	prb &= ~SELMASK(drive);
-	ciab.prb = prb;
-	rel_hw();
+#ifdef MODULE
+/*
+this is the last interrupt for any drive access, happens after
+release (from floppy_off). So we have to wait until now to decrease
+the use count.
+*/
+       if (decusecount)
+         MOD_DEC_USE_COUNT;
+#endif
 }
 
-static void fd_deselect (int drive)
+static void floppy_off (unsigned int nr)
 {
-	unsigned char prb;
-	unsigned long flags;
-
-	drive&=3;
-	if (drive != selected)
-		return;
-
-	get_hw(drive);
-	save_flags (flags);
-	sti();
-
-	selected = -1;
-
-	prb = ciab.prb;
-	prb |= (SELMASK(0)|SELMASK(1)|SELMASK(2)|SELMASK(3));
-	ciab.prb = prb;
-
-	restore_flags (flags);
-	rel_hw();
+int drive;
 
+	drive = nr & 3;
+	del_timer(motor_off_timer + drive);
+	motor_off_timer[drive].expires = jiffies + 3*HZ;
+	/* called this way it is always from interrupt */
+	motor_off_timer[drive].data = nr | 0x80000000;
+	add_timer(motor_off_timer + nr);
 }
 
-/*======================================================================
-  Seek the drive to track 0.
-  The drive must be active and the motor must be running.
-  Returns standard floppy error code.
-======================================================================*/
 static int fd_calibrate(int drive)
 {
 	unsigned char prb;
 	int n;
 
 	drive &= 3;
-	get_hw(drive);
-	if (!motor_on (drive))
+	get_fdc(drive);
+	if (!fd_motor_on (drive))
 		return 0;
 	fd_select (drive);
 	prb = ciab.prb;
@@ -511,46 +476,45 @@
 		if ((ciaa.pra & DSKTRACK0) == 0)
 			break;
 		if (--n == 0) {
-			printk (KERN_ERR "calibrate failed, turning motor off\n");
+			printk (KERN_ERR "fd%d: calibrate failed, turning motor off\n", drive);
 			fd_motor_off (drive);
 			unit[drive].track = -1;
-			rel_hw();
+			rel_fdc();
 			return 0;
 		}
 	}
 	unit[drive].track = 0;
 	ms_delay(unit[drive].type->settle_time);
 
-	rel_hw();
+	rel_fdc();
+	fd_deselect(drive);
 	return 1;
 }
 
-/*======================================================================
-  Seek the drive to the requested cylinder.
-  The drive must have been calibrated at some point before this.
-  The drive must also be active and the motor must be running.
-======================================================================*/
 static int fd_seek(int drive, int track)
 {
 	unsigned char prb;
 	int cnt;
 
+#ifdef DEBUG
+printk("seeking drive %d to track %d\n",drive,track);
+#endif
 	drive &= 3;
-	get_hw(drive);
+	get_fdc(drive);
 	if (unit[drive].track == track) {
-		rel_hw();
+		rel_fdc();
 		return 1;
 	}
-	if (!motor_on(drive)) {
-		rel_hw();
+	if (!fd_motor_on(drive)) {
+		rel_fdc();
 		return 0;
 	}
-	fd_select (drive);
 	if (unit[drive].track < 0 && !fd_calibrate(drive)) {
-		rel_hw();
+		rel_fdc();
 		return 0;
 	}
 
+	fd_select (drive);
 	cnt = unit[drive].track/2 - track/2;
 	prb = ciab.prb;
 	prb |= DSKSIDE | DSKDIREC;
@@ -565,7 +529,8 @@
 		ms_delay (unit[drive].type->side_time);
 	unit[drive].track = track;
 	if (cnt == 0) {
-		rel_hw();
+		rel_fdc();
+		fd_deselect(drive);
 		return 1;
 	}
 	do {
@@ -578,119 +543,191 @@
 	} while (--cnt != 0);
 	ms_delay (unit[drive].type->settle_time);
 
-	rel_hw();
+	rel_fdc();
+	fd_deselect(drive);
 	return 1;
 }
 
-static void encode(unsigned long data, unsigned long *dest)
+static unsigned long fd_get_drive_id(int drive)
 {
-  unsigned long data2;
+	int i;
+	ulong id = 0;
 
-  data &= 0x55555555;
-  data2 = data ^ 0x55555555;
-  data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
+  	drive&=3;
+  	get_fdc(drive);
+	fd_select(drive);
+	/* set up for ID */
+	MOTOR_ON;
+	udelay(2);
+	SELECT(SELMASK(drive));
+	udelay(2);
+	DESELECT(SELMASK(drive));
+	udelay(2);
+	MOTOR_OFF;
+	udelay(2);
+	SELECT(SELMASK(drive));
+	udelay(2);
+	DESELECT(SELMASK(drive));
+	udelay(2);
 
-  if (*(dest - 1) & 0x00000001)
-    data &= 0x7FFFFFFF;
+	/* loop and read disk ID */
+	for (i=0; i<32; i++) {
+		SELECT(SELMASK(drive));
+		udelay(2);
 
-  *dest = data;
+		/* read and store value of DSKRDY */
+		id <<= 1;
+		id |= (ciaa.pra & DSKRDY) ? 0 : 1;	/* cia regs are low-active! */
+
+		DESELECT(SELMASK(drive));
+	}
+
+	fd_deselect(drive);
+	rel_fdc();
+
+        /*
+         * RB: At least A500/A2000's df0: don't identify themselves.
+         * As every (real) Amiga has at least a 3.5" DD drive as df0:
+         * we default to that if df0: doesn't identify as a certain
+         * type.
+         */
+        if(drive == 0 && id == FD_NODRIVE)
+         {
+                id = fd_def_df0;
+                printk(KERN_NOTICE "fd: drive 0 didn't identify, setting default %08lx\n", (ulong)fd_def_df0);
+         }
+	/* return the ID value */
+	return (id);
 }
 
-static void encode_block(unsigned long *dest, unsigned long *src, int len)
+static void fd_block_done(int irq, void *dummy, struct pt_regs *fp)
 {
-  int cnt, to_cnt = 0;
-  unsigned long data;
+  if (block_flag)
+    custom.dsklen = 0x4000;
 
-  /* odd bits */
-  for (cnt = 0; cnt < len / 4; cnt++) {
-    data = src[cnt] >> 1;
-    encode(data, dest + to_cnt++);
+  if (block_flag == 2) { /* writing */
+    writepending = 2;
+    post_write_timer.expires = jiffies + 1; /* at least 2 ms */
+    post_write_timer.data = selected;
+    add_timer(&post_write_timer);
   }
-
-  /* even bits */
-  for (cnt = 0; cnt < len / 4; cnt++) {
-    data = src[cnt];
-    encode(data, dest + to_cnt++);
+  else {                /* reading */
+    block_flag = 0;
+    wake_up (&wait_fd_block);
   }
 }
 
-unsigned long checksum(unsigned long *addr, int len)
+static void raw_read(int drive)
 {
-	unsigned long csum = 0;
+	drive&=3;
+	get_fdc(drive);
+	while (block_flag)
+		sleep_on(&wait_fd_block);
+	fd_select(drive);
+	/* setup adkcon bits correctly */
+	custom.adkcon = ADK_MSBSYNC;
+	custom.adkcon = ADK_SETCLR|ADK_WORDSYNC|ADK_FAST;
 
-	len /= sizeof(*addr);
-	while (len-- > 0)
-		csum ^= *addr++;
-	csum = ((csum>>1) & 0x55555555)  ^  (csum & 0x55555555);
+	custom.dsksync = MFM_SYNC;
 
-	return csum;
-}
+	custom.dsklen = 0;
+	custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf);
+	custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN;
+	custom.dsklen = unit[drive].type->read_size/sizeof(short) | DSKLEN_DMAEN;
 
-struct header {
-	unsigned char magic;
-	unsigned char track;
-	unsigned char sect;
-	unsigned char ord;
-	unsigned char labels[16];
-	unsigned long hdrchk;
-	unsigned long datachk;
-};
+	block_flag = 1;
+
+	while (block_flag)
+		sleep_on (&wait_fd_block);
+
+	custom.dsklen = 0;
+	fd_deselect(drive);
+	rel_fdc();
+}
 
-static unsigned long *putsec(int disk, unsigned long *raw, int track, int cnt,
-			     unsigned char *data)
+static int raw_write(int drive)
 {
-	struct header hdr;
-	int i;
+	ushort adk;
 
-	disk&=3;
-	*raw = (raw[-1]&1) ? 0x2AAAAAAA : 0xAAAAAAAA;
-	raw++;
-	*raw++ = 0x44894489;
+	drive&=3;
+	get_fdc(drive); /* corresponds to rel_fdc() in post_write() */
+	if ((ciaa.pra & DSKPROT) == 0) {
+		rel_fdc();
+		return 0;
+	}
+	while (block_flag)
+		sleep_on(&wait_fd_block);
+	fd_select(drive);
+	/* clear adkcon bits */
+	custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
+	/* set appropriate adkcon bits */
+	adk = ADK_SETCLR|ADK_FAST;
+	if ((ulong)unit[drive].track >= unit[drive].type->precomp2)
+		adk |= ADK_PRECOMP1;
+	else if ((ulong)unit[drive].track >= unit[drive].type->precomp1)
+		adk |= ADK_PRECOMP0;
+	custom.adkcon = adk;
 
-	hdr.magic = 0xFF;
-	hdr.track = track;
-	hdr.sect = cnt;
-	hdr.ord = unit[disk].sects-cnt;
-	for (i = 0; i < 16; i++)
-		hdr.labels[i] = 0;
-	hdr.hdrchk = checksum((ulong *)&hdr,
-			      (char *)&hdr.hdrchk-(char *)&hdr);
-	hdr.datachk = checksum((ulong *)data, 512);
+	custom.dsklen = DSKLEN_WRITE;
+	custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)raw_buf);
+	custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
+	custom.dsklen = unit[drive].type->write_size/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
+
+	block_flag = 2;
+	return 1;
+}
+
+/*
+ * to be called at least 2ms after the write has finished but before any
+ * other access to the hardware.
+ */
+static void post_write (unsigned long drive)
+{
+#ifdef DEBUG
+printk("post_write for drive %ld\n",drive);
+#endif
+  drive &= 3;
+  custom.dsklen = 0;
+  block_flag = 0;
+  writepending = 0;
+  writefromint = 0;
+  unit[drive].dirty = 0;
+  wake_up(&wait_fd_block);
+  fd_deselect(drive);
+  rel_fdc(); /* corresponds to get_fdc() in raw_write */
+}
 
-	encode_block(raw, (ulong *)&hdr.magic, 4);
-	raw += 2;
-	encode_block(raw, (ulong *)&hdr.labels, 16);
-	raw += 8;
-	encode_block(raw, (ulong *)&hdr.hdrchk, 4);
-	raw += 2;
-	encode_block(raw, (ulong *)&hdr.datachk, 4);
-	raw += 2;
-	encode_block(raw, (ulong *)data, 512);
-	raw += 256;
 
-	return raw;
-}
+/*
+ * The following functions are to convert the block contents into raw data
+ * written to disk and vice versa.
+ * (Add other formats here ;-))
+ */
+
+static unsigned long scan_sync(unsigned long raw, unsigned long end)
+{
+	ushort *ptr = (ushort *)raw, *endp = (ushort *)end;
 
+	while (ptr < endp && *ptr++ != 0x4489)
+		;
+	if (ptr < endp) {
+		while (*ptr == 0x4489 && ptr < endp)
+			ptr++;
+		return (ulong)ptr;
+	}
+	return 0;
+}
 
-/*==========================================================================
-  amiga_write converts track/labels data to raw track data
-==========================================================================*/
-static void amiga_write(int disk, unsigned long raw, unsigned char *data,
-			int track)
+static inline unsigned long checksum(unsigned long *addr, int len)
 {
-	unsigned int cnt;
-	unsigned long *ptr = (unsigned long *)raw;
+	unsigned long csum = 0;
 
-	disk&=3;
-	/* gap space */
-	for (cnt = 0; cnt < 415 * unit[disk].type->sect_mult; cnt++)
-		*ptr++ = 0xaaaaaaaa;
+	len /= sizeof(*addr);
+	while (len-- > 0)
+		csum ^= *addr++;
+	csum = ((csum>>1) & 0x55555555)  ^  (csum & 0x55555555);
 
-	/* sectors */
-	for (cnt = 0; cnt < unit[disk].sects; cnt++)
-		ptr = putsec (disk, ptr, track, cnt, data + cnt*512);
-	*(ushort *)ptr = (ptr[-1]&1) ? 0x2AA8 : 0xAAA8;
-	raw = (unsigned long)ptr + 2;
+	return csum;
 }
 
 static unsigned long decode (unsigned long *data, unsigned long *raw,
@@ -713,45 +750,29 @@
 	return (ulong)raw;
 }
 
-#define MFM_NOSYNC	1
-#define MFM_HEADER	2
-#define MFM_DATA	3
-#define MFM_TRACK	4
-
-/*==========================================================================
- scan_sync - looks for the next start of sector marked by a sync. d3 is the
-		sector number (10..0). When d3 = 10, can't be certain of a
-		starting sync.
-==========================================================================*/
-static unsigned long scan_sync(unsigned long raw, unsigned long end)
-{
-	ushort *ptr = (ushort *)raw, *endp = (ushort *)end;
-
-	while (ptr < endp && *ptr++ != 0x4489)
-		;
-	if (ptr < endp) {
-		while (*ptr == 0x4489 && ptr < endp)
-			ptr++;
-		return (ulong)ptr;
-	}
-	return 0;
-}
+struct header {
+	unsigned char magic;
+	unsigned char track;
+	unsigned char sect;
+	unsigned char ord;
+	unsigned char labels[16];
+	unsigned long hdrchk;
+	unsigned long datachk;
+};
 
-/*==========================================================================
-  amiga_read reads a raw track of data into a track buffer
-==========================================================================*/
-static int amiga_read(int drive, unsigned char *track_data,
-		      unsigned long raw, int track)
+static int amiga_read(int drive)
 {
+	unsigned long raw;
 	unsigned long end;
 	int scnt;
 	unsigned long csum;
 	struct header hdr;
 
 	drive&=3;
+	raw = (long) raw_buf;
 	end = raw + unit[drive].type->read_size;
 
-	for (scnt = 0;scnt < unit[drive].sects; scnt++) {
+	for (scnt = 0;scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) {
 		if (!(raw = scan_sync(raw, end))) {
 			printk (KERN_INFO "can't find sync for sector %d\n", scnt);
 			return MFM_NOSYNC;
@@ -778,24 +799,24 @@
 		}
 
 		/* verify track */
-		if (hdr.track != track) {
-			printk(KERN_INFO "MFM_TRACK: %d, %d\n", hdr.track, track);
+		if (hdr.track != unit[drive].track) {
+			printk(KERN_INFO "MFM_TRACK: %d, %d\n", hdr.track, unit[drive].track);
 			return MFM_TRACK;
 		}
 
-		raw = decode ((ulong *)(track_data + hdr.sect*512),
+		raw = decode ((ulong *)(unit[drive].trackbuf + hdr.sect*512),
 			      (ulong *)raw, 512);
-		csum = checksum((ulong *)(track_data + hdr.sect*512), 512);
+		csum = checksum((ulong *)(unit[drive].trackbuf + hdr.sect*512), 512);
 
 		if (hdr.datachk != csum) {
 			printk(KERN_INFO "MFM_DATA: (%x:%d:%d:%d) sc=%d %lx, %lx\n",
 			       hdr.magic, hdr.track, hdr.sect, hdr.ord, scnt,
 			       hdr.datachk, csum);
 			printk (KERN_INFO "data=(%lx,%lx,%lx,%lx)\n",
-				((ulong *)(track_data+hdr.sect*512))[0],
-				((ulong *)(track_data+hdr.sect*512))[1],
-				((ulong *)(track_data+hdr.sect*512))[2],
-				((ulong *)(track_data+hdr.sect*512))[3]);
+				((ulong *)(unit[drive].trackbuf+hdr.sect*512))[0],
+				((ulong *)(unit[drive].trackbuf+hdr.sect*512))[1],
+				((ulong *)(unit[drive].trackbuf+hdr.sect*512))[2],
+				((ulong *)(unit[drive].trackbuf+hdr.sect*512))[3]);
 			return MFM_DATA;
 		}
 	}
@@ -803,6 +824,89 @@
 	return 0;
 }
 
+static void encode(unsigned long data, unsigned long *dest)
+{
+  unsigned long data2;
+
+  data &= 0x55555555;
+  data2 = data ^ 0x55555555;
+  data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
+
+  if (*(dest - 1) & 0x00000001)
+    data &= 0x7FFFFFFF;
+
+  *dest = data;
+}
+
+static void encode_block(unsigned long *dest, unsigned long *src, int len)
+{
+  int cnt, to_cnt = 0;
+  unsigned long data;
+
+  /* odd bits */
+  for (cnt = 0; cnt < len / 4; cnt++) {
+    data = src[cnt] >> 1;
+    encode(data, dest + to_cnt++);
+  }
+
+  /* even bits */
+  for (cnt = 0; cnt < len / 4; cnt++) {
+    data = src[cnt];
+    encode(data, dest + to_cnt++);
+  }
+}
+
+static unsigned long *putsec(int disk, unsigned long *raw, int track, int cnt)
+{
+	struct header hdr;
+	int i;
+
+	disk&=3;
+	*raw = (raw[-1]&1) ? 0x2AAAAAAA : 0xAAAAAAAA;
+	raw++;
+	*raw++ = 0x44894489;
+
+	hdr.magic = 0xFF;
+	hdr.track = track;
+	hdr.sect = cnt;
+	hdr.ord = unit[disk].dtype->sects * unit[disk].type->sect_mult - cnt;
+	for (i = 0; i < 16; i++)
+		hdr.labels[i] = 0;
+	hdr.hdrchk = checksum((ulong *)&hdr,
+			      (char *)&hdr.hdrchk-(char *)&hdr);
+	hdr.datachk = checksum((ulong *)unit[disk].trackbuf+cnt*512, 512);
+
+	encode_block(raw, (ulong *)&hdr.magic, 4);
+	raw += 2;
+	encode_block(raw, (ulong *)&hdr.labels, 16);
+	raw += 8;
+	encode_block(raw, (ulong *)&hdr.hdrchk, 4);
+	raw += 2;
+	encode_block(raw, (ulong *)&hdr.datachk, 4);
+	raw += 2;
+	encode_block(raw, (ulong *)unit[disk].trackbuf+cnt*512, 512);
+	raw += 256;
+
+	return raw;
+}
+
+static void amiga_write(int disk)
+{
+	unsigned int cnt;
+	unsigned long *ptr = (unsigned long *)raw_buf;
+
+	disk&=3;
+	/* gap space */
+	for (cnt = 0; cnt < 415 * unit[disk].type->sect_mult; cnt++)
+		*ptr++ = 0xaaaaaaaa;
+
+	/* sectors */
+	for (cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++)
+		ptr = putsec (disk, ptr, unit[disk].track, cnt);
+	*(ushort *)ptr = (ptr[-1]&1) ? 0x2AA8 : 0xAAA8;
+}
+
+
 struct dos_header {
 unsigned char track,   /* 0-80 */
               side,    /* 0-1 */
@@ -811,22 +915,12 @@
 unsigned short crc;     /* on 68000 we got an alignment problem, 
                            but this compiler solves it  by adding silently 
                            adding a pad byte so data won't fit
-                           and this cost about 3h to discover.... */
+                           and this took about 3h to discover.... */
 unsigned char gap1[22];     /* for longword-alignedness (0x4e) */
 };
 
 /* crc routines are borrowed from the messydos-handler  */
 
-static inline ushort dos_hdr_crc (struct dos_header *hdr)
-{
-return dos_crc(&(hdr->track), 0xb2, 0x30, 3); /* precomputed magic */
-}
-
-static inline ushort dos_data_crc(unsigned char *data)
-{
-return dos_crc(data, 0xe2, 0x95 ,511); /* precomputed magic */
-}
-
 /* excerpt from the messydos-device           
 ; The CRC is computed not only over the actual data, but including
 ; the SYNC mark (3 * $a1) and the 'ID/DATA - Address Mark' ($fe/$fb).
@@ -937,6 +1031,16 @@
 return (crch<<8)|crcl;
 }
 
+static inline ushort dos_hdr_crc (struct dos_header *hdr)
+{
+return dos_crc(&(hdr->track), 0xb2, 0x30, 3); /* precomputed magic */
+}
+
+static inline ushort dos_data_crc(unsigned char *data)
+{
+return dos_crc(data, 0xe2, 0x95 ,511); /* precomputed magic */
+}
+
 static inline unsigned char dos_decode_byte(ushort word)
 {
 register ushort w2;
@@ -970,25 +1074,23 @@
 }
 #endif
 
-/*******************************************************************
-   this reads a raw track of data into trackbuffer for ms-disks 
-*******************************************************************/
-static int dos_read(int drive, unsigned char *track_data,
-	unsigned long raw, int track)
+static int dos_read(int drive)
 {
   unsigned long end;
+  unsigned long raw;
   int scnt;
   unsigned short crc,data_crc[2];
   struct dos_header hdr;
 
   drive&=3;
+  raw = (long) raw_buf;
   end = raw + unit[drive].type->read_size;
 
-  for (scnt=0;scnt<unit[drive].sects;scnt++) {
+  for (scnt=0; scnt < unit[drive].dtype->sects * unit[drive].type->sect_mult; scnt++) {
   do { /* search for the right sync of each sec-hdr */
     if (!(raw = scan_sync (raw, end))) {
       printk(KERN_INFO "dos_read: no hdr sync on track %d, unit %d for sector %d\n",
-        track,drive,scnt);
+        unit[drive].track,drive,scnt);
       return MFM_NOSYNC;
     }
 #ifdef DEBUG
@@ -1008,15 +1110,15 @@
     printk(KERN_INFO "dos_read: MFM_HEADER %04x,%04x\n", hdr.crc, crc);
     return MFM_HEADER;
   }
-  if (hdr.track != track/unit[drive].type->heads) {
+  if (hdr.track != unit[drive].track/unit[drive].type->heads) {
     printk(KERN_INFO "dos_read: MFM_TRACK %d, %d\n", hdr.track,
-      track/unit[drive].type->heads);
+      unit[drive].track/unit[drive].type->heads);
     return MFM_TRACK;
   }
 
-  if (hdr.side != track%unit[drive].type->heads) {
+  if (hdr.side != unit[drive].track%unit[drive].type->heads) {
     printk(KERN_INFO "dos_read: MFM_SIDE %d, %d\n", hdr.side,
-      track%unit[drive].type->heads);
+      unit[drive].track%unit[drive].type->heads);
     return MFM_TRACK;
   }
 
@@ -1029,7 +1131,7 @@
 #endif
   if (!(raw = scan_sync (raw, end))) {
     printk(KERN_INFO "dos_read: no data sync on track %d, unit %d for sector%d, disk sector %d\n",
-      track, drive, scnt, hdr.sec);
+      unit[drive].track, drive, scnt, hdr.sec);
     return MFM_NOSYNC;
   }
 #ifdef DEBUG
@@ -1043,19 +1145,19 @@
   }
 
   raw+=2;  /* skip data mark (included in checksum) */
-  raw = dos_decode((unsigned char *)(track_data + (hdr.sec - 1) * 512), (ushort *) raw, 512);
+  raw = dos_decode((unsigned char *)(unit[drive].trackbuf + (hdr.sec - 1) * 512), (ushort *) raw, 512);
   raw = dos_decode((unsigned char  *)data_crc,(ushort *) raw,4);
-  crc = dos_data_crc(track_data + (hdr.sec - 1) * 512);
+  crc = dos_data_crc(unit[drive].trackbuf + (hdr.sec - 1) * 512);
 
   if (crc != data_crc[0]) {
     printk(KERN_INFO "dos_read: MFM_DATA (%d,%d,%d,%d) sc=%d, %x %x\n",
       hdr.track, hdr.side, hdr.sec, hdr.len_desc,
       scnt,data_crc[0], crc);
     printk(KERN_INFO "data=(%lx,%lx,%lx,%lx,...)\n",
-      ((ulong *)(track_data+(hdr.sec-1)*512))[0],
-      ((ulong *)(track_data+(hdr.sec-1)*512))[1],
-      ((ulong *)(track_data+(hdr.sec-1)*512))[2],
-      ((ulong *)(track_data+(hdr.sec-1)*512))[3]);
+      ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[0],
+      ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[1],
+      ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[2],
+      ((ulong *)(unit[drive].trackbuf+(hdr.sec-1)*512))[3]);
     return MFM_DATA;
   }
   }
@@ -1086,8 +1188,7 @@
 }
 }
 
-static unsigned long *ms_putsec(int drive, unsigned long *raw, int track, int cnt,
-   unsigned char *data)
+static unsigned long *ms_putsec(int drive, unsigned long *raw, int track, int cnt)
 {
 static struct dos_header hdr={0,0,0,2,0,
   {78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78}};
@@ -1111,240 +1212,93 @@
 
 /* header (without "magic") and id gap 2*/
 dos_encode_block((ushort *)raw,(unsigned char *) &hdr.track,28);
-raw+=14;
-
-/*id gap 3 */
-for(i=0;i<6;i++)
-  *raw++=0xaaaaaaaa;
-
-/* 3 syncs and 1 datamark */
-*raw++=0x44894489;
-*raw++=0x44895545;
-
-/* data */
-dos_encode_block((ushort *)raw,(unsigned char *)data,512);
-raw+=256;
-
-/*data crc + jd's special gap (long words :-/) */
-crc[0]=dos_data_crc(data);
-dos_encode_block((ushort *) raw,(unsigned char *)crc,4);
-raw+=2;
-
-/* data gap */
-for(i=0;i<38;i++)
-  *raw++=0x92549254;
-
-return raw; /* wrote 652 MFM words */
-}
-
-
-/**************************************************************
-  builds encoded track data from trackbuffer data
-**************************************************************/
-static void dos_write(int disk, unsigned long raw, unsigned char *data,
-    int track)
-{
-int cnt;
-unsigned long *ptr=(unsigned long *)raw;
-
-disk&=3;
-/* really gap4 + indexgap , but we write it first and round it up */
-for (cnt=0;cnt<425;cnt++)
-  *ptr++=0x92549254;
-
-/* the following is just guessed */
-if (unit[disk].type->sect_mult==2)  /* check for HD-Disks */
-  for(cnt=0;cnt<473;cnt++)
-    *ptr++=0x92549254;
-
-/* now the index marks...*/
-for (cnt=0;cnt<20;cnt++)
-  *ptr++=0x92549254;
-for (cnt=0;cnt<6;cnt++)
-  *ptr++=0xaaaaaaaa;
-*ptr++=0x52245224;
-*ptr++=0x52245552;
-for (cnt=0;cnt<20;cnt++)
-  *ptr++=0x92549254;
-
-/* sectors */
-for(cnt=0;cnt<unit[disk].sects;cnt++)
-  ptr=ms_putsec(disk,ptr,track,cnt,data+cnt*512);
-
-*(ushort *)ptr = 0xaaa8; /* MFM word before is always 0x9254 */
-}
-
-static void request_done(int uptodate)
-{
-  timer_active &= ~(1 << FLOPPY_TIMER);
-  end_request(uptodate);
-}
-
-/*
- * floppy-change is never called from an interrupt, so we can relax a bit
- * here, sleep etc. Note that floppy-on tries to set current_DOR to point
- * to the desired drive, but it will probably not survive the sleep if
- * several floppies are used at the same time: thus the loop.
- */
-static int amiga_floppy_change(kdev_t dev)
-{
-	int drive = dev & 3;
-	int changed;
-	static int first_time = 1;
-
-	if (MAJOR(dev) != MAJOR_NR) {
-		printk(KERN_CRIT "floppy_change: not a floppy\n");
-		return 0;
-	}
-
-	if (first_time)
-		changed = first_time--;
-	else {
-		get_hw(drive);
-		fd_select (drive);
-		changed = !(ciaa.pra & DSKCHANGE);
-		fd_deselect (drive);
-		rel_hw();
-	}
-
-	if (changed) {
-		fd_probe(dev);
-		unit[drive].track = -1;
-		selected = -1;
-		savedtrack = -1;
-		writepending = 0; /* if this was true before, too bad! */
-		writefromint = 0;
-		return 1;
-	}
-	return 0;
-}
-
-static __inline__ void copy_buffer(void *from, void *to)
-{
-  ulong *p1,*p2;
-  int cnt;
-
-  p1 = (ulong *)from;
-  p2 = (ulong *)to;
-
-  for (cnt = 0; cnt < 512/4; cnt++)
-    *p2++ = *p1++;
-}
+raw+=14;
 
-static void raw_read(int drive, int track, char *ptrack, int len)
-{
-	drive&=3;
-	get_hw(drive);
-	/* setup adkcon bits correctly */
-	custom.adkcon = ADK_MSBSYNC;
-	custom.adkcon = ADK_SETCLR|ADK_WORDSYNC|ADK_FAST;
+/*id gap 3 */
+for(i=0;i<6;i++)
+  *raw++=0xaaaaaaaa;
 
-	custom.dsksync = MFM_SYNC;
+/* 3 syncs and 1 datamark */
+*raw++=0x44894489;
+*raw++=0x44895545;
 
-	custom.dsklen = 0;
-#if 0
-	ms_delay (unit[drive].type->side_time);
-#endif
-	custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)ptrack);
-	custom.dsklen = len/sizeof(short) | DSKLEN_DMAEN;
-	custom.dsklen = len/sizeof(short) | DSKLEN_DMAEN;
+/* data */
+dos_encode_block((ushort *)raw,(unsigned char *)unit[drive].trackbuf+cnt*512,512);
+raw+=256;
 
-	block_flag = 1;
+/*data crc + jd's special gap (long words :-/) */
+crc[0]=dos_data_crc(unit[drive].trackbuf+cnt*512);
+dos_encode_block((ushort *) raw,(unsigned char *)crc,4);
+raw+=2;
 
-	while (block_flag == 1)
-		sleep_on (&wait_fd_block);
+/* data gap */
+for(i=0;i<38;i++)
+  *raw++=0x92549254;
 
-	custom.dsklen = 0;
-	rel_hw();
+return raw; /* wrote 652 MFM words */
 }
 
-static int raw_write(int drive, int track, char *ptrack, int len)
+static void dos_write(int disk)
 {
-	ushort adk;
+int cnt;
+unsigned long raw = (unsigned long) raw_buf;
+unsigned long *ptr=(unsigned long *)raw;
 
-	drive&=3;
-	if ((ciaa.pra & DSKPROT) == 0)
-		return 0;
+disk&=3;
+/* really gap4 + indexgap , but we write it first and round it up */
+for (cnt=0;cnt<425;cnt++)
+  *ptr++=0x92549254;
 
-	get_hw(drive); /* corresponds to rel_hw() in post_write() */
-	/* clear adkcon bits */
-	custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
-	/* set appropriate adkcon bits */
-	adk = ADK_SETCLR|ADK_FAST;
-	if ((ulong)track >= unit[drive].type->precomp2)
-		adk |= ADK_PRECOMP1;
-	else if ((ulong)track >= unit[drive].type->precomp1)
-		adk |= ADK_PRECOMP0;
-	custom.adkcon = adk;
+/* the following is just guessed */
+if (unit[disk].type->sect_mult==2)  /* check for HD-Disks */
+  for(cnt=0;cnt<473;cnt++)
+    *ptr++=0x92549254;
 
-	custom.dsklen = DSKLEN_WRITE;
-#if 0
-	ms_delay (unit[drive].type->side_time);
-#endif
-	custom.dskptr = (u_char *)ZTWO_PADDR((u_char *)ptrack);
-	custom.dsklen = len/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
-	custom.dsklen = len/sizeof(short) | DSKLEN_DMAEN|DSKLEN_WRITE;
+/* now the index marks...*/
+for (cnt=0;cnt<20;cnt++)
+  *ptr++=0x92549254;
+for (cnt=0;cnt<6;cnt++)
+  *ptr++=0xaaaaaaaa;
+*ptr++=0x52245224;
+*ptr++=0x52245552;
+for (cnt=0;cnt<20;cnt++)
+  *ptr++=0x92549254;
 
-	block_flag = 2;
-	return 1;
-}
+/* sectors */
+for(cnt = 0; cnt < unit[disk].dtype->sects * unit[disk].type->sect_mult; cnt++)
+  ptr=ms_putsec(disk,ptr,unit[disk].track,cnt);
 
-static void post_write (unsigned long dummy)
-{
-  custom.dsklen = 0;
-  writepending = 0;
-  writefromint = 0;
-  rel_hw(); /* corresponds to get_hw() in raw_write */
+*(ushort *)ptr = 0xaaa8; /* MFM word before is always 0x9254 */
 }
 
-static int get_track(int drive, int track)
-{
-	int error, errors;
-
-	drive&=3;
-        get_hw(drive);
-        if (!motor_on(drive)) {
-          rel_hw();
-          return -1;
-        }
-        fd_select(drive);
-        errors = 0;
-        while (errors < MAX_ERRORS) {
-          if (!fd_seek(drive, track)) {
-            rel_hw();
-            return -1; /* we can not calibrate - no chance */
-          }
-          if ((lastdrive == drive) && (savedtrack == track)) {
-            rel_hw();
-            return 0;
-          }
-          lastdrive = drive;
-          raw_read(drive, track, raw_buf, unit[drive].type->read_size);
-          savedtrack = -1;
-          error = (*unit[drive].dtype->read_fkt)(drive, trackdata, (unsigned long)raw_buf, track);
-          if (error == 0) {
-            savedtrack = track;
-            rel_hw();
-            return 0;
-          }
-          if (error == MFM_TRACK)
-            unit[drive].track = -1;
-          errors++;
-	}
-	rel_hw();
-	return -1;
-}
+/*
+ * Here comes the high level stuff (i.e. the filesystem interface)
+ * and helper functions.
+ * Normally this should be the only part that has to be adapted to
+ * different kernel versions.
+ */
 
+/* FIXME: this assumes the drive is still spinning -
+ * which is only true if we complete writing a track within three seconds
+ */
 static void flush_track_callback(unsigned long nr)
 {
-  nr&=3;
-  writefromint = 1;
-  (*unit[nr].dtype->write_fkt)(nr, (unsigned long)raw_buf, trackdata, savedtrack);
-  if (!raw_write(nr, savedtrack, raw_buf, unit[nr].type->write_size)) {
-    printk (KERN_NOTICE "floppy disk write protected\n");
-    writefromint = 0;
-    writepending = 0;
-  }
+	nr&=3;
+	writefromint = 1;
+	if (!try_fdc(nr)) {
+		/* we might block in an interrupt, so try again later */
+		flush_track_timer[nr].expires = jiffies + 1;
+		add_timer(flush_track_timer + nr);
+		return;
+	}
+	get_fdc(nr);
+	(*unit[nr].dtype->write_fkt)(nr);
+	if (!raw_write(nr)) {
+		printk (KERN_NOTICE "floppy disk write protected\n");
+		writefromint = 0;
+		writepending = 0;
+	}
+	rel_fdc();
 }
 
 static int non_int_flush_track (unsigned long nr)
@@ -1354,12 +1308,18 @@
   nr&=3;
   writefromint = 0;
   del_timer(&post_write_timer);
+  get_fdc(nr);
+  if (!fd_motor_on(nr)) {
+  	writepending = 0;
+  	rel_fdc();
+  	return 0;
+  }
   save_flags(flags);
   cli();
   if (writepending != 2) {
     restore_flags(flags);
-    (*unit[nr].dtype->write_fkt)(nr, (unsigned long)raw_buf, trackdata, savedtrack);
-    if (!raw_write(nr, savedtrack, raw_buf, unit[nr].type->write_size)) {
+    (*unit[nr].dtype->write_fkt)(nr);
+    if (!raw_write(nr)) {
       printk (KERN_NOTICE "floppy disk write protected in write!\n");
       writepending = 0;
       return 0;
@@ -1367,13 +1327,50 @@
     while (block_flag == 2)
       sleep_on (&wait_fd_block);
   }
-  else
+  else {
     restore_flags(flags);
-  ms_delay(2); /* 2 ms post_write delay */
-  post_write(0);
+    ms_delay(2); /* 2 ms post_write delay */
+    post_write(nr);
+  }
+  rel_fdc();
   return 1;
 }
 
+static int get_track(int drive, int track)
+{
+	int error, errcnt;
+
+	drive&=3;
+	if (unit[drive].track == track)
+		return 0;
+	get_fdc(drive);
+	if (!fd_motor_on(drive)) {
+		rel_fdc();
+		return -1;
+	}
+
+	if (unit[drive].dirty == 1) {
+		del_timer (flush_track_timer + drive);
+		non_int_flush_track (drive);
+	}
+	errcnt = 0;
+	while (errcnt < MAX_ERRORS) {
+		if (!fd_seek(drive, track))
+			return -1;
+		raw_read(drive);
+		error = (*unit[drive].dtype->read_fkt)(drive);
+		if (error == 0) {
+			rel_fdc();
+			return 0;
+		}
+		/* Read Error Handling: recalibrate and try again */
+		unit[drive].track = -1;
+		errcnt++;
+	}
+	rel_fdc();
+	return -1;
+}
+
 static void redo_fd_request(void)
 {
 	unsigned int cnt, block, track, sector;
@@ -1388,10 +1385,7 @@
 
     repeat:
 	if (!CURRENT) {
-		if (fdc_busy < 0)
-			printk(KERN_CRIT "FDC access conflict!");
-		rel_fdc();
-		CLEAR_INTR;
+		/* Nothing left to do */
 		return;
 	}
 
@@ -1401,66 +1395,44 @@
 	if (CURRENT->bh && !buffer_locked(CURRENT->bh))
 		panic(DEVICE_NAME ": block not locked");
 
-	probing = 0;
 	device = MINOR(CURRENT_DEVICE);
-	if (device > 3) {
+	if (device < 8) {
 		/* manual selection */
 		drive = device & 3;
 		floppy = unit + drive;
 	} else {
 		/* Auto-detection */
-		/* printk("redo_fd_request: can't handle auto detect\n");*/
-		/* printk("redo_fd_request: default to normal\n");*/
+#ifdef DEBUG
+		printk("redo_fd_request: can't handle auto detect\n");
+		printk("redo_fd_request: default to normal\n");
+#endif
 		drive = device & 3;
 		floppy = unit + drive;
 	}
 
-	save_flags (flags);
-	cli();
-	if (drive != selected && writepending) {
-	  del_timer (&flush_track_timer);
-	  restore_flags (flags);
-	  if (!non_int_flush_track (selected)) {
-	    end_request(0);
-	    goto repeat;
-	  }
-	} else
-	  restore_flags (flags);
-
  /* Here someone could investigate to be more efficient */
 	for (cnt = 0; cnt < CURRENT->current_nr_sectors; cnt++) { 
 #ifdef DEBUG
-		printk("fd: sector %d + %d requested\n",CURRENT->sector,cnt);
+		printk("fd: sector %ld + %d requested for %s\n",CURRENT->sector,cnt,
+			(CURRENT->cmd==READ)?"read":"write");
 #endif
 		block = CURRENT->sector + cnt;
 		if ((int)block > floppy->blocks) {
-			request_done(0);
+			end_request(0);
 			goto repeat;
 		}
 
-		track = block / floppy->sects;
-		sector = block % floppy->sects;
+		track = block / floppy->dtype->sects * floppy->type->sect_mult;
+		sector = block % floppy->dtype->sects * floppy->type->sect_mult;
 		data = CURRENT->buffer + 512 * cnt;
 
-		save_flags (flags);
-		cli();
-		if (track != savedtrack && writepending) {
-		  del_timer (&flush_track_timer);
-		  restore_flags (flags);
-		  if (!non_int_flush_track (selected)) {
-		    end_request(0);
-		    goto repeat;
-		  }
-		} else
-		  restore_flags (flags);
-
 		switch (CURRENT->cmd) {
 		    case READ:
 			if (get_track(drive, track) == -1) {
 				end_request(0);
 				goto repeat;
 			}
-			copy_buffer(trackdata + sector * 512, data);
+			memcpy(data, unit[drive].trackbuf + sector * 512, 512);
 			break;
 
 		    case WRITE:
@@ -1468,7 +1440,13 @@
 				end_request(0);
 				goto repeat;
 			}
-			copy_buffer(data, trackdata + sector * 512);
+			memcpy(unit[drive].trackbuf + sector * 512, data, 512);
+
+			/* keep the drive spinning while writes are scheduled */
+			if (!fd_motor_on(drive)) {
+				end_request(0);
+				goto repeat;
+			}
 			/*
 			 * setup a callback to write the track buffer
 			 * after a short (1 tick) delay.
@@ -1476,33 +1454,30 @@
 			save_flags (flags);
 			cli();
 
-			if (writepending)
-			    /* reset the timer */
-			    del_timer (&flush_track_timer);
+			unit[drive].dirty = 1;
+		        /* reset the timer */
+		        del_timer (flush_track_timer + drive);
 			    
-			writepending = 1;
-			flush_track_timer.data = drive;
-			flush_track_timer.expires = jiffies + 1;
-			add_timer (&flush_track_timer);
+			flush_track_timer[drive].expires = jiffies + 1;
+			add_timer (flush_track_timer + drive);
 			restore_flags (flags);
 			break;
 
 		    default:
 			printk(KERN_WARNING "do_fd_request: unknown command\n");
-			request_done(0);
+			end_request(0);
 			goto repeat;
 		}
 	}
 	CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
 	CURRENT->sector += CURRENT->current_nr_sectors;
 
-	request_done(1);
+	end_request(1);
 	goto repeat;
 }
 
 static void do_fd_request(void)
 {
-	get_fdc(CURRENT_DEVICE & 3);
 	redo_fd_request();
 }
 
@@ -1513,14 +1488,13 @@
 	static struct floppy_struct getprm;
 	struct super_block * sb;
 	int error;
-	unsigned long flags;
 
 	switch(cmd){
 	case HDIO_GETGEO:
 	{
 		struct hd_geometry loc;
 		loc.heads = unit[drive].type->heads;
-		loc.sectors = unit[drive].sects;
+		loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
 		loc.cylinders = unit[drive].type->tracks;
 		loc.start = 0;
 		if ((error = copy_to_user((void *)param, (void *)&loc,
@@ -1529,37 +1503,33 @@
 		break;
 	}
 	case FDFMTBEG:
-		get_hw(drive);
+		get_fdc(drive);
 		if (fd_ref[drive] > 1) {
-			rel_hw();
+			rel_fdc();
 			return -EBUSY;
 		}
 		fsync_dev(inode->i_rdev);
-		if (motor_on(drive) == 0) {
-			rel_hw();
+		if (fd_motor_on(drive) == 0) {
+			rel_fdc();
 			return -ENODEV;
 		}
 		if (fd_calibrate(drive) == 0) {
-			rel_hw();
+			rel_fdc();
 			return -ENXIO;
 		}
 		floppy_off(drive);
-		rel_hw();
+		rel_fdc();
 		break;
 	case FDFMTTRK:
 		if (param < unit[drive].type->tracks * unit[drive].type->heads)
 		{
 			get_fdc(drive);
-			get_hw(drive);
-			fd_select(drive);
-			if (fd_seek(drive,param)!=0){
-				savedtrack=param;
-				memset(trackdata, FD_FILL_BYTE,
-				       unit[drive].sects*512);
+			if (fd_seek(drive,param) != 0){
+				memset(unit[drive].trackbuf, FD_FILL_BYTE,
+				       unit[drive].dtype->sects * unit[drive].type->sect_mult * 512);
 				non_int_flush_track(drive);
 			}
 			floppy_off(drive);
-			rel_hw();
 			rel_fdc();
 		}
 		else
@@ -1576,7 +1546,7 @@
 		memset((void *)&getprm, 0, sizeof (getprm));
 		getprm.track=unit[drive].type->tracks;
 		getprm.head=unit[drive].type->heads;
-		getprm.sect=unit[drive].sects;
+		getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;
 		getprm.size=unit[drive].blocks;
 		if ((error = copy_to_user((void *)param,
 					  (void *)&getprm,
@@ -1590,16 +1560,9 @@
 	case FDSETPRM:
 	case FDDEFPRM:
 		return -EINVAL;
-	case FDFLUSH:
-		save_flags(flags);
-		cli();
-		if ((drive == selected) && (writepending)) {
-			del_timer (&flush_track_timer);
-			restore_flags(flags);
-			non_int_flush_track(selected);
-		}
-		else
-			restore_flags(flags);
+	case FDFLUSH: /* unconditionally, even if not needed */
+		del_timer (flush_track_timer + drive);
+		non_int_flush_track(drive);
 		break;
 #ifdef RAW_IOCTL
 	case IOCTL_RAW_TRACK:
@@ -1617,64 +1580,6 @@
 	return 0;
 }
 
-/*======================================================================
-  Return unit ID number of given disk
-======================================================================*/
-static unsigned long get_drive_id(int drive)
-{
-	static int called = 0;
-	int i;
-	ulong id = 0;
-
-  	drive&=3;
-  	get_hw(drive);
-	/* set up for ID */
-	MOTOR_ON;
-	udelay(2);
-	SELECT(SELMASK(drive));
-	udelay(2);
-	DESELECT(SELMASK(drive));
-	udelay(2);
-	MOTOR_OFF;
-	udelay(2);
-	SELECT(SELMASK(drive));
-	udelay(2);
-	DESELECT(SELMASK(drive));
-	udelay(2);
-
-	/* loop and read disk ID */
-	for (i=0; i<32; i++) {
-		SELECT(SELMASK(drive));
-		udelay(2);
-
-		/* read and store value of DSKRDY */
-		id <<= 1;
-		id |= (ciaa.pra & DSKRDY) ? 0 : 1;	/* cia regs are low-active! */
-
-		DESELECT(SELMASK(drive));
-	}
-
-	selected = -1;
-	rel_hw();
-
-        /*
-         * RB: At least A500/A2000's df0: don't identify themselves.
-         * As every (real) Amiga has at least a 3.5" DD drive as df0:
-         * we default to that if df0: doesn't identify as a certain
-         * type.
-         */
-        if(drive == 0 && id == FD_NODRIVE)
-         {
-                id = fd_def_df0;
-                printk("%sfd: drive 0 didn't identify, setting default %08lx\n",
-			(called == 0)? KERN_NOTICE:"", (ulong)fd_def_df0);
-		if (called == 0)
-			called++;
-         }
-	/* return the ID value */
-	return (id);
-}
-
 static void fd_probe(int dev)
 {
 	unsigned long code;
@@ -1683,7 +1588,7 @@
 	int system;
 
 	drive = dev & 3;
-	code = get_drive_id(drive);
+	code = fd_get_drive_id(drive);
 
 	/* get drive type */
 	unit[drive].type = NULL;
@@ -1709,30 +1614,13 @@
 
 	system=(dev & 4)>>2;
 	unit[drive].dtype=&data_types[system];
-	unit[drive].sects=data_types[system].sects*unit[drive].type->sect_mult;
 	unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
-	    unit[drive].sects;
+		data_types[system].sects*unit[drive].type->sect_mult;
 
 	floppy_sizes[MINOR(dev)] = unit[drive].blocks >> 1;
 
 }
 
-__initfunc(static void probe_drives(void))
-{
-	int drive,found;
-
-	printk(KERN_INFO "FD: probing units\n" KERN_INFO "found ");
-	found=0;
-	for(drive=0;drive<FD_MAX_UNITS;drive++) {
-	  fd_probe(drive);
-	  if (unit[drive].type->code != FD_NODRIVE) {
-	    printk("fd%d ",drive);
-	    found=1;
-	  }
-	}
-	printk("%s\n",(found==0)?" no drives":"");
-}
-
 /*
  * floppy_open check for aliasing (/dev/fd0 can be the same as
  * /dev/PS0 etc), and disallows simultaneous access to the same
@@ -1758,11 +1646,11 @@
   if (filp && (filp->f_flags & (O_WRONLY|O_RDWR))) {
 	  int wrprot;
 
-	  get_hw(drive);
+	  get_fdc(drive);
 	  fd_select (drive);
 	  wrprot = !(ciaa.pra & DSKPROT);
 	  fd_deselect (drive);
-	  rel_hw();
+	  rel_fdc();
 
 	  if (wrprot)
 		  return -EROFS;
@@ -1786,11 +1674,10 @@
 
   system=(inode->i_rdev & 4)>>2;
   unit[drive].dtype=&data_types[system];
-  unit[drive].sects=data_types[system].sects*unit[drive].type->sect_mult;
   unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
-        unit[drive].sects;
+		data_types[system].sects*unit[drive].type->sect_mult;
 
-printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,unit[drive].type->name,
+  printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,unit[drive].type->name,
   data_types[system].name);
 
   return 0;
@@ -1798,38 +1685,73 @@
 
 static int floppy_release(struct inode * inode, struct file * filp)
 {
-  unsigned long flags;
+#ifdef DEBUG
   struct super_block * sb;
+#endif
+  int drive = MINOR(inode->i_rdev) & 3;
 
   fsync_dev(inode->i_rdev);
+
+#ifdef DEBUG
+  /* This is now handled in floppy_change, but still useful for debugging */
   sb = get_super(inode->i_rdev);
   if (sb)
 	  invalidate_inodes(sb);
   invalidate_buffers(inode->i_rdev);
-  save_flags (flags);
-  cli();
-  if ((inode->i_rdev & 3) == selected && writepending) {
-    del_timer (&flush_track_timer);
-    restore_flags (flags);
-    non_int_flush_track (selected);
-  } else
-    restore_flags (flags);
+#endif
+
+  if (unit[drive].dirty == 1) {
+	  del_timer (flush_track_timer + drive);
+	  non_int_flush_track (drive);
+  }
   
-  if (!fd_ref[inode->i_rdev & 3]--) {
+  if (!fd_ref[drive]--) {
     printk(KERN_CRIT "floppy_release with fd_ref == 0");
-    fd_ref[inode->i_rdev & 3] = 0;
+    fd_ref[drive] = 0;
   }
 #ifdef MODULE
 /* the mod_use counter is handled this way */
-  floppy_off (inode->i_rdev & 3);
+  floppy_off (drive | 0x40000000);
 #endif
   return 0;
 }
 
-__initfunc(void amiga_floppy_setup (char *str, int *ints))
+/*
+ * floppy-change is never called from an interrupt, so we can relax a bit
+ * here, sleep etc. Note that floppy-on tries to set current_DOR to point
+ * to the desired drive, but it will probably not survive the sleep if
+ * several floppies are used at the same time: thus the loop.
+ */
+static int amiga_floppy_change(kdev_t dev)
 {
-	printk ("amiflop: Setting default df0 to %x\n", ints[1]);
-	fd_def_df0 = ints[1];
+	int drive = MINOR(dev) & 3;
+	int changed;
+	static int first_time = 1;
+
+	if (MAJOR(dev) != MAJOR_NR) {
+		printk(KERN_CRIT "floppy_change: not a floppy\n");
+		return 0;
+	}
+
+	if (first_time)
+		changed = first_time--;
+	else {
+		get_fdc(drive);
+		fd_select (drive);
+		changed = !(ciaa.pra & DSKCHANGE);
+		fd_deselect (drive);
+		rel_fdc();
+	}
+
+	if (changed) {
+		fd_probe(dev);
+		unit[drive].track = -1;
+		unit[drive].dirty = 0;
+		writepending = 0; /* if this was true before, too bad! */
+		writefromint = 0;
+		return 1;
+	}
+	return 0;
 }
 
 static struct file_operations floppy_fops = {
@@ -1848,24 +1770,40 @@
 	NULL,			/* revalidate */
 };
 
-static void fd_block_done(int irq, void *dummy, struct pt_regs *fp)
+__initfunc(void amiga_floppy_setup (char *str, int *ints))
 {
-  if (block_flag)
-    custom.dsklen = 0x4000;
-
-  block_flag = 0;
-  wake_up (&wait_fd_block);
+	printk (KERN_INFO "amiflop: Setting default df0 to %x\n", ints[1]);
+	fd_def_df0 = ints[1];
+}
 
-  if (writefromint) {
-    /* 
-     * if it was a write from an interrupt,
-     * we will call post_write from here
-     */
-    writepending = 2;
-    post_write_timer.expires = 1; /* at least 2 ms */
-    add_timer(&post_write_timer);
-  }
+__initfunc(static int fd_probe_drives(void))
+{
+	int drive,drives,nomem;
 
+	printk(KERN_INFO "FD: probing units\n" KERN_INFO "found ");
+	drives=0;
+	nomem=0;
+	for(drive=0;drive<FD_MAX_UNITS;drive++) {
+	  fd_probe(drive);
+	  if (unit[drive].type->code != FD_NODRIVE) {
+	    drives++;
+	    if ((unit[drive].trackbuf = kmalloc(MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {
+	      printk("no mem for ");
+	      unit[drive].type = &drive_types[num_dr_types - 1]; /* FD_NODRIVE */
+	      drives--;
+	      nomem = 1;
+	    }
+	    printk("fd%d ",drive);
+	  }
+	}
+	if ((drives > 0) || (nomem == 0)) {
+	  if (drives == 0)
+	    printk("no drives");
+	  printk("\n");
+	  return drives;
+	}
+	printk("\n");
+	return -ENOMEM;
 }
 
 __initfunc(int amiga_floppy_init(void))
@@ -1874,11 +1812,36 @@
 
   if (!AMIGAHW_PRESENT(AMI_FLOPPY))
     return -ENXIO;
-
   if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
-    printk("Unable to get major %d for floppy\n",MAJOR_NR);
+    printk("fd: Unable to get major %d for floppy\n",MAJOR_NR);
     return -EBUSY;
   }
+  if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE)) == NULL) {
+  	printk("fd: cannot get chip mem buffer\n");
+  	unregister_blkdev(MAJOR_NR,"fd");
+  	return -ENOMEM;
+  }
+
+  if (request_irq(IRQ_FLOPPY, fd_block_done, 0, "floppy_dma", NULL) != 0) {
+  	printk("fd: cannot get irq for dma\n");
+  	amiga_chip_free(raw_buf);
+  	unregister_blkdev(MAJOR_NR,"fd");
+  	return -EBUSY;
+  }
+  if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL) != 0) {
+  	printk("fd: cannot get irq for timer\n");
+  	free_irq(IRQ_FLOPPY, NULL);
+  	amiga_chip_free(raw_buf);
+  	unregister_blkdev(MAJOR_NR,"fd");
+  	return -EBUSY;
+  }
+  if (fd_probe_drives() < 1) { /* No usable drives */
+  	free_irq(IRQ_AMIGA_CIAA_TB, NULL);
+  	free_irq(IRQ_FLOPPY, NULL);
+  	amiga_chip_free(raw_buf);
+  	unregister_blkdev(MAJOR_NR,"fd");
+  	return -ENXIO;
+  }
 
   /* initialize variables */
   motor_on_timer.next = NULL;
@@ -1890,18 +1853,17 @@
 	  motor_off_timer[i].next = NULL;
 	  motor_off_timer[i].prev = NULL;
 	  motor_off_timer[i].expires = 0;
-	  motor_off_timer[i].data = i;
+	  motor_off_timer[i].data = i|0x80000000;
 	  motor_off_timer[i].function = fd_motor_off;
+	  flush_track_timer[i].next = NULL;
+	  flush_track_timer[i].prev = NULL;
+	  flush_track_timer[i].expires = 0;
+	  flush_track_timer[i].data = i;
+	  flush_track_timer[i].function = flush_track_callback;
 
 	  unit[i].track = -1;
   }
 
-  flush_track_timer.next = NULL;
-  flush_track_timer.prev = NULL;
-  flush_track_timer.expires = 0;
-  flush_track_timer.data = 0;
-  flush_track_timer.function = flush_track_callback;
-
   post_write_timer.next = NULL;
   post_write_timer.prev = NULL;
   post_write_timer.expires = 0;
@@ -1913,9 +1875,6 @@
   blk_size[MAJOR_NR] = floppy_sizes;
 
 
-  timer_table[FLOPPY_TIMER].fn = NULL;
-  timer_active &= ~(1 << FLOPPY_TIMER);
-
   #if 0 /* Doesn't seem to be correct */
   if (fd_def_df0==0) {
     if ((amiga.model == AMI_3000) || (amiga.model == AMI_3000T) ||
@@ -1929,14 +1888,10 @@
   fd_def_df0 = FD_DD_3;
   #endif
 
-  probe_drives();
-
-  raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE);
-
   for (i = 0; i < 128; i++)
-    mfmdecode[i]=255;
+	  mfmdecode[i]=255;
   for (i = 0; i < 16; i++)
-    mfmdecode[mfmencode[i]]=i;
+	  mfmdecode[mfmencode[i]]=i;
 
   /* make sure that disk DMA is enabled */
   custom.dmacon = DMAF_SETCLR | DMAF_DISK;
@@ -1944,9 +1899,7 @@
   /* init ms timer */
   ciaa.crb = 8; /* one-shot, stop */
 
-  request_irq(IRQ_FLOPPY, fd_block_done, 0, "floppy_dma", NULL);
-  request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL);
-
+  (void)do_floppy; /* avoid warning about unused variable */
   return 0;
 }
 
@@ -1962,11 +1915,15 @@
 
 void cleanup_module(void)
 {
+int i;
+
+for( i = 0; i < FD_MAX_UNITS; i++)
+  if (unit[i].type->code != FD_NODRIVE)
+    kfree(unit[i].trackbuf);
 free_irq(IRQ_AMIGA_CIAA_TB, NULL);
 free_irq(IRQ_FLOPPY, NULL);
 custom.dmacon = DMAF_DISK; /* disable DMA */
 amiga_chip_free(raw_buf);
-timer_active &= ~(1 << FLOPPY_TIMER);
 blk_size[MAJOR_NR] = NULL;
 blksize_size[MAJOR_NR] = NULL;
 blk_dev[MAJOR_NR].request_fn = NULL;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/char/Makefile m68k-2.1.77/drivers/char/Makefile
--- /usr/src/m68k-2.1.77/drivers/char/Makefile	Thu Jan  8 22:04:55 1998
+++ m68k-2.1.77/drivers/char/Makefile	Fri Jan  9 01:19:23 1998
@@ -26,8 +26,16 @@
 L_OBJS += vt.o vc_screen.o consolemap.o consolemap_deftbl.o
 LX_OBJS += selection.o
 
-ifneq "$(ARCH)" "m68k"
-L_OBJS += console.o
+ifdef CONFIG_ABSTRACT_CONSOLE
+  L_OBJS += console.new.o
+else
+  L_OBJS += console.o
+  ifdef CONFIG_TGA_CONSOLE
+    L_OBJS += tga.o
+  endif
+  ifdef CONFIG_VGA_CONSOLE
+    L_OBJS += vga.o vesa_blank.o
+  endif
 endif
 
 ifdef CONFIG_FB
@@ -517,17 +525,6 @@
   endif
 endif
   
-ifneq "$(ARCH)" "m68k" 
-ifdef CONFIG_VT
-  ifdef CONFIG_TGA_CONSOLE
-  L_OBJS += tga.o
-  endif
-  ifdef CONFIG_VGA_CONSOLE
-  L_OBJS += vga.o vesa_blank.o
-  endif
-endif
-endif
-
 ifeq ($(CONFIG_HFMODEM),y)
 ALL_SUB_DIRS += hfmodem
 SUB_DIRS += hfmodem
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/char/console.new.c m68k-2.1.77/drivers/char/console.new.c
--- /usr/src/m68k-2.1.77/drivers/char/console.new.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/char/console.new.c	Fri Jan  9 01:23:46 1998
@@ -0,0 +1,2746 @@
+/*
+ *  linux/drivers/char/console.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+/*
+ *	console.c
+ *
+ * This module exports the console io functions:
+ *
+ *     'int vc_allocate(unsigned int console)'
+ *     'int vc_cons_allocated(unsigned int console)'
+ *     'int vc_resize(unsigned long lines, unsigned long cols)'
+ *     'int vc_resize_con(unsigned long lines, unsigned long cols,
+ *			  unsigned int currcons)'
+ *     'void vc_disallocate(unsigned int currcons)'
+ *
+ *     'unsigned long con_init(unsigned long)'
+ *     'int con_open(struct tty_struct *tty, struct file * filp)'
+ *     'void con_write(struct tty_struct * tty)'
+ *     'void vt_console_print(struct console *co, const char * b,
+ *                            unsigned count)'
+ *     'void update_screen(int new_console)'
+ *
+ *     'void do_blank_screen(int)'
+ *     'void do_unblank_screen(void)'
+ *     'void poke_blanked_console(void)'
+ *
+ *     'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
+ *     'void complement_pos(int currcons, int offset)'
+ *     'void invert_screen(int currcons, int offset, int count, int shift)'
+ *
+ *     'void scrollback(int lines)'
+ *     'void scrollfront(int lines)'
+ *
+ *     'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
+ *     'int mouse_reporting(void)'
+ *
+ * Hopefully this will be a rather complete VT102 implementation.
+ *
+ * Beeping thanks to John T Kohl.
+ *
+ * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
+ *   Chars, and VT100 enhancements by Peter MacDonald.
+ *
+ * Copy and paste function by Andrew Haylett,
+ *   some enhancements by Alessandro Rubini.
+ *
+ * Code to check for different video-cards mostly by Galen Hunt,
+ * <g-hunt@ee.utah.edu>
+ *
+ * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
+ * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
+ *
+ * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
+ * Resizing of consoles, aeb, 940926
+ *
+ * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
+ * <poe@daimi.aau.dk>
+ *
+ * User-defined bell sound, new setterm control sequences and printk
+ * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
+ *
+ * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
+ *
+ * Merge with the abstract console driver by Geert Uytterhoeven
+ * <Geert.Uytterhoeven@cs.kuleuven.ac.be>, Jan 1997.
+ *
+ *   Original m68k console driver modifications by
+ *
+ *     - Arno Griffioen <arno@usn.nl>
+ *     - David Carter <carter@cs.bris.ac.uk>
+ * 
+ *   Note that the abstract console driver allows all consoles to be of
+ *   potentially different sizes, so the following variables depend on the
+ *   current console (currcons):
+ *
+ *     - video_num_columns
+ *     - video_num_lines
+ *     - video_size_row
+ *     - video_screen_size
+ *     - can_do_color
+ *
+ *   The abstract console driver provides a generic interface for a text
+ *   console. It supports VGA text mode, frame buffer based graphical consoles
+ *   and special graphics processors that are only accessible through some
+ *   registers (e.g. a TMS340x0 GSP).
+ *
+ *   The interface to the hardware is specified using a special structure
+ *   (struct consw) which contains function pointers to the following
+ *   operations:
+ *
+ *     unsigned long con_startup(unsigned long kmem_start,
+ *				 const char **display_desc)
+ *     void con_init(struct vc_data *conp)
+ *     int con_deinit(struct vc_data *conp)
+ *     int con_clear(struct vc_data *conp, int sy, int sx, int height,
+ *		     int width)
+ *     int con_putc(struct vc_data *conp, int c, int y, int x)
+ *     int con_putcs(struct vc_data *conp, const char *s, int count, int y,
+ *		     int x)
+ *     int con_cursor(struct vc_data *conp, int mode)
+ *     int con_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+ *     int con_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+ *		     int height, int width)
+ *     int con_switch(struct vc_data *conp)
+ *     int con_blank(int blank)
+ *     int con_get_font(struct vc_data *conp, int *w, int *h, char *data)
+ *     int con_set_font(struct vc_data *conp, int w, int h, char *data)
+ *     int con_set_palette(struct vc_data *conp, unsigned char *table)
+ *     int con_scrolldelta(int lines)
+ *
+ * Support for changeable cursor shape
+ * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
+ */
+
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
+#include <linux/kbd_kern.h>
+#include <linux/consolemap.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#define INCLUDE_LINUX_LOGO_DATA
+#include <asm/linux_logo.h>
+
+
+struct consw *conswitchp = NULL;
+
+int (*console_show_logo)(void) __initdata = NULL;
+
+static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
+
+static inline void hide_cursor(int currcons)
+{
+    sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
+}
+
+void set_cursor(int currcons)
+{
+    if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
+	return;
+    if (deccm)
+	sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
+    else
+	hide_cursor(currcons);
+}
+
+    /*
+     *  Adjust the screen to fit a font of a certain height
+     *
+     *  Returns < 0 for error, 0 if nothing changed, and the number
+     *  of lines on the adjusted console if changed.
+     */
+
+int con_adjust_height(unsigned long fontheight)
+{
+    int currcons = fg_console;
+    /* ++Geert: Always assume that the number of lines did change? */
+    return video_num_lines;
+}
+
+/* dummy functions */
+
+void no_scroll(char *str, int *ints)
+{
+}
+
+
+#define BLANK 0x0020
+
+/* A bitmap for codes <32. A bit of 1 indicates that the code
+ * corresponding to that bit number invokes some special action
+ * (such as cursor movement) and should not be displayed as a
+ * glyph unless the disp_ctrl mode is explicitly enabled.
+ */
+#define CTRL_ACTION 0x0d00ff81
+#define CTRL_ALWAYS 0x0800f501	/* Cannot be overridden by disp_ctrl */
+
+/*
+ * Here is the default bell parameters: 750HZ, 1/8th of a second
+ */
+#define DEFAULT_BELL_PITCH	750
+#define DEFAULT_BELL_DURATION	(HZ/8)
+
+/*
+ *  NOTE!!! We sometimes disable and enable interrupts for a short while
+ * (to put a word in video IO), but this will work even for keyboard
+ * interrupts. We know interrupts aren't enabled when getting a keyboard
+ * interrupt, as we use trap-gates. Hopefully all is well.
+ */
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+struct tty_driver console_driver;
+static int console_refcount;
+static struct tty_struct *console_table[MAX_NR_CONSOLES];
+static struct termios *console_termios[MAX_NR_CONSOLES];
+static struct termios *console_termios_locked[MAX_NR_CONSOLES];
+unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
+struct vc vc_cons [MAX_NR_CONSOLES];
+
+static int con_open(struct tty_struct *, struct file *);
+static void vc_init(unsigned int console, unsigned long rows,
+		    unsigned long cols, int do_clear);
+static void blank_screen(void);
+static void unblank_screen(void);
+extern void change_console(unsigned int);
+extern void poke_blanked_console(void);
+static void update_attr(int currcons);
+static void gotoxy(int currcons, int new_x, int new_y);
+static void save_cur(int currcons);
+static void reset_terminal(int currcons, int do_clear);
+extern void reset_vc(unsigned int new_console);
+extern void vt_init(void);
+extern void set_vesa_blanking(unsigned long arg);
+extern void vesa_blank(void);
+extern void vesa_powerdown(void);
+extern void compute_shiftstate(void);
+extern void reset_palette(int currcons);
+extern void set_palette(void);
+
+static int printable = 0;		/* Is console ready for printing? */
+
+int		video_mode_512ch = 0;	/* 512-character mode */
+unsigned long	video_font_height;	/* Height of current screen font */
+unsigned long	video_scan_lines;	/* Number of scan lines on screen */
+static unsigned short console_charmask = 0x0ff;
+
+/* used by kbd_bh - set by keyboard_interrupt */
+       int do_poke_blanked_console = 0;
+       int console_blanked = 0;
+static int blankinterval = 10*60*HZ;
+static int vesa_off_interval = 0;
+
+static char putcs_buf[256];
+
+/*
+ * fg_console is the current virtual console,
+ * last_console is the last used one,
+ * want_console is the console we want to switch to,
+ * kmsg_redirect is the console for kernel messages,
+ */
+int fg_console = 0;
+int last_console = 0;
+int want_console = -1;
+int kmsg_redirect = 0;
+
+int vc_cons_allocated(unsigned int i)
+{
+	return (i < MAX_NR_CONSOLES && vc_cons[i].d);
+}
+
+void visual_init(int currcons)
+{
+    /* ++Geert: sw->con_init determines console size */
+    sw = conswitchp;
+    cons_num = currcons;
+    sw->con_init(vc_cons[currcons].d);
+    video_size_row = video_num_columns<<1;
+    video_screen_size = video_num_lines*video_size_row;
+}
+
+int vc_allocate(unsigned int currcons)		/* return 0 on success */
+{
+	if (currcons >= MAX_NR_CONSOLES)
+	  return -ENXIO;
+	if (!vc_cons[currcons].d) {
+	    long p, q;
+
+	    /* prevent users from taking too much memory */
+	    if (currcons >= MAX_NR_USER_CONSOLES && !suser())
+	      return -EPERM;
+
+	    /* due to the granularity of kmalloc, we waste some memory here */
+	    /* the alloc is done in two steps, to optimize the common situation
+	       of a 25x80 console (structsize=216, video_screen_size=4000) */
+	    p = (long) kmalloc(structsize, GFP_KERNEL);
+	    if (!p)
+		return -ENOMEM;
+	    vc_cons[currcons].d = (struct vc_data *)p;
+	    vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
+	    visual_init(currcons);
+	    q = (long)kmalloc(video_screen_size, GFP_KERNEL);
+	    if (!q) {
+		kfree_s((char *) p, structsize);
+		vc_cons[currcons].d = NULL;
+		vt_cons[currcons] = NULL;
+		return -ENOMEM;
+	    }
+	    vc_scrbuf[currcons] = (unsigned short *) q;
+	    vc_cons[currcons].d->vc_kmalloced = 1;
+	    vc_cons[currcons].d->vc_screenbuf_size = video_screen_size;
+	    vc_init(currcons, video_num_lines, video_num_columns, 1);
+	}
+	return 0;
+}
+
+/*
+ * Change # of rows and columns (0 means unchanged/the size of fg_console)
+ * [this is to be used together with some user program
+ * like resize that changes the hardware videomode]
+ */
+int vc_resize(unsigned long lines, unsigned long cols)
+{
+	unsigned long cc, ll, ss, sr;
+	unsigned long occ, oll, oss, osr;
+	unsigned short *p;
+	unsigned int currcons = fg_console, i;
+	unsigned short *newscreens[MAX_NR_CONSOLES];
+	long ol, nl, rlth, rrem;
+
+	cc = (cols ? cols : video_num_columns);
+	ll = (lines ? lines : video_num_lines);
+	sr = cc << 1;
+	ss = sr * ll;
+
+	/*
+	 * Some earlier version had all consoles of potentially
+	 * different sizes, but that was really messy.
+	 * So now we only change if there is room for all consoles
+	 * of the same size.
+	 */
+	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
+	    if (!vc_cons_allocated(currcons))
+	      newscreens[currcons] = 0;
+	    else {
+		p = (unsigned short *) kmalloc(ss, GFP_USER);
+		if (!p) {
+		    for (i = 0; i< currcons; i++)
+		      if (newscreens[i])
+			kfree_s(newscreens[i], ss);
+		    return -ENOMEM;
+		}
+		newscreens[currcons] = p;
+	    }
+	}
+
+	for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
+	    if (!vc_cons_allocated(currcons))
+	      continue;
+
+	    oll = video_num_lines;
+	    occ = video_num_columns;
+	    osr = video_size_row;
+	    oss = video_screen_size;
+
+	    video_num_lines = ll;
+	    video_num_columns = cc;
+	    video_size_row = sr;
+	    video_screen_size = ss;
+
+	    rlth = MIN(osr, sr);
+	    rrem = sr - rlth;
+	    ol = origin;
+	    nl = (long) newscreens[currcons];
+	    if (ll < oll)
+	      ol += (oll - ll) * osr;
+
+	    update_attr(currcons);
+	    while (ol < scr_end) {
+		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
+		if (rrem)
+		  memsetw((void *)(nl + rlth), video_erase_char, rrem);
+		ol += osr;
+		nl += sr;
+	    }
+
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], oss);
+	    vc_scrbuf[currcons] = newscreens[currcons];
+	    kmalloced = 1;
+	    screenbuf_size = ss;
+
+	    origin = video_mem_start = (long) vc_scrbuf[currcons];
+	    scr_end = video_mem_end = video_mem_start + ss;
+
+	    if (scr_end > nl)
+	      memsetw((void *) nl, video_erase_char, scr_end - nl);
+
+	    /* do part of a reset_terminal() */
+	    top = 0;
+	    bottom = video_num_lines;
+	    gotoxy(currcons, x, y);
+	    save_cur(currcons);
+	}
+
+	/* don't update in graphics mode */
+	if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
+	    update_screen(fg_console);
+
+	set_cursor(fg_console);
+
+	return 0;
+}
+
+/*
+ * ++Geert: Change # of rows and columns for one specific console.
+ * Of course it's not messy to have all consoles of potentially different
+ * sizes, except on PCish hardware :-)
+ */
+void vc_resize_con(unsigned long lines, unsigned long cols,
+		   unsigned int currcons)
+{
+	unsigned long cc, ll, ss, sr;
+	unsigned long occ, oll, oss, osr;
+	unsigned short *newscreen;
+	long ol, nl, rlth, rrem;
+	struct winsize ws, *cws;
+
+	if (!cols || !lines || currcons >= MAX_NR_CONSOLES)
+	    return;
+
+	cc = cols;
+	ll = lines;
+	sr = cc << 1;
+	ss = sr * ll;
+
+	if (!vc_cons_allocated(currcons))
+	    newscreen = 0;
+	else if (!(newscreen = (unsigned short *)kmalloc(ss, GFP_USER)))
+	    return;
+
+	if (vc_cons_allocated(currcons)) {
+	    oll = video_num_lines;
+	    occ = video_num_columns;
+	    osr = video_size_row;
+	    oss = video_screen_size;
+
+	    video_num_lines = ll;
+	    video_num_columns = cc;
+	    video_size_row = sr;
+	    video_screen_size = ss;
+
+	    rlth = MIN(osr, sr);
+	    rrem = sr - rlth;
+	    ol = origin;
+	    nl = (long) newscreen;
+	    if (ll < oll)
+		ol += (oll - ll) * osr;
+
+	    /* ++Geert: TODO: Because the attributes have different meanings
+	       for monochrome and color, they should really be converted if
+	       can_do_color changes... */
+	    update_attr(currcons);
+	    while (ol < scr_end) {
+		memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
+		if (rrem)
+		    memsetw((void *)(nl + rlth), video_erase_char, rrem);
+		ol += osr;
+		nl += sr;
+	    }
+
+	    if (kmalloced)
+		kfree_s(vc_scrbuf[currcons], oss);
+	    vc_scrbuf[currcons] = newscreen;
+	    kmalloced = 1;
+	    screenbuf_size = ss;
+
+	    origin = video_mem_start = (long) vc_scrbuf[currcons];
+	    scr_end = video_mem_end = video_mem_start + ss;
+
+	    if (scr_end > nl)
+		memsetw((void *) nl, video_erase_char, scr_end - nl);
+
+	    /* do part of a reset_terminal() */
+	    top = 0;
+	    bottom = video_num_lines;
+	    gotoxy(currcons, x, y);
+	    save_cur(currcons);
+
+	    cws = &console_table[currcons]->winsize;
+	    ws.ws_row = video_num_lines;
+	    ws.ws_col = video_num_columns;
+	    if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
+		console_table[currcons]->pgrp > 0)
+		kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
+	    *cws = ws;
+	}
+
+	/* don't update in graphics mode */
+	if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
+	    update_screen(fg_console);
+}
+
+
+void vc_disallocate(unsigned int currcons)
+{
+	if (vc_cons_allocated(currcons)) {
+	    sw->con_deinit(vc_cons[currcons].d);
+	    if (kmalloced)
+	      kfree_s(vc_scrbuf[currcons], screenbuf_size);
+	    if (currcons >= MIN_NR_CONSOLES)
+	      kfree_s(vc_cons[currcons].d, structsize);
+	    vc_cons[currcons].d = 0;
+	}
+}
+
+
+#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
+#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
+#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
+
+#define decarm		VC_REPEAT
+#define decckm		VC_CKMODE
+#define kbdapplic	VC_APPLIC
+#define lnm		VC_CRLF
+
+/*
+ * this is what the terminal answers to a ESC-Z or csi0c query.
+ */
+#define VT100ID "\033[?1;2c"
+#define VT102ID "\033[?6c"
+
+unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
+				       8,12,10,14, 9,13,11,15 };
+
+/* the default colour table, for VGA+ colour systems */
+int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
+    0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
+int default_grn[] = {0x00,0x00,0xaa,0xaa,0x00,0x00,0xaa,0xaa,
+    0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
+int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
+    0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
+
+/*
+ * gotoxy() must verify all boundaries, because the arguments
+ * might also be negative. If the given position is out of
+ * bounds, the cursor is placed at the nearest margin.
+ */
+static void gotoxy(int currcons, int new_x, int new_y)
+{
+	int min_y, max_y;
+
+	if (new_x < 0)
+		x = 0;
+	else
+		if (new_x >= video_num_columns)
+			x = video_num_columns - 1;
+		else
+			x = new_x;
+ 	if (decom) {
+		min_y = top;
+		max_y = bottom;
+	} else {
+		min_y = 0;
+		max_y = video_num_lines;
+	}
+	if (new_y < min_y)
+		y = min_y;
+	else if (new_y >= max_y)
+		y = max_y - 1;
+	else
+		y = new_y;
+	pos = origin + y*video_size_row + (x<<1);
+	need_wrap = 0;
+}
+
+/* for absolute user moves, when decom is set */
+static void gotoxay(int currcons, int new_x, int new_y)
+{
+	gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
+}
+
+/*
+ * Hardware scrollback support
+ */
+static inline void scrolldelta(int lines)
+{
+    int currcons = fg_console;
+    sw->con_scrolldelta(lines);
+}
+
+void scrollback(int lines)
+{
+	int currcons = fg_console;
+
+	if (!lines)
+		lines = video_num_lines/2;
+	scrolldelta(-lines);
+}
+
+void scrollfront(int lines)
+{
+	int currcons = fg_console;
+
+	if (!lines)
+		lines = video_num_lines/2;
+	scrolldelta(lines);
+}
+
+static void scrup(int currcons, unsigned int t, unsigned int b, int nr)
+{
+	unsigned short *d, *s;
+
+	if (t+nr >= b)
+		nr = b - t - 1;
+	if (b > video_num_lines || t >= b || nr < 1)
+		return;
+	d = (unsigned short *) (origin+video_size_row*t);
+	s = (unsigned short *) (origin+video_size_row*(t+nr));
+	memcpyw(d, s, (b-t-nr) * video_size_row);
+	memsetw(d + (b-t-nr) * video_num_columns, video_erase_char, video_size_row*nr);
+	if (currcons == fg_console)
+		sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
+}
+
+static void
+scrdown(int currcons, unsigned int t, unsigned int b, int nr)
+{
+	unsigned short *s;
+	unsigned int count;
+	unsigned int step;
+
+	if (t+nr >= b)
+		nr = b - t - 1;
+	if (b > video_num_lines || t >= b || nr < 1)
+		return;
+	s = (unsigned short *) (origin+video_size_row*(b-nr-1));
+	step = video_num_columns * nr;
+	count = b - t - nr;
+	while (count--) {
+		memcpyw(s + step, s, video_size_row);
+		s -= video_num_columns;
+	}
+	count = nr;
+	while (count--) {
+		s += video_num_columns;
+		memsetw(s, video_erase_char, video_size_row);
+	}
+	has_scrolled = 1;
+	if (currcons == fg_console)
+		sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
+}
+
+static void lf(int currcons)
+{
+    	/* don't scroll if above bottom of scrolling region, or
+	 * if below scrolling region
+	 */
+    	if (y+1 == bottom)
+		scrup(currcons,top,bottom,1);
+	else if (y < video_num_lines-1) {
+	    	y++;
+		pos += video_size_row;
+	}
+	need_wrap = 0;
+}
+
+static void ri(int currcons)
+{
+    	/* don't scroll if below top of scrolling region, or
+	 * if above scrolling region
+	 */
+	if (y == top)
+		scrdown(currcons,top,bottom,1);
+	else if (y > 0) {
+		y--;
+		pos -= video_size_row;
+	}
+	need_wrap = 0;
+}
+
+static inline void cr(int currcons)
+{
+	pos -= x<<1;
+	need_wrap = x = 0;
+}
+
+static inline void bs(int currcons)
+{
+	if (x) {
+		pos -= 2;
+		x--;
+		need_wrap = 0;
+	}
+}
+
+static inline void del(int currcons)
+{
+	/* ignored */
+}
+
+static void csi_J(int currcons, int vpar)
+{
+	unsigned long count;
+	unsigned short * start;
+
+	switch (vpar) {
+		case 0:	/* erase from cursor to end of display */
+			count = (scr_end-pos)>>1;
+			start = (unsigned short *) pos;
+			if (currcons == fg_console) {
+				/* do in two stages */
+				sw->con_clear(vc_cons[currcons].d, y, x, 1,
+					      video_num_columns-x);
+				sw->con_clear(vc_cons[currcons].d, y+1, 0,
+					      video_num_lines-y-1,
+					      video_num_columns);
+			}
+			break;
+		case 1:	/* erase from start to cursor */
+			count = ((pos-origin)>>1)+1;
+			start = (unsigned short *) origin;
+			if (currcons == fg_console) {
+				/* do in two stages */
+				sw->con_clear(vc_cons[currcons].d, 0, 0, y,
+					      video_num_columns);
+				sw->con_clear(vc_cons[currcons].d, y, 0, 1,
+					      x + 1);
+			}
+			break;
+		case 2: /* erase whole display */
+			count = video_num_columns * video_num_lines;
+			start = (unsigned short *) origin;
+			if (currcons == fg_console)
+				sw->con_clear(vc_cons[currcons].d, 0, 0,
+					      video_num_lines,
+					      video_num_columns);
+			break;
+		default:
+			return;
+	}
+	memsetw(start, video_erase_char, 2*count);
+	need_wrap = 0;
+}
+
+static void csi_K(int currcons, int vpar)
+{
+	unsigned long count;
+	unsigned short * start;
+
+	switch (vpar) {
+		case 0:	/* erase from cursor to end of line */
+			count = video_num_columns-x;
+			start = (unsigned short *) pos;
+			if (currcons == fg_console)
+				sw->con_clear(vc_cons[currcons].d, y, x, 1,
+					      video_num_columns-x);
+			break;
+		case 1:	/* erase from start of line to cursor */
+			start = (unsigned short *) (pos - (x<<1));
+			count = x+1;
+			if (currcons == fg_console)
+				sw->con_clear(vc_cons[currcons].d, y, 0, 1,
+					      x + 1);
+			break;
+		case 2: /* erase whole line */
+			start = (unsigned short *) (pos - (x<<1));
+			count = video_num_columns;
+			if (currcons == fg_console)
+				sw->con_clear(vc_cons[currcons].d, y, 0, 1,
+					      video_num_columns);
+			break;
+		default:
+			return;
+	}
+	memsetw(start, video_erase_char, 2 * count);
+	need_wrap = 0;
+}
+
+static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
+{					  /* not vt100? */
+	int count;
+
+	if (!vpar)
+		vpar++;
+	count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
+
+	memsetw((unsigned short *) pos, video_erase_char, 2 * count);
+	if (currcons == fg_console)
+		sw->con_clear(vc_cons[currcons].d, y, x, 1, count);
+	need_wrap = 0;
+}
+
+static void update_attr(int currcons)
+{
+/*
+ * ++roman: I completely changed the attribute format for monochrome
+ * mode (!can_do_color). The formerly used MDA (monochrome display
+ * adapter) format didn't allow the combination of certain effects.
+ * Now the attribute is just a bit vector:
+ *  Bit 0..1: intensity (0..2)
+ *  Bit 2   : underline
+ *  Bit 3   : reverse
+ *  Bit 7   : blink
+ *
+ * ++Geert: TODO: Because the attributes have different meanings
+ * for monochrome and color, they should really be converted if
+ * can_do_color changes...
+ */
+	if (!can_do_color) {
+		/* Special treatment for monochrome */
+		attr = intensity |
+			(underline ? 4 : 0) |
+			((reverse ^ decscnm) ? 8 : 0) |
+			(blink ? 0x80 : 0);
+		video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
+		return;
+	}
+	attr = color;
+	if (can_do_color) {
+		if (underline)
+			attr = (attr & 0xf0) | ulcolor;
+		else if (intensity == 0)
+			attr = (attr & 0xf0) | halfcolor;
+	}
+	if (reverse ^ decscnm)
+		attr = reverse_video_char(attr);
+	if (blink)
+		attr ^= 0x80;
+	if (intensity == 2)
+		attr ^= 0x08;
+	if (decscnm)
+		video_erase_char = (reverse_video_char(color) << 8) | ' ';
+	else
+		video_erase_char = (color << 8) | ' ';
+}
+
+static void default_attr(int currcons)
+{
+	intensity = 1;
+	underline = 0;
+	reverse = 0;
+	blink = 0;
+	color = def_color;
+}
+
+static void csi_m(int currcons)
+{
+	int i;
+
+	for (i=0;i<=npar;i++)
+		switch (par[i]) {
+			case 0:	/* all attributes off */
+				default_attr(currcons);
+				break;
+			case 1:
+				intensity = 2;
+				break;
+			case 2:
+				intensity = 0;
+				break;
+			case 4:
+				underline = 1;
+				break;
+			case 5:
+				blink = 1;
+				break;
+			case 7:
+				reverse = 1;
+				break;
+			case 10: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select primary font, don't display
+				  * control chars if defined, don't set
+				  * bit 8 on output.
+				  */
+				translate = set_translate(charset == 0
+						? G0_charset
+						: G1_charset);
+				disp_ctrl = 0;
+				toggle_meta = 0;
+				break;
+			case 11: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select first alternate font, lets
+				  * chars < 32 be displayed as ROM chars.
+				  */
+				translate = set_translate(IBMPC_MAP);
+				disp_ctrl = 1;
+				toggle_meta = 0;
+				break;
+			case 12: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Select second alternate font, toggle
+				  * high bit before displaying as ROM char.
+				  */
+				translate = set_translate(IBMPC_MAP);
+				disp_ctrl = 1;
+				toggle_meta = 1;
+				break;
+			case 21:
+			case 22:
+				intensity = 1;
+				break;
+			case 24:
+				underline = 0;
+				break;
+			case 25:
+				blink = 0;
+				break;
+			case 27:
+				reverse = 0;
+				break;
+			case 38: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Enables underscore, white foreground
+				  * with white underscore (Linux - use
+				  * default foreground).
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 1;
+				break;
+			case 39: /* ANSI X3.64-1979 (SCO-ish?)
+				  * Disable underline option.
+				  * Reset colour to default? It did this
+				  * before...
+				  */
+				color = (def_color & 0x0f) | background;
+				underline = 0;
+				break;
+			case 49:
+				color = (def_color & 0xf0) | foreground;
+				break;
+			default:
+				if (par[i] >= 30 && par[i] <= 37)
+					color = color_table[par[i]-30]
+						| background;
+				else if (par[i] >= 40 && par[i] <= 47)
+					color = (color_table[par[i]-40]<<4)
+						| foreground;
+				break;
+		}
+	update_attr(currcons);
+}
+
+static void respond_string(const char * p, struct tty_struct * tty)
+{
+	while (*p) {
+		tty_insert_flip_char(tty, *p, 0);
+		p++;
+	}
+	tty_schedule_flip(tty);
+}
+
+static void cursor_report(int currcons, struct tty_struct * tty)
+{
+	char buf[40];
+
+	sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
+	respond_string(buf, tty);
+}
+
+static inline void status_report(struct tty_struct * tty)
+{
+	respond_string("\033[0n", tty);	/* Terminal ok */
+}
+
+static inline void respond_ID(struct tty_struct * tty)
+{
+	respond_string(VT102ID, tty);
+}
+
+void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
+{
+	char buf[8];
+
+	sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
+		(char)('!' + mry));
+	respond_string(buf, tty);
+}
+
+/* invoked via ioctl(TIOCLINUX) and through set_selection */
+int mouse_reporting(void)
+{
+	int currcons = fg_console;
+
+	return report_mouse;
+}
+
+int tioclinux(struct tty_struct *tty, unsigned long arg)
+{
+	char type, data;
+
+	if (tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
+		return -EINVAL;
+	if (current->tty != tty && !suser())
+		return -EPERM;
+	if (get_user(type, (char *)arg))
+		return -EFAULT;
+	switch (type)
+	{
+		case 2:
+			return set_selection(arg, tty, 1);
+		case 3:
+			return paste_selection(tty);
+		case 4:
+			do_unblank_screen();
+			return 0;
+		case 5:
+			return sel_loadlut(arg);
+		case 6:
+			
+	/*
+	 * Make it possible to react to Shift+Mousebutton.
+	 * Note that 'shift_state' is an undocumented
+	 * kernel-internal variable; programs not closely
+	 * related to the kernel should not use this.
+	 */
+	 		data = shift_state;
+			return __put_user(data, (char *) arg);
+		case 7:
+			data = mouse_reporting();
+			return __put_user(data, (char *) arg);
+		case 10:
+			set_vesa_blanking(arg);
+			return 0;
+		case 11:	/* set kmsg redirect */
+			if (!suser())
+				return -EPERM;
+			if (get_user(data, (char *)arg+1))
+					return -EFAULT;
+			kmsg_redirect = data;
+			return 0;
+		case 12:	/* get fg_console */
+			return fg_console;
+	}
+	return -EINVAL;
+}
+
+static inline unsigned short *screenpos(int currcons, int offset, int viewed)
+{
+	unsigned short *p = (unsigned short *)(origin + offset);
+	return p;
+}
+
+static inline void visual_putc_attr(int currcons, unsigned short new,
+				    int yy, int xx)
+{
+    unsigned short oldattr = attr;
+    attr = new >> 8;
+    sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
+    attr = oldattr;
+}
+
+static inline void visual_putc_attr_next(int currcons, unsigned short new,
+					 int *yy, int *xx)
+{
+    attr = new >> 8;
+    sw->con_putc(vc_cons[currcons].d, new & 0xff, *yy, *xx);
+    if (++(*xx) == video_num_columns)
+	*xx = 0, ++(*yy);
+}
+
+
+/* Note: inverting the screen twice should revert to the original state */
+void invert_screen(int currcons, int offset, int count, int viewed)
+{
+	unsigned short *p;
+	int xx = (offset >> 1) % video_num_columns;
+	int yy = (offset >> 1) / video_num_columns;
+	unsigned short oldattr = attr;
+
+	count /= 2;
+	p = screenpos(currcons, offset, viewed);
+	if (can_do_color)
+		while (count--) {
+			unsigned short old = scr_readw(p);
+			unsigned short new = reverse_video_short(old);
+			scr_writew(new, p);
+			p++;
+			if (currcons == fg_console)
+				visual_putc_attr_next(currcons, new, &yy, &xx);
+		}
+	else
+		while (count--) {
+			unsigned short old = scr_readw(p);
+			unsigned short new = reverse_video_short_mono(old);
+			scr_writew(new, p);
+			p++;
+			if (currcons == fg_console)
+				visual_putc_attr_next(currcons, new, &yy, &xx);
+		}
+	attr = oldattr;
+}
+
+/* used by selection: complement pointer position */
+void complement_pos(int currcons, int offset)
+{
+	static unsigned short *p = NULL;
+	static unsigned short old = 0;
+	static unsigned short oldx = 0, oldy = 0;
+
+	if (p) {
+		scr_writew(old, p);
+		if (currcons == fg_console)
+			visual_putc_attr(currcons, old, oldy, oldx);
+	}
+	if (offset == -1)
+		p = NULL;
+	else {
+		unsigned short new;
+		p = screenpos(currcons, offset, 1);
+		old = scr_readw(p);
+		oldx = (offset >> 1) % video_num_columns;
+		oldy = (offset >> 1) / video_num_columns;
+		new = complement_video_short(old);
+		scr_writew(new, p);
+		if (currcons == fg_console)
+			visual_putc_attr(currcons, new, oldy, oldx);
+	}
+}
+
+/* used by selection */
+unsigned short screen_word(int currcons, int offset, int viewed)
+{
+	return scr_readw(screenpos(currcons, offset, viewed));
+}
+
+/* used by selection - convert a screen word to a glyph number */
+int scrw2glyph(unsigned short scr_word)
+{
+	return ( video_mode_512ch )
+		? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
+		: scr_word & 0x00ff;
+}
+
+/* used by vcs - note the word offset */
+unsigned short *screen_pos(int currcons, int w_offset, int viewed)
+{
+	return screenpos(currcons, 2 * w_offset, viewed);
+}
+
+void getconsxy(int currcons, char *p)
+{
+	p[0] = x;
+	p[1] = y;
+}
+
+void putconsxy(int currcons, char *p)
+{
+	gotoxy(currcons, p[0], p[1]);
+	set_cursor(currcons);
+}
+
+static void set_mode(int currcons, int on_off)
+{
+	int i;
+
+	for (i=0; i<=npar; i++)
+		if (ques) switch(par[i]) {	/* DEC private modes set/reset */
+			case 1:			/* Cursor keys send ^[Ox/^[[x */
+				if (on_off)
+					set_kbd(decckm);
+				else
+					clr_kbd(decckm);
+				break;
+			case 3:	/* 80/132 mode switch unimplemented */
+				deccolm = on_off;
+#if 0
+				(void) vc_resize(video_num_lines, deccolm ? 132 : 80);
+				/* this alone does not suffice; some user mode
+				   utility has to change the hardware regs */
+#endif
+				break;
+			case 5:			/* Inverted screen on/off */
+				if (decscnm != on_off) {
+					decscnm = on_off;
+					invert_screen(currcons, 0, video_screen_size, 0);
+					update_attr(currcons);
+				}
+				break;
+			case 6:			/* Origin relative/absolute */
+				decom = on_off;
+				gotoxay(currcons,0,0);
+				break;
+			case 7:			/* Autowrap on/off */
+				decawm = on_off;
+				break;
+			case 8:			/* Autorepeat on/off */
+				if (on_off)
+					set_kbd(decarm);
+				else
+					clr_kbd(decarm);
+				break;
+			case 9:
+				report_mouse = on_off ? 1 : 0;
+				break;
+			case 25:		/* Cursor on/off */
+				deccm = on_off;
+				set_cursor(currcons);
+				break;
+			case 1000:
+				report_mouse = on_off ? 2 : 0;
+				break;
+		} else switch(par[i]) {		/* ANSI modes set/reset */
+			case 3:			/* Monitor (display ctrls) */
+				disp_ctrl = on_off;
+				break;
+			case 4:			/* Insert Mode on/off */
+				decim = on_off;
+				break;
+			case 20:		/* Lf, Enter == CrLf/Lf */
+				if (on_off)
+					set_kbd(lnm);
+				else
+					clr_kbd(lnm);
+				break;
+		}
+}
+
+static void setterm_command(int currcons)
+{
+	switch(par[0]) {
+		case 1:	/* set color for underline mode */
+			if (can_do_color && par[1] < 16) {
+				ulcolor = color_table[par[1]];
+				if (underline)
+					update_attr(currcons);
+			}
+			break;
+		case 2:	/* set color for half intensity mode */
+			if (can_do_color && par[1] < 16) {
+				halfcolor = color_table[par[1]];
+				if (intensity == 0)
+					update_attr(currcons);
+			}
+			break;
+		case 8:	/* store colors as defaults */
+			def_color = attr;
+			default_attr(currcons);
+			update_attr(currcons);
+			break;
+		case 9:	/* set blanking interval */
+			blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			poke_blanked_console();
+			break;
+		case 10: /* set bell frequency in Hz */
+			if (npar >= 1)
+				bell_pitch = par[1];
+			else
+				bell_pitch = DEFAULT_BELL_PITCH;
+			break;
+		case 11: /* set bell duration in msec */
+			if (npar >= 1)
+				bell_duration = (par[1] < 2000) ?
+					par[1]*HZ/1000 : 0;
+			else
+				bell_duration = DEFAULT_BELL_DURATION;
+			break;
+		case 12: /* bring specified console to the front */
+			if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
+				update_screen(par[1]-1);
+			break;
+		case 13: /* unblank the screen */
+			unblank_screen();
+			break;
+		case 14: /* set vesa powerdown interval */
+			vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			break;
+	}
+}
+
+static void visual_insert_chars(int currcons, unsigned int nr)
+{
+    unsigned short oldattr = attr;
+    sw->con_bmove(vc_cons[currcons].d,y,x,y,x+nr,1,video_num_columns-x-nr);
+    attr = video_erase_char >> 8;
+    while (nr--)
+	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x+nr);
+    attr = oldattr;
+}
+
+static void insert_char(int currcons)
+{
+	unsigned int i = x;
+	unsigned short tmp, old = video_erase_char;
+	unsigned short * p = (unsigned short *) pos;
+
+	while (i++ < video_num_columns) {
+		tmp = scr_readw(p);
+		scr_writew(old, p);
+		old = tmp;
+		p++;
+	}
+	need_wrap = 0;
+	if (currcons == fg_console)
+		visual_insert_chars(currcons, 1);
+}
+
+static void insert_line(int currcons, unsigned int nr)
+{
+	scrdown(currcons,y,bottom,nr);
+	need_wrap = 0;
+}
+
+static void delete_line(int currcons, unsigned int nr)
+{
+	scrup(currcons,y,bottom,nr);
+	need_wrap = 0;
+}
+
+static void csi_at(int currcons, unsigned int nr)
+{
+	unsigned int i;
+	unsigned short *p;
+
+	if (nr > video_num_columns - x)
+		nr = video_num_columns - x;
+	else if (!nr)
+		nr = 1;
+	i = video_num_columns-nr-x;
+	p = (unsigned short *)pos + i;
+	while (i--) {
+		p--;
+		scr_writew(scr_readw(p), p+nr);
+	}
+	memsetw(p, video_erase_char, 2 * nr);
+	need_wrap = 0;
+	if (currcons == fg_console)
+		visual_insert_chars(currcons, nr);
+}
+
+static void csi_L(int currcons, unsigned int nr)
+{
+	if (nr > video_num_lines - y)
+		nr = video_num_lines - y;
+	else if (!nr)
+		nr = 1;
+	insert_line(currcons, nr);
+}
+
+static void csi_P(int currcons, unsigned int nr)
+{
+	unsigned int i;
+	unsigned short *p;
+
+	if (nr > video_num_columns - x)
+		nr = video_num_columns - x;
+	else if (!nr)
+		nr = 1;
+	i = video_num_columns-nr-x;
+	p = (unsigned short *)pos;
+	while (i--) {
+		scr_writew(scr_readw(p+nr), p);
+		p++;
+	}
+	memsetw(p, video_erase_char, 2 * nr);
+	need_wrap = 0;
+	if (currcons == fg_console) {
+		unsigned short oldattr = attr;
+		sw->con_bmove(vc_cons[currcons].d, y, x+nr, y, x, 1,
+			      video_num_columns-x-nr);
+		attr = video_erase_char >> 8;
+		while (nr--)
+			sw->con_putc(vc_cons[currcons].d,
+				     (video_erase_char & 0x00ff), y,
+				     video_num_columns-1-nr);
+		attr = oldattr;
+	}
+}
+
+static void csi_M(int currcons, unsigned int nr)
+{
+	if (nr > video_num_lines - y)
+		nr = video_num_lines - y;
+	else if (!nr)
+		nr=1;
+	delete_line(currcons, nr);
+}
+
+static void save_cur(int currcons)
+{
+	saved_x		= x;
+	saved_y		= y;
+	s_intensity	= intensity;
+	s_underline	= underline;
+	s_blink		= blink;
+	s_reverse	= reverse;
+	s_charset	= charset;
+	s_color		= color;
+	saved_G0	= G0_charset;
+	saved_G1	= G1_charset;
+}
+
+static void restore_cur(int currcons)
+{
+	gotoxy(currcons,saved_x,saved_y);
+	intensity	= s_intensity;
+	underline	= s_underline;
+	blink		= s_blink;
+	reverse		= s_reverse;
+	charset		= s_charset;
+	color		= s_color;
+	G0_charset	= saved_G0;
+	G1_charset	= saved_G1;
+	translate	= set_translate(charset ? G1_charset : G0_charset);
+	update_attr(currcons);
+	need_wrap = 0;
+}
+
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
+	EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
+	ESpalette };
+
+static void reset_terminal(int currcons, int do_clear)
+{
+	top		= 0;
+	bottom		= video_num_lines;
+	vc_state	= ESnormal;
+	ques		= 0;
+	translate	= set_translate(LAT1_MAP);
+	G0_charset	= LAT1_MAP;
+	G1_charset	= GRAF_MAP;
+	charset		= 0;
+	need_wrap	= 0;
+	report_mouse	= 0;
+	utf             = 0;
+	utf_count       = 0;
+
+	disp_ctrl	= 0;
+	toggle_meta	= 0;
+
+	decscnm		= 0;
+	decom		= 0;
+	decawm		= 1;
+	deccm		= 1;
+	decim		= 0;
+
+	set_kbd(decarm);
+	clr_kbd(decckm);
+	clr_kbd(kbdapplic);
+	clr_kbd(lnm);
+	kbd_table[currcons].lockstate = 0;
+	kbd_table[currcons].slockstate = 0;
+	kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
+	kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
+	set_leds();
+
+	cursor_type = CUR_DEFAULT;
+
+	default_attr(currcons);
+	update_attr(currcons);
+
+	tab_stop[0]	= 0x01010100;
+	tab_stop[1]	=
+	tab_stop[2]	=
+	tab_stop[3]	=
+	tab_stop[4]	= 0x01010101;
+
+	bell_pitch = DEFAULT_BELL_PITCH;
+	bell_duration = DEFAULT_BELL_DURATION;
+
+	gotoxy(currcons,0,0);
+	save_cur(currcons);
+	if (do_clear)
+	    csi_J(currcons,2);
+}
+
+/*
+ * Turn the Scroll-Lock LED on when the tty is stopped
+ */
+static void con_stop(struct tty_struct *tty)
+{
+	int console_num;
+	if (!tty)
+		return;
+	console_num = MINOR(tty->device) - (tty->driver.minor_start);
+	if (!vc_cons_allocated(console_num))
+		return;
+#if !CONFIG_AP1000
+	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+	set_leds();
+#endif
+}
+
+/*
+ * Turn the Scroll-Lock LED off when the console is started
+ */
+static void con_start(struct tty_struct *tty)
+{
+	int console_num;
+	if (!tty)
+		return;
+	console_num = MINOR(tty->device) - (tty->driver.minor_start);
+	if (!vc_cons_allocated(console_num))
+		return;
+#if !CONFIG_AP1000
+	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
+	set_leds();
+#endif
+}
+
+static void con_flush_chars(struct tty_struct *tty)
+{
+	unsigned int currcons;
+	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+	currcons = vt->vc_num;
+	if (vcmode != KD_GRAPHICS)
+		set_cursor(currcons);
+}
+
+static int do_con_write(struct tty_struct * tty, int from_user,
+			const unsigned char *buf, int count)
+{
+	int c, tc, ok, n = 0;
+	unsigned int currcons;
+	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+#if CONFIG_AP1000
+        ap_write(1,buf,count);
+        return(count);
+#endif
+
+	currcons = vt->vc_num;
+	if (!vc_cons_allocated(currcons)) {
+	    /* could this happen? */
+	    static int error = 0;
+	    if (!error) {
+		error = 1;
+		printk("con_write: tty %d not allocated\n", currcons+1);
+	    }
+	    return 0;
+	}
+
+	/* undraw cursor first */
+	if (currcons == fg_console)
+		hide_cursor(currcons);
+
+	/* clear the selection */
+	if (currcons == sel_cons)
+		clear_selection();
+
+	if (from_user) {
+		/* just to make sure that noone lurks at places he shouldn't see. */
+		if (verify_area(VERIFY_READ, buf, count))
+			return 0; /* ?? are error codes legal here ?? */
+	}
+
+	disable_bh(CONSOLE_BH);
+	while (count) {
+		enable_bh(CONSOLE_BH);
+		if (from_user)
+			__get_user(c, buf);
+		else
+			c = *buf;
+		buf++; n++; count--;
+		disable_bh(CONSOLE_BH);
+
+		if (utf) {
+		    /* Combine UTF-8 into Unicode */
+		    /* Incomplete characters silently ignored */
+		    if(c > 0x7f) {
+			if (utf_count > 0 && (c & 0xc0) == 0x80) {
+				utf_char = (utf_char << 6) | (c & 0x3f);
+				utf_count--;
+				if (utf_count == 0)
+				    tc = c = utf_char;
+				else continue;
+			} else {
+				if ((c & 0xe0) == 0xc0) {
+				    utf_count = 1;
+				    utf_char = (c & 0x1f);
+				} else if ((c & 0xf0) == 0xe0) {
+				    utf_count = 2;
+				    utf_char = (c & 0x0f);
+				} else if ((c & 0xf8) == 0xf0) {
+				    utf_count = 3;
+				    utf_char = (c & 0x07);
+				} else if ((c & 0xfc) == 0xf8) {
+				    utf_count = 4;
+				    utf_char = (c & 0x03);
+				} else if ((c & 0xfe) == 0xfc) {
+				    utf_count = 5;
+				    utf_char = (c & 0x01);
+				} else
+				    utf_count = 0;
+				continue;
+			      }
+		    } else {
+		      tc = c;
+		      utf_count = 0;
+		    }
+		} else {	/* no utf */
+		  tc = translate[toggle_meta ? (c|0x80) : c];
+		}
+
+                /* If the original code was a control character we
+                 * only allow a glyph to be displayed if the code is
+                 * not normally used (such as for cursor movement) or
+                 * if the disp_ctrl mode has been explicitly enabled.
+                 * Certain characters (as given by the CTRL_ALWAYS
+                 * bitmap) are always displayed as control characters,
+                 * as the console would be pretty useless without
+                 * them; to display an arbitrary font position use the
+                 * direct-to-font zone in UTF-8 mode.
+                 */
+                ok = tc && (c >= 32 ||
+                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS
+                                         : CTRL_ACTION) >> c) & 1)))
+                        && (c != 127 || disp_ctrl)
+			&& (c != 128+27);
+
+		if (vc_state == ESnormal && ok) {
+			/* Now try to find out how to display it */
+			tc = conv_uni_to_pc(tc);
+			if ( tc == -4 ) {
+                                /* If we got -4 (not found) then see if we have
+                                   defined a replacement character (U+FFFD) */
+                                tc = conv_uni_to_pc(0xfffd);
+                        } else if ( tc == -3 ) {
+                                /* Bad hash table -- hope for the best */
+                                tc = c;
+                        }
+			if (tc & ~console_charmask)
+                                continue; /* Conversion failed */
+
+			if (need_wrap) {
+				cr(currcons);
+				lf(currcons);
+			}
+
+                        /* DPC: 1994-04-12
+                         *   Speed up overstrike mode, using new putcs.
+                         *
+                         * P.S. I hate 8 spaces per tab! Use Emacs!
+			 */
+
+			/* Only use this for the foreground console,
+                           where we really draw the chars */
+
+                        if (count > 2 &&
+			    !decim && !utf && currcons == fg_console) {
+				char   *p     = putcs_buf;
+				int putcs_count  = 1;
+				ushort nextx  = x + 1;
+
+				*p++ = tc;
+				scr_writew((attr << 8) + tc,
+					   (unsigned short *)pos);
+				pos+=2;
+
+				if (nextx == video_num_columns) {
+					sw->con_putc(vc_cons[currcons].d,
+						     *putcs_buf, y, x);
+					pos-=2;
+					need_wrap = decawm;
+					continue;
+				}
+
+				/* TAB TAB TAB - Arghh!!!! */
+
+				while (count) {
+					enable_bh(CONSOLE_BH);
+					if (from_user)
+						get_user(c, buf);
+					else
+						c = *buf;
+					disable_bh(CONSOLE_BH);
+					tc = translate[toggle_meta ? (c|0x80) : c];
+					if (!tc ||
+					    !(c >= 32
+					      || !(((disp_ctrl ? CTRL_ALWAYS
+						   : CTRL_ACTION) >> c) & 1)))
+					  break;
+					tc = conv_uni_to_pc(tc);
+					if (tc == -4)
+					  tc = conv_uni_to_pc(0xfffd);
+					else if (tc == -3)
+					  tc = c;
+
+					buf++; n++; count--;
+					if (tc & ~console_charmask)
+					  continue; /* Conversion failed */
+
+					*p++ = tc;
+					scr_writew((attr << 8) + tc,
+						   (unsigned short *)pos);
+					pos+=2;
+					++putcs_count;
+					++nextx;
+					if (nextx == video_num_columns ||
+					    putcs_count == sizeof (putcs_buf))
+						break;
+				}
+
+				sw->con_putcs(vc_cons[currcons].d,
+					      putcs_buf, putcs_count, y, x);
+				if (nextx == video_num_columns) {
+					pos-=2;
+					x         = video_num_columns-1;
+					need_wrap = decawm;
+				} else
+					x += putcs_count;
+				continue;
+                        }
+
+                        /* DPC: End of putcs support */
+
+			if (decim)
+				insert_char(currcons);
+			scr_writew( video_mode_512ch ?
+			   ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
+			   (tc & 0x0ff) : (attr << 8) + tc,
+			   (unsigned short *) pos);
+			if (currcons == fg_console)
+				sw->con_putc(vc_cons[currcons].d, tc, y, x);
+
+			if (x == video_num_columns - 1)
+				need_wrap = decawm;
+			else {
+				x++;
+				pos+=2;
+			}
+			continue;
+		}
+
+		/*
+		 *  Control characters can be used in the _middle_
+		 *  of an escape sequence.
+		 */
+		switch (c) {
+			case 0:
+				continue;
+			case 7:
+				if (bell_duration)
+					kd_mksound(bell_pitch, bell_duration);
+				continue;
+			case 8:
+				bs(currcons);
+				continue;
+			case 9:
+				pos -= (x << 1);
+				while (x < video_num_columns - 1) {
+					x++;
+					if (tab_stop[x >> 5] & (1 << (x & 31)))
+						break;
+				}
+				pos += (x << 1);
+				continue;
+			case 10: case 11: case 12:
+				lf(currcons);
+				if (!is_kbd(lnm))
+					continue;
+			case 13:
+				cr(currcons);
+				continue;
+			case 14:
+				charset = 1;
+				translate = set_translate(G1_charset);
+				disp_ctrl = 1;
+				continue;
+			case 15:
+				charset = 0;
+				translate = set_translate(G0_charset);
+				disp_ctrl = 0;
+				continue;
+			case 24: case 26:
+				vc_state = ESnormal;
+				continue;
+			case 27:
+				vc_state = ESesc;
+				continue;
+			case 127:
+				del(currcons);
+				continue;
+			case 128+27:
+				vc_state = ESsquare;
+				continue;
+		}
+		switch(vc_state) {
+			case ESesc:
+				vc_state = ESnormal;
+				switch (c) {
+				  case '[':
+					vc_state = ESsquare;
+					continue;
+				  case ']':
+					vc_state = ESnonstd;
+					continue;
+				  case '%':
+					vc_state = ESpercent;
+					continue;
+				  case 'E':
+					cr(currcons);
+					lf(currcons);
+					continue;
+				  case 'M':
+					ri(currcons);
+					continue;
+				  case 'D':
+					lf(currcons);
+					continue;
+				  case 'H':
+					tab_stop[x >> 5] |= (1 << (x & 31));
+					continue;
+				  case 'Z':
+					respond_ID(tty);
+					continue;
+				  case '7':
+					save_cur(currcons);
+					continue;
+				  case '8':
+					restore_cur(currcons);
+					continue;
+				  case '(':
+					vc_state = ESsetG0;
+					continue;
+				  case ')':
+					vc_state = ESsetG1;
+					continue;
+				  case '#':
+					vc_state = EShash;
+					continue;
+				  case 'c':
+					reset_terminal(currcons,1);
+					continue;
+				  case '>':  /* Numeric keypad */
+					clr_kbd(kbdapplic);
+					continue;
+				  case '=':  /* Appl. keypad */
+					set_kbd(kbdapplic);
+				 	continue;
+				}
+				continue;
+			case ESnonstd:
+				if (c=='P') {   /* palette escape sequence */
+					for (npar=0; npar<NPAR; npar++)
+						par[npar] = 0 ;
+					npar = 0 ;
+					vc_state = ESpalette;
+					continue;
+				} else if (c=='R') {   /* reset palette */
+					reset_palette (currcons);
+					vc_state = ESnormal;
+				} else
+					vc_state = ESnormal;
+				continue;
+			case ESpalette:
+				if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
+					par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
+					if (npar==7) {
+						int i = par[0]*3, j = 1;
+						palette[i] = 16*par[j++];
+						palette[i++] += par[j++];
+						palette[i] = 16*par[j++];
+						palette[i++] += par[j++];
+						palette[i] = 16*par[j++];
+						palette[i] += par[j];
+						set_palette() ;
+						vc_state = ESnormal;
+					}
+				} else
+					vc_state = ESnormal;
+				continue;
+			case ESsquare:
+				for(npar = 0 ; npar < NPAR ; npar++)
+					par[npar] = 0;
+				npar = 0;
+				vc_state = ESgetpars;
+				if (c == '[') { /* Function key */
+					vc_state=ESfunckey;
+					continue;
+				}
+				ques = (c=='?');
+				if (ques)
+					continue;
+			case ESgetpars:
+				if (c==';' && npar<NPAR-1) {
+					npar++;
+					continue;
+				} else if (c>='0' && c<='9') {
+					par[npar] *= 10;
+					par[npar] += c-'0';
+					continue;
+				} else vc_state=ESgotpars;
+			case ESgotpars:
+				vc_state = ESnormal;
+				switch(c) {
+					case 'h':
+						set_mode(currcons,1);
+						continue;
+					case 'l':
+						set_mode(currcons,0);
+						continue;
+					case 'c':
+						if (par[0])
+							cursor_type = par[0] | (par[1]<<8) | (par[2]<<16);
+						else
+							cursor_type = CUR_DEFAULT;
+						set_cursor(currcons);
+						continue;
+					case 'n':
+						if (!ques) {
+							if (par[0] == 5)
+								status_report(tty);
+							else if (par[0] == 6)
+								cursor_report(currcons,tty);
+						}
+						continue;
+				}
+				if (ques) {
+					ques = 0;
+					continue;
+				}
+				switch(c) {
+					case 'G': case '`':
+						if (par[0]) par[0]--;
+						gotoxy(currcons,par[0],y);
+						continue;
+					case 'A':
+						if (!par[0]) par[0]++;
+						gotoxy(currcons,x,y-par[0]);
+						continue;
+					case 'B': case 'e':
+						if (!par[0]) par[0]++;
+						gotoxy(currcons,x,y+par[0]);
+						continue;
+					case 'C': case 'a':
+						if (!par[0]) par[0]++;
+						gotoxy(currcons,x+par[0],y);
+						continue;
+					case 'D':
+						if (!par[0]) par[0]++;
+						gotoxy(currcons,x-par[0],y);
+						continue;
+					case 'E':
+						if (!par[0]) par[0]++;
+						gotoxy(currcons,0,y+par[0]);
+						continue;
+					case 'F':
+						if (!par[0]) par[0]++;
+						gotoxy(currcons,0,y-par[0]);
+						continue;
+					case 'd':
+						if (par[0]) par[0]--;
+						gotoxay(currcons,x,par[0]);
+						continue;
+					case 'H': case 'f':
+						if (par[0]) par[0]--;
+						if (par[1]) par[1]--;
+						gotoxay(currcons,par[1],par[0]);
+						continue;
+					case 'J':
+						csi_J(currcons,par[0]);
+						continue;
+					case 'K':
+						csi_K(currcons,par[0]);
+						continue;
+					case 'L':
+						csi_L(currcons,par[0]);
+						continue;
+					case 'M':
+						csi_M(currcons,par[0]);
+						continue;
+					case 'P':
+						csi_P(currcons,par[0]);
+						continue;
+					case 'c':
+						if (!par[0])
+							respond_ID(tty);
+						continue;
+					case 'g':
+						if (!par[0])
+							tab_stop[x >> 5] &= ~(1 << (x & 31));
+						else if (par[0] == 3) {
+							tab_stop[0] =
+							tab_stop[1] =
+							tab_stop[2] =
+							tab_stop[3] =
+							tab_stop[4] = 0;
+						}
+						continue;
+					case 'm':
+						csi_m(currcons);
+						continue;
+					case 'q': /* DECLL - but only 3 leds */
+						/* map 0,1,2,3 to 0,1,2,4 */
+						if (par[0] < 4)
+						  setledstate(kbd_table + currcons,
+							      (par[0] < 3) ? par[0] : 4);
+						continue;
+					case 'r':
+						if (!par[0])
+							par[0]++;
+						if (!par[1])
+							par[1] = video_num_lines;
+						/* Minimum allowed region is 2 lines */
+						if (par[0] < par[1] &&
+						    par[1] <= video_num_lines) {
+							top=par[0]-1;
+							bottom=par[1];
+							gotoxay(currcons,0,0);
+						}
+						continue;
+					case 's':
+						save_cur(currcons);
+						continue;
+					case 'u':
+						restore_cur(currcons);
+						continue;
+					case 'X':
+						csi_X(currcons, par[0]);
+						continue;
+					case '@':
+						csi_at(currcons,par[0]);
+						continue;
+					case ']': /* setterm functions */
+						setterm_command(currcons);
+						continue;
+				}
+				continue;
+			case ESpercent:
+				vc_state = ESnormal;
+				switch (c) {
+				  case '@':  /* defined in ISO 2022 */
+					utf = 0;
+					continue;
+				  case 'G':  /* prelim official escape code */
+				  case '8':  /* retained for compatibility */
+					utf = 1;
+					continue;
+				}
+				continue;
+			case ESfunckey:
+				vc_state = ESnormal;
+				continue;
+			case EShash:
+				vc_state = ESnormal;
+				if (c == '8') {
+					/* DEC screen alignment test. kludge :-) */
+					video_erase_char =
+						(video_erase_char & 0xff00) | 'E';
+					/* Arno:
+					* Doesn't work, because csi_J(c,2)
+					* calls con_clear and doesn't print
+					* the erase char..
+					*/
+					csi_J(currcons, 2);
+					video_erase_char =
+						(video_erase_char & 0xff00) | ' ';
+				}
+				continue;
+			case ESsetG0:
+				if (c == '0')
+					G0_charset = GRAF_MAP;
+				else if (c == 'B')
+					G0_charset = LAT1_MAP;
+				else if (c == 'U')
+					G0_charset = IBMPC_MAP;
+				else if (c == 'K')
+					G0_charset = USER_MAP;
+				if (charset == 0)
+					translate = set_translate(G0_charset);
+				vc_state = ESnormal;
+				continue;
+			case ESsetG1:
+				if (c == '0')
+					G1_charset = GRAF_MAP;
+				else if (c == 'B')
+					G1_charset = LAT1_MAP;
+				else if (c == 'U')
+					G1_charset = IBMPC_MAP;
+				else if (c == 'K')
+					G1_charset = USER_MAP;
+				if (charset == 1)
+					translate = set_translate(G1_charset);
+				vc_state = ESnormal;
+				continue;
+			default:
+				vc_state = ESnormal;
+		}
+	}
+	enable_bh(CONSOLE_BH);
+	return n;
+}
+
+static int con_write(struct tty_struct * tty, int from_user,
+		     const unsigned char *buf, int count)
+{
+	int	retval;
+
+	retval = do_con_write(tty, from_user, buf, count);
+	con_flush_chars(tty);
+
+	return retval;
+}
+
+static void con_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	do_con_write(tty, 0, &ch, 1);
+}
+
+static int con_write_room(struct tty_struct *tty)
+{
+	if (tty->stopped)
+		return 0;
+	return 4096;		/* No limit, really; we're not buffering */
+}
+
+static int con_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0;		/* we're not buffering */
+}
+
+void poke_blanked_console(void)
+{
+	timer_active &= ~(1<<BLANK_TIMER);
+	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+		return;
+	if (console_blanked) {
+		timer_table[BLANK_TIMER].fn = unblank_screen;
+		timer_table[BLANK_TIMER].expires = 0;
+		timer_active |= 1<<BLANK_TIMER;
+	} else if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+}
+
+#ifdef CONFIG_VT_CONSOLE
+void vt_console_print(struct console *co, const char * b, unsigned count)
+{
+	int currcons = fg_console;
+	unsigned char c;
+	static int printing = 0;
+	const char *start = b;
+	ushort cnt = 0;
+	ushort myx = x;
+
+#if CONFIG_AP1000
+        prom_printf(b);
+        return;
+#endif
+	if (!printable || printing)
+		return;	 /* console not yet initialized */
+	printing = 1;
+
+	if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
+		currcons = kmsg_redirect - 1;
+
+	if (!vc_cons_allocated(currcons)) {
+		/* impossible */
+		printk("vt_console_print: tty %d not allocated ??\n", currcons+1);
+		return;
+	}
+
+	/* undraw cursor first */
+	hide_cursor(currcons);
+
+	/* Contrived structure to try to emulate original need_wrap behaviour
+	 * Problems caused when we have need_wrap set on '\n' character */
+	while (count--) {
+		c = *b++;
+		if (c == 10 || c == 13 || c == 8 || need_wrap) {
+			if ((cnt = b - start - 1) > 0) {
+				sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);
+				x += cnt;
+				if (need_wrap)
+					x--;
+			}
+			if (c == 8) {		/* backspace */
+				bs(currcons);
+				start = b;
+				myx = x;
+				continue;
+			}
+			if (c != 13)
+				lf(currcons);
+			cr(currcons);
+			if (c == 10 || c == 13) {
+				start = b;
+				myx = x;
+				continue;
+			}
+			start = b-1;
+			myx = x;
+		}
+		scr_writew((attr << 8) + c, (unsigned short *) pos);
+		if (myx == video_num_columns - 1) {
+			need_wrap = 1;
+			continue;
+		}
+		pos+=2;
+		myx++;
+	}
+	if ((cnt = b - start) > 0) {
+		sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);
+		x += cnt;
+		if (x == video_num_columns) {
+			x--;
+			need_wrap = 1;
+		}
+	}
+	set_cursor(currcons);
+	poke_blanked_console();
+	printing = 0;
+}
+
+static kdev_t vt_console_device(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, c->index ? c->index : fg_console + 1);
+}
+
+extern int keyboard_wait_for_keypress(struct console *);
+
+struct console vt_console_driver = {
+	"tty",
+	vt_console_print,
+	NULL,
+	vt_console_device,
+	keyboard_wait_for_keypress,
+	do_unblank_screen,
+	NULL,
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+#endif
+
+/*
+ * con_throttle and con_unthrottle are only used for
+ * paste_selection(), which has to stuff in a large number of
+ * characters...
+ */
+static void con_throttle(struct tty_struct *tty)
+{
+}
+
+static void con_unthrottle(struct tty_struct *tty)
+{
+	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
+
+	wake_up_interruptible(&vt->paste_wait);
+}
+
+static void vc_init(unsigned int currcons, unsigned long rows, unsigned long cols, int do_clear)
+{
+	long base = (long) vc_scrbuf[currcons];
+	int j, k ;
+
+	video_num_columns = cols;
+	video_num_lines = rows;
+	video_size_row = cols<<1;
+	video_screen_size = video_num_lines * video_size_row;
+
+	pos = origin = video_mem_start = base;
+	scr_end = base + video_screen_size;
+	video_mem_end = base + video_screen_size;
+	reset_vc(currcons);
+	for (j=k=0; j<16; j++) {
+		vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
+		vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
+		vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
+	}
+	def_color       = 0x07;   /* white */
+	ulcolor		= 0x0f;   /* bold white */
+	halfcolor       = 0x08;   /* grey */
+	vt_cons[currcons]->paste_wait = 0;
+	reset_terminal(currcons, do_clear);
+}
+
+/*
+ * This is the console switching bottom half handler.
+ *
+ * Doing console switching in a bottom half handler allows
+ * us to do the switches asynchronously (needed when we want
+ * to switch due to a keyboard interrupt), while still giving
+ * us the option to easily disable it to avoid races when we
+ * need to write to the console.
+ */
+static void console_bh(void)
+{
+	if (want_console >= 0) {
+		if (want_console != fg_console) {
+			change_console(want_console);
+			/* we only changed when the console had already
+			   been allocated - a new console is not created
+			   in an interrupt routine */
+		}
+		want_console = -1;
+	}
+	if (do_poke_blanked_console) { /* do not unblank for a LED change */
+		do_poke_blanked_console = 0;
+		poke_blanked_console();
+	}
+}
+
+/*
+ *  unsigned long con_init(unsigned long);
+ *
+ * This routine initializes console interrupts, and does nothing
+ * else. If you want the screen to clear, call tty_write with
+ * the appropriate escape-sequence.
+ *
+ * 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))
+{
+	const char *display_desc = NULL;
+	unsigned int currcons = 0;
+	char q[2] = { 0, 1 };
+
+	if (conswitchp)
+		kmem_start = conswitchp->con_startup(kmem_start,
+						     &display_desc);
+	if (!display_desc) {
+		fg_console = 0;
+		return kmem_start;
+	}
+
+	memset(&console_driver, 0, sizeof(struct tty_driver));
+	console_driver.magic = TTY_DRIVER_MAGIC;
+	console_driver.name = "tty";
+	console_driver.name_base = 1;
+	console_driver.major = TTY_MAJOR;
+	console_driver.minor_start = 1;
+	console_driver.num = MAX_NR_CONSOLES;
+	console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
+	console_driver.init_termios = tty_std_termios;
+	console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
+	console_driver.refcount = &console_refcount;
+	console_driver.table = console_table;
+	console_driver.termios = console_termios;
+	console_driver.termios_locked = console_termios_locked;
+
+	console_driver.open = con_open;
+	console_driver.write = con_write;
+	console_driver.write_room = con_write_room;
+	console_driver.put_char = con_put_char;
+	console_driver.flush_chars = con_flush_chars;
+	console_driver.chars_in_buffer = con_chars_in_buffer;
+	console_driver.ioctl = vt_ioctl;
+	console_driver.stop = con_stop;
+	console_driver.start = con_start;
+	console_driver.throttle = con_throttle;
+	console_driver.unthrottle = con_unthrottle;
+
+	if (tty_register_driver(&console_driver))
+		panic("Couldn't register console driver\n");
+
+#if CONFIG_AP1000
+        return(kmem_start);
+#endif
+
+	timer_table[BLANK_TIMER].fn = blank_screen;
+	timer_table[BLANK_TIMER].expires = 0;
+	if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+
+	/* Due to kmalloc roundup allocating statically is more efficient -
+	   so provide MIN_NR_CONSOLES for people with very little memory */
+	for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
+		int j, k ;
+
+		vc_cons[currcons].d = (struct vc_data *) kmem_start;
+		kmem_start += sizeof(struct vc_data);
+		vt_cons[currcons] = (struct vt_struct *) kmem_start;
+		kmem_start += sizeof(struct vt_struct);
+		visual_init(currcons);
+		vc_scrbuf[currcons] = (unsigned short *) kmem_start;
+		kmem_start += video_screen_size;
+		kmalloced = 0;
+		screenbuf_size = video_screen_size;
+       		vc_init(currcons, video_num_lines, video_num_columns, currcons);
+		for (j=k=0; j<16; j++) {
+			vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
+			vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
+			vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
+		}
+	}
+
+	currcons = fg_console = 0;
+
+	gotoxy(currcons,0,0);
+	csi_J(currcons, 0);
+	update_screen(fg_console);
+	if (console_show_logo)
+	    q[1] += console_show_logo();
+	conswitchp->con_putcs(vc_cons[fg_console].d, linux_logo_banner,
+			      sizeof(linux_logo_banner)-1, q[1]-1, q[0]);
+	putconsxy(0, q);
+	sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
+	printk("Console: %s %s %ldx%ld",
+		can_do_color ? "colour" : "mono",
+		display_desc, video_num_columns, video_num_lines);
+	printable = 1;
+	printk("\n");
+
+#ifdef CONFIG_VT_CONSOLE
+	register_console(&vt_console_driver);
+#endif
+
+	init_bh(CONSOLE_BH, console_bh);
+	return kmem_start;
+}
+
+void set_vesa_blanking(unsigned long arg)
+{
+    char *argp = (char *)arg + 1;
+    unsigned int mode;
+    get_user(mode, argp);
+    vesa_blank_mode = (mode < 4) ? mode : 0;
+}
+
+void vesa_blank(void)
+{
+    vc_cons[fg_console].d->vc_sw->con_blank(vesa_blank_mode + 1);
+}
+
+void vesa_powerdown(void)
+{
+    /*
+     *  Power down if currently suspended (1 or 2),
+     *  suspend if currently blanked (0),
+     *  else do nothing (i.e. already powered down (3)).
+     *  Called only if powerdown features are allowed.
+     */
+    switch (vesa_blank_mode) {
+	case 0:
+	    vc_cons[fg_console].d->vc_sw->con_blank(2);
+	    break;
+	case 1:
+	case 2:
+	    vc_cons[fg_console].d->vc_sw->con_blank(4);
+	    break;
+    }
+}
+
+void vesa_powerdown_screen(void)
+{
+	timer_active &= ~(1<<BLANK_TIMER);
+	timer_table[BLANK_TIMER].fn = unblank_screen;
+
+	vesa_powerdown();
+}
+
+void do_blank_screen(int nopowersave)
+{
+	int currcons;
+
+	if (console_blanked)
+		return;
+
+	/* don't blank graphics */
+	if (vt_cons[fg_console]->vc_mode != KD_TEXT) {
+		console_blanked = fg_console + 1;
+		hide_cursor(fg_console);
+		return;
+	}
+	if(vesa_off_interval && !nopowersave) {
+		timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
+		timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
+		timer_active |= (1<<BLANK_TIMER);
+	} else {
+		timer_active &= ~(1<<BLANK_TIMER);
+		timer_table[BLANK_TIMER].fn = unblank_screen;
+	}
+
+	/* try not to lose information by blanking, and not to waste memory */
+	currcons = fg_console;
+	has_scrolled = 0;
+	sw->con_blank(1);
+	console_blanked = fg_console + 1;
+
+	if(!nopowersave)
+	{
+#ifdef CONFIG_APM
+		if (apm_display_blank())
+			return;
+#endif
+		vesa_blank();
+	}
+}
+
+void do_unblank_screen(void)
+{
+	int currcons;
+	if (!console_blanked)
+		return;
+	if (!vc_cons_allocated(fg_console)) {
+		/* impossible */
+		printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
+		return;
+	}
+	timer_table[BLANK_TIMER].fn = blank_screen;
+	if (blankinterval) {
+		timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
+		timer_active |= 1<<BLANK_TIMER;
+	}
+
+	currcons = fg_console;
+	console_blanked = 0;
+	if (sw->con_blank(0))
+		/* Low-level driver cannot restore -> do it ourselves */
+		update_screen(fg_console);
+	set_cursor(fg_console);
+}
+
+/*
+ * If a blank_screen is due to a timer, then a power save is allowed.
+ * If it is related to console_switching, then avoid vesa_blank().
+ */
+static void blank_screen(void)
+{
+	do_blank_screen(0);
+}
+
+static void unblank_screen(void)
+{
+	do_unblank_screen();
+}
+
+void update_screen(int new_console)
+{
+	int currcons = fg_console;
+	int xx, yy, startx, attr_save;
+	char *bufp;
+	unsigned short *p;
+	static int lock = 0;
+
+	if (lock)
+		return;
+	if (!vc_cons_allocated(new_console)) {
+		/* strange ... */
+		printk("update_screen: tty %d not allocated ??\n", new_console+1);
+		return;
+	}
+	lock = 1;
+
+	clear_selection();
+
+	currcons = fg_console = new_console;
+	sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
+	sw->con_switch (vc_cons[new_console].d);
+	/* Update the screen contents */
+	p = (unsigned short *)video_mem_start;
+	attr_save = attr;
+	for (yy = 0; yy < video_num_lines; yy++) {
+	    bufp = putcs_buf;
+	    for (startx = xx = 0; xx < video_num_columns; xx++) {
+		if (attr != ((scr_readw(p) >> 8) & 0xff)) {
+		    if (bufp > putcs_buf)
+		      sw->con_putcs (vc_cons[currcons].d, putcs_buf,
+				     bufp - putcs_buf, yy, startx);
+		    startx = xx;
+		    bufp = putcs_buf;
+		    attr = (scr_readw(p) >> 8) & 0xff;
+		}
+		*bufp++ = scr_readw(p++);
+		if (bufp == putcs_buf + sizeof (putcs_buf)) {
+		    sw->con_putcs (vc_cons[currcons].d, putcs_buf,
+				   bufp - putcs_buf, yy, startx);
+		    startx = xx + 1;
+		    bufp = putcs_buf;
+		}
+	    }
+	    if (bufp > putcs_buf)
+		sw->con_putcs (vc_cons[currcons].d, putcs_buf,
+			       bufp - putcs_buf, yy, startx);
+	}
+	set_cursor (currcons);
+	attr = attr_save;
+	set_leds();
+	compute_shiftstate();
+	lock = 0;
+}
+
+/*
+ * Allocate the console screen memory.
+ */
+static int con_open(struct tty_struct *tty, struct file * filp)
+{
+	unsigned int	currcons;
+	int i;
+
+	currcons = MINOR(tty->device) - tty->driver.minor_start;
+
+	i = vc_allocate(currcons);
+	if (i)
+		return i;
+
+	vt_cons[currcons]->vc_num = currcons;
+	tty->driver_data = vt_cons[currcons];
+
+	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+		tty->winsize.ws_row = video_num_lines;
+		tty->winsize.ws_col = video_num_columns;
+	}
+	return 0;
+}
+
+void set_palette(void)
+{
+    if (vt_cons[fg_console]->vc_mode != KD_GRAPHICS)
+	conswitchp->con_set_palette(vc_cons[fg_console].d, color_table);
+}
+
+int set_get_cmap(unsigned char *arg, int set)
+{
+    int i, j, k;
+
+    for (i = 0; i < 16; i++)
+	if (set) {
+	    get_user(default_red[i], arg++);
+	    get_user(default_grn[i], arg++);
+	    get_user(default_blu[i], arg++);
+	} else {
+	    put_user(default_red[i], arg++);
+	    put_user(default_grn[i], arg++);
+	    put_user(default_blu[i], arg++);
+	}
+    if (set) {
+	for (i = 0; i < MAX_NR_CONSOLES; i++)
+	    if (vc_cons_allocated(i))
+		for (j = k = 0; j < 16; j++) {
+		    vc_cons[i].d->vc_palette[k++] = default_red[j];
+		    vc_cons[i].d->vc_palette[k++] = default_grn[j];
+		    vc_cons[i].d->vc_palette[k++] = default_blu[j];
+		}
+	set_palette();
+    }
+    return 0;
+}
+
+/*
+ * Load palette into the DAC registers. arg points to a colour
+ * map, 3 bytes per colour, 16 colours, range from 0 to 255.
+ */
+
+int con_set_cmap (unsigned char *arg)
+{
+	return set_get_cmap (arg,1);
+}
+
+int con_get_cmap (unsigned char *arg)
+{
+	return set_get_cmap (arg,0);
+}
+
+void reset_palette (int currcons)
+{
+	int j, k ;
+	for (j=k=0; j<16; j++) {
+		palette[k++] = default_red[j];
+		palette[k++] = default_grn[j];
+		palette[k++] = default_blu[j];
+	}
+	set_palette() ;
+}
+
+/*
+ *  PIO_FONT support.
+ *
+ *  Currently we only support 8 pixels wide fonts, at a maximum height
+ *  of 32 pixels. Userspace fontdata is stored with 32 bytes reserved
+ *  for each character which is kinda wasty, but this is done in order
+ *  to maintain compatibility with the EGA/VGA fonts. It is upto the
+ *  actual low-level console-driver convert data into its favorite
+ *  format (maybe we should add a `fontoffset' field to the `display'
+ *  structure so we wont have to convert the fontdata all the time.
+ *  /Jes
+ */
+
+#define cmapsz 8192
+
+int set_get_font(unsigned char * arg, int set, int ch512)
+{
+    int i, unit, size;
+    char *charmap;
+
+    if (!arg)
+	return -EINVAL;
+
+
+    size = ch512 ? 2*cmapsz : cmapsz;
+
+    charmap = (char *)kmalloc(size, GFP_USER);
+
+    if (set) {
+	if (copy_from_user(charmap, arg, size)) {
+	    kfree(charmap);
+	    return -EFAULT;
+	}
+
+	for (unit = 32; unit > 0; unit--)
+	    for (i = 0; i < (ch512 ? 512 : 256); i++)
+		if (charmap[32*i+unit-1])
+		    goto nonzero;
+    nonzero:
+	i = conswitchp->con_set_font(vc_cons[fg_console].d, 8, unit, charmap);
+    } else {
+	memset(charmap, 0, size);
+	i = conswitchp->con_get_font(vc_cons[fg_console].d, &unit, &unit,
+				     charmap);
+	if (i == 0 && copy_to_user(arg, charmap, size))
+	    i = -EFAULT;
+    }
+    kfree(charmap);
+
+    return i;
+}
+
+/*
+ * Load font into the EGA/VGA character generator. arg points to a 8192
+ * byte map, 32 bytes per character. Only first H of them are used for
+ * 8xH fonts (0 < H <= 32).
+ */
+
+int con_set_font (char *arg, int ch512)
+{
+	int i;
+
+	i = set_get_font (arg,1,ch512);
+  	if ( !i ) {
+		hashtable_contents_valid = 0;
+      		video_mode_512ch = ch512;
+      		console_charmask = ch512 ? 0x1ff : 0x0ff;
+	}
+	return i;
+}
+
+int con_get_font (char *arg)
+{
+	return set_get_font (arg,0,video_mode_512ch);
+}
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/char/fbmem.c m68k-2.1.77/drivers/char/fbmem.c
--- /usr/src/m68k-2.1.77/drivers/char/fbmem.c	Thu Jan  8 22:04:55 1998
+++ m68k-2.1.77/drivers/char/fbmem.c	Fri Jan  9 01:19:33 1998
@@ -54,6 +54,9 @@
 extern unsigned long vfb_init(unsigned long mem_start);
 extern void vfb_setup(char *options, int *ints);
 extern unsigned long offb_init(unsigned long mem_start);
+extern void offb_setup(char *options, int *ints);
+extern unsigned long atyfb_init(unsigned long mem_start);
+extern void atyfb_setup(char *options, int *ints);
 extern unsigned long dnfb_init(unsigned long mem_start);
 extern unsigned long mach64fb_init(unsigned long mem_start);
 extern void mach64fb_setup(char *options, int *ints);
@@ -84,13 +87,19 @@
 	{ "vfb", vfb_init, vfb_setup },
 #endif
 #ifdef CONFIG_FB_OPEN_FIRMWARE
-	{ "offb", offb_init, NULL },
+	{ "offb", offb_init, offb_setup },
+#endif
+#ifdef CONFIG_FB_ATY
+	{ "atyfb", atyfb_init, atyfb_setup },
 #endif
 #ifdef CONFIG_APOLLO
 	{ "apollo", dnfb_init, NULL },
 #endif
+#ifdef CONFIG_FB_MACH64
+      { "mach64", mach64fb_init, mach64fb_setup },
+#endif
 #ifdef CONFIG_FB_TGA
-	{ "tga", tgafb_init, NULL },
+      { "tga", tgafb_init, NULL },
 #endif
 #ifdef CONFIG_GSP_RESOLVER
 	/* Not a real frame buffer device... */
@@ -150,7 +159,8 @@
 	unsigned long p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
 	int fbidx = GET_FB_IDX(inode->i_rdev);
-	struct fb_ops *fb = registered_fb[fbidx]->fbops;
+	struct fb_info *info = registered_fb[fbidx];
+	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
 	char *base_addr;
 	ssize_t copy_size;
@@ -158,7 +168,7 @@
 	if (! fb)
 		return -ENODEV;
 
-	fb->fb_get_fix(&fix,PROC_CONSOLE(), fbidx);
+	fb->fb_get_fix(&fix,PROC_CONSOLE(), info);
 	base_addr=(char *) fix.smem_start;
 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
 	copy_to_user(buf, base_addr+p, copy_size);
@@ -172,14 +182,15 @@
 	unsigned long p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
 	int fbidx = GET_FB_IDX(inode->i_rdev);
-	struct fb_ops *fb = registered_fb[fbidx]->fbops;
+	struct fb_info *info = registered_fb[fbidx];
+	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
 	char *base_addr;
 	ssize_t copy_size;
 
 	if (! fb)
 		return -ENODEV;
-	fb->fb_get_fix(&fix, PROC_CONSOLE(), fbidx);
+	fb->fb_get_fix(&fix, PROC_CONSOLE(), info);
 	base_addr=(char *) fix.smem_start;
 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
 	copy_from_user(base_addr+p, buf, copy_size); 
@@ -197,9 +208,9 @@
     if (newidx != con2fb_map[unit]) {
        oldfb = registered_fb[oldidx];
        newfb = registered_fb[newidx];
-       if (newfb->fbops->fb_open(newidx))
+       if (newfb->fbops->fb_open(newfb))
 	   return;
-       oldfb->fbops->fb_release(oldidx);
+       oldfb->fbops->fb_release(oldfb);
        conp = fb_display[unit].conp;
        con2fb_map[unit] = newidx;
        fb_display[unit] = *(newfb->disp);
@@ -227,52 +238,48 @@
 fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	 unsigned long arg)
 {
-	struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)]->fbops;
+	int fbidx = GET_FB_IDX(inode->i_rdev);
+	struct fb_info *info = registered_fb[fbidx];
+	struct fb_ops *fb = info->fbops;
 	struct fb_cmap cmap;
 	struct fb_var_screeninfo var;
 	struct fb_fix_screeninfo fix;
 	struct fb_con2fbmap con2fb;
-	int i, fbidx;
+	int i;
 	
 	if (! fb)
 		return -ENODEV;
 	switch (cmd) {
 	case FBIOGET_VSCREENINFO:
-		fbidx=GET_FB_IDX(inode->i_rdev);
-		if ((i = fb->fb_get_var(&var, PROC_CONSOLE(), fbidx)))
+		if ((i = fb->fb_get_var(&var, PROC_CONSOLE(), info)))
 			return i;
 		return copy_to_user((void *) arg, &var,
 				    sizeof(var)) ? -EFAULT : 0;
 	case FBIOPUT_VSCREENINFO:
-		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		if ((i = fb->fb_set_var(&var, PROC_CONSOLE(), fbidx)))
+		if ((i = fb->fb_set_var(&var, PROC_CONSOLE(), info)))
 			return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
 		return 0;
 	case FBIOGET_FSCREENINFO:
-		fbidx=GET_FB_IDX(inode->i_rdev);
-		if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE(), fbidx)))
+		if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE(), info)))
 			return i;
 		return copy_to_user((void *) arg, &fix, sizeof(fix)) ?
 			-EFAULT : 0;
 	case FBIOPUTCMAP:
-		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
 			return -EFAULT;
-		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(), fbidx));
+		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(), info));
 	case FBIOGETCMAP:
-		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
 			return -EFAULT;
-		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(), fbidx));
+		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(), info));
 	case FBIOPAN_DISPLAY:
-		fbidx=GET_FB_IDX(inode->i_rdev);
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(), fbidx)))
+		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(), info)))
 			return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
@@ -306,9 +313,8 @@
 			set_con2fb_map(i, con2fb.framebuffer);
 		return 0;
 	default:
-		fbidx=GET_FB_IDX(inode->i_rdev);
-		return (fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(),
-				     fbidx));
+		return fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(),
+				    info);
 	}
 }
 
@@ -316,14 +322,15 @@
 fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
 	int fbidx = GET_FB_IDX(file->f_dentry->d_inode->i_rdev);
-	struct fb_ops *fb = registered_fb[fbidx]->fbops;
+	struct fb_info *info = registered_fb[fbidx];
+	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
 	unsigned char *start;
 	unsigned long len;
 
 	if (! fb)
 		return -ENODEV;
-	fb->fb_get_fix(&fix, PROC_CONSOLE(), fbidx);
+	fb->fb_get_fix(&fix, PROC_CONSOLE(), info);
 	if (vma->vm_offset < fix.smem_len) {
 		/* frame buffer memory */
 		start = fix.smem_start;
@@ -365,23 +372,25 @@
 static int
 fb_open(struct inode *inode, struct file *file)
 {
-	int fbidx=GET_FB_IDX(inode->i_rdev);
+	int fbidx = GET_FB_IDX(inode->i_rdev);
+	struct fb_info *info;
 
 #ifdef CONFIG_KERNELD
-	if (!registered_fb[fbidx])
+	if (!(info = registered_fb[fbidx]))
 		try_to_load(fbidx);
 #endif
-	if (!registered_fb[fbidx])
+	if (!(info = registered_fb[fbidx]))
 		return -ENODEV;
-	return registered_fb[fbidx]->fbops->fb_open(fbidx);
+	return info->fbops->fb_open(info);
 }
 
 static int 
 fb_release(struct inode *inode, struct file *file)
 {
-	int fbidx=GET_FB_IDX(inode->i_rdev);
+	int fbidx = GET_FB_IDX(inode->i_rdev);
+	struct fb_info *info = registered_fb[fbidx];
 
-	registered_fb[fbidx]->fbops->fb_release(fbidx);
+	info->fbops->fb_release(info);
 	return 0;
 }
 
@@ -419,7 +428,7 @@
 		 */
 		for (j = 0; j < MAX_NR_CONSOLES; j++)
 			if (con2fb_map[j] == i)
-				fb_info->fbops->fb_open(i);
+				fb_info->fbops->fb_open(fb_info);
 		fb_ever_opened[i] = 1;
 	}
 	return 0;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/char/selection.c m68k-2.1.77/drivers/char/selection.c
--- /usr/src/m68k-2.1.77/drivers/char/selection.c	Thu Sep 11 22:30:58 1997
+++ m68k-2.1.77/drivers/char/selection.c	Fri Jan  9 01:19:33 1998
@@ -23,6 +23,7 @@
 
 #include <linux/vt_kern.h>
 #include <linux/consolemap.h>
+#include <linux/console_struct.h>
 #include <linux/selection.h>
 
 #ifndef MIN
@@ -121,15 +122,11 @@
 	int sel_mode, new_sel_start, new_sel_end, spc;
 	char *bp, *obp;
 	int i, ps, pe;
-	unsigned long num_lines, num_columns, size_row;
+	unsigned int currcons = fg_console;
 
 	do_unblank_screen();
 	poke_blanked_console();
 
-	num_lines = get_video_num_lines(fg_console);
-	num_columns = get_video_num_columns(fg_console);
-	size_row = get_video_size_row(fg_console);
-
 	{ unsigned short *args, xs, ys, xe, ye;
 
 	  args = (unsigned short *)(arg + 1);
@@ -151,12 +148,12 @@
 		  sel_mode = *args;
 	  }
 	  xs--; ys--; xe--; ye--;
-	  xs = limit(xs, num_columns - 1);
-	  ys = limit(ys, num_lines - 1);
-	  xe = limit(xe, num_columns - 1);
-	  ye = limit(ye, num_lines - 1);
-	  ps = ys * size_row + (xs << 1);
-	  pe = ye * size_row + (xe << 1);
+	  xs = limit(xs, video_num_columns - 1);
+	  ys = limit(ys, video_num_lines - 1);
+	  xe = limit(xe, video_num_columns - 1);
+	  ye = limit(ye, video_num_lines - 1);
+	  ps = ys * video_size_row + (xs << 1);
+	  pe = ye * video_size_row + (xe << 1);
 
 	  if (sel_mode == 4) {
 	      /* useful for screendump without selection highlights */
@@ -196,7 +193,7 @@
 				    (!spc && !inword(sel_pos(ps))))
 					break;
 				new_sel_start = ps;
-				if (!(ps % size_row))
+				if (!(ps % video_size_row))
 					break;
 			}
 			spc = isspace(sel_pos(pe));
@@ -206,14 +203,14 @@
 				    (!spc && !inword(sel_pos(pe))))
 					break;
 				new_sel_end = pe;
-				if (!((pe + 2) % size_row))
+				if (!((pe + 2) % video_size_row))
 					break;
 			}
 			break;
 		case 2:	/* line-by-line selection */
-			new_sel_start = ps - ps % size_row;
-			new_sel_end = pe + size_row
-				    - pe % size_row - 2;
+			new_sel_start = ps - ps % video_size_row;
+			new_sel_end = pe + video_size_row
+				    - pe % video_size_row - 2;
 			break;
 		case 3:
 			highlight_pointer(pe);
@@ -227,9 +224,11 @@
 
 	/* select to end of line if on trailing space */
 	if (new_sel_end > new_sel_start &&
-		!atedge(new_sel_end, size_row) && isspace(sel_pos(new_sel_end))) {
+		!atedge(new_sel_end, video_size_row) &&
+		isspace(sel_pos(new_sel_end))) {
 		for (pe = new_sel_end + 2; ; pe += 2)
-			if (!isspace(sel_pos(pe)) || atedge(pe, size_row))
+			if (!isspace(sel_pos(pe)) ||
+			    atedge(pe, video_size_row))
 				break;
 		if (isspace(sel_pos(pe)))
 			new_sel_end = pe;
@@ -274,7 +273,7 @@
 		*bp = sel_pos(i);
 		if (!isspace(*bp++))
 			obp = bp;
-		if (! ((i + 2) % size_row)) {
+		if (! ((i + 2) % video_size_row)) {
 			/* strip trailing blanks from line and add newline,
 			   unless non-space at end of line. */
 			if (obp != bp) {
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/char/vc_screen.c m68k-2.1.77/drivers/char/vc_screen.c
--- /usr/src/m68k-2.1.77/drivers/char/vc_screen.c	Sun Jan  4 22:27:33 1998
+++ m68k-2.1.77/drivers/char/vc_screen.c	Fri Jan  9 01:19:33 1998
@@ -32,8 +32,10 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/vt_kern.h>
+#include <linux/console_struct.h>
 #include <linux/selection.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 #undef attr
 #undef org
@@ -56,18 +58,17 @@
 vcs_size(struct inode *inode)
 {
 	int size;
-#ifdef CONFIG_FB_CONSOLE
-	int cons = MINOR(inode->i_rdev) & 127;
-
-	if (cons == 0)
-		cons = fg_console;
+   	int currcons = MINOR(inode->i_rdev) & 127;
+#ifdef CONFIG_ABSTRACT_CONSOLE
+	if (currcons == 0)
+		currcons = fg_console;
 	else
-		cons--;
-	if (!vc_cons_allocated(cons))
+		currcons--;
+	if (!vc_cons_allocated(currcons))
 		return -ENXIO;
 #endif
 
-	size = get_video_num_lines(cons) * get_video_num_columns(cons);
+	size = video_num_lines * video_num_columns;
 
 	if (MINOR(inode->i_rdev) & 128)
 		size = 2*size + HEADER_SIZE;
@@ -135,8 +136,8 @@
 	} else {
 		if (p < HEADER_SIZE) {
 			char header[HEADER_SIZE];
-			header[0] = (char) get_video_num_lines(currcons);
-			header[1] = (char) get_video_num_columns(currcons);
+			header[0] = (char) video_num_lines;
+			header[1] = (char) video_num_columns;
 			getconsxy(currcons, header+2);
 			while (p < HEADER_SIZE && count > 0)
 			    { count--; put_user(header[p++], buf++); }
@@ -145,7 +146,11 @@
 		    p -= HEADER_SIZE;
 		    org = screen_pos(currcons, p/2, viewed);
 		    if ((p & 1) && count > 0)
+#ifdef __BIG_ENDIAN
+			    { count--; put_user(func_scr_readw(org++) & 0xff, buf++); }
+#else
 			    { count--; put_user(func_scr_readw(org++) >> 8, buf++); }
+#endif
 		}
 		while (count > 1) {
 			put_user(func_scr_readw(org++), (unsigned short *) buf);
@@ -153,7 +158,11 @@
 			count -= 2;
 		}
 		if (count > 0)
+#ifdef __BIG_ENDIAN
+			put_user(func_scr_readw(org) >> 8, buf++);
+#else
 			put_user(func_scr_readw(org) & 0xff, buf++);
+#endif
 	}
 	read = buf - buf0;
 	*ppos += read;
@@ -215,8 +224,13 @@
 			    char c;
 				count--;
 				get_user(c,buf++);
+#ifdef __BIG_ENDIAN
+				func_scr_writew(c |
+				     (func_scr_readw(org) & 0xff00), org);
+#else
 				func_scr_writew((c << 8) |
 				     (func_scr_readw(org) & 0xff), org);
+#endif
 				org++;
 			}
 		}
@@ -230,10 +244,14 @@
 		if (count > 0) {
 			unsigned char c;
 			get_user(c, (const unsigned char*)buf++);
+#ifdef __BIG_ENDIAN
+			func_scr_writew((func_scr_readw(org) & 0xff) | (c << 8), org);
+#else
 			func_scr_writew((func_scr_readw(org) & 0xff00) | c, org);
+#endif
 		}
 	}
-#ifdef CONFIG_FB_CONSOLE
+#ifdef CONFIG_ABSTRACT_CONSOLE
 	if (currcons == fg_console)
 		/* Horribly inefficient if count < screen size.  */
 		update_screen(currcons);
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/char/vt.c m68k-2.1.77/drivers/char/vt.c
--- /usr/src/m68k-2.1.77/drivers/char/vt.c	Wed Dec 17 22:56:43 1997
+++ m68k-2.1.77/drivers/char/vt.c	Fri Jan  9 01:19:33 1998
@@ -265,9 +265,12 @@
 		    if (kbd->kbdmode != VC_UNICODE)
 				return -EINVAL;
 
+		/* ++Geert: non-PC keyboards may generate keycode zero */
+#if !defined(__mc68000__) && !defined(__powerpc__)
 		/* assignment to entry 0 only tests validity of args */
 		if (!i)
 			break;
+#endif
 
 		if (!(key_map = key_maps[s])) {
 			int j;
@@ -438,7 +441,15 @@
 			if (i)
 				return i;
 			i = con_adjust_height(cfdarg.charheight);
+#ifdef CONFIG_ABSTRACT_CONSOLE
+			/*
+			 *  ++Geert: vc_resize_con() will take note of the
+			 *	     changed screen size, if necessary
+			 */
+			return (i <= 0) ? i : 0;
+#else
 			return (i <= 0) ? i : kd_size_changed(i, 0);
+#endif
 		} else
 			return -EINVAL;
 	case GIO_FONTX:
@@ -1095,7 +1106,14 @@
 		if (i) return i;
 
 		i = con_adjust_height(default_font_height);
+#ifdef CONFIG_ABSTRACT_CONSOLE
+			/*
+			 *  ++Geert: vc_resize_con() will take note of the
+			 *	     changed screen size, if necessary
+			 */
+#else
 		if ( i > 0 ) kd_size_changed(i, 0);
+#endif
 		con_set_default_unimap();
 
 		return 0;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/Config.in m68k-2.1.77/drivers/video/Config.in
--- /usr/src/m68k-2.1.77/drivers/video/Config.in	Wed Dec  3 21:12:26 1997
+++ m68k-2.1.77/drivers/video/Config.in	Fri Jan  9 01:27:57 1998
@@ -16,16 +16,32 @@
     fi
     tristate 'Amiga Cybervision support' CONFIG_FB_CYBER
     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_CV3D
       tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3
     fi
   fi
   if [ "$CONFIG_ATARI" = "y" ]; then
     bool 'Atari native chipset support' CONFIG_FB_ATARI
-#    tristate 'Mach64 Frame Buffer support' CONFIG_FB_MACH64
+    tristate 'Mach64 Frame Buffer support' CONFIG_FB_MACH64
+  fi
+  if [ "$CONFIG_MAC" = "y" ]; then
+    define_bool CONFIG_FB_MAC y
   fi
   if [ "$CONFIG_CHRP" = "y" -o "$CONFIG_PMAC" = "y" ]; then
     bool 'Open Firmware frame buffer device support' CONFIG_FB_OPEN_FIRMWARE
   fi 
+  if [ "$CONFIG_FB_OPEN_FIRMWARE" = "y" ]; then
+#   bool 'Apple "control" display support' CONFIG_FB_CONTROL
+#   bool 'Apple "platinum" display support' CONFIG_FB_PLATINUM
+#   bool 'Apple "valkyrie" display support' CONFIG_FB_VALKYRIE
+    bool 'ATI Mach64 display support' CONFIG_FB_ATY
+#   bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT
+#   bool 'Chips 65550 display support' CONFIG_FB_CT65550
+#   bool 'S3 Trio display support' CONFIG_FB_S3TRIO
+  fi
+  if [ "$CONFIG_TGA_CONSOLE" = "y" ]; then
+    define_bool CONFIG_FB_TGA y
+  fi
   tristate 'Virtual Frame Buffer support' CONFIG_FB_VIRTUAL
 
   bool 'Advanced low level driver options' CONFIG_FBCON_ADVANCED
@@ -36,13 +52,22 @@
     tristate 'Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
     tristate 'Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4
     tristate 'Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
+    tristate '2 bpp packed pixel support' CONFIG_FBCON_CFB2
+    tristate '4 bpp packed pixel support' CONFIG_FBCON_CFB4
     tristate '8 bpp packed pixel support' CONFIG_FBCON_CFB8
     tristate '16 bpp packed pixel support' CONFIG_FBCON_CFB16
+#   tristate '24 bpp packed pixel support' CONFIG_FBCON_CFB24
+    tristate '32 bpp packed pixel support' CONFIG_FBCON_CFB32
+    tristate 'Mac packed pixel support' CONFIG_FBCON_MAC
     tristate 'Cybervision support (accelerated)' CONFIG_FBCON_CYBER
+    tristate 'Cybervision3D support (accelerated)' CONFIG_FBCON_VIRGE
     tristate 'RetinaZ3 support (accelerated)' CONFIG_FBCON_RETINAZ3
+    tristate 'Mach64 support (accelerated)' CONFIG_FBCON_MACH64
+#   tristate 'S3Trio support (accelerated)' CONFIG_FBCON_TRIO
   else
     if [ "$CONFIG_FB_AMIGA" != "n" -o "$CONFIG_FB_ATARI" != "n" -o \
 	 "$CONFIG_FB_CYBER" != "n" -o "$CONFIG_FB_RETINAZ3" != "n" -o \
+	 "$CONFIG_FB_CV3D" != "n" -o "$CONFIG_FB_MAC" != "n" -o \
 	 "$CONFIG_FB_VIRTUAL" != "n" ]; then
       define_bool CONFIG_FBCON_MFB y
     fi
@@ -55,21 +80,46 @@
       define_bool CONFIG_FBCON_IPLAN2P4 y
       define_bool CONFIG_FBCON_IPLAN2P8 y
     fi
-    if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
-	 "$CONFIG_FB_OPEN_FIRMWARE" = "y" -o \
+    if [ "$CONFIG_FB_MAC" = "y" -o \
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
+      define_bool CONFIG_FBCON_MAC  y
+      define_bool CONFIG_FBCON_CFB2 y
+      define_bool CONFIG_FBCON_CFB4 y
+    fi
+    if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
+	 "$CONFIG_FB_OPEN_FIRMWARE" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
+	 "$CONFIG_FB_TGA" = "y" -o \
+	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" -o ]; then
       define_bool CONFIG_FBCON_CFB8 y
     fi
     if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
+	 "$CONFIG_FB_OPEN_FIRMWARE" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
 	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
       define_bool CONFIG_FBCON_CFB16 y
     fi
+    if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
+	 "$CONFIG_FB_OPEN_FIRMWARE" = "y" -o \
+	 "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
+      define_bool CONFIG_FBCON_CFB32 y
+    fi
     if [ "$CONFIG_FB_CYBER" = "y" -o "$CONFIG_FB_CYBER" = "m" ]; then
       define_bool CONFIG_FBCON_CYBER y
     fi
+    if [ "$CONFIG_FB_CV3D" = "y" ]; then
+      define_bool CONFIG_FBCON_VIRGE y
+    fi
     if [ "$CONFIG_FB_RETINAZ3" = "y" -o "$CONFIG_FB_RETINAZ3" = "m" ]; then
       define_bool CONFIG_FBCON_RETINAZ3 y
     fi
+    if [ "$CONFIG_FB_MACH64" = "y" -o "$CONFIG_FB_MACH64" = "m" ]; then
+      define_bool CONFIG_FBCON_MACH64 y
+    fi
+    if [ "$CONFIG_FB_ATY" = "y" ]; then
+      define_bool CONFIG_FBCON_ATY y
+    fi
+#   if [ "$CONFIG_FB_S3TRIO" = "y" -o "$CONFIG_FB_S3TRIO" = "m" ]; then
+#     define_bool CONFIG_FBCON_TRIO y
+#   fi
   fi
 
   endmenu
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/Makefile m68k-2.1.77/drivers/video/Makefile
--- /usr/src/m68k-2.1.77/drivers/video/Makefile	Thu Jan  8 22:04:58 1998
+++ m68k-2.1.77/drivers/video/Makefile	Fri Jan  9 01:19:33 1998
@@ -22,8 +22,8 @@
 # Frame Buffer Console
 
 ifeq ($(CONFIG_FB),y)
-  L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o
-  LX_OBJS += fbcon.o fbcmap.o
+  L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o font_6x11.o
+  LX_OBJS += fbcon.o fbcmap.o fbgen.o
 endif
 
 # Frame buffer devices
@@ -48,11 +48,23 @@
   endif
 endif
 
+ifeq ($(CONFIG_MAC),y)
+L_OBJS += macfb.o
+endif
+
 ifeq ($(CONFIG_FB_CYBER),y)
 LX_OBJS += cyberfb.o
 else
   ifeq ($(CONFIG_FB_CYBER),m)
   MX_OBJS += cyberfb.o
+  else
+    ifeq ($(CONFIG_FB_CV3D),y)
+    LX_OBJS += cyberfb.o
+    else
+      ifeq ($(CONFIG_FB_CV3D),m)
+      MX_OBJS += cyberfb.o
+      endif
+    endif
   endif
 endif
 
@@ -76,6 +88,10 @@
 L_OBJS += offb.o
 endif
 
+ifeq ($(CONFIG_FB_ATY),y)
+L_OBJS += atyfb.o
+endif
+
 ifeq ($(CONFIG_FB_MACH64),y)
 L_OBJS += mach64fb.o
 else
@@ -88,6 +104,14 @@
 L_OBJS += tgafb.o
 endif
 
+ifeq ($(CONFIG_FB_S3TRIO),y)
+L_OBJS += S3triofb.o
+else
+  ifeq ($(CONFIG_FB_S3TRIO),m)
+  M_OBJS += S3triofb.o
+  endif
+endif
+
 # Low level drivers
 
 ifeq ($(CONFIG_FBCON_AFB),y)
@@ -98,6 +122,22 @@
   endif
 endif
 
+ifeq ($(CONFIG_FBCON_CFB2),y)
+L_OBJS += fbcon-cfb2.o
+else
+  ifeq ($(CONFIG_FBCON_CFB2),m)
+  M_OBJS += fbcon-cfb2.o
+  endif
+endif
+
+ifeq ($(CONFIG_FBCON_CFB4),y)
+L_OBJS += fbcon-cfb4.o
+else
+  ifeq ($(CONFIG_FBCON_CFB4),m)
+  M_OBJS += fbcon-cfb4.o
+  endif
+endif
+
 ifeq ($(CONFIG_FBCON_CFB8),y)
 L_OBJS += fbcon-cfb8.o
 else
@@ -114,6 +154,22 @@
   endif
 endif
 
+ifeq ($(CONFIG_FBCON_CFB24),y)
+LX_OBJS += fbcon-cfb24.o
+else
+  ifeq ($(CONFIG_FBCON_CFB24),m)
+  MX_OBJS += fbcon-cfb24.o
+  endif
+endif
+
+ifeq ($(CONFIG_FBCON_CFB32),y)
+LX_OBJS += fbcon-cfb32.o
+else
+  ifeq ($(CONFIG_FBCON_CFB32),m)
+  MX_OBJS += fbcon-cfb32.o
+  endif
+endif
+
 ifeq ($(CONFIG_FBCON_ILBM),y)
 L_OBJS += fbcon-ilbm.o
 else
@@ -162,6 +218,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_FBCON_VIRGE),y)
+L_OBJS += fbcon-virge.o
+else
+  ifeq ($(CONFIG_FBCON_VIRGE),m)
+  M_OBJS += fbcon-virge.o
+  endif
+endif
+
 ifeq ($(CONFIG_FBCON_RETINAZ3),y)
 L_OBJS += fbcon-retz3.o
 else
@@ -176,6 +240,30 @@
   ifeq ($(CONFIG_FBCON_MACH64),m)
   M_OBJS += fbcon-mach64.o
   endif
+endif
+
+ifeq ($(CONFIG_FBCON_MAC),y)
+L_OBJS += fbcon-mac.o
+else
+  ifeq ($(CONFIG_FBCON_MAC),m)
+  M_OBJS += fbcon-mac.o
+  endif
+endif
+
+ifeq ($(CONFIG_FBCON_ATY),y)
+L_OBJS += fbcon-aty.o
+else
+  ifeq ($(CONFIG_FBCON_ATY),m)
+  M_OBJS += fbcon-aty.o
+  endif
+endif
+
+ifeq ($(CONFIG_FBCON_TRIO),y)
+L_OBJS += fbcon-trio.o
+else
+  ifeq ($(CONFIG_FBCON_TRIO),m)
+  M_OBJS += fbcon-trio.o
+  endif 
 endif
 
 # GSP Console
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/amifb.c m68k-2.1.77/drivers/video/amifb.c
--- /usr/src/m68k-2.1.77/drivers/video/amifb.c	Thu Jan  8 22:04:58 1998
+++ m68k-2.1.77/drivers/video/amifb.c	Fri Jan  9 01:19:33 1998
@@ -1155,19 +1155,22 @@
 
 void amifb_setup(char *options, int *ints);
 
-static int amifb_open(int fbidx);
-static int amifb_release(int fbidx);
-static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
-static int amifb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int amifb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int amifb_open(struct fb_info *info);
+static int amifb_release(struct fb_info *info);
+static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info);
+static int amifb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int amifb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
 static int amifb_pan_display(struct fb_var_screeninfo *var, int con,
-				int fbidx);
+			     struct fb_info *info);
 static int amifb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			  struct fb_info *info);
 static int amifb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			  struct fb_info *info);
 static int amifb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                          u_long arg, int con, int fbidx);
+		       u_long arg, int con, struct fb_info *info);
 
 static int amifb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con);
 static int amifb_get_var_cursorinfo(struct fb_var_cursorinfo *var,
@@ -1182,15 +1185,15 @@
 	 */
 
 unsigned long amifb_init(unsigned long mem_start);
-static int amifbcon_switch(int con);
-static int amifbcon_updatevar(int con);
-static void amifbcon_blank(int blank);
+static int amifbcon_switch(int con, struct fb_info *info);
+static int amifbcon_updatevar(int con, struct fb_info *info);
+static void amifbcon_blank(int blank, struct fb_info *info);
 
 	/*
 	 * Internal routines
 	 */
 
-static void do_install_cmap(int con);
+static void do_install_cmap(int con, struct fb_info *info);
 static int flash_cursor(void);
 static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
 static void get_video_mode(const char *name);
@@ -1216,9 +1219,9 @@
 static void ami_pan_var(struct fb_var_screeninfo *var);
 static int ami_update_par(void);
 static int ami_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp);
+                         u_int *transp, struct fb_info *info);
 static int ami_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp);
+                         u_int transp, struct fb_info *info);
 static void ami_update_display(void);
 static void ami_init_display(void);
 static void ami_do_blank(void);
@@ -1384,7 +1387,7 @@
 	 * Open/Release the frame buffer device
 	 */
 
-static int amifb_open(int fbidx)
+static int amifb_open(struct fb_info *info)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -1394,7 +1397,7 @@
 	return(0);
 }
 
-static int amifb_release(int fbidx)
+static int amifb_release(struct fb_info *info)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -1405,7 +1408,8 @@
 	 * Get the Fixed Part of the Display
 	 */
 
-static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
 {
 	struct amifb_par par;
 
@@ -1424,7 +1428,8 @@
 	 * Get the User Defined Part of the Display
 	 */
 
-static int amifb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int amifb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
 	int err = 0;
 
@@ -1442,7 +1447,8 @@
 	 * Set the User Defined Part of the Display
 	 */
 
-static int amifb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int amifb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
 	int err, activate = var->activate;
 	int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
@@ -1495,7 +1501,7 @@
 		if (oldbpp != var->bits_per_pixel) {
 			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 				return err;
-			do_install_cmap(con);
+			do_install_cmap(con, info);
 		}
 		if (con == currcon)
 			ami_set_var(&display->var);
@@ -1510,7 +1516,7 @@
 	 */
 
 static int amifb_pan_display(struct fb_var_screeninfo *var, int con,
-				int fbidx)
+				struct fb_info *info)
 {
 	if (var->vmode & FB_VMODE_YWRAP) {
 		if (var->yoffset<0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
@@ -1540,15 +1546,15 @@
 	 */
 
 static int amifb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			  struct fb_info *info)
 {
 	if (con == currcon) /* current console? */
 		return fb_get_cmap(cmap, &fb_display[con].var, kspc,
-				   ami_getcolreg);
+				   ami_getcolreg, info);
 	else if (fb_display[con].cmap.len) /* non default colormap? */
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			     cmap, kspc ? 0 : 2);
 	return 0;
 }
@@ -1558,7 +1564,7 @@
 	 */
 
 static int amifb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			  struct fb_info *info)
 {
 	int err;
 
@@ -1570,7 +1576,7 @@
 	}
 	if (con == currcon)			/* current console? */
 		return fb_set_cmap(cmap, &fb_display[con].var, kspc,
-				   ami_setcolreg);
+				   ami_setcolreg, info);
 	else
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
@@ -1581,7 +1587,7 @@
 	 */
 
 static int amifb_ioctl(struct inode *inode, struct file *file,
-                          u_int cmd, u_long arg, int con, int fbidx)
+                       u_int cmd, u_long arg, int con, struct fb_info *info)
 {
 	int i;
 
@@ -1866,7 +1872,7 @@
 	custom.intena = IF_VERTB;
 	custom.intena = IF_SETCLR | IF_COPER;
 
-	amifb_set_var(&amifb_default, -1, GET_FB_IDX(fb_info.node));
+	amifb_set_var(&amifb_default, -1, &fb_info);
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, videomemorysize>>10);
@@ -1877,17 +1883,17 @@
 	return mem_start;
 }
 
-static int amifbcon_switch(int con)
+static int amifbcon_switch(int con, struct fb_info *info)
 {
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
 		fb_get_cmap(&fb_display[currcon].cmap,
-			    &fb_display[currcon].var, 1, ami_getcolreg);
+			    &fb_display[currcon].var, 1, ami_getcolreg, info);
 
 	currcon = con;
 	ami_set_var(&fb_display[con].var);
 	/* Install new colormap */
-	do_install_cmap(con);
+	do_install_cmap(con, info);
 	return 0;
 }
 
@@ -1895,7 +1901,7 @@
 	 * Update the `var' structure (called by fbcon.c)
 	 */
 
-static int amifbcon_updatevar(int con)
+static int amifbcon_updatevar(int con, struct fb_info *info)
 {
 	ami_pan_var(&fb_display[con].var);
 	return 0;
@@ -1905,7 +1911,7 @@
 	 * Blank the display.
 	 */
 
-static void amifbcon_blank(int blank)
+static void amifbcon_blank(int blank, struct fb_info *info)
 {
 	do_blank = blank ? blank : -1;
 }
@@ -1914,17 +1920,17 @@
 	 * Set the colormap
 	 */
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-			    ami_setcolreg);
+			    ami_setcolreg, info);
 	else
-		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 					    &fb_display[con].var, 1,
-					    ami_setcolreg);
+					    ami_setcolreg, info);
 }
 
 static int flash_cursor(void)
@@ -2750,7 +2756,7 @@
 	 */
 
 static int ami_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp)
+                         u_int *transp, struct fb_info *info)
 {
 	if (IS_AGA) {
 		if (regno > 255)
@@ -2774,7 +2780,7 @@
 	 */
 
 static int ami_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp)
+                         u_int transp, struct fb_info *info)
 {
 #if defined(CONFIG_FB_AMIGA_AGA)
 	u_short bplcon3 = currentpar.bplcon3;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/atafb.c m68k-2.1.77/drivers/video/atafb.c
--- /usr/src/m68k-2.1.77/drivers/video/atafb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/atafb.c	Fri Jan  9 01:19:33 1998
@@ -240,7 +240,7 @@
 extern unsigned char fontdata_8x16[];
 
 /* import first 16 colors from fbcon.c */
-extern unsigned short packed16_cmap[16];
+extern unsigned short cfb16_cmap[16];
 
 
 /* ++roman: This structure abstracts from the underlying hardware (ST(e),
@@ -278,14 +278,14 @@
  *   
  * int (*setcolreg)( unsigned regno, unsigned red,
  *                   unsigned green, unsigned blue,
- *                   unsigned transp )
+ *                   unsigned transp, struct fb_info *info )
  *   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.
  *
  * int (*getcolreg)( unsigned regno, unsigned *red,
  *                   unsigned *green, unsigned *blue,
- *                   unsigned *transp )
+ *                   unsigned *transp, struct fb_info *info )
  *   Read a single color register and split it into
  *   colors/transparent. Return != 0 for invalid regno.
  *
@@ -314,10 +314,10 @@
 	void (*set_par)( struct atafb_par *par );
 	int  (*getcolreg)( unsigned regno, unsigned *red,
 					   unsigned *green, unsigned *blue,
-					   unsigned *transp );
+					   unsigned *transp, struct fb_info *info );
 	int  (*setcolreg)( unsigned regno, unsigned red,
 					   unsigned green, unsigned blue,
-					   unsigned transp );
+					   unsigned transp, struct fb_info *info );
 	void (*set_screen_base)( unsigned long s_base );
 	int  (*blank)( int blank_mode );
 	int  (*pan_display)( struct fb_var_screeninfo *var,
@@ -675,7 +675,7 @@
 
 static int tt_getcolreg( unsigned regno, unsigned *red,
 						 unsigned *green, unsigned *blue,
-						 unsigned *transp )
+						 unsigned *transp, struct fb_info *info )
 {
 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH)
 		regno += 254;
@@ -692,7 +692,7 @@
 
 static int tt_setcolreg( unsigned regno, unsigned red,
 						 unsigned green, unsigned blue,
-						 unsigned transp )
+						 unsigned transp, struct fb_info *info )
 {
 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH)
 		regno += 254;
@@ -1595,7 +1595,7 @@
 
 static int falcon_getcolreg( unsigned regno, unsigned *red,
 				 unsigned *green, unsigned *blue,
-				 unsigned *transp )
+				 unsigned *transp, struct fb_info *info )
 {	unsigned long col;
 	
 	if (regno > 255)
@@ -1615,7 +1615,7 @@
 
 static int falcon_setcolreg( unsigned regno, unsigned red,
 							 unsigned green, unsigned blue,
-							 unsigned transp )
+							 unsigned transp, struct fb_info *info )
 {
 	if (regno > 255)
 		return 1;
@@ -1626,7 +1626,7 @@
 			(((green & 0xe) >> 1) | ((green & 1) << 3) << 4) |
 			((blue & 0xe) >> 1) | ((blue & 1) << 3);
 #ifdef CONFIG_FBCON_CFB16
-		packed16_cmap[regno] = (red << 11) | (green << 5) | blue;
+		cfb16_cmap[regno] = (red << 11) | (green << 5) | blue;
 #endif
 	}
 	return 0;
@@ -1908,7 +1908,7 @@
 
 static int stste_getcolreg( unsigned regno, unsigned *red,
 							unsigned *green, unsigned *blue,
-							unsigned *transp )
+							unsigned *transp, struct fb_info *info )
 {	unsigned col;
 	
 	if (regno > 15)
@@ -1931,7 +1931,7 @@
 
 static int stste_setcolreg( unsigned regno, unsigned red,
 						 unsigned green, unsigned blue,
-						 unsigned transp )
+						 unsigned transp, struct fb_info *info )
 {
 	if (regno > 15)
 		return 1;
@@ -2178,7 +2178,7 @@
 
 static int ext_getcolreg( unsigned regno, unsigned *red,
 						  unsigned *green, unsigned *blue,
-						  unsigned *transp )
+						  unsigned *transp, struct fb_info *info )
 {
 	if (! external_vgaiobase)
 		return 1;
@@ -2192,7 +2192,7 @@
 	
 static int ext_setcolreg( unsigned regno, unsigned red,
 						  unsigned green, unsigned blue,
-						  unsigned transp )
+						  unsigned transp, struct fb_info *info )
 
 {	unsigned char colmask = (1 << external_bitspercol) - 1;
 
@@ -2334,7 +2334,7 @@
 /* used for hardware scrolling */
 
 static int
-fb_update_var(int con)
+fb_update_var(int con, struct fb_info *info)
 {
 	int off=fb_display[con].var.yoffset*fb_display[con].var.xres_virtual*
 			fb_display[con].var.bits_per_pixel>>3;
@@ -2364,17 +2364,17 @@
 /* Functions for handling colormap */
 
 static void
-do_install_cmap(int con)
+do_install_cmap(int con, struct fb_info *info)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, &(fb_display[con].var), 1,
-			    fbhw->setcolreg);
+			    fbhw->setcolreg, info);
 	else
-		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 					    &(fb_display[con].var), 1,
-					    fbhw->setcolreg);		
+					    fbhw->setcolreg, info);		
 }
 
 
@@ -2382,7 +2382,7 @@
 	 * Open/Release the frame buffer device
 	 */
 
-static int atafb_open(int fbidx)
+static int atafb_open(struct fb_info *info)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -2392,7 +2392,7 @@
 	return(0);
 }
 
-static int atafb_release(int fbidx)
+static int atafb_release(struct fb_info *info)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -2400,7 +2400,7 @@
 
 
 static int
-atafb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+atafb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
 {
 	struct atafb_par par;
 	if (con == -1)
@@ -2412,7 +2412,7 @@
 }
 	
 static int
-atafb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+atafb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	struct atafb_par par;
 	if (con == -1) {
@@ -2425,7 +2425,7 @@
 }
 
 static void
-atafb_set_disp(int con)
+atafb_set_disp(int con, struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -2435,8 +2435,7 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	/* ### FN: Needs fixes later */
-	atafb_get_fix(&fix, con, 0);
+	atafb_get_fix(&fix, con, info);
 	if (con == -1)
 		con=0;
 	display->screen_base = (u_char *)fix.smem_start;
@@ -2456,7 +2455,7 @@
 }
 
 static int
-atafb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+atafb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	int err,oldxres,oldyres,oldbpp,oldxres_virtual,
 	    oldyres_virtual,oldyoffset;
@@ -2475,10 +2474,10 @@
 		    || oldyres_virtual != var->yres_virtual
 		    || oldbpp != var->bits_per_pixel
 		    || oldyoffset != var->yoffset) {
-			atafb_set_disp(con);
+			atafb_set_disp(con, info);
 			(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
-			do_install_cmap(con);
+			do_install_cmap(con, info);
 		}
 	}
 	var->activate=0;
@@ -2488,22 +2487,22 @@
 
 
 static int
-atafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+atafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
 {
 	if (con == currcon) /* current console ? */
 		return fb_get_cmap(cmap, &(fb_display[con].var), kspc,
-				   fbhw->getcolreg);
+				   fbhw->getcolreg, info);
 	else
 		if (fb_display[con].cmap.len) /* non default colormap ? */
 			fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 		else
-			fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+			fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 				     cmap, kspc ? 0 : 2);
 	return 0;
 }
 
 static int
-atafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+atafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
 {
 	int err;
 	if (! fb_display[con].cmap.len) { /* no colormap allocated ? */
@@ -2514,14 +2513,14 @@
 	}
 	if (con == currcon) /* current console ? */
 		return fb_set_cmap(cmap, &(fb_display[con].var), kspc,
-				   fbhw->setcolreg);
+				   fbhw->setcolreg, info);
 	else
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
 }
 
 static int
-atafb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+atafb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
 	int xoffset = var->xoffset;
 	int yoffset = var->yoffset;
@@ -2546,7 +2545,7 @@
 
 static int
 atafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-	       unsigned long arg, int con, int fbidx)
+	       unsigned long arg, int con, struct fb_info *info)
 {
 	switch (cmd) {
 #ifdef FBCMD_GET_CURRENTPAR
@@ -2616,16 +2615,17 @@
 }
 
 static int
-atafb_switch(int con)
+atafb_switch(int con, struct fb_info *info)
 {
 	/* Do we have to save the colormap ? */
 	if (fb_display[currcon].cmap.len)
 		fb_get_cmap(&fb_display[currcon].cmap,
-			    &(fb_display[currcon].var), 1, fbhw->getcolreg);
+			    &(fb_display[currcon].var), 1, fbhw->getcolreg,
+			    info);
 	do_fb_set_var(&fb_display[con].var,1);
 	currcon=con;
 	/* Install new colormap */
-	do_install_cmap(con);
+	do_install_cmap(con, info);
 	return 0;
 }
 
@@ -2637,7 +2637,7 @@
  * 4 = off
  */
 static void
-atafb_blank(int blank)
+atafb_blank(int blank, struct fb_info *info)
 {
 	unsigned short black[16];
 	struct fb_cmap cmap;
@@ -2652,10 +2652,10 @@
 		cmap.start=0;
 		cmap.len=16;
 		fb_set_cmap(&cmap, &(fb_display[currcon].var), 1,
-			    fbhw->setcolreg);
+			    fbhw->setcolreg, info);
 	}
 	else
-		do_install_cmap(currcon);
+		do_install_cmap(currcon, info);
 }
 
 __initfunc(unsigned long atafb_init(unsigned long mem_start))
@@ -2761,15 +2761,15 @@
 	if (err < 0)
 		return(err);
 
-	atafb_get_var(&disp.var, -1, GET_FB_IDX(fb_info.node));
-	atafb_set_disp(-1);
+	atafb_get_var(&disp.var, -1, &fb_info);
+	atafb_set_disp(-1, &fb_info);
 	printk("Determined %dx%d, depth %d\n",
 	       disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
 	if ((disp.var.xres != disp.var.xres_virtual) ||
 	    (disp.var.yres != disp.var.yres_virtual))
 	   printk("   virtual %dx%d\n",
 			  disp.var.xres_virtual, disp.var.yres_virtual);
-	do_install_cmap(0);
+	do_install_cmap(0, &fb_info);
 	printk("%s frame buffer device, using %dK of video memory\n",
 	       fb_info.modename, screen_len>>10);
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/ati-gt.h m68k-2.1.77/drivers/video/ati-gt.h
--- /usr/src/m68k-2.1.77/drivers/video/ati-gt.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/ati-gt.h	Fri Jan  9 01:23:54 1998
@@ -0,0 +1,203 @@
+/* the usage for the following structs vary from the gx and vt:
+and sdram and sgram gt's
+	pll registers (sdram) 6,7,11;
+	crtc_h_sync_strt_wid[3];
+	dsp1[3] (sdram,sgram,unused)
+	dsp2[3] (offset regbase+24, depends on colour mode);
+	crtc_h_tot_disp,crtc_v_tot_disp,crtc_v_sync_strt_wid,unused;
+	pll registers (sgram) 7,11;
+*/
+
+/* Register values for 1280x1024, 75Hz mode (20). no 16/32 */
+static struct aty_regvals aty_gt_reg_init_20 = {
+	{ 0x41, 0xf9, 0x04 },
+	{ 0xe02a7, 0x1401a6, 0 },
+	{ 0x260957, 0x2806d6, 0 },
+	{ 0x10006b6, 0x20006b6, 0x30006b6 },
+
+	0x9f00d2, 0x03ff0429, 0x30400, 0,
+	{ 0xb5, 0x04 }
+};
+
+#if 0
+/* Register values for 1280x960, 75Hz mode (19) */
+static struct aty_regvals aty_gt_reg_init_19 = {
+};
+#endif
+
+/* Register values for 1152x870, 75Hz mode (18) */
+static struct aty_regvals aty_gt_reg_init_18 = {
+	{ 0x41, 0xe6, 0x04 },
+	{ 0x300295, 0x300194, 0x300593 },
+	{ 0x260a1c, 0x380561, 0},
+	{ 0x1000744, 0x2000744, 0x3000744 },
+
+	0x8f00b5, 0x3650392, 0x230368, 0,
+	{ 0xe6, 0x04 }
+};
+
+/* Register values for 1024x768, 75Hz mode (17), 32 bpp untested */
+static struct aty_regvals aty_gt_reg_init_17 = {
+	{ 0x41, 0xb5, 0x04 },
+	{ 0xc0283, 0xc0182, 0xc0581 },
+	{ 0x36066d, 0x3806d6, 0},
+	{ 0xa0049e, 0x100049e, 0x200049e },
+
+	0x7f00a3, 0x2ff031f, 0x30300, 0,
+	{ 0xb8, 0x04 }
+};
+
+#if 0
+/* Register values for x, Hz mode (16) */
+static struct aty_regvals aty_gt_reg_init_16 = {
+};
+#endif
+
+/* Register values for 1024x768, 70Hz mode (15) */
+static struct aty_regvals aty_gt_reg_init_15 = {
+	{ 0x41, 0xad, 0x04 },
+	{ 0x310284, 0x310183, 0x310582 },
+	{ 0x0, 0x380727 },
+	{ 0x0 },
+	0x7f00a5, 0x2ff0325, 0x260302,
+};    
+
+/* Register values for 1024x768, 60Hz mode (14) */
+static struct aty_regvals aty_gt_reg_init_14 = {
+	{ 0x40, 0xe1, 0x14 },
+	{ 0x310284, 0x310183, 0x310582 },
+	{ 0x3607c0, 0x380840, 0x0 },
+	{ 0xa80592, 0x1000592, 0x0 },
+
+	0x7f00a7, 0x2ff0325, 0x260302, 0,
+	{ 0xe1, 0x14 }
+};  
+
+/* Register values for 832x624, 75Hz mode (13) */
+static struct aty_regvals aty_gt_reg_init_13 = {
+	{ 0x40, 0xc6, 0x14 },
+	{ 0x28026d, 0x28016c, 0x28056b },
+	{ 0x3608cf, 0x380960, 0 },
+	{ 0xb00655, 0x1000655, 0x2000655 },
+
+	0x67008f, 0x26f029a, 0x230270, 0,
+	{ 0xc6, 0x14 }
+};
+
+/* Register values for 800x600, 75Hz mode (12) */
+static struct aty_regvals aty_gt_reg_init_12 = {
+	{ 0x42, 0xe4, 0x04 },
+	{ 0xa0267, 0xa0166, 0x0a0565},
+	{ 0x360a33, 0x48056d, 0},
+	{ 0xc00755, 0x1000755, 0x02000755},
+
+	0x630083, 0x2570270, 0x30258, 0,
+	{ 0xe4, 0x4 }
+};
+
+/* Register values for 800x600, 72Hz mode (11) */
+static struct aty_regvals aty_gt_reg_init_11 = {
+	{ 0x42, 0xe6, 0x04 },
+	{ 0xf026c, 0xf016b, 0xf056a },
+	{ 0x360a1d, 0x480561, 0},
+	{ 0xc00745, 0x1000745, 0x2000745 },
+	
+	0x630081, 0x02570299, 0x6027c
+};
+
+/* Register values for 800x600, 60Hz mode (10) */
+static struct aty_regvals aty_gt_reg_init_10 = {
+	{ 0x42, 0xb8, 0x04 },
+	{ 0x10026a, 0x100169, 0x100568 },
+	{ 0x460652, 0x4806ba, 0},
+	{ 0x68048b, 0xa0048b, 0x100048b },
+
+	0x630083, 0x02570273, 0x40258, 0,
+	{ 0xb8, 0x4 }
+};
+
+/* Register values for 800x600, 56Hz mode (9) */
+static struct aty_regvals aty_gt_reg_init_9 = {
+	{ 0x42, 0xf9, 0x14 },
+	{ 0x90268, 0x90167, 0x090566 },
+	{ 0x460701, 0x480774, 0},
+	{ 0x700509, 0xa80509, 0x1000509 },
+
+	0x63007f, 0x2570270, 0x20258
+};
+
+#if 0
+/* Register values for 768x576, 50Hz mode (8) */
+static struct aty_regvals aty_gt_reg_init_8 = {
+};
+
+/* Register values for 640x870, 75Hz Full Page Display (7) */
+static struct aty_regvals aty_gt_reg_init_7 = {
+};
+#endif
+
+/* Register values for 640x480, 67Hz mode (6) */
+static struct aty_regvals aty_gt_reg_init_6 = {
+	{ 0x42, 0xd1, 0x14 },
+	{ 0x280259, 0x280158, 0x280557 },
+	{ 0x460858, 0x4808e2, 0},
+	{ 0x780600, 0xb00600, 0x1000600 },
+
+	0x4f006b, 0x1df020c, 0x2301e2, 0,
+	{ 0x8b, 0x4 }
+};
+
+/* Register values for 640x480, 60Hz mode (5) */
+static struct aty_regvals aty_gt_reg_init_5 = {
+	{ 0x43, 0xe8, 0x04 },
+	{ 0x2c0253, 0x2c0152, 0x2c0551 },
+	{ 0x460a06, 0x580555, 0},
+	{ 0x880734, 0xc00734, 0x1000734 },
+
+	0x4f0063, 0x1df020c, 0x2201e9, 0,
+	{ 0xe8, 0x04 }
+};
+
+#if 0
+/* Register values for x, Hz mode (4) */
+static struct aty_regvals aty_gt_reg_init_4 = {
+};
+
+/* Register values for x, Hz mode (3) */
+static struct aty_regvals aty_gt_reg_init_3 = {
+};
+
+/* Register values for x, Hz mode (2) */
+static struct aty_regvals aty_gt_reg_init_2 = {
+};
+
+/* Register values for x, Hz mode (1) */
+static struct aty_regvals aty_gt_reg_init_1 = {
+};
+#endif
+
+/* yikes, more data structures (dsp2)
+ * XXX kludge for sgram
+ */
+static int sgram_dsp[20][3] = {
+	{0,0,0},
+	{0,0,0},
+	{0,0,0},
+	{0,0,0},
+	{0x5203d7,0x7803d9,0xb803dd}, //5
+	{0x940666,0xe0066a,0x1700672}, //6
+	{0,0,0},
+	{0,0,0},
+	{0x88055f,0xd80563,0x170056b}, //9
+	{0x8404d9,0xb804dd,0x17004e5}, //10
+	{0x7803e2,0xb803e6,0x17003ee}, //11
+	{0x7803eb,0xb803ef,0x17003f7}, //12
+	{0xe806c5,0x17006cd,0x2e006dd}, //13
+	{0xe005f6,0x17005fe,0x2e0060e}, //14
+	{0xd8052c,0x1700534,0x2e00544}, //15
+	{0,0,0},
+	{0xb804f2,0x17004e5,0x2e0050a}, //17
+	{0xb803e6,0x17003ee,0x2e003fe}, //18
+	{0,0,0},
+	{0,0,0},
+};
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/ati-gx.h m68k-2.1.77/drivers/video/ati-gx.h
--- /usr/src/m68k-2.1.77/drivers/video/ati-gx.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/ati-gx.h	Fri Jan  9 01:23:59 1998
@@ -0,0 +1,149 @@
+#if 0		/* not filled inaty_gt_reg_init yet */
+/* Register values for 1280x1024, 75Hz mode (20) */
+static struct aty_regvals aty_gx_reg_init_20 = {
+	{ 0x10, 0x28, 0x3c },
+	{ },
+	{ }	/* pixel clock = 134.61MHz for V=74.81Hz */
+};
+
+/* Register values for 1280x960, 75Hz mode (19) */
+static struct aty_regvals aty_gx_reg_init_19 = {
+	{ 0x10, 0x28, 0x3c },
+	{ },
+	{ }	/* pixel clock = 126.01MHz for V=75.01 Hz */
+};
+
+/* Register values for 1152x870, 75Hz mode (18) */
+static struct aty_regvals aty_gx_reg_init_18 = {
+	{ 0x10, 0x28, 0x50 },
+	{ },
+	{ }	/* pixel clock = 100.33MHz for V=75.31Hz */
+};
+
+/* Register values for 1024x768, 75Hz mode (17) */
+static struct aty_regvals aty_gx_reg_init_17 = {
+	{ 0x10, 0x28, 0x50 },
+	{ },
+	{ }	/* pixel clock = 79.55MHz for V=74.50Hz */
+};
+
+/* Register values for 1024x768, 72Hz mode (15) */
+static struct aty_regvals aty_gx_reg_init_15 = {
+	{ 0x10, 0x28, 0x50 },
+	{ },
+	{ }	/* pixel clock = 78.12MHz for V=72.12Hz */
+};
+
+#endif
+
+
+/* Register values for 1280x1024, 60Hz mode (20) */
+static struct aty_regvals aty_gx_reg_init_20 = {
+   { 0, 0, 0 },
+
+    { 0x310086, 0x310084, 0x310084 },
+    { 0x3070200, 0x30e0300, 0x30e0300 },
+    { 0x2002312, 0x3002312, 0x3002312 },
+
+    0x7f00a5, 0x2ff0325, 0x260302, 0x20100000,
+    { 0x88, 0x7 }
+};     
+
+/* Register values for 1024x768, 75Hz mode (17) */
+static struct aty_regvals aty_gx_reg_init_17 = {
+    { 0, 0, 0 },
+
+    { 0xc0085, 0xc0083, 0xc0083 },
+    { 0x3070200, 0x30e0300, 0x30e0300 },
+    { 0x2002312, 0x3002312, 0x3002312 },
+
+    0x7f00a3, 0x2ff031f, 0x30300, 0x20100000,
+    { 0x41, 0x3 }
+};
+
+/* Register values for 1024x768, 72Hz mode (15) */
+static struct aty_regvals aty_gx_reg_init_15 = {
+    { 0, 0, 0 },
+
+    { 0x310086, 0x310084, 0x310084 },
+    { 0x3070200, 0x30e0300, 0x30e0300 },
+    { 0x2002312, 0x3002312, 0x3002312 },
+
+    0x7f00a5, 0x2ff0325, 0x260302, 0x20100000,
+    { 0x88, 0x7 }
+};    
+
+/* Register values for 1024x768, 60Hz mode (14) */
+static struct aty_regvals aty_gx_reg_init_14 = {
+	{ 0, 0, 0 },
+
+	{ 0x310086, 0x310084, 0x310084 },
+	{ 0x3060200, 0x30d0300, 0x30d0300 },
+	{ 0x2002312, 0x3002312, 0x3002312 },
+
+	0x7f00a7, 0x2ff0325, 0x260302, 0x20100000,
+	{ 0x6c, 0x6 }
+};  
+
+/* Register values for 832x624, 75Hz mode (13) */
+static struct aty_regvals aty_gx_reg_init_13 = {
+	{ 0x200, 0x200, 0x200 },
+
+	{ 0x28006f, 0x28006d, 0x28006c },
+	{ 0x3050200, 0x30b0300, 0x30e0600 },
+	{ 0x2002312, 0x3002312, 0x6002312 },
+
+	0x67008f, 0x26f029a, 0x230270, 0x1a100040,
+        { 0x4f, 0x05 }
+};
+
+#if 0		/* not filled in yet */
+/* Register values for 800x600, 75Hz mode (12) */
+static struct aty_regvals aty_gx_reg_init_12 = {
+	{ 0x10, 0x28, 0x50 },
+	{ },
+	{ }	/* pixel clock = 49.11MHz for V=74.40Hz */
+};
+
+/* Register values for 800x600, 72Hz mode (11) */
+static struct aty_regvals aty_gx_reg_init_11 = {
+	{ 0x10, 0x28, 0x50 },
+	{ },
+	{ }	/* pixel clock = 49.63MHz for V=71.66Hz */
+};
+
+/* Register values for 800x600, 60Hz mode (10) */
+static struct aty_regvals aty_gx_reg_init_10 = {
+	{ 0x10, 0x28, 0x50 },
+	{ },
+	{ }	/* pixel clock = 41.41MHz for V=59.78Hz */
+};
+
+/* Register values for 640x870, 75Hz Full Page Display (7) */
+static struct aty_regvals aty_gx_reg_init_7 = {
+	{ 0x10, 0x30, 0x68 },
+	{ },
+	{ }	/* pixel clock = 57.29MHz for V=75.01Hz */
+};
+#endif
+
+/* Register values for 640x480, 67Hz mode (6) */
+static struct aty_regvals aty_gx_reg_init_6 = {
+	{ 0x200, 0x200, 0x200 },
+
+	{ 0x28005b, 0x280059, 0x280058 },
+	{ 0x3040200, 0x3060300, 0x30c0600 },
+	{ 0x2002312, 0x3002312, 0x6002312 },
+
+	0x4f006b, 0x1df020c, 0x2301e2, 0x14100040,
+        { 0x35, 0x07 }
+};
+
+#if 0		/* not filled in yet */
+/* Register values for 640x480, 60Hz mode (5) */
+static struct aty_regvals aty_gx_reg_init_5 = {
+	{ 0x200, 0x200, 0x200 },
+	{ },
+        { 0x35, 0x07 }
+};
+#endif
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/ati-vt.h m68k-2.1.77/drivers/video/ati-vt.h
--- /usr/src/m68k-2.1.77/drivers/video/ati-vt.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/ati-vt.h	Fri Jan  9 01:24:05 1998
@@ -0,0 +1,147 @@
+/* Register values for 1280x1024, 60Hz mode (20) */
+static struct aty_regvals aty_vt_reg_init_20 = {
+  { 0, 0, 0 },
+     
+  { 0x002e02a7, 0x002e02a7, 0 },
+  { 0x03070200, 0x03070200, 0 },
+  { 0x0a00cb22, 0x0b00cb23, 0 },
+     
+    0x009f00d2, 0x03ff0429, 0x00030400, 0x28000000,
+  { 0x00, 0xaa }
+};
+
+/* Register values for 1280x960, 75Hz mode (19) */
+static struct aty_regvals aty_vt_reg_init_19 = {
+  { 0, 0, 0 },
+  { 0x003202a3, 0x003201a2, 0 },
+  { 0x030b0200, 0x030b0300, 0 },
+  { 0x0a00cb22, 0x0b00cb23, 0 },
+
+    0x009f00d1, 0x03bf03e7, 0x000303c0, 0x28000000,
+  { 0x00, 0xc6 }
+};
+
+/* Register values for 1152x870, 75Hz mode (18) */
+static struct aty_regvals aty_vt_reg_init_18 = {
+  { 0, 0, 0 },
+     
+  { 0x00300295, 0x00300194, 0 },
+  { 0x03080200, 0x03080300, 0 },
+  { 0x0a00cb21, 0x0b00cb22, 0 },
+     
+    0x008f00b5, 0x03650392, 0x00230368, 0x24000000,
+  { 0x00, 0x9d }
+};
+
+/* Register values for 1024x768, 75Hz mode (17) */
+static struct aty_regvals aty_vt_reg_init_17 = {
+  { 0, 0, 0 },
+
+  { 0x002c0283, 0x002c0182, 0 },
+  { 0x03080200, 0x03080300, 0 },
+  { 0x0a00cb21, 0x0b00cb22, 0 },
+     
+    0x007f00a3, 0x02ff031f, 0x00030300, 0x20000000,
+  { 0x01, 0xf7 }
+};
+
+/* Register values for 1024x768, 70Hz mode (15) */
+static struct aty_regvals aty_vt_reg_init_15 = {
+  { 0, 0, 0 },
+  { 0x00310284, 0x00310183, 0 },
+  { 0x03080200, 0x03080300, 0 },
+  { 0x0a00cb21, 0x0b00cb22, 0 },
+
+    0x007f00a5, 0x02ff0325, 0x00260302, 0x20000000,
+  { 0x01, 0xeb }
+};    
+
+/* Register values for 1024x768, 60Hz mode (14) */
+static struct aty_regvals aty_vt_reg_init_14 = {
+  { 0, 0, 0 },
+     
+  { 0x00310284, 0x00310183, 0x00310582 }, /* 32 bit 0x00310582 */
+  { 0x03080200, 0x03080300, 0x03070600 }, /* 32 bit 0x03070600 */
+  { 0x0a00cb21, 0x0b00cb22, 0x0e00cb23 },
+    
+    0x007f00a7, 0x02ff0325, 0x00260302, 0x20000000,
+  { 0x01, 0xcc }
+};  
+
+/* Register values for 832x624, 75Hz mode (13) */
+static struct aty_regvals aty_vt_reg_init_13 = {
+  { 0, 0, 0 },
+
+  { 0x0028026d, 0x0028016c, 0x0028056b },
+  { 0x03080200, 0x03070300, 0x03090600 },
+  { 0x0a00cb21, 0x0b00cb21, 0x0e00cb22 },
+
+    0x0067008f, 0x026f029a, 0x00230270, 0x1a000000,
+  { 0x01, 0xb4 }
+};
+
+/* Register values for 800x600, 75Hz mode (12) */
+static struct aty_regvals aty_vt_reg_init_12 = {
+  { 0, 0, 0 },
+     
+  { 0x002a0267, 0x002a0166, 0x002a0565 },
+  { 0x03040200, 0x03060300, 0x03070600 },
+  { 0x0a00cb21, 0x0b00cb21, 0x0e00cb22 },
+     
+    0x00630083, 0x02570270, 0x00030258, 0x19000000,
+  { 0x01, 0x9c }
+};
+
+/* Register values for 800x600, 72Hz mode (11) */
+static struct aty_regvals aty_vt_reg_init_11 = {
+  { 0, 0, 0 },
+     
+  { 0x002f026c, 0x002f016b, 0x002f056a },
+  { 0x03050200, 0x03070300, 0x03090600 },
+  { 0x0a00cb21, 0x0b00cb21, 0x0e00cb22 },
+
+    0x00630081, 0x02570299, 0x0006027c, 0x19000000,
+  { 0x01, 0x9d }
+};
+
+/* Register values for 800x600, 60Hz mode (10) */
+static struct aty_regvals aty_vt_reg_init_10 = {
+  { 0, 0, 0 },
+     
+  { 0x0030026a, 0x00300169, 0x00300568 },
+  { 0x03050200, 0x03070300, 0x03090600 },
+  { 0x0a00cb21, 0x0b00cb21, 0x0e00cb22 },
+     
+    0x00630083, 0x02570273, 0x00040258, 0x19000000,
+  { 0x02, 0xfb }
+};
+
+/* Register values for 640x480, 67Hz mode (6) */
+static struct aty_regvals aty_vt_reg_init_6 = {
+  { 0, 0, 0 },
+      
+  { 0x00280259, 0x00280158, 0x00280557 },
+  { 0x03050200, 0x03070300, 0x030a0600 },
+  { 0x0a00cb21, 0x0b00cb21, 0x0e00cb22 },
+      
+    0x004f006b, 0x01df020c, 0x002301e2, 0x14000000,
+  { 0x02, 0xbe }
+};
+
+/* Register values for 640x480, 60Hz mode (5) */
+static struct aty_regvals aty_vt_reg_init_5 = {
+  { 0, 0, 0 },
+      
+  { 0x002c0253, 0x002c0152, 0x002c0551 },
+  { 0x03050200, 0x03070300, 0x03090600 },
+  { 0x0a00cb21, 0x0b00cb21, 0x0e00cb22 },
+
+    0x004f0063, 0x01df020c, 0x002201e9, 0x14000000,
+  { 0x02, 0x9e }
+};
+                               /*     8 bit       15 bit      32 bit   */
+static int vt_mem_cntl[3][3] = { { 0x0A00CB21, 0x0B00CB21, 0x0E00CB21 },  /* 1 MB VRAM */
+                                 { 0x0A00CB22, 0x0B00CB22, 0x0E00CB22 },  /* 2 MB VRAM */
+                                { 0x0200053B, 0x0300053B, 0x0600053B }   /* 4 M B VRAM */
+ };
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/aty.h m68k-2.1.77/drivers/video/aty.h
--- /usr/src/m68k-2.1.77/drivers/video/aty.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/aty.h	Fri Jan  9 01:24:09 1998
@@ -0,0 +1,908 @@
+/*
+ * Exported procedures for the ATI/mach64 display driver on PowerMacs.
+ *
+ * Copyright (C) 1997 Michael AK Tesch
+ *  written with much help from Jon Howell
+ *
+ * Updated for 3D RAGE PRO by Geert Uytterhoeven
+ *	
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * most of the rest of this file comes from ATI sample code
+ */
+#ifndef REGMACH64_H
+#define REGMACH64_H
+
+/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
+
+#define CRTC_H_TOTAL_DISP	0x0000	/* Dword offset 0_00 */
+#define CRTC_H_SYNC_STRT_WID	0x0004	/* Dword offset 0_01 */
+#define CRTC_H_SYNC_STRT	0x0004
+#define CRTC_H_SYNC_DLY		0x0005
+#define CRTC_H_SYNC_WID		0x0006
+
+#define CRTC_V_TOTAL_DISP	0x0008	/* Dword offset 0_02 */
+#define CRTC_V_TOTAL		0x0008
+#define CRTC_V_DISP		0x000A
+#define CRTC_V_SYNC_STRT_WID	0x000C	/* Dword offset 0_03 */
+#define CRTC_V_SYNC_STRT	0x000C
+#define CRTC_V_SYNC_WID		0x000E
+
+#define CRTC_VLINE_CRNT_VLINE	0x0010	/* Dword offset 0_04 */
+#define CRTC_OFF_PITCH		0x0014	/* Dword offset 0_05 */
+#define CRTC_OFFSET		0x0014
+#define CRTC_PITCH		0x0016
+
+#define CRTC_INT_CNTL		0x0018	/* Dword offset 0_06 */
+#define CRTC_GEN_CNTL		0x001C	/* Dword offset 0_07 */
+#define CRTC_PIX_WIDTH		0x001D
+#define CRTC_FIFO		0x001E
+#define CRTC_EXT_DISP		0x001F
+
+#define DSP_CONFIG		0x0020	/* Dword offset 0_08 */
+#define DSP_ON_OFF		0x0024	/* Dword offset 0_09 */
+#define TIMER_CONFIG		0x0028	/* Dword offset 0_0A */
+#define MEM_BUF_CNTL		0x002C	/* Dword offset 0_0B */
+#define MEM_ADDR_CONFIG		0x0034	/* Dword offset 0_0D */
+
+#define CRT_TRAP		0x0038	/* Dword offset 0_0E */
+
+#define I2C_CNTL_0		0x003C	/* Dword offset 0_0F */
+
+#define OVR_CLR			0x0040	/* Dword offset 0_10 */
+#define OVR_WID_LEFT_RIGHT	0x0044	/* Dword offset 0_11 */
+#define OVR_WID_TOP_BOTTOM	0x0048	/* Dword offset 0_12 */
+
+#define VGA_DSP_CONFIG		0x004C	/* Dword offset 0_13 */
+#define VGA_DSP_ON_OFF		0x0050	/* Dword offset 0_14 */
+
+#define CUR_CLR0		0x0060	/* Dword offset 0_18 */
+#define CUR_CLR1		0x0064	/* Dword offset 0_19 */
+#define CUR_OFFSET		0x0068	/* Dword offset 0_1A */
+#define CUR_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
+#define CUR_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
+
+#define GP_IO			0x0078	/* Dword offset 0_1E */
+
+#define HW_DEBUG		0x007C	/* Dword offset 0_1F */
+
+#define SCRATCH_REG0		0x0080	/* Dword offset 0_20 */
+#define SCRATCH_REG1		0x0084	/* Dword offset 0_21 */
+
+#define CLOCK_CNTL		0x0090	/* Dword offset 0_24 */
+#define CLOCK_SEL_CNTL		0x0090	/* Dword offset 0_24 */
+
+#define CONFIG_STAT1		0x0094	/* Dword offset 0_25 */
+#define CONFIG_STAT2		0x0098	/* Dword offset 0_26 */
+
+#define BUS_CNTL		0x00A0	/* Dword offset 0_28 */
+
+#define EXT_MEM_CNTL		0x00AC	/* Dword offset 0_2B */
+#define MEM_CNTL		0x00B0	/* Dword offset 0_2C */
+
+#define MEM_VGA_WP_SEL		0x00B4	/* Dword offset 0_2D */
+#define MEM_VGA_RP_SEL		0x00B8	/* Dword offset 0_2E */
+
+#define DAC_REGS		0x00C0	/* Dword offset 0_30 */
+#define DAC_W_INDEX		0x00C0	/* Dword offset 0_30 */
+#define DAC_DATA		0x00C1	/* Dword offset 0_30 */
+#define DAC_MASK		0x00C2	/* Dword offset 0_30 */
+#define DAC_R_INDEX		0x00C3	/* Dword offset 0_30 */
+#define DAC_CNTL		0x00C4	/* Dword offset 0_31 */
+
+#define EXT_DAC_REGS		0x00C8	/* Dword offset 0_32 */
+
+#define GEN_TEST_CNTL		0x00D0	/* Dword offset 0_34 */
+
+#define CUSTOM_MACRO_CNTL	0x00D4	/* Dword offset 0_35 */
+
+#define CONFIG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
+#define CONFIG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
+#define CONFIG_STAT0		0x00E4	/* Dword offset 0_39 */
+#define CRC_SIG			0x00E8	/* Dword offset 0_3A */
+
+
+/* GUI MEMORY MAPPED Registers */
+
+#define DST_OFF_PITCH		0x0100	/* Dword offset 0_40 */
+#define DST_X			0x0104	/* Dword offset 0_41 */
+#define DST_Y			0x0108	/* Dword offset 0_42 */
+#define DST_Y_X			0x010C	/* Dword offset 0_43 */
+#define DST_WIDTH		0x0110	/* Dword offset 0_44 */
+#define DST_HEIGHT		0x0114	/* Dword offset 0_45 */
+#define DST_HEIGHT_WIDTH	0x0118	/* Dword offset 0_46 */
+#define DST_X_WIDTH		0x011C	/* Dword offset 0_47 */
+#define DST_BRES_LNTH		0x0120	/* Dword offset 0_48 */
+#define DST_BRES_ERR		0x0124	/* Dword offset 0_49 */
+#define DST_BRES_INC		0x0128	/* Dword offset 0_4A */
+#define DST_BRES_DEC		0x012C	/* Dword offset 0_4B */
+#define DST_CNTL		0x0134	/* Dword offset 0_4C */
+#define DST_Y_X__ALIAS__	0x0138	/* Dword offset 0_4D */
+#define TRAIL_BRES_ERR		0x013C	/* Dword offset 0_4E */
+#define TRAIL_BRES_INC		0x0140	/* Dword offset 0_4F */
+#define TRAIL_BRES_DEC		0x0144	/* Dword offset 0_50 */
+#define LEAD_BRES_LNTH		0x0148	/* Dword offset 0_51 */
+#define Z_OFF_PITCH		0x014C	/* Dword offset 0_52 */
+#define Z_CNTL			0x0150	/* Dword offset 0_53 */
+#define ALPHA_TST_CNTL		0x0154	/* Dword offset 0_54 */
+#define SECONDARY_STW_EXP	0x0158	/* Dword offset 0_56 */
+#define SECONDARY_S_X_INC	0x015C	/* Dword offset 0_57 */
+#define SECONDARY_S_Y_INC	0x0160	/* Dword offset 0_58 */
+#define SECONDARY_S_START	0x0164	/* Dword offset 0_59 */
+#define SECONDARY_W_X_INC	0x0168	/* Dword offset 0_5A */
+#define SECONDARY_W_Y_INC	0x016C	/* Dword offset 0_5B */
+#define SECONDARY_W_START	0x0170	/* Dword offset 0_5C */
+#define SECONDARY_T_X_INC	0x0174	/* Dword offset 0_5D */
+#define SECONDARY_T_Y_INC	0x0178	/* Dword offset 0_5E */
+#define SECONDARY_T_START	0x017C	/* Dword offset 0_5F */
+
+#define SRC_OFF_PITCH		0x0180	/* Dword offset 0_60 */
+#define SRC_X			0x0184	/* Dword offset 0_61 */
+#define SRC_Y			0x0188	/* Dword offset 0_62 */
+#define SRC_Y_X			0x018C	/* Dword offset 0_63 */
+#define SRC_WIDTH1		0x0190	/* Dword offset 0_64 */
+#define SRC_HEIGHT1		0x0194	/* Dword offset 0_65 */
+#define SRC_HEIGHT1_WIDTH1	0x0198	/* Dword offset 0_66 */
+#define SRC_X_START		0x019C	/* Dword offset 0_67 */
+#define SRC_Y_START		0x01A0	/* Dword offset 0_68 */
+#define SRC_Y_X_START		0x01A4	/* Dword offset 0_69 */
+#define SRC_WIDTH2		0x01A8	/* Dword offset 0_6A */
+#define SRC_HEIGHT2		0x01AC	/* Dword offset 0_6B */
+#define SRC_HEIGHT2_WIDTH2	0x01B0	/* Dword offset 0_6C */
+#define SRC_CNTL		0x01B4	/* Dword offset 0_6D */
+
+#define SCALE_OFF		0x01C0	/* Dword offset 0_70 */
+#define SECONDARY_SCALE_OFF	0x01C4	/* Dword offset 0_71 */
+
+#define TEX_0_OFF		0x01C0	/* Dword offset 0_70 */
+#define TEX_1_OFF		0x01C4	/* Dword offset 0_71 */
+#define TEX_2_OFF		0x01C8	/* Dword offset 0_72 */
+#define TEX_3_OFF		0x01CC	/* Dword offset 0_73 */
+#define TEX_4_OFF		0x01D0	/* Dword offset 0_74 */
+#define TEX_5_OFF		0x01D4	/* Dword offset 0_75 */
+#define TEX_6_OFF		0x01D8	/* Dword offset 0_76 */
+#define TEX_7_OFF		0x01DC	/* Dword offset 0_77 */
+
+#define SCALE_WIDTH		0x01DC	/* Dword offset 0_77 */
+#define SCALE_HEIGHT		0x01E0	/* Dword offset 0_78 */
+
+#define TEX_8_OFF		0x01E0	/* Dword offset 0_78 */
+#define TEX_9_OFF		0x01E4	/* Dword offset 0_79 */
+#define TEX_10_OFF		0x01E8	/* Dword offset 0_7A */
+#define S_Y_INC			0x01EC	/* Dword offset 0_7B */
+
+#define SCALE_PITCH		0x01EC	/* Dword offset 0_7B */
+#define SCALE_X_INC		0x01F0	/* Dword offset 0_7C */
+
+#define RED_X_INC		0x01F0	/* Dword offset 0_7C */
+#define GREEN_X_INC		0x01F4	/* Dword offset 0_7D */
+
+#define SCALE_Y_INC		0x01F4	/* Dword offset 0_7D */
+#define SCALE_VACC		0x01F8	/* Dword offset 0_7E */
+#define SCALE_3D_CNTL		0x01FC	/* Dword offset 0_7F */
+
+#define HOST_DATA0		0x0200	/* Dword offset 0_80 */
+#define HOST_DATA1		0x0204	/* Dword offset 0_81 */
+#define HOST_DATA2		0x0208	/* Dword offset 0_82 */
+#define HOST_DATA3		0x020C	/* Dword offset 0_83 */
+#define HOST_DATA4		0x0210	/* Dword offset 0_84 */
+#define HOST_DATA5		0x0214	/* Dword offset 0_85 */
+#define HOST_DATA6		0x0218	/* Dword offset 0_86 */
+#define HOST_DATA7		0x021C	/* Dword offset 0_87 */
+#define HOST_DATA8		0x0220	/* Dword offset 0_88 */
+#define HOST_DATA9		0x0224	/* Dword offset 0_89 */
+#define HOST_DATAA		0x0228	/* Dword offset 0_8A */
+#define HOST_DATAB		0x022C	/* Dword offset 0_8B */
+#define HOST_DATAC		0x0230	/* Dword offset 0_8C */
+#define HOST_DATAD		0x0234	/* Dword offset 0_8D */
+#define HOST_DATAE		0x0238	/* Dword offset 0_8E */
+#define HOST_DATAF		0x023C	/* Dword offset 0_8F */
+#define HOST_CNTL		0x0240	/* Dword offset 0_90 */
+
+#define BM_HOSTDATA		0x0244	/* Dword offset 0_91 */
+#define BM_ADDR			0x0248	/* Dword offset 0_92 */
+#define BM_DATA			0x0248	/* Dword offset 0_92 */
+#define BM_GUI_TABLE_CMD	0x024C	/* Dword offset 0_93 */
+
+#define PAT_REG0		0x0280	/* Dword offset 0_A0 */
+#define PAT_REG1		0x0284	/* Dword offset 0_A1 */
+#define PAT_CNTL		0x0288	/* Dword offset 0_A2 */
+
+#define SC_LEFT			0x02A0	/* Dword offset 0_A8 */
+#define SC_RIGHT		0x02A4	/* Dword offset 0_A9 */
+#define SC_LEFT_RIGHT		0x02A8	/* Dword offset 0_AA */
+#define SC_TOP			0x02AC	/* Dword offset 0_AB */
+#define SC_BOTTOM		0x02B0	/* Dword offset 0_AC */
+#define SC_TOP_BOTTOM		0x02B4	/* Dword offset 0_AD */
+
+#define DP_BKGD_CLR		0x02C0	/* Dword offset 0_B0 */
+#define DP_FOG_CLR		0x02C4	/* Dword offset 0_B1 */
+#define DP_FRGD_CLR		0x02C4	/* Dword offset 0_B1 */
+#define DP_WRITE_MSK		0x02C8	/* Dword offset 0_B2 */
+#define DP_CHAIN_MSK		0x02CC	/* Dword offset 0_B3 */
+#define DP_PIX_WIDTH		0x02D0	/* Dword offset 0_B4 */
+#define DP_MIX			0x02D4	/* Dword offset 0_B5 */
+#define DP_SRC			0x02D8	/* Dword offset 0_B6 */
+#define DP_FRGD_CLR_MIX		0x02DC	/* Dword offset 0_B7 */
+#define DP_FRGD_BLGD_CLR	0x02E0	/* Dword offset 0_B8 */
+
+#define DST_X_Y			0x02E8	/* Dword offset 0_BA */
+#define DST_WIDTH_HEIGHT	0x02EC	/* Dword offset 0_BB */
+#define USR_DST_PICTH		0x02F0	/* Dword offset 0_BC */
+#define DP_SET_GUI_ENGINE2	0x02F8	/* Dword offset 0_BE */
+#define DP_SET_GUI_ENGINE	0x02FC	/* Dword offset 0_BF */
+
+#define CLR_CMP_CLR		0x0300	/* Dword offset 0_C0 */
+#define CLR_CMP_MSK		0x0304	/* Dword offset 0_C1 */
+#define CLR_CMP_CNTL		0x0308	/* Dword offset 0_C2 */
+
+#define FIFO_STAT		0x0310	/* Dword offset 0_C4 */
+
+#define CONTEXT_MASK		0x0320	/* Dword offset 0_C8 */
+#define CONTEXT_LOAD_CNTL	0x032C	/* Dword offset 0_CB */
+
+#define GUI_TRAJ_CNTL		0x0330	/* Dword offset 0_CC */
+#define GUI_STAT		0x0338	/* Dword offset 0_CE */
+
+#define TEX_PALETTE_INDEX	0x0340	/* Dword offset 0_D0 */
+#define STW_EXP			0x0344	/* Dword offset 0_D1 */
+#define LOG_MAX_INC		0x0348	/* Dword offset 0_D2 */
+#define S_X_INC			0x034C	/* Dword offset 0_D3 */
+#define S_Y_INC__ALIAS__	0x0350	/* Dword offset 0_D4 */
+
+#define SCALE_PITCH__ALIAS__	0x0350	/* Dword offset 0_D4 */
+
+#define S_START			0x0354	/* Dword offset 0_D5 */
+#define W_X_INC			0x0358	/* Dword offset 0_D6 */
+#define W_Y_INC			0x035C	/* Dword offset 0_D7 */
+#define W_START			0x0360	/* Dword offset 0_D8 */
+#define T_X_INC			0x0364	/* Dword offset 0_D9 */
+#define T_Y_INC			0x0368	/* Dword offset 0_DA */
+
+#define SECONDARY_SCALE_PITCH	0x0368	/* Dword offset 0_DA */
+
+#define T_START			0x036C	/* Dword offset 0_DB */
+#define TEX_SIZE_PITCH		0x0370	/* Dword offset 0_DC */
+#define TEX_CNTL		0x0374	/* Dword offset 0_DD */
+#define SECONDARY_TEX_OFFSET	0x0378	/* Dword offset 0_DE */
+#define TEX_PALETTE		0x037C	/* Dword offset 0_DF */
+
+#define SCALE_PITCH_BOTH	0x0380	/* Dword offset 0_E0 */
+#define SECONDARY_SCALE_OFF_ACC	0x0384	/* Dword offset 0_E1 */
+#define SCALE_OFF_ACC		0x0388	/* Dword offset 0_E2 */
+#define SCALE_DST_Y_X		0x038C	/* Dword offset 0_E3 */
+
+#define COMPOSITE_SHADOW_ID	0x0398	/* Dword offset 0_E6 */
+
+#define SECONDARY_SCALE_X_INC	0x039C	/* Dword offset 0_E7 */
+
+#define SPECULAR_RED_X_INC	0x039C	/* Dword offset 0_E7 */
+#define SPECULAR_RED_Y_INC	0x03A0	/* Dword offset 0_E8 */
+#define SPECULAR_RED_START	0x03A4	/* Dword offset 0_E9 */
+
+#define SECONDARY_SCALE_HACC	0x03A4	/* Dword offset 0_E9 */
+
+#define SPECULAR_GREEN_X_INC	0x03A8	/* Dword offset 0_EA */
+#define SPECULAR_GREEN_Y_INC	0x03AC	/* Dword offset 0_EB */
+#define SPECULAR_GREEN_START	0x03B0	/* Dword offset 0_EC */
+#define SPECULAR_BLUE_X_INC	0x03B4	/* Dword offset 0_ED */
+#define SPECULAR_BLUE_Y_INC	0x03B8	/* Dword offset 0_EE */
+#define SPECULAR_BLUE_START	0x03BC	/* Dword offset 0_EF */
+
+#define SCALE_X_INC__ALIAS__	0x03C0	/* Dword offset 0_F0 */
+
+#define RED_X_INC__ALIAS__	0x03C0	/* Dword offset 0_F0 */
+#define RED_Y_INC		0x03C4	/* Dword offset 0_F1 */
+#define RED_START		0x03C8	/* Dword offset 0_F2 */
+
+#define SCALE_HACC		0x03C8	/* Dword offset 0_F2 */
+#define SCALE_Y_INC__ALIAS__	0x03CC	/* Dword offset 0_F3 */
+
+#define GREEN_X_INC__ALIAS__	0x03CC	/* Dword offset 0_F3 */
+#define GREEN_Y_INC		0x03D0	/* Dword offset 0_F4 */
+
+#define SECONDARY_SCALE_Y_INC	0x03D0	/* Dword offset 0_F4 */
+#define SECONDARY_SCALE_VACC	0x03D4	/* Dword offset 0_F5 */
+
+#define GREEN_START		0x03D4	/* Dword offset 0_F5 */
+#define BLUE_X_INC		0x03D8	/* Dword offset 0_F6 */
+#define BLUE_Y_INC		0x03DC	/* Dword offset 0_F7 */
+#define BLUE_START		0x03E0	/* Dword offset 0_F8 */
+#define Z_X_INC			0x03E4	/* Dword offset 0_F9 */
+#define Z_Y_INC			0x03E8	/* Dword offset 0_FA */
+#define Z_START			0x03EC	/* Dword offset 0_FB */
+#define ALPHA_X_INC		0x03F0	/* Dword offset 0_FC */
+#define FOG_X_INC		0x03F0	/* Dword offset 0_FC */
+#define ALPHA_Y_INC		0x03F4	/* Dword offset 0_FD */
+#define FOG_Y_INC		0x03F4	/* Dword offset 0_FD */
+#define ALPHA_START		0x03F8	/* Dword offset 0_FE */
+#define FOG_START		0x03F8	/* Dword offset 0_FE */
+
+#define OVERLAY_Y_X_START		0x0400	/* Dword offset 1_00 */
+#define OVERLAY_Y_X_END			0x0404	/* Dword offset 1_01 */
+#define OVERLAY_VIDEO_KEY_CLR		0x0408	/* Dword offset 1_02 */
+#define OVERLAY_VIDEO_KEY_MSK		0x040C	/* Dword offset 1_03 */
+#define OVERLAY_GRAPHICS_KEY_CLR	0x0410	/* Dword offset 1_04 */
+#define OVERLAY_GRAPHICS_KEY_MSK	0x0414	/* Dword offset 1_05 */
+#define OVERLAY_KEY_CNTL		0x0418	/* Dword offset 1_06 */
+
+#define OVERLAY_SCALE_INC	0x0420	/* Dword offset 1_08 */
+#define OVERLAY_SCALE_CNTL	0x0424	/* Dword offset 1_09 */
+#define SCALER_HEIGHT_WIDTH	0x0428	/* Dword offset 1_0A */
+#define SCALER_TEST		0x042C	/* Dword offset 1_0B */
+#define SCALER_BUF0_OFFSET	0x0434	/* Dword offset 1_0D */
+#define SCALER_BUF1_OFFSET	0x0438	/* Dword offset 1_0E */
+#define SCALE_BUF_PITCH		0x043C	/* Dword offset 1_0F */
+
+#define CAPTURE_START_END	0x0440	/* Dword offset 1_10 */
+#define CAPTURE_X_WIDTH		0x0444	/* Dword offset 1_11 */
+#define VIDEO_FORMAT		0x0448	/* Dword offset 1_12 */
+#define VBI_START_END		0x044C	/* Dword offset 1_13 */
+#define CAPTURE_CONFIG		0x0450	/* Dword offset 1_14 */
+#define TRIG_CNTL		0x0454	/* Dword offset 1_15 */
+
+#define OVERLAY_EXCLUSIVE_HORZ	0x0458	/* Dword offset 1_16 */
+#define OVERLAY_EXCLUSIVE_VERT	0x045C	/* Dword offset 1_17 */
+
+#define VAL_WIDTH		0x0460	/* Dword offset 1_18 */
+#define CAPTURE_DEBUG		0x0464	/* Dword offset 1_19 */
+#define VIDEO_SYNC_TEST		0x0468	/* Dword offset 1_1A */
+
+#define SNAPSHOT_VH_COUNTS	0x0470	/* Dword offset 1_1C */
+#define SNAPSHOT_F_COUNT	0x0474	/* Dword offset 1_1D */
+#define N_VIF_COUNT		0x0478	/* Dword offset 1_1E */
+#define SNAPSHOT_VIF_COUNT	0x047C	/* Dword offset 1_1F */
+
+#define CAPTURE_BUF0_OFFSET	0x0480	/* Dword offset 1_20 */
+#define CAPTURE_BUF1_OFFSET	0x0484	/* Dword offset 1_21 */
+#define CAPTURE_BUF_PITCH	0x0488	/* Dword offset 1_22 */
+
+#define MPP_CONFIG		0x04C0	/* Dword offset 1_30 */
+#define MPP_STROBE_SEQ		0x04C4	/* Dword offset 1_31 */
+#define MPP_ADDR		0x04C8	/* Dword offset 1_32 */
+#define MPP_DATA		0x04CC	/* Dword offset 1_33 */
+#define TVO_CNTL		0x0500	/* Dword offset 1_40 */
+
+#define CRT_HORZ_VERT_LOAD	0x0544	/* Dword offset 1_51 */
+
+#define AGP_BASE		0x0548	/* Dword offset 1_52 */
+#define AGP_CNTL		0x054C	/* Dword offset 1_53 */
+
+#define SCALER_COLOUR_CNTL	0x0550	/* Dword offset 1_54 */
+#define SCALER_H_COEFF0		0x0554	/* Dword offset 1_55 */
+#define SCALER_H_COEFF1		0x0558	/* Dword offset 1_56 */
+#define SCALER_H_COEFF2		0x055C	/* Dword offset 1_57 */
+#define SCALER_H_COEFF3		0x0560	/* Dword offset 1_58 */
+#define SCALER_H_COEFF4		0x0564	/* Dword offset 1_59 */
+
+#define GUI_CNTL		0x0578	/* Dword offset 1_5E */
+
+#define BM_FRAME_BUF_OFFSET	0x0580	/* Dword offset 1_60 */
+#define BM_SYSTEM_MEM_ADDR	0x0584	/* Dword offset 1_61 */
+#define BM_COMMAND		0x0588	/* Dword offset 1_62 */
+#define BM_STATUS		0x058C	/* Dword offset 1_63 */
+#define BM_GUI_TABLE		0x05B8	/* Dword offset 1_6E */
+#define BM_SYSTEM_TABLE		0x05BC	/* Dword offset 1_6F */
+
+#define SCALER_BUF0_OFFSET_U	0x05D4	/* Dword offset 1_75 */
+#define SCALER_BUF0_OFFSET_V	0x05D8	/* Dword offset 1_76 */
+#define SCALER_BUF1_OFFSET_U	0x05DC	/* Dword offset 1_77 */
+#define SCALER_BUF1_OFFSET_V	0x05E0	/* Dword offset 1_78 */
+
+#define VERTEX_1_S		0x0640	/* Dword offset 1_90 */
+#define VERTEX_1_T		0x0644	/* Dword offset 1_91 */
+#define VERTEX_1_W		0x0648	/* Dword offset 1_92 */
+#define VERTEX_1_SPEC_ARGB	0x064C	/* Dword offset 1_93 */
+#define VERTEX_1_Z		0x0650	/* Dword offset 1_94 */
+#define VERTEX_1_ARGB		0x0654	/* Dword offset 1_95 */
+#define VERTEX_1_X_Y		0x0658	/* Dword offset 1_96 */
+#define ONE_OVER_AREA		0x065C	/* Dword offset 1_97 */
+#define VERTEX_2_S		0x0660	/* Dword offset 1_98 */
+#define VERTEX_2_T		0x0664	/* Dword offset 1_99 */
+#define VERTEX_2_W		0x0668	/* Dword offset 1_9A */
+#define VERTEX_2_SPEC_ARGB	0x066C	/* Dword offset 1_9B */
+#define VERTEX_2_Z		0x0670	/* Dword offset 1_9C */
+#define VERTEX_2_ARGB		0x0674	/* Dword offset 1_9D */
+#define VERTEX_2_X_Y		0x0678	/* Dword offset 1_9E */
+#define ONE_OVER_AREA		0x065C	/* Dword offset 1_9F */
+#define VERTEX_3_S		0x0680	/* Dword offset 1_A0 */
+#define VERTEX_3_T		0x0684	/* Dword offset 1_A1 */
+#define VERTEX_3_W		0x0688	/* Dword offset 1_A2 */
+#define VERTEX_3_SPEC_ARGB	0x068C	/* Dword offset 1_A3 */
+#define VERTEX_3_Z		0x0690	/* Dword offset 1_A4 */
+#define VERTEX_3_ARGB		0x0694	/* Dword offset 1_A5 */
+#define VERTEX_3_X_Y		0x0698	/* Dword offset 1_A6 */
+#define ONE_OVER_AREA		0x065C	/* Dword offset 1_A7 */
+#define VERTEX_1_S		0x0640	/* Dword offset 1_AB */
+#define VERTEX_1_T		0x0644	/* Dword offset 1_AC */
+#define VERTEX_1_W		0x0648	/* Dword offset 1_AD */
+#define VERTEX_2_S		0x0660	/* Dword offset 1_AE */
+#define VERTEX_2_T		0x0664	/* Dword offset 1_AF */
+#define VERTEX_2_W		0x0668	/* Dword offset 1_B0 */
+#define VERTEX_3_SECONDARY_S	0x06C0	/* Dword offset 1_B0 */
+#define VERTEX_3_S		0x0680	/* Dword offset 1_B1 */
+#define VERTEX_3_SECONDARY_T	0x06C4	/* Dword offset 1_B1 */
+#define VERTEX_3_T		0x0684	/* Dword offset 1_B2 */
+#define VERTEX_3_SECONDARY_W	0x06C8	/* Dword offset 1_B2 */
+#define VERTEX_3_W		0x0688	/* Dword offset 1_B3 */
+#define VERTEX_1_SPEC_ARGB	0x064C	/* Dword offset 1_B4 */
+#define VERTEX_2_SPEC_ARGB	0x066C	/* Dword offset 1_B5 */
+#define VERTEX_3_SPEC_ARGB	0x068C	/* Dword offset 1_B6 */
+#define VERTEX_1_Z		0x0650	/* Dword offset 1_B7 */
+#define VERTEX_2_Z		0x0670	/* Dword offset 1_B8 */
+#define VERTEX_3_Z		0x0690	/* Dword offset 1_B9 */
+#define VERTEX_1_ARGB		0x0654	/* Dword offset 1_BA */
+#define VERTEX_2_ARGB		0x0674	/* Dword offset 1_BB */
+#define VERTEX_3_ARGB		0x0694	/* Dword offset 1_BC */
+#define VERTEX_1_X_Y		0x0658	/* Dword offset 1_BD */
+#define VERTEX_2_X_Y		0x0678	/* Dword offset 1_BE */
+#define VERTEX_3_X_Y		0x0698	/* Dword offset 1_BF */
+#define ONE_OVER_AREA_UC	0x0700	/* Dword offset 1_C0 */
+#define SETUP_CNTL		0x0704	/* Dword offset 1_C1 */
+#define VERTEX_1_SECONDARY_S	0x0728	/* Dword offset 1_CA */
+#define VERTEX_1_SECONDARY_T	0x072C	/* Dword offset 1_CB */
+#define VERTEX_1_SECONDARY_W	0x0730	/* Dword offset 1_CC */
+#define VERTEX_2_SECONDARY_S	0x0734	/* Dword offset 1_CD */
+#define VERTEX_2_SECONDARY_T	0x0738	/* Dword offset 1_CE */
+#define VERTEX_2_SECONDARY_W	0x073C	/* Dword offset 1_CF */
+
+
+/* CRTC control values (mostly CRTC_GEN_CNTL) */
+
+#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_BLANK		0x00000040
+
+#define CRTC_PIX_WIDTH_MASK	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
+
+/* DSP_CONFIG register constants */
+#define DSP_XCLKS_PER_QW	0x00003fff
+#define DSP_LOOP_LATENCY	0x000f0000
+#define DSP_PRECISION		0x00700000
+
+/* DSP_ON_OFF register constants */
+#define DSP_OFF			0x000007ff
+#define DSP_ON			0x07ff0000
+
+/* 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
+
+#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
+
+/* Wait until "v" queue entries are free */
+#define aty_WaitQueue(v)    { while ((aty_ld_le32(FIFO_STAT) & 0xffff) > \
+			 ((unsigned short)(0x8000 >> (v)))); }
+
+/* Wait until GP is idle and queue is empty */
+#define aty_WaitIdleEmpty() { aty_WaitQueue(16); \
+			  while ((aty_ld_le32(GUI_STAT) & 1) != 0); }
+
+#define SKIP_2(_v) ((((_v)<<1)&0xfff8)|((_v)&0x3)|(((_v)&0x80)>>5))
+
+#define MACH64_BIT_BLT(_srcx, _srcy, _dstx, _dsty, _w, _h, _dir) \
+{ \
+    aty_WaitQueue(5); \
+    aty_st_le32(SRC_Y_X, (((_srcx) << 16) | ((_srcy) & 0x0000ffff))); \
+    aty_st_le32(SRC_WIDTH1, (_w)); \
+    aty_st_le32(DST_CNTL, (_dir)); \
+    aty_st_le32(DST_Y_X, (((_dstx) << 16) | ((_dsty) & 0x0000ffff))); \
+    aty_st_le32(DST_HEIGHT_WIDTH, (((_w) << 16) | ((_h) & 0x0000ffff))); \
+}
+#endif /* REGMACH64_H */
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/atyfb.c m68k-2.1.77/drivers/video/atyfb.c
--- /usr/src/m68k-2.1.77/drivers/video/atyfb.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/atyfb.c	Fri Jan  9 01:24:15 1998
@@ -0,0 +1,1539 @@
+/*
+ *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI/Open Firmware
+ *
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This driver is partly based on the PowerMac console driver:
+ *
+ *	Copyright (C) 1996 Paul Mackerras
+ *
+ *  and on the PowerMac ATI/mach64 display driver:
+ *
+ *	Copyright (C) 1997 Michael AK Tesch
+ *
+ *	      with work by Jon Howell
+ *			   Harry AC Eaton
+ *			   Anthony Tong <atong@uiuc.edu>
+ *
+ *  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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/bios32.h>
+#include <linux/nvram.h>
+#include <linux/vc_ioctl.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include "aty.h"
+
+
+static int currcon = 0;
+static struct display fb_disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+
+/* hack to tell fbcon-cfb{16,32} the colormap */
+extern u16 cfb16_cmap[16];
+extern u32 cfb32_cmap[16];
+
+static char atyfb_name[16] = "ATY Mach64";
+
+struct atyfb_par {
+    int video_mode;
+    int color_mode;
+};
+
+
+/*
+ * Video mode values.
+ * These are supposed to be the same as the values that
+ * Apple uses in MacOS.
+ */
+#define VMODE_NVRAM		0	/* use value stored in nvram */
+#define VMODE_512_384_60I	1	/* 512x384, 60Hz interlaced (NTSC) */
+#define VMODE_512_384_60	2	/* 512x384, 60Hz */
+#define VMODE_640_480_50I	3	/* 640x480, 50Hz interlaced (PAL) */
+#define VMODE_640_480_60I	4	/* 640x480, 60Hz interlaced (NTSC) */
+#define VMODE_640_480_60	5	/* 640x480, 60Hz (VGA) */
+#define VMODE_640_480_67	6	/* 640x480, 67Hz */
+#define VMODE_640_870_75P	7	/* 640x870, 75Hz (portrait) */
+#define VMODE_768_576_50I	8	/* 768x576, 50Hz (PAL full frame) */
+#define VMODE_800_600_56	9	/* 800x600, 56Hz */
+#define VMODE_800_600_60	10	/* 800x600, 60Hz */
+#define VMODE_800_600_72	11	/* 800x600, 72Hz */
+#define VMODE_800_600_75	12	/* 800x600, 75Hz */
+#define VMODE_832_624_75	13	/* 832x624, 75Hz */
+#define VMODE_1024_768_60	14	/* 1024x768, 60Hz */
+#define VMODE_1024_768_70	15	/* 1024x768, 70Hz (or 72Hz?) */
+#define VMODE_1024_768_75V	16	/* 1024x768, 75Hz (VESA) */
+#define VMODE_1024_768_75	17	/* 1024x768, 75Hz */
+#define VMODE_1152_870_75	18	/* 1152x870, 75Hz */
+#define VMODE_1280_960_75	19	/* 1280x960, 75Hz */
+#define VMODE_1280_1024_75	20	/* 1280x1024, 75Hz */
+#define VMODE_MAX		20
+#define VMODE_CHOOSE		99	/* choose based on monitor sense */
+
+/*
+ * Color mode values, used to select number of bits/pixel.
+ */
+#define CMODE_NVRAM		-1	/* use value stored in nvram */
+#define CMODE_8			0	/* 8 bits/pixel */
+#define CMODE_16		1	/* 16 (actually 15) bits/pixel */
+#define CMODE_32		2	/* 32 (actually 24) bits/pixel */
+
+
+static struct atyfb_par default_par = { VMODE_NVRAM, CMODE_NVRAM };
+static struct atyfb_par current_par;
+
+
+/*
+ * Addresses in NVRAM where video mode and pixel size are stored.
+ */
+#define NV_VMODE	0x140f
+#define NV_CMODE	0x1410
+
+/*
+ * Horizontal and vertical resolution information.
+ */
+extern struct vmode_attr {
+	int	hres;
+	int	vres;
+	int	vfreq;
+	int	interlaced;
+} vmode_attrs[VMODE_MAX];
+
+
+/*
+ * Horizontal and vertical resolution for each mode.
+ */
+static struct vmode_attr vmode_attrs[VMODE_MAX] = {
+    {512, 384, 60, 1},
+    {512, 384, 60},
+    {640, 480, 50, 1},
+    {640, 480, 60, 1},
+    {640, 480, 60},
+    {640, 480, 67},
+    {640, 870, 75},
+    {768, 576, 50, 1},
+    {800, 600, 56},
+    {800, 600, 60},
+    {800, 600, 72},
+    {800, 600, 75},
+    {832, 624, 75},
+    {1024, 768, 60},
+    {1024, 768, 72},
+    {1024, 768, 75},
+    {1024, 768, 75},
+    {1152, 870, 75},
+    {1280, 960, 75},
+    {1280, 1024, 75}
+};
+
+
+/*
+ * We get a sense value from the monitor and use it to choose
+ * what resolution to use.  This structure maps sense values
+ * to display mode values (which determine the resolution and
+ * frequencies).
+ */
+static struct mon_map {
+	int	sense;
+	int	vmode;
+} monitor_map [] = {
+	{0x000, VMODE_1280_1024_75},	/* 21" RGB */
+	{0x114, VMODE_640_870_75P},	/* Portrait Monochrome */
+	{0x221, VMODE_512_384_60},	/* 12" RGB*/
+	{0x331, VMODE_1280_1024_75},	/* 21" RGB (Radius) */
+	{0x334, VMODE_1280_1024_75},	/* 21" mono (Radius) */
+	{0x335, VMODE_1280_1024_75},	/* 21" mono */
+	{0x40A, VMODE_640_480_60I},	/* NTSC */
+	{0x51E, VMODE_640_870_75P},	/* Portrait RGB */
+	{0x603, VMODE_832_624_75},	/* 12"-16" multiscan */
+	{0x60b, VMODE_1024_768_70},	/* 13"-19" multiscan */
+	{0x623, VMODE_1152_870_75},	/* 13"-21" multiscan */
+	{0x62b, VMODE_640_480_67},	/* 13"/14" RGB */
+	{0x700, VMODE_640_480_50I},	/* PAL */
+	{0x714, VMODE_640_480_60I},	/* NTSC */
+	{0x717, VMODE_800_600_75},	/* VGA */
+	{0x72d, VMODE_832_624_75},	/* 16" RGB (Goldfish) */
+	{0x730, VMODE_768_576_50I},	/* PAL (Alternate) */
+	{0x73a, VMODE_1152_870_75},	/* 3rd party 19" */
+	{-1,	VMODE_640_480_60},	/* catch-all, must be last */
+};
+
+static int map_monitor_sense(int sense)
+{
+	struct mon_map *map;
+
+	for (map = monitor_map; map->sense >= 0; ++map)
+		if (map->sense == sense)
+			break;
+	return map->vmode;
+}
+
+struct aty_cmap_regs {
+    unsigned char windex;
+    unsigned char lut;
+    unsigned char mask;
+    unsigned char rindex;
+    unsigned char cntl;
+};
+
+typedef struct aty_regvals {
+    int offset[3];		/* first pixel address */
+
+    int crtc_h_sync_strt_wid[3];	/* depth dependant */
+    int crtc_gen_cntl[3];
+    int mem_cntl[3];
+
+    int crtc_h_tot_disp;	/* mode dependant */
+    int crtc_v_tot_disp;
+    int crtc_v_sync_strt_wid;
+    int crtc_off_pitch;
+
+    unsigned char clock_val[2];	/* vals for 20 and 21 */
+} aty_regvals;
+
+struct rage_regvals {
+    int h_total, h_sync_start, h_sync_width;
+    int v_total, v_sync_start, v_sync_width;
+    int h_sync_neg, v_sync_neg;
+};
+
+static int aty_vram_reqd(const struct atyfb_par *par);
+static struct aty_regvals *get_aty_struct(const struct atyfb_par *par);
+
+static unsigned char *frame_buffer;
+
+static int total_vram;		/* total amount of video memory, bytes */
+static int chip_type;		/* what chip type was detected */
+
+static unsigned long ati_regbase;
+static struct aty_cmap_regs *aty_cmap_regs;
+
+#include "ati-gx.h"
+#include "ati-gt.h"
+#include "ati-vt.h"
+
+static struct aty_regvals *aty_gt_reg_init[20] = {
+	NULL, NULL, NULL, NULL,
+	&aty_gt_reg_init_5,
+	&aty_gt_reg_init_6,
+	NULL, NULL,
+	&aty_gt_reg_init_9,
+	&aty_gt_reg_init_10,
+	&aty_gt_reg_init_11,
+	&aty_gt_reg_init_12,
+	&aty_gt_reg_init_13,
+	&aty_gt_reg_init_14,
+	&aty_gt_reg_init_15,
+	NULL,
+	&aty_gt_reg_init_17,
+	&aty_gt_reg_init_18,
+	NULL,
+	&aty_gt_reg_init_20
+};
+
+static struct aty_regvals *aty_gx_reg_init[20] = {
+	NULL, NULL, NULL, NULL,
+	&aty_gx_reg_init_6,
+	&aty_gx_reg_init_6,
+	NULL, NULL, NULL, NULL, NULL, NULL,
+	&aty_gx_reg_init_13,
+	&aty_gx_reg_init_14,
+	&aty_gx_reg_init_15,
+	NULL,
+	&aty_gx_reg_init_17,
+	NULL, NULL,
+	&aty_gx_reg_init_20
+};
+
+static struct aty_regvals *aty_vt_reg_init[21] = {
+	NULL, NULL, NULL, NULL,
+	&aty_vt_reg_init_5,
+	&aty_vt_reg_init_6,
+	NULL, NULL, NULL,
+	&aty_vt_reg_init_10,
+	&aty_vt_reg_init_11,
+	&aty_vt_reg_init_12,
+	&aty_vt_reg_init_13,
+	&aty_vt_reg_init_14,
+	&aty_vt_reg_init_15,
+	NULL,
+	&aty_vt_reg_init_17,
+	&aty_vt_reg_init_18,
+	&aty_vt_reg_init_19,
+	&aty_vt_reg_init_20
+};
+
+    /*
+     *  Interface used by the world
+     */
+
+unsigned long atyfb_init(unsigned long mem_start);
+void atyfb_setup(char *options, int *ints);
+
+static int atyfb_open(struct fb_info *info);
+static int atyfb_release(struct fb_info *info);
+static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info);
+static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info);
+static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info);
+static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info);
+static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg, int con, struct fb_info *info);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+extern struct vc_mode display_info;
+extern int (*console_setmode_ptr)(struct vc_mode *, int);
+static int atyfb_console_setmode(struct vc_mode *, int);
+#endif
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+static int atyfbcon_switch(int con, struct fb_info *info);
+static int atyfbcon_updatevar(int con, struct fb_info *info);
+static void atyfbcon_blank(int blank, struct fb_info *info);
+
+
+    /*
+     *  Internal routines
+     */
+
+static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+			 u_int *transp, struct fb_info *info);
+static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			 u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+
+static struct fb_ops atyfb_ops = {
+    atyfb_open, atyfb_release, atyfb_get_fix, atyfb_get_var, atyfb_set_var,
+    atyfb_get_cmap, atyfb_set_cmap, atyfb_pan_display, atyfb_ioctl
+};
+
+
+static inline int aty_vram_reqd(const struct atyfb_par *par)
+{
+    return vmode_attrs[par->video_mode-1].vres *
+	(vmode_attrs[par->video_mode-1].hres << par->color_mode);
+}
+
+extern inline unsigned aty_ld_le32(volatile unsigned long addr)
+{
+    register unsigned long temp = ati_regbase,val;
+
+    asm("lwbrx %0,%1,%2": "=r"(val):"r"(addr), "r"(temp));
+    return val;
+}
+
+extern inline void aty_st_le32(volatile unsigned long addr, unsigned val)
+{
+    register unsigned long temp = ati_regbase;
+    asm("stwbrx %0,%1,%2": : "r"(val), "r"(addr), "r"(temp):"memory");
+}
+
+extern inline unsigned char aty_ld_8(volatile unsigned long addr)
+{
+    return *(char *) ((long) addr + (long) ati_regbase);
+}
+
+extern inline void aty_st_8(volatile unsigned long addr, unsigned char val)
+{
+    *(unsigned char *) (addr + (unsigned long) ati_regbase) = val;
+}
+
+static void aty_st_514(int offset, char val)
+{
+    aty_WaitQueue(5);
+    aty_st_8(DAC_CNTL, 1);
+    aty_st_8(DAC_W_INDEX, offset & 0xff);	/* right addr byte */
+    aty_st_8(DAC_DATA, (offset >> 8) & 0xff);	/* left addr byte */
+    eieio();
+    aty_st_8(DAC_MASK, val);
+    eieio();
+    aty_st_8(DAC_CNTL, 0);
+}
+
+static void aty_st_pll(int offset, char val)
+{
+    aty_WaitQueue(3);
+    aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN);	/* write addr byte */
+    eieio();
+    aty_st_8(CLOCK_CNTL + 2, val);	/* write the register value */
+    eieio();
+    aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN);
+}
+
+static struct aty_regvals *get_aty_struct(const struct atyfb_par *par)
+{
+    int v = par->video_mode - 1;
+
+    switch (chip_type) {
+	case MACH64_GT_ID:
+	    return aty_gt_reg_init[v];
+	    break;
+	case MACH64_VT_ID:
+	    return aty_vt_reg_init[v];
+	    break;
+	default: /* default to MACH64_GX_ID */
+	    return aty_gx_reg_init[v];
+	    break;
+    }
+}
+
+static int read_aty_sense(void)
+{
+    int sense, i;
+
+    aty_st_le32(GP_IO, 0x31003100);	/* drive outputs high */
+    __delay(200);
+    aty_st_le32(GP_IO, 0);		/* turn off outputs */
+    __delay(2000);
+    i = aty_ld_le32(GP_IO);		/* get primary sense value */
+    sense = ((i & 0x3000) >> 3) | (i & 0x100);
+
+    /* drive each sense line low in turn and collect the other 2 */
+    aty_st_le32(GP_IO, 0x20000000);	/* drive A low */
+    __delay(2000);
+    i = aty_ld_le32(GP_IO);
+    sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
+    aty_st_le32(GP_IO, 0x20002000);	/* drive A high again */
+    __delay(200);
+
+    aty_st_le32(GP_IO, 0x10000000);	/* drive B low */
+    __delay(2000);
+    i = aty_ld_le32(GP_IO);
+    sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
+    aty_st_le32(GP_IO, 0x10001000);	/* drive B high again */
+    __delay(200);
+
+    aty_st_le32(GP_IO, 0x01000000);	/* drive C low */
+    __delay(2000);
+    sense |= (aty_ld_le32(GP_IO) & 0x3000) >> 12;
+    aty_st_le32(GP_IO, 0);		/* turn off outputs */
+
+    return sense;
+}
+
+static void RGB514_Program(int cmode)
+{
+    typedef struct {
+	char pixel_dly;
+	char misc2_cntl;
+	char pixel_rep;
+	char pixel_cntl_index;
+	char pixel_cntl_v1;
+    } RGB514_DAC_Table;
+
+    static RGB514_DAC_Table RGB514DAC_Tab[8] = {
+	{0, 0x41, 0x03, 0x71, 0x45},	// 8bpp
+	{0, 0x45, 0x04, 0x0c, 0x01},	// 555
+	{0, 0x45, 0x06, 0x0e, 0x00},	// XRGB
+    };
+    RGB514_DAC_Table *pDacProgTab;
+
+    pDacProgTab = &RGB514DAC_Tab[cmode];
+
+    aty_st_514(0x90, 0x00);
+    aty_st_514(0x04, pDacProgTab->pixel_dly);
+    aty_st_514(0x05, 0x00);
+
+    aty_st_514(0x2, 0x1);
+    aty_st_514(0x71, pDacProgTab->misc2_cntl);
+    aty_st_514(0x0a, pDacProgTab->pixel_rep);
+
+    aty_st_514(pDacProgTab->pixel_cntl_index, pDacProgTab->pixel_cntl_v1);
+}
+
+/* handle video scrollback; offset is in # of scanlines */
+static void ati_set_origin(const struct atyfb_par *par, unsigned short lines)
+{
+	int x = (vmode_attrs[par->video_mode-1].hres + 7) & 0xfff8;
+	int reg;
+
+	reg = ((x >> 3) << 22) |	/* calculate pitch */
+	  ((lines * x * (1<<par->color_mode)) >> 3);
+
+	aty_st_le32(CRTC_OFF_PITCH, reg);
+	aty_st_le32(DST_OFF_PITCH, reg);
+	aty_st_le32(SRC_OFF_PITCH, reg);
+}
+
+static void atyfb_set_par(struct atyfb_par *par)
+{
+    int i, hres;
+    struct aty_regvals *init = get_aty_struct(par);
+    int vram_type = aty_ld_le32(CONFIG_STAT0) & 7;
+
+    if (init == 0)	/* paranoia, shouldn't get here */
+	panic("aty: display mode %d not supported", par->video_mode);
+
+    current_par = *par;
+    hres = vmode_attrs[par->video_mode-1].hres;
+
+    /* clear FIFO errors */
+    aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_HOST_ERR_ACK
+			  | BUS_FIFO_ERR_ACK);
+
+    /* Reset engine */
+    i = aty_ld_le32(GEN_TEST_CNTL);
+    aty_st_le32(GEN_TEST_CNTL, i & ~GUI_ENGINE_ENABLE);
+    eieio();
+    aty_WaitIdleEmpty();
+    aty_st_le32(GEN_TEST_CNTL, i | GUI_ENGINE_ENABLE);
+    aty_WaitIdleEmpty();
+
+    if ( chip_type != MACH64_GT_ID ) {
+	i = aty_ld_le32(CRTC_GEN_CNTL);
+	aty_st_le32(CRTC_GEN_CNTL, i | CRTC_EXT_DISP_EN);
+    }
+
+    if ( chip_type == MACH64_GX_ID ) {
+	i = aty_ld_le32(GEN_TEST_CNTL);
+	aty_st_le32(GEN_TEST_CNTL, i | GEN_OVR_OUTPUT_EN );
+    }
+
+    switch (chip_type) {
+	case MACH64_VT_ID:
+	    aty_st_pll(PLL_MACRO_CNTL, 0xb5);
+	    aty_st_pll(PLL_REF_DIV, 0x2d);
+	    aty_st_pll(PLL_GEN_CNTL, 0x14);
+	    aty_st_pll(MCLK_FB_DIV, 0xbd);
+	    aty_st_pll(PLL_VCLK_CNTL, 0x0b);
+	    aty_st_pll(VCLK_POST_DIV, init->clock_val[0]);
+	    aty_st_pll(VCLK0_FB_DIV, init->clock_val[1]);
+	    aty_st_pll(VCLK1_FB_DIV, 0xd6);
+	    aty_st_pll(VCLK2_FB_DIV, 0xee);
+	    aty_st_pll(VCLK3_FB_DIV, 0xf8);
+	    aty_st_pll(PLL_XCLK_CNTL, 0x0);
+	    aty_st_pll(PLL_TEST_CTRL, 0x0);
+	    aty_st_pll(PLL_TEST_COUNT, 0x0);
+	    break;
+	case MACH64_GT_ID:
+	    if (vram_type == 5) {
+		aty_st_pll(0, 0xcd);
+		aty_st_pll(PLL_MACRO_CNTL,
+			   par->video_mode >= VMODE_1024_768_60 ? 0xd3: 0xd5);
+		aty_st_pll(PLL_REF_DIV, 0x21);
+		aty_st_pll(PLL_GEN_CNTL, 0x44);
+		aty_st_pll(MCLK_FB_DIV, 0xe8);
+		aty_st_pll(PLL_VCLK_CNTL, 0x03);
+		aty_st_pll(VCLK_POST_DIV, init->offset[0]);
+		aty_st_pll(VCLK0_FB_DIV, init->offset[1]);
+		aty_st_pll(VCLK1_FB_DIV, 0x8e);
+		aty_st_pll(VCLK2_FB_DIV, 0x9e);
+		aty_st_pll(VCLK3_FB_DIV, 0xc6);
+		aty_st_pll(PLL_XCLK_CNTL, init->offset[2]);
+		aty_st_pll(12, 0xa6);
+		aty_st_pll(13, 0x1b);
+	    } else {
+		aty_st_pll(PLL_MACRO_CNTL, 0xd5);
+		aty_st_pll(PLL_REF_DIV, 0x21);
+		aty_st_pll(PLL_GEN_CNTL, 0xc4);
+		aty_st_pll(MCLK_FB_DIV, 0xda);
+		aty_st_pll(PLL_VCLK_CNTL, 0x03);
+		/* offset actually holds clock values */
+		aty_st_pll(VCLK_POST_DIV, init->offset[0]);
+		aty_st_pll(VCLK0_FB_DIV, init->offset[1]);
+		aty_st_pll(VCLK1_FB_DIV, 0x8e);
+		aty_st_pll(VCLK2_FB_DIV, 0x9e);
+		aty_st_pll(VCLK3_FB_DIV, 0xc6);
+		aty_st_pll(PLL_TEST_CTRL, 0x0);
+		aty_st_pll(PLL_XCLK_CNTL, init->offset[2]);
+		aty_st_pll(12, 0xa0);
+		aty_st_pll(13, 0x1b);
+	    }
+	    break;
+	default:
+	    RGB514_Program(par->color_mode);
+	    aty_WaitIdleEmpty();
+	    aty_st_514(0x06, 0x02);
+	    aty_st_514(0x10, 0x01);
+	    aty_st_514(0x70, 0x01);
+	    aty_st_514(0x8f, 0x1f);
+	    aty_st_514(0x03, 0x00);
+	    aty_st_514(0x05, 0x00);
+	    aty_st_514(0x20, init->clock_val[0]);
+	    aty_st_514(0x21, init->clock_val[1]);
+	    break;
+    }
+
+    aty_ld_8(DAC_REGS);	/* clear counter */
+    aty_WaitIdleEmpty();
+
+    aty_st_le32(CRTC_H_TOTAL_DISP, init->crtc_h_tot_disp);
+    aty_st_le32(CRTC_H_SYNC_STRT_WID, init->crtc_h_sync_strt_wid[par->color_mode]);
+    aty_st_le32(CRTC_V_TOTAL_DISP, init->crtc_v_tot_disp);
+    aty_st_le32(CRTC_V_SYNC_STRT_WID, init->crtc_v_sync_strt_wid);
+
+    aty_st_8(CLOCK_CNTL, 0);
+    aty_st_8(CLOCK_CNTL, CLOCK_STROBE);
+
+    aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0);
+
+    if (chip_type == MACH64_GT_ID) {
+	aty_st_le32(BUS_CNTL, 0x7b23a040);
+
+	/* we calculate this so we can use a scrollback buffer.
+	 * this should theoretically work with other ati's
+	 * OFF_PITCH == (((hres + 7) & 0xfff8) >> 3) << 22
+	 */
+	ati_set_origin(par, 0);
+
+	/* need to set DSP values !! assume sdram */
+	i = init->crtc_gen_cntl[0] - (0x100000 * par->color_mode);
+	if ( vram_type == 5 )
+	    i = init->crtc_gen_cntl[1] - (0x100000 * par->color_mode);
+	aty_st_le32(DSP_CONFIG, i);
+
+	i = aty_ld_le32(MEM_CNTL) & MEM_SIZE_ALIAS;
+	if ( vram_type == 5 ) {
+	    i |= ((1 * par->color_mode) << 26) | 0x4215b0;
+	    aty_st_le32(DSP_ON_OFF,sgram_dsp[par->video_mode-1][par->color_mode]);
+
+	//aty_st_le32(CLOCK_CNTL,8192);
+	} else {
+	    i |= ((1 * par->color_mode) << 26) | 0x300090;
+	    aty_st_le32(DSP_ON_OFF, init->mem_cntl[par->color_mode]);
+	}
+
+	aty_st_le32(MEM_CNTL, i);
+	aty_st_le32(EXT_MEM_CNTL, 0x5000001);
+
+	/* if (total_vram > 0x400000)	
+	    i |= 0x538; this not been verified on > 4Megs!! */
+    } else {
+	aty_st_le32(CRTC_OFF_PITCH, init->crtc_off_pitch);
+
+/* The magic constant below translates into:
+* 5   = No RDY delay, 1 wait st for mem write, increment during burst transfer
+* 9   = DAC access delayed, 1 wait state for DAC
+* 0   = Disables interupts for FIFO errors
+* e   = Allows FIFO to generate 14 wait states before generating error
+* 1   = DAC snooping disabled, ROM disabled
+* 0   = ROM page at 0 (disabled so doesn't matter)
+* f   = 15 ROM wait states (disabled so doesn't matter)
+* f   = 15 BUS wait states (I'm not sure this applies to PCI bus types)
+* at some point it would be good to experiment with bench marks to see if
+* we can gain some speed by fooling with the wait states etc.
+*/
+	if (chip_type == MACH64_VT_ID)
+	    aty_st_le32(BUS_CNTL, 0x680000f9);
+	else
+	    aty_st_le32(BUS_CNTL, 0x590e10ff);
+
+	switch (total_vram) {
+	    case 0x00100000:
+		aty_st_le32(MEM_CNTL, vt_mem_cntl[0][par->color_mode]);
+		break;
+	    case 0x00200000:
+		aty_st_le32(MEM_CNTL, vt_mem_cntl[1][par->color_mode]);
+		break;
+	    case 0x00400000:
+		aty_st_le32(MEM_CNTL, vt_mem_cntl[2][par->color_mode]);
+		break;
+	    default:
+		i = aty_ld_le32(MEM_CNTL) & 0x000F;
+		aty_st_le32(MEM_CNTL,
+			    (init->mem_cntl[par->color_mode] & 0xFFFFFFF0) | i);
+	}
+    }
+/* These magic constants are harder to figure out
+* on the vt chipset bit 2 set makes the screen brighter
+* and bit 15 makes the screen black! But nothing else
+* seems to matter for the vt DAC_CNTL
+*/
+    switch (chip_type) {
+	case MACH64_GT_ID:
+	    i = 0x86010102;
+	    break;
+	case MACH64_VT_ID:
+	    i = 0x87010184;
+	    break;
+	default:
+	    i = 0x47012100;
+	    break;
+    }
+
+    aty_st_le32(DAC_CNTL, i);
+    aty_st_8(DAC_MASK, 0xff);
+
+    switch (par->color_mode) {
+	case CMODE_16:
+	    i = CRTC_PIX_WIDTH_15BPP; break;
+	/*case CMODE_24: */
+	case CMODE_32:
+	    i = CRTC_PIX_WIDTH_32BPP; break;
+	case CMODE_8:
+	default:
+	    i = CRTC_PIX_WIDTH_8BPP; break;
+    }
+
+    if (chip_type != MACH64_GT_ID) {
+	aty_st_le32(CRTC_INT_CNTL, 0x00000002);
+	aty_st_le32(GEN_TEST_CNTL, GUI_ENGINE_ENABLE | BLOCK_WRITE_ENABLE);	/* gui_en block_en */
+	i |= init->crtc_gen_cntl[par->color_mode];
+    }
+    /* Gentlemen, start your crtc engine */
+    aty_st_le32(CRTC_GEN_CNTL, CRTC_EXT_DISP_EN | CRTC_EXT_EN | i);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+    display_info.height = vmode_attrs[par->video_mode-1].vres;
+    display_info.width = vmode_attrs[par->video_mode-1].hres;
+    display_info.depth = 8<<par->color_mode;
+    display_info.pitch = vmode_attrs[par->video_mode-1].hres<<par->color_mode;
+    display_info.mode = par->video_mode;
+    strcpy(display_info.name, atyfb_name);
+    display_info.fb_address = ((chip_type != MACH64_GT_ID) ?
+	(unsigned long) frame_buffer + init->offset[par->color_mode] :
+	(unsigned long) frame_buffer);
+    display_info.cmap_adr_address = (unsigned long) &aty_cmap_regs->windex;
+    display_info.cmap_data_address = (unsigned long) &aty_cmap_regs->lut;
+    display_info.disp_reg_address = ati_regbase;
+#endif /* CONFIG_FB_COMPAT_XPMAC) */
+}
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int atyfb_open(struct fb_info *info)
+
+{
+    /*
+     *  Nothing, only a usage count for the moment
+     */
+
+    MOD_INC_USE_COUNT;
+    return(0);
+}
+
+static int atyfb_release(struct fb_info *info)
+{
+    MOD_DEC_USE_COUNT;
+    return(0);
+}
+
+
+static int encode_fix(struct fb_fix_screeninfo *fix,
+		       const struct atyfb_par *par)
+{
+    struct aty_regvals *init;
+
+    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+    strcpy(fix->id, atyfb_name);
+    init = get_aty_struct(par);
+    fix->smem_start = (char *)
+	((chip_type != MACH64_GT_ID) ?
+	    (unsigned long) frame_buffer + init->offset[par->color_mode] :
+	    (unsigned long) frame_buffer);
+    fix->smem_len = (unsigned long)total_vram-4096;	/* last page is MMIO */
+    fix->mmio_start = (char *)((unsigned long)ati_regbase & ~0xfff);
+    fix->mmio_len = 4096;
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    fix->type_aux = 0;
+    fix->line_length = vmode_attrs[par->video_mode-1].hres<<par->color_mode;
+    fix->visual = par->color_mode == CMODE_8 ? FB_VISUAL_PSEUDOCOLOR
+					     : FB_VISUAL_TRUECOLOR;
+    fix->ywrapstep = 0;
+    fix->xpanstep = 0;
+    fix->ypanstep = 0;
+
+    return 0;
+}
+
+
+static int decode_var(struct fb_var_screeninfo *var,
+		      struct atyfb_par *par)
+{
+    int xres = var->xres;
+    int yres = var->yres;
+    int bpp = var->bits_per_pixel;
+    struct aty_regvals *init;
+
+    /* This should support more video modes */
+
+    /* No virtual screen yet */
+    if (var->xres_virtual > xres || var->yres_virtual > yres)
+	return -EINVAL;
+
+    if (xres <= 512 && yres <= 384)
+	par->video_mode = VMODE_512_384_60;	/* 512x384, 60Hz */
+    else if (xres <= 640 && yres <= 480)
+	par->video_mode = VMODE_640_480_67;	/* 640x480, 67Hz */
+    else if (xres <= 640 && yres <= 870)
+	par->video_mode = VMODE_640_870_75P;	/* 640x870, 75Hz (portrait) */
+    else if (xres <= 768 && yres <= 576)
+	par->video_mode = VMODE_768_576_50I;	/* 768x576, 50Hz (PAL full frame) */
+    else if (xres <= 800 && yres <= 600)
+	par->video_mode = VMODE_800_600_75;	/* 800x600, 75Hz */
+    else if (xres <= 832 && yres <= 624)
+	par->video_mode = VMODE_832_624_75;	/* 832x624, 75Hz */
+    else if (xres <= 1024 && yres <= 768)
+	par->video_mode = VMODE_1024_768_75;	/* 1024x768, 75Hz */
+    else if (xres <= 1152 && yres <= 870)
+	par->video_mode = VMODE_1152_870_75;	/* 1152x870, 75Hz */
+    else if (xres <= 1280 && yres <= 960)
+	par->video_mode = VMODE_1280_960_75;	/* 1280x960, 75Hz */
+    else if (xres <= 1280 && yres <= 1024)
+	par->video_mode = VMODE_1280_1024_75;	/* 1280x1024, 75Hz */
+    else
+	return -EINVAL;
+
+    if (bpp <= 8)
+	par->color_mode = CMODE_8;
+    else if (bpp <= 16)
+	par->color_mode = CMODE_16;
+    else if (bpp <= 32)
+	par->color_mode = CMODE_32;
+    else
+	return -EINVAL;
+
+    if (aty_vram_reqd(par) > total_vram)
+	return -EINVAL;
+
+    /* Check if we know about the wanted video mode */
+    init = get_aty_struct(par);
+    if (init == NULL || init->crtc_h_sync_strt_wid[par->color_mode] == 0 ||
+	(chip_type != MACH64_GT_ID &&
+	 init->crtc_gen_cntl[par->color_mode] == 0) ||
+	(chip_type == MACH64_GT_ID && (aty_ld_le32(CONFIG_STAT0) & 7) == 5 &&
+	 init->crtc_gen_cntl[1] == 0))
+	return -EINVAL;
+
+    return 0;
+}
+
+static int encode_var(struct fb_var_screeninfo *var,
+		      const struct atyfb_par *par)
+{
+    memset(var, 0, sizeof(struct fb_var_screeninfo));
+
+    var->xres = var->xres_virtual = vmode_attrs[par->video_mode-1].hres;
+    var->yres = var->yres_virtual = vmode_attrs[par->video_mode-1].vres;
+    var->xoffset = 0;
+    var->yoffset = 0;
+    var->grayscale = 0;
+    switch (par->color_mode) {
+	case CMODE_8:
+	    var->bits_per_pixel = 8;
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 0;
+	    var->green.length = 8;
+	    var->blue.offset = 0;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case CMODE_16:	/* RGB 555 */
+	    var->bits_per_pixel = 16;
+	    var->red.offset = 10;
+	    var->red.length = 5;
+	    var->green.offset = 5;
+	    var->green.length = 5;
+	    var->blue.offset = 0;
+	    var->blue.length = 5;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+	case CMODE_32:	/* RGB 888 */
+	    var->bits_per_pixel = 32;
+	    var->red.offset = 0;
+	    var->red.length = 8;
+	    var->green.offset = 8;
+	    var->green.length = 8;
+	    var->blue.offset = 16;
+	    var->blue.length = 8;
+	    var->transp.offset = 0;
+	    var->transp.length = 0;
+	    break;
+    }
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+    var->nonstd = 0;
+    var->activate = 0;
+    var->height = -1;
+    var->width = -1;
+    var->accel = /* FB_ACCEL_ATY */ 0;
+    var->vmode = FB_VMODE_NONINTERLACED;
+    var->left_margin = var->right_margin = 64;	/* guesses */
+    var->upper_margin = var->lower_margin = 32;
+    var->hsync_len = 64;
+    var->vsync_len = 2;
+
+    /* no long long support in the kernel :-( */
+    /* this splittig trick will work if xres > 232 */
+    var->pixclock = 1000000000/
+	(var->left_margin+var->xres+var->right_margin+var->hsync_len);
+    var->pixclock *= 1000;
+    var->pixclock /= vmode_attrs[par->video_mode-1].vfreq*
+	 (var->upper_margin+var->yres+var->lower_margin+var->vsync_len);
+    var->sync = 0;
+
+    return 0;
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
+{
+    struct atyfb_par par;
+
+    if (con == -1)
+	par = default_par;
+    else
+	decode_var(&fb_display[con].var, &par);
+    encode_fix(fix, &par);
+    return 0;
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+    if (con == -1)
+	encode_var(var, &default_par);
+    else
+	*var=fb_display[con].var;
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+    struct atyfb_par par;
+    struct display *display;
+    int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+    int err;
+    int activate = var->activate;
+
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &fb_disp;	/* used during initialization */
+
+    if ((err = decode_var(var, &par)))
+	return err;
+
+    encode_var(var, &par);
+
+    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	oldxres = display->var.xres;
+	oldyres = display->var.yres;
+	oldvxres = display->var.xres_virtual;
+	oldvyres = display->var.yres_virtual;
+	oldbpp = display->var.bits_per_pixel;
+	display->var = *var;
+	if (oldxres != var->xres || oldyres != var->yres ||
+	    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+	    oldbpp != var->bits_per_pixel) {
+	    struct fb_fix_screeninfo fix;
+
+	    encode_fix(&fix, &par);
+	    display->screen_base = (u_char *)fix.smem_start;
+	    display->visual = fix.visual;
+	    display->type = fix.type;
+	    display->type_aux = fix.type_aux;
+	    display->ypanstep = fix.ypanstep;
+	    display->ywrapstep = fix.ywrapstep;
+	    display->line_length = fix.line_length;
+	    display->can_soft_blank = 1;
+	    display->inverse = 0;
+	    if (fb_info.changevar)
+		(*fb_info.changevar)(con);
+	}
+	if (con == currcon)
+	    atyfb_set_par(&par);
+	if (oldbpp != var->bits_per_pixel) {
+	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+		return err;
+	    do_install_cmap(con, info);
+	}
+    }
+
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info)
+{
+    if (var->xoffset || var->yoffset)
+	return -EINVAL;
+    else
+	return 0;
+}
+
+    /*
+     *  Get the Colormap
+     */
+
+static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, atyfb_getcolreg,
+			   info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+				 1<<fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console? */
+	return fb_set_cmap(cmap, &fb_display[con].var, kspc, atyfb_setcolreg,
+			   info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg, int con, struct fb_info *info)
+{
+    return -EINVAL;
+}
+
+
+    /*
+     *  Initialisation
+     */
+
+__initfunc(unsigned long atyfb_init(unsigned long mem_start))
+{
+#ifdef __powerpc__
+    /* We don't want to be called like this. */
+    /* We rely on Open Firmware (offb) instead. */
+    return mem_start;
+#else /* !__powerpc__ */
+    /* To be merged with Bernd's mach64fb */
+    return mem_start;
+#endif /* !__powerpc__ */
+}
+
+
+unsigned long atyfb_of_init(unsigned long mem_start, struct device_node *dp)
+{
+    int i, err, sense;
+    struct fb_var_screeninfo var;
+    struct aty_regvals *init;
+    unsigned long addr;
+    unsigned char bus, devfn;
+    unsigned short cmd;
+
+    if (dp->next)
+	printk("Warning: only using first ATI card detected\n");
+    if (dp->n_addrs != 1 && dp->n_addrs != 3)
+	printk("Warning: expecting 1 or 3 addresses for ATY (got %d)",
+	       dp->n_addrs);
+
+    ati_regbase = (int)ioremap((0x7ffc00 + dp->addrs[0].address), 0x1000);
+    aty_cmap_regs = (struct aty_cmap_regs *)(ati_regbase + 0xC0);
+
+    /* enable memory-space accesses using config-space command register */
+    if (pci_device_loc(dp, &bus, &devfn) == 0) {
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
+	if (cmd != 0xffff) {
+	    cmd |= PCI_COMMAND_MEMORY;
+	    pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+	}
+    }
+    chip_type = (aty_ld_le32(CONFIG_CHIP_ID) & CFG_CHIP_TYPE);
+
+    i = aty_ld_le32(MEM_CNTL);
+    if (chip_type != MACH64_GT_ID)
+	switch (i & MEM_SIZE_ALIAS) {
+	    case MEM_SIZE_512K:
+		total_vram = 0x80000;
+		break;
+	    case MEM_SIZE_1M:
+		total_vram = 0x100000;
+		break;
+	    case MEM_SIZE_2M:
+		total_vram = 0x200000;
+		break;
+	    case MEM_SIZE_4M:
+		total_vram = 0x400000;
+		break;
+	    case MEM_SIZE_6M:
+		total_vram = 0x600000;
+		break;
+	    case MEM_SIZE_8M:
+		total_vram = 0x800000;
+		break;
+	    default:
+		total_vram = 0x80000;
+	}
+    else
+	switch (i & 0xF) {	/* 0xF used instead of MEM_SIZE_ALIAS */
+	    case MEM_SIZE_512K:
+		total_vram = 0x80000;
+		break;
+	    case MEM_SIZE_1M:
+		total_vram = 0x100000;
+		break;
+	    case MEM_SIZE_2M_GTB:
+		total_vram = 0x200000;
+		break;
+	    case MEM_SIZE_4M_GTB:
+		total_vram = 0x400000;
+		break;
+	    case MEM_SIZE_6M_GTB:
+		total_vram = 0x600000;
+		break;
+	    case MEM_SIZE_8M_GTB:
+		total_vram = 0x800000;
+		break;
+	    default:
+		total_vram = 0x80000;
+	}
+
+#if 1
+    printk("aty_display_init: node = %p, addrs = ", dp->node);
+    printk(" %x(%x)", dp->addrs[0].address, dp->addrs[0].size);
+    printk(", intrs =");
+    for (i = 0; i < dp->n_intrs; ++i)
+    printk(" %x", dp->intrs[i]);
+    printk("\nregbase: %x pci loc: %x:%x total_vram: %x cregs: %p\n",
+	   (int)ati_regbase, bus, devfn, total_vram, aty_cmap_regs);
+#endif
+
+    /* Map in frame buffer */
+    addr = dp->addrs[0].address;
+
+    /* use the big-endian aperture (??) */
+    addr += 0x800000;
+    frame_buffer = ioremap(addr, 0x800000);
+
+    if (default_par.video_mode != -1) {
+	sense = read_aty_sense();
+	printk("monitor sense = %x\n", sense);
+	if (default_par.video_mode == VMODE_NVRAM) {
+	    default_par.video_mode = nvram_read_byte(NV_VMODE);
+	    init = get_aty_struct(&default_par);
+	    if (default_par.video_mode <= 0 ||
+		default_par.video_mode > VMODE_MAX || init == 0)
+		default_par.video_mode = VMODE_CHOOSE;
+	}
+	if (default_par.video_mode == VMODE_CHOOSE)
+	    default_par.video_mode = map_monitor_sense(sense);
+
+	init = get_aty_struct(&default_par);
+	if (!init)
+	    default_par.video_mode = VMODE_640_480_60;
+    }
+
+    /*
+     * Reduce the pixel size if we don't have enough VRAM.
+     */
+
+    if (default_par.color_mode == CMODE_NVRAM)
+	default_par.color_mode = nvram_read_byte(NV_CMODE);
+    if (default_par.color_mode < CMODE_8 ||
+	default_par.color_mode > CMODE_32)
+	default_par.color_mode = CMODE_8;
+
+    while (aty_vram_reqd(&default_par) > total_vram) {
+	while (default_par.color_mode > CMODE_8 &&
+	       aty_vram_reqd(&default_par) > total_vram)
+	    --default_par.color_mode;
+	/*
+	 * adjust the video mode smaller if there still is not enough VRAM
+	 */
+	if (aty_vram_reqd(&default_par) > total_vram)
+	    do {
+		default_par.video_mode--;
+		init = get_aty_struct(&default_par);
+	    } while ((init == 0) &&
+		     (default_par.video_mode > VMODE_640_480_60));
+    }
+
+    if (chip_type == MACH64_GT_ID && (aty_ld_le32(CONFIG_STAT0) & 7) == 5
+	&& init->crtc_gen_cntl[1] == 0) {
+	    default_par.video_mode = VMODE_640_480_67;
+	    default_par.color_mode = CMODE_8;
+    }
+
+    switch (chip_type) {
+	case MACH64_GX_ID:
+	    strcat(atyfb_name, "GX");
+	    break;
+	case MACH64_VT_ID:
+	    strcat(atyfb_name, "VT");
+	    break;
+	case MACH64_GT_ID:
+	    strcat(atyfb_name, "GT");
+	    break;
+	default:
+	    break;
+    }
+    strcpy(fb_info.modename, atyfb_name);
+    fb_info.node = -1;
+    fb_info.fbops = &atyfb_ops;
+    fb_info.disp = &fb_disp;
+    fb_info.fontname[0] = '\0';
+    fb_info.changevar = NULL;
+    fb_info.switch_con = &atyfbcon_switch;
+    fb_info.updatevar = &atyfbcon_updatevar;
+    fb_info.blank = &atyfbcon_blank;
+
+    err = register_framebuffer(&fb_info);
+    if (err < 0)
+	return mem_start;
+
+    for (i = 0; i < 16; i++) {
+	int j = color_table[i];
+	palette[i].red = default_red[j];
+	palette[i].green = default_grn[j];
+	palette[i].blue = default_blu[j];
+#ifdef CONFIG_FBCON_CFB16
+	cfb16_cmap[i] = ((i << 10) & 0x7c00) | ((i << 5) & 0x03e0) | (i & 0x1f);
+#endif
+#ifdef CONFIG_FBCON_CFB32
+	cfb32_cmap[i] = (i << 24) | (i << 16) | (i << 8) | i;
+#endif
+    }
+    atyfb_set_par(&default_par);
+    encode_var(&var, &default_par);
+    atyfb_set_var(&var, -1, &fb_info);
+
+    printk("%s frame buffer device on %s\n", atyfb_name, dp->full_name);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+    console_setmode_ptr = atyfb_console_setmode;
+#endif /* CONFIG_FB_COMPAT_XPMAC) */
+
+    return mem_start;
+}
+
+
+/* XXX: doesn't work yet */
+void atyfb_setup(char *options, int *ints)
+{
+    char *this_opt;
+    int vmode;
+    int depth;
+
+    if (!options || !*options)
+	return;
+
+    for (this_opt = strtok(options, ","); this_opt;
+	 this_opt = strtok(NULL, ",")) {
+	if (!strncmp(this_opt, "vmode:", 6)) {
+	    vmode = simple_strtoul(this_opt+6, NULL, 0);
+	    if (vmode > 0 && vmode <= VMODE_MAX)
+		default_par.video_mode = vmode;
+	} else if (!strncmp(this_opt, "cmode:", 6)) {
+	    depth = simple_strtoul(this_opt+6, NULL, 0);
+	    switch (depth) {
+		case 8:
+		    default_par.color_mode = CMODE_8;
+		    break;
+		case 15:
+		case 16:
+		    default_par.color_mode = CMODE_16;
+		    break;
+		case 24:
+		case 32:
+		    default_par.color_mode = CMODE_32;
+		    break;
+	    };
+	}
+    }
+}
+
+
+static int atyfbcon_switch(int con, struct fb_info *info)
+{
+    struct atyfb_par par;
+
+    /* 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,
+		    atyfb_getcolreg, info);
+    currcon = con;
+    decode_var(&fb_display[con].var, &par);
+    atyfb_set_par(&par);
+    /* Install new colormap */
+    do_install_cmap(con, info);
+    return 0;
+}
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+static int atyfbcon_updatevar(int con, struct fb_info *info)
+{
+    /* Nothing */
+    return 0;
+}
+
+    /*
+     *  Blank the display.
+     */
+
+static void atyfbcon_blank(int blank, struct fb_info *info)
+{
+    char gen_cntl;
+
+    gen_cntl = aty_ld_8(CRTC_GEN_CNTL);
+    if (blank & VESA_VSYNC_SUSPEND)
+	    gen_cntl |= 0x8;
+    if (blank & VESA_HSYNC_SUSPEND)
+	    gen_cntl |= 0x4;
+    if ((blank & VESA_POWERDOWN) == VESA_POWERDOWN)
+	    gen_cntl |= 0x40;
+    if (blank == VESA_NO_BLANKING)
+	    gen_cntl &= ~(0x4c);
+    aty_st_8(CRTC_GEN_CNTL, gen_cntl);
+}
+
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+
+static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+			 u_int *transp, struct fb_info *info)
+{
+    if (regno > 255)
+	return 1;
+    *red = palette[regno].red;
+    *green = palette[regno].green;
+    *blue = palette[regno].blue;
+    return 0;
+}
+
+
+    /*
+     *  Set a single color register. The values supplied are already
+     *  rounded down to the hardware's capabilities (according to the
+     *  entries in the var structure). Return != 0 for invalid regno.
+     */
+
+static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			 u_int transp, struct fb_info *info)
+{
+    int i, scale;
+
+    if (regno > 255)
+	return 1;
+    palette[regno].red = red;
+    palette[regno].green = green;
+    palette[regno].blue = blue;
+    aty_WaitQueue(2);
+    i = aty_ld_8(DAC_CNTL) & 0xfc;
+    if (chip_type == MACH64_GT_ID)
+	    i |= 0x2;	/*DAC_CNTL|0x2 turns off the extra brightness for gt*/
+    aty_st_8(DAC_CNTL, i);
+    aty_st_8(DAC_REGS + DAC_MASK, 0xff);
+    eieio();
+    scale = ((chip_type != MACH64_GX_ID) &&
+	     (current_par.color_mode == CMODE_16)) ? 3 : 0;
+    aty_WaitQueue(4);
+    aty_cmap_regs->windex = regno << scale;
+    eieio();
+    aty_cmap_regs->lut = red << scale;
+    eieio();
+    aty_cmap_regs->lut = green << scale;
+    eieio();
+    aty_cmap_regs->lut = blue << scale;
+    eieio();
+    return 0;
+}
+
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+		    atyfb_setcolreg, info);
+    else
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+				    &fb_display[con].var, 1, atyfb_setcolreg,
+		    info);
+}
+
+
+    /*
+     *  Accelerated functions
+     */
+
+void aty_waitblit(void)
+{
+    aty_WaitIdleEmpty();	/* Make sure that all commands have finished */
+}
+
+void aty_rectcopy(int srcx, int srcy, int dstx, int dsty, u_int width,
+		  u_int height)
+{
+    u_int direction = 0;
+
+    if (srcy < dsty) {
+	dsty += height - 1;
+	srcy += height - 1;
+    } else
+	direction |= DST_Y_TOP_TO_BOTTOM;
+
+    if (srcx < dstx) {
+	dstx += width - 1;
+	srcx += width - 1;
+    } else
+	direction |= DST_X_LEFT_TO_RIGHT;
+
+    aty_WaitQueue(4);
+    aty_st_le32(DP_WRITE_MSK, 0x000000FF /* pGC->planemask */ );
+    aty_st_le32(DP_MIX, (MIX_SRC << 16) |  MIX_DST);
+    aty_st_le32(DP_SRC, FRGD_SRC_BLIT);
+
+    aty_WaitQueue(5);
+    aty_st_le32(SRC_Y_X, (srcx << 16) | (srcy & 0x0000ffff));
+    aty_st_le32(SRC_WIDTH1, width);
+    aty_st_le32(DST_CNTL, direction);
+    aty_st_le32(DST_Y_X, (dstx << 16) | (dsty & 0x0000ffff));
+    aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | (height & 0x0000ffff));
+
+    aty_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.
+     */
+    aty_st_le32(DST_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+}
+
+void aty_rectfill(int dstx, int dsty, u_int width, u_int height, u_int color)
+{
+    if (!width || !height)
+	return;
+
+    aty_WaitQueue(5);
+    aty_st_le32(DP_FRGD_CLR, color              /* pGC->fgPixel */ );
+    aty_st_le32(DP_WRITE_MSK, 0x000000FF       /* pGC->planemask */ );
+    aty_st_le32(DP_MIX, (MIX_SRC << 16) | MIX_DST);
+    aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR);
+
+    aty_st_le32(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+    aty_WaitQueue(2);
+    aty_st_le32(DST_Y_X, (((u_int)dstx << 16) | ((u_int)dsty & 0x0000ffff)));
+    aty_st_le32(DST_HEIGHT_WIDTH, (((u_int)width << 16) | height));
+
+    aty_WaitIdleEmpty();	/* Make sure that all commands have finished */
+}
+
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+
+    /*
+     *  Backward compatibility mode for Xpmac
+     */
+
+static int atyfb_console_setmode(struct vc_mode *mode, int doit)
+{
+    int err;
+    struct fb_var_screeninfo var;
+    struct atyfb_par par;
+
+    if (mode->mode <= 0 || mode->mode > VMODE_MAX )
+	return -EINVAL;
+    par.video_mode = mode->mode;
+
+    switch (mode->depth) {
+        case 24:
+        case 32:
+	    par.color_mode = CMODE_32;
+	    break;
+        case 16:
+	    par.color_mode = CMODE_16;
+	    break;
+        case 8:
+        case 0:			/* (default) */
+	    par.color_mode = CMODE_8;
+	    break;
+        default:
+	    return -EINVAL;
+    }
+    encode_var(&var, &par);
+    if ((err = decode_var(&var, &par)))
+	return err;
+    if (doit)
+	atyfb_set_var(&var, currcon, 0);
+    return 0;
+}
+
+#endif /* CONFIG_FB_COMPAT_XPMAC */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/cyberfb.c m68k-2.1.77/drivers/video/cyberfb.c
--- /usr/src/m68k-2.1.77/drivers/video/cyberfb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/cyberfb.c	Fri Jan  9 01:20:34 1998
@@ -20,7 +20,9 @@
  * for more details.
  */
 
+#define CYBERFBDEBUG
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -36,11 +38,55 @@
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/pgtable.h>
+#include <asm/amigahw.h>
 #include "s3blit.h"
 
+#ifdef CYBERFBDEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
 
 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
 
+#if 1
+#define vgawb_3d(reg,dat) \
+                (*((unsigned char *)(CyberVGARegs + (reg ^ 3))) = dat)
+#define vgaww_3d(reg,dat) \
+                (*((unsigned word *)(CyberVGARegs + (reg ^ 2))) = swab16(dat))
+#define vgawl_3d(reg,dat) \
+                (*((unsigned long *)(CyberVGARegs + reg)) = swab32(dat))
+#else
+     /*
+      * Dunno why this doesn't work at the moment - we'll have to look at
+      * it later.
+      */
+#define vgawb_3d(reg,dat) \
+                (*((unsigned char *)(CyberRegs + 0x8000 + reg)) = dat)
+#define vgaww_3d(reg,dat) \
+                (*((unsigned word *)(CyberRegs + 0x8000 + reg)) = dat)
+#define vgawl_3d(reg,dat) \
+                (*((unsigned long *)(CyberRegs + 0x8000 + reg)) = dat)
+#endif
+
+     /*
+      * We asume P5 mapped the big-endian version of these registers.
+      */
+#define wb_3d(reg,dat) \
+                (*((unsigned char volatile *)(CyberRegs + reg)) = dat)
+#define ww_3d(reg,dat) \
+                (*((unsigned word volatile *)(CyberRegs + reg)) = dat)
+#define wl_3d(reg,dat) \
+                (*((unsigned long volatile *)(CyberRegs + reg)) = dat)
+
+#define rl_3d(reg) \
+                (*((unsigned long volatile *)(CyberRegs + reg)))
+
+
+#define wb_64(reg,dat) (*((unsigned char volatile *)CyberRegs + reg) = dat)
+
+
+
 struct cyberfb_par {
    int xres;
    int yres;
@@ -72,9 +118,9 @@
    int (*decode_var)(struct fb_var_screeninfo *var, struct cyberfb_par *par);
    int (*encode_var)(struct fb_var_screeninfo *var, struct cyberfb_par *par);
    int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
-                    u_int *transp);
+                    u_int *transp, struct fb_info *info);
    int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
-                    u_int transp);
+                    u_int transp, struct fb_info *info);
    void (*blank)(int blank);
 } *fbhw;
 
@@ -106,7 +152,8 @@
 static unsigned long CyberMem;
 static unsigned long CyberSize;
 static volatile char *CyberRegs;
-
+static volatile unsigned long CyberVGARegs; /* ++Andre: for CV64/3D, see macros at the beginning */
+ 
 
 /*
  *    Predefined Video Modes
@@ -114,34 +161,55 @@
 
 static struct fb_videomode cyberfb_predefined[] __initdata = {
     {
-	"cyber8", {		/* Cybervision 8 bpp */
-	    CYBER8_WIDTH, CYBER8_HEIGHT, CYBER8_WIDTH, CYBER8_HEIGHT, 0, 0, 8, 0,
+	"640x480-8", {		/* Cybervision 8 bpp */
+	    640, 480, 640, 480, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
 	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
 	}
     }, {
-	"cyber16", {		/* Cybervision 16 bpp */
-	    800, 600, 800, 600, 0, 0, 16, 0,
-	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	"800x600-8", {		/* Cybervision 8 bpp */
+	    800, 600, 800, 600, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
 	}
     }, {
-	"800x600x8", {		/* Cybervision 8 bpp */
-	    800, 600, 800, 600, 0, 0, 8, 0,
+	"1024x768-8", {		/* Cybervision 8 bpp */
+	    1024, 768, 1024, 768, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
 	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
 	}
     }, {
-	"640x480x8", {		/* Cybervision 8 bpp */
-	    640, 480, 640, 480, 0, 0, 8, 0,
+	"1152x886-8", {		/* Cybervision 8 bpp */
+	    1152, 886, 1152, 886, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }, {
+	"1280x1024-8", {	/* Cybervision 8 bpp */
+	    1280, 1024, 1280, 1024, 0, 0, 8, 0,
+	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }, {
+	"1600x1200-8", {	/* Cybervision 8 bpp */
+	    1600, 1200, 1600, 1200, 0, 0, 8, 0,
 	    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
 	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
 	}
-    },
+    }, {
+	"800x600-16", {		/* Cybervision 16 bpp */
+	    800, 600, 800, 600, 0, 0, 16, 0,
+	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+	    0, 0, -1, -1, FB_ACCEL_NONE, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	}
+    }
 };
 
 
@@ -154,13 +222,14 @@
 static int Cyberfb_Cyber16 = 0;       /* Use Cybervision board */
 #endif
 
+static int CV3D = 0;
 
 /*
  *    Some default modes
  */
 
-#define CYBER8_DEFMODE     (1)
-#define CYBER16_DEFMODE    (2)
+#define CYBER8_DEFMODE     (0)
+#define CYBER16_DEFMODE    (6)
 
 static struct fb_var_screeninfo cyberfb_default;
 
@@ -171,19 +240,22 @@
 
 void cyberfb_setup(char *options, int *ints);
 
-static int cyberfb_open(int fbidx);
-static int cyberfb_release(int fbidx);
-static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
-static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int cyberfb_open(struct fb_info *info);
+static int cyberfb_release(struct fb_info *info);
+static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct
+fb_info *info);
+static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, struct
+fb_info *info);
+static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, struct
+fb_info *info);
 static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
-				int fbidx);
+			       struct fb_info *info);
 static int cyberfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                          u_long arg, int con, int fbidx);
+                         u_long arg, int con, struct fb_info *info);
 
 
 /*
@@ -191,9 +263,9 @@
  */
 
 unsigned long cyberfb_init(unsigned long mem_start);
-static int Cyberfb_switch(int con);
-static int Cyberfb_updatevar(int con);
-static void Cyberfb_blank(int blank);
+static int Cyberfb_switch(int con, struct fb_info *info);
+static int Cyberfb_updatevar(int con, struct fb_info *info);
+static void Cyberfb_blank(int blank, struct fb_info *info);
 
 
 /*
@@ -221,9 +293,9 @@
 static int Cyber_encode_var(struct fb_var_screeninfo *var,
                           struct cyberfb_par *par);
 static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp);
+                         u_int *transp, struct fb_info *info);
 static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp);
+                         u_int transp, struct fb_info *info);
 static void Cyber_blank(int blank);
 
 
@@ -231,11 +303,12 @@
  *    Internal routines
  */
 
+static int Cyber_probe(void);	/* looks whether a CV64 or a CV64/3D is plugged in */
 static void cyberfb_get_par(struct cyberfb_par *par);
 static void cyberfb_set_par(struct cyberfb_par *par);
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static void do_install_cmap(int con);
-static void cyberfb_set_disp(int con);
+static void do_install_cmap(int con, struct fb_info *info);
+static void cyberfb_set_disp(int con, struct fb_info *info);
 static int get_video_mode(const char *name);
 
 
@@ -256,30 +329,60 @@
 	volatile u_long *CursorBase;
 
 	for (i = 0; i < 256; i++)
-
-		for (i = 0; i < 256; i++)
-		{
-			Cyber_colour_table [i][0] = i;
-			Cyber_colour_table [i][1] = i;
-			Cyber_colour_table [i][2] = i;
-			Cyber_colour_table [i][3] = 0;
-		}
+	{
+		Cyber_colour_table [i][0] = i;
+		Cyber_colour_table [i][1] = i;
+		Cyber_colour_table [i][2] = i;
+		Cyber_colour_table [i][3] = 0;
+	}
 
 	/*
 	 * Just clear the thing for the biggest mode.
+	 *
+	 * ++Andre, TODO: determine size first, then clear all memory
+	 *                (the 3D penguin might need texture memory :-) )
 	 */
 
-	memset ((char*)CyberMem, 0, CYBER8_WIDTH * CYBER8_HEIGHT);
+	memset ((char*)CyberMem, 0, 1600 * 1200);
 
 	/* Disable hardware cursor */
-	*(CyberRegs + S3_CRTC_ADR)  = S3_REG_LOCK2;
-	*(CyberRegs + S3_CRTC_DATA) = 0xa0;
-	*(CyberRegs + S3_CRTC_ADR)  = S3_HGC_MODE;
-	*(CyberRegs + S3_CRTC_DATA) = 0x00;
-	*(CyberRegs + S3_CRTC_ADR)  = S3_HWGC_DX;
-	*(CyberRegs + S3_CRTC_DATA) = 0x00;
-	*(CyberRegs + S3_CRTC_ADR)  = S3_HWGC_DY;
-	*(CyberRegs + S3_CRTC_DATA) = 0x00;
+	if (CV3D)
+	{
+		CyberSize = 0x00400000; /* 4 MB */
+
+		vgawb_3d(0x3c8, 255);
+		vgawb_3d(0x3c9, 56);
+		vgawb_3d(0x3c9, 100);
+		vgawb_3d(0x3c9, 160);
+
+		vgawb_3d(0x3c8, 254);
+		vgawb_3d(0x3c9, 0);
+		vgawb_3d(0x3c9, 0);
+		vgawb_3d(0x3c9, 0);
+
+		/* Disable hardware cursor */
+		vgawb_3d(S3_CRTC_ADR, S3_REG_LOCK2);
+		vgawb_3d(S3_CRTC_DATA, 0xa0);
+		vgawb_3d(S3_CRTC_ADR, S3_HGC_MODE);
+		vgawb_3d(S3_CRTC_DATA, 0x00);
+		vgawb_3d(S3_CRTC_ADR, S3_HWGC_DX);
+		vgawb_3d(S3_CRTC_DATA, 0x00);
+		vgawb_3d(S3_CRTC_ADR, S3_HWGC_DY);
+		vgawb_3d(S3_CRTC_DATA, 0x00);
+
+		return 0; /* TODO: hardware cursor for CV64/3D */
+	}
+	else
+	{
+		wb_64(S3_CRTC_ADR, S3_REG_LOCK2);
+		wb_64(S3_CRTC_DATA, 0xa0);
+		wb_64(S3_CRTC_ADR, S3_HGC_MODE);
+		wb_64(S3_CRTC_DATA, 0x00);
+		wb_64(S3_CRTC_ADR, S3_HWGC_DX);
+		wb_64(S3_CRTC_DATA, 0x00);
+		wb_64(S3_CRTC_ADR, S3_HWGC_DY);
+		wb_64(S3_CRTC_DATA, 0x00);
+	}
 
 	/* Get memory size (if not 2MB it is 4MB) */
 	*(CyberRegs + S3_CRTC_ADR) = S3_LAW_CTL;
@@ -306,8 +409,8 @@
 		*(CursorBase+3+(i*4)) = 0xffff0000;
 	}
 
-	Cyber_setcolreg (255, 56, 100, 160, 0);
-	Cyber_setcolreg (254, 0, 0, 0, 0);
+	Cyber_setcolreg (255, 56, 100, 160, 0, NULL /* unused */);
+	Cyber_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);
 
 	return 0;
 }
@@ -327,7 +430,7 @@
 	fix->smem_start = (caddr_t)CyberMem;
 	fix->smem_len = CyberSize;
 	fix->mmio_start = (unsigned char *)CyberRegs;
-	fix->mmio_len = 0x10000;
+	fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
 
 	fix->type = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux = 0;
@@ -420,7 +523,18 @@
 
 	var->height = -1;
 	var->width = -1;
-	var->accel = FB_ACCEL_CYBERVISION;
+
+	if (CV3D)
+	{
+		var->accel = FB_ACCEL_CYBERVISION3D;
+		DPRINTK("accel CV64/3D\n");
+	}
+	else
+	{
+		var->accel = FB_ACCEL_CYBERVISION;
+		DPRINTK("accel CV64\n");
+	}
+
 	var->vmode = FB_VMODE_NONINTERLACED;
 
 	/* Dummy values */
@@ -451,20 +565,41 @@
  */
 
 static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			   u_int transp)
+			   u_int transp, struct fb_info *info)
 {
 	if (regno > 255)
+	{
 		return (1);
+	}
+
+	/*
+	 * No colors on the CV3D yet.
+	 */
 
-	*(CyberRegs + 0x3c8) = (char)regno;
-	Cyber_colour_table [regno][0] = red & 0xff;
-	Cyber_colour_table [regno][1] = green & 0xff;
-	Cyber_colour_table [regno][2] = blue & 0xff;
-	Cyber_colour_table [regno][3] = transp;
-
-	*(CyberRegs + 0x3c9) = (red & 0xff) >> 2;
-	*(CyberRegs + 0x3c9) = (green & 0xff) >> 2;
-	*(CyberRegs + 0x3c9) = (blue & 0xff) >> 2;
+	if (CV3D)
+	{
+		vgawb_3d(0x3c8, (unsigned char) regno);
+		Cyber_colour_table [regno][0] = red & 0xff;
+		Cyber_colour_table [regno][1] = green & 0xff;
+		Cyber_colour_table [regno][2] = blue & 0xff;
+		Cyber_colour_table [regno][3] = transp;
+
+		vgawb_3d(0x3c9, ((red & 0xff) >> 2));
+		vgawb_3d(0x3c9, ((green & 0xff) >> 2));
+		vgawb_3d(0x3c9, ((blue & 0xff) >> 2));
+	}
+	else
+	{
+		wb_64(0x3c8, (unsigned char) regno);
+		Cyber_colour_table [regno][0] = red & 0xff;
+		Cyber_colour_table [regno][1] = green & 0xff;
+		Cyber_colour_table [regno][2] = blue & 0xff;
+		Cyber_colour_table [regno][3] = transp;
+
+		wb_64(0x3c9, (red & 0xff) >> 2);
+		wb_64(0x3c9, (green & 0xff) >> 2);
+		wb_64(0x3c9, (blue & 0xff) >> 2);
+	}
 
 	return (0);
 }
@@ -476,13 +611,13 @@
  */
 
 static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			   u_int *transp)
+			   u_int *transp, struct fb_info *info)
 {
 	if (regno >= 256)
 		return (1);
-	*red    = Cyber_colour_table [regno][0];
-	*green  = Cyber_colour_table [regno][1];
-	*blue   = Cyber_colour_table [regno][2];
+	*red	= Cyber_colour_table [regno][0];
+	*green	= Cyber_colour_table [regno][1];
+	*blue	= Cyber_colour_table [regno][2];
 	*transp = Cyber_colour_table [regno][3];
 	return (0);
 }
@@ -496,24 +631,156 @@
 {
 	int i;
 
-	if (blank)
-		for (i = 0; i < 256; i++)
+	if (CV3D)
+	{
+		if (blank)
+		{
+			for (i = 0; i < 256; i++)
+			{
+				vgawb_3d(0x3c8, (unsigned char) i);
+				vgawb_3d(0x3c9, 0);
+				vgawb_3d(0x3c9, 0);
+				vgawb_3d(0x3c9, 0);
+			}
+		}
+		else
 		{
-			*(CyberRegs + 0x3c8) = i;
-			*(CyberRegs + 0x3c9) = 0;
-			*(CyberRegs + 0x3c9) = 0;
-			*(CyberRegs + 0x3c9) = 0;
+			for (i = 0; i < 256; i++)
+			{
+				vgawb_3d(0x3c8, (unsigned char) i);
+				vgawb_3d(0x3c9, Cyber_colour_table[i][0] >> 2);
+				vgawb_3d(0x3c9, Cyber_colour_table[i][1] >> 2);
+				vgawb_3d(0x3c9, Cyber_colour_table[i][2] >> 2);
+			}
 		}
+	}
 	else
-		for (i = 0; i < 256; i++)
+	{
+		if (blank)
 		{
-			*(CyberRegs + 0x3c8) = i;
-			*(CyberRegs + 0x3c9) = Cyber_colour_table [i][0] >> 2;
-			*(CyberRegs + 0x3c9) = Cyber_colour_table [i][1] >> 2;
-			*(CyberRegs + 0x3c9) = Cyber_colour_table [i][2] >> 2;
+			for (i = 0; i < 256; i++)
+			{
+				wb_64(0x3c8, (unsigned char) i);
+				wb_64(0x3c9, 0);
+				wb_64(0x3c9, 0);
+				wb_64(0x3c9, 0);
+			}
 		}
+		else
+		{
+			for (i = 0; i < 256; i++)
+			{
+				wb_64(0x3c8, (unsigned char) i);
+				wb_64(0x3c9, Cyber_colour_table[i][0] >> 2);
+				wb_64(0x3c9, Cyber_colour_table[i][1] >> 2);
+				wb_64(0x3c9, Cyber_colour_table[i][2] >> 2);
+			}
+		}
+	}
 }
 
+#ifdef CONFIG_FB_CV3D
+
+/*
+ * CV3D low-level support
+ */
+
+#define Cyber3D_WaitQueue(v)	 { do { while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); } while (0); }
+
+static inline void Cyber3D_WaitBusy(void)
+{
+unsigned long status;
+
+	do {
+		status = rl_3d(0x8504);
+	} while (!(status & (1 << 13)));
+}
+
+#define S3V_BITBLT	(0x0 << 27)
+#define S3V_RECTFILL	(0x2 << 27)
+#define S3V_AUTOEXE	0x01
+#define S3V_HWCLIP	0x02
+#define S3V_DRAW	0x20
+#define S3V_DST_8BPP	0x00
+#define S3V_DST_16BPP	0x04
+#define S3V_DST_24BPP	0x08
+#define S3V_MONO_PAT	0x100
+
+#define S3V_BLT_COPY	(0xcc<<17)
+#define S3V_BLT_CLEAR	(0x00<<17)
+#define S3V_BLT_SET	(0xff<<17)
+
+ /*
+  * BitBLT - Through the Plane
+  */
+
+void Cyber3D_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
+		     u_short width, u_short height)
+{
+	unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_DST_8BPP;
+
+	blitcmd |= S3V_BLT_COPY;
+
+	/* Set drawing direction */
+	/* -Y, X maj, -X (default) */
+	if (curx > destx)
+	{
+		blitcmd |= (1 << 25);  /* Drawing direction +X */
+	}
+	else
+	{
+		curx  += (width - 1);
+		destx += (width - 1);
+	}
+
+	if (cury > desty)
+	{
+		blitcmd |= (1 << 26);  /* Drawing direction +Y */
+	}
+	else
+	{
+		cury  += (height - 1);
+		desty += (height - 1);
+	}
+
+	wl_3d(0xa4f4, 1); /* pattern fb color */
+
+	wl_3d(0xa4e8, ~0); /* mono pat 0 */
+	wl_3d(0xa4ec, ~0); /* mono pat 1 */
+
+	wl_3d(0xa504, ((width << 16) | height));	/* rwidth_height */
+	wl_3d(0xa508, ((curx << 16)  | cury));		/* rsrc_xy */
+	wl_3d(0xa50c, ((destx << 16) | desty));		/* rdest_xy */
+
+	wl_3d(0xa500, blitcmd);				/* GO! */
+
+	Cyber3D_WaitBusy();
+}
+
+/*
+ * Rectangle Fill Solid
+ */
+
+void Cyber3D_RectFill (u_short x, u_short y, u_short width, u_short height,
+		       u_short color)
+{
+	unsigned int tmp;
+	unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW | S3V_DST_8BPP |
+		S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
+
+	tmp = color & 0xff;
+	wl_3d(0xa4f4, tmp);
+
+	wl_3d(0xa504, ((width << 16) | height));	/* rwidth_height */
+	wl_3d(0xa50c, ((x << 16) | y));			/* rdest_xy */
+
+	wl_3d(0xa500, blitcmd);				/* GO! */
+	Cyber3D_WaitBusy();
+}
+
+#endif
+
+#ifdef CONFIG_FB_CYBER
 
 /**************************************************************
  * We are waiting for "fifo" FIFO-slots empty
@@ -547,7 +814,7 @@
  * BitBLT - Through the Plane
  */
 void Cyber_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
-                   u_short width, u_short height, u_short mode)
+		   u_short width, u_short height, u_short mode)
 {
 	u_short blitcmd = S3_BITBLT;
 
@@ -590,10 +857,18 @@
  * Rectangle Fill Solid
  */
 void Cyber_RectFill (u_short x, u_short y, u_short width, u_short height,
-                     u_short mode, u_short color)
+		     u_short mode, u_short color)
 {
 	u_short blitcmd = S3_FILLEDRECT;
 
+#if 0
+	if (CV3D)
+	{
+		printk("Belly up .... RectFill on a 3D\n");
+		return;
+	}
+#endif
+
 	Cyber_WaitQueue (0x8000);
 
 	*((u_short volatile *)(CyberRegs + S3_PIXEL_CNTL)) = 0xa000;
@@ -610,13 +885,20 @@
 
 	*((u_short volatile *)(CyberRegs + S3_CMD)) = blitcmd;
 }
-
+#endif
 
 /**************************************************************
  * Move cursor to x, y
  */
 void Cyber_MoveCursor (u_short x, u_short y)
 {
+
+	if (CV3D)
+	{
+		printk("Yuck .... MoveCursor on a 3D\n");
+		return;
+	}
+
 	*(CyberRegs + S3_CRTC_ADR)  = 0x39;
 	*(CyberRegs + S3_CRTC_DATA) = 0xa0;
 
@@ -651,9 +933,13 @@
 static void cyberfb_get_par(struct cyberfb_par *par)
 {
 	if (current_par_valid)
+	{
 		*par = current_par;
+	}
 	else
+	{
 		fbhw->decode_var(&cyberfb_default, par);
+	}
 }
 
 
@@ -667,11 +953,24 @@
 static void cyber_set_video(struct fb_var_screeninfo *var)
 {
 	/* Set clipping rectangle to current screen size */
-	*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x1000;
-	*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x2000;
+ 
+	if (CV3D)
+	{
+		unsigned int clip;
 
-	*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x3000 | (var->yres - 1);
-	*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x4000 | (var->xres - 1);
+		clip = ((0 << 16) | (var->xres - 1));
+		wl_3d(0xa4dc, clip);
+		clip = ((0 << 16) | (var->yres - 1));
+		wl_3d(0xa4e0, clip);
+	}
+	else
+	{
+		*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x1000;
+		*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x2000;
+
+		*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x3000 | (var->yres - 1);
+		*((u_short volatile *)(CyberRegs + 0xbee8)) = 0x4000 | (var->xres - 1);
+	}
 }
 
 
@@ -693,16 +992,16 @@
 }
 
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-			    fbhw->setcolreg);
+			    fbhw->setcolreg, info);
 	else
-		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
-			    &fb_display[con].var, 1, fbhw->setcolreg);
+		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+			    &fb_display[con].var, 1, fbhw->setcolreg, info);
 }
 
 
@@ -710,7 +1009,7 @@
  *  Open/Release the frame buffer device
  */
 
-static int cyberfb_open(int fbidx)
+static int cyberfb_open(struct fb_info *info)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -720,7 +1019,7 @@
 	return(0);
 }
 
-static int cyberfb_release(int fbidx)
+static int cyberfb_release(struct fb_info *info)
 {
 	MOD_DEC_USE_COUNT;
 	return(0);
@@ -731,7 +1030,8 @@
  *    Get the Fixed Part of the Display
  */
 
-static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			   struct fb_info *info)
 {
 	struct cyberfb_par par;
 	int error = 0;
@@ -748,21 +1048,28 @@
  *    Get the User Defined Part of the Display
  */
 
-static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
 {
 	struct cyberfb_par par;
 	int error = 0;
 
-	if (con == -1) {
+	if (con == -1)
+	{
 		cyberfb_get_par(&par);
 		error = fbhw->encode_var(var, &par);
-	} else
+		disp.var = *var;   /* ++Andre: don't know if this is the right place */
+	}
+	else
+	{
 		*var = fb_display[con].var;
+	}
+
 	return(error);
 }
 
 
-static void cyberfb_set_disp(int con)
+static void cyberfb_set_disp(int con, struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -772,8 +1079,7 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	/* ### FN: Needs fixes later */
-	cyberfb_get_fix(&fix, con, 0);
+	cyberfb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
 	display->screen_base = (u_char *)fix.smem_start;
@@ -791,7 +1097,8 @@
  *    Set the User Defined Part of the Display
  */
 
-static int cyberfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
 
@@ -808,10 +1115,10 @@
 		    oldvxres != var->xres_virtual ||
 		    oldvyres != var->yres_virtual ||
 		    oldbpp != var->bits_per_pixel) {
-			cyberfb_set_disp(con);
+			cyberfb_set_disp(con, info);
 			(*fb_info.changevar)(con);
 			fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
-			do_install_cmap(con);
+			do_install_cmap(con, info);
 		}
 	}
 	var->activate = 0;
@@ -824,15 +1131,15 @@
  */
 
 static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			    struct fb_info *info)
 {
 	if (con == currcon) /* current console? */
 		return(fb_get_cmap(cmap, &fb_display[con].var,
-				   kspc, fbhw->getcolreg));
+				   kspc, fbhw->getcolreg, info));
 	else if (fb_display[con].cmap.len) /* non default colormap? */
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			     cmap, kspc ? 0 : 2);
 	return(0);
 }
@@ -843,7 +1150,7 @@
  */
 
 static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			    struct fb_info *info)
 {
 	int err;
 
@@ -852,9 +1159,9 @@
 				 1<<fb_display[con].var.bits_per_pixel, 0)))
 			return(err);
 	}
-	if (con == currcon)              /* current console? */
+	if (con == currcon)		 /* current console? */
 		return(fb_set_cmap(cmap, &fb_display[con].var,
-				   kspc, fbhw->setcolreg));
+				   kspc, fbhw->setcolreg, info));
 	else
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return(0);
@@ -867,18 +1174,19 @@
  *    This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  */
 
-static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
+			       struct fb_info *info)
 {
 	return(-EINVAL);
 }
 
 
 /*
-    *    Cybervision Frame Buffer Specific ioctls
+    *	 Cybervision Frame Buffer Specific ioctls
     */
 
 static int cyberfb_ioctl(struct inode *inode, struct file *file,
-                          u_int cmd, u_long arg, int con, int fbidx)
+			 u_int cmd, u_long arg, int con, struct fb_info *info)
 {
 	return(-EINVAL);
 }
@@ -891,6 +1199,21 @@
 };
 
 
+static int Cyber_probe(void)
+{
+#ifdef CONFIG_FB_CYBER
+	if ((CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64, 0, 0)))
+		CV3D = 0;
+	else
+#endif
+#ifdef CONFIG_FB_CV3D
+	if ((CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64_3D, 0, 0)))
+		CV3D = 1;
+#endif
+	return CyberKey;
+}
+
+
 __initfunc(void cyberfb_setup(char *options, int *ints))
 {
 	char *this_opt;
@@ -906,8 +1229,18 @@
 			fb_invert_cmaps();
 		} else if (!strncmp(this_opt, "font:", 5))
 			strcpy(fb_info.fontname, this_opt+5);
+		else if (!strcmp (this_opt, "cyber8")){
+			cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
+		}
+		else if (!strcmp (this_opt, "cyber16")){
+			cyberfb_default = cyberfb_predefined[CYBER16_DEFMODE].var;
+		}
 		else
 			get_video_mode(this_opt);
+
+	DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",cyberfb_default.xres,
+                                                           cyberfb_default.yres,
+		                                           cyberfb_default.bits_per_pixel);
 }
 
 
@@ -922,7 +1255,7 @@
 	unsigned long board_addr;
 	const struct ConfigDev *cd;
 
-	if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64, 0, 0)))
+	if (!(CyberKey = Cyber_probe()))
 		return mem_start;
 
 	cd = zorro_get_board (CyberKey);
@@ -930,9 +1263,41 @@
 	board_addr = (unsigned long)cd->cd_BoardAddr;
 
 	/* This includes the video memory as well as the S3 register set */
-	CyberMem = kernel_map (board_addr + 0x01400000, 0x01000000,
-			       KERNELMAP_NOCACHE_SER, &mem_start);
-	CyberRegs = (char*) (CyberMem + 0x00c00000);
+        if (!CV3D)
+	{
+		CyberMem = kernel_map (board_addr + 0x01400000, 0x01000000,
+				       KERNELMAP_NOCACHE_SER, &mem_start);
+		CyberRegs = (char*) (CyberMem + 0x00c00000);
+	}
+	else
+	{
+        	if ((unsigned long)cd->cd_BoardAddr < 0x01000000)
+		{
+                        /*
+                         * Ok we got the board running in Z2 space.
+                         */
+ 
+			CyberMem = ZTWO_VADDR(board_addr);
+                        printk("CV3D detected running in Z2 mode ... not yet supported!\n");
+                        return -ENODEV;
+                }
+		else
+		{
+                        CyberVGARegs = kernel_map(board_addr +0x0c000000,
+                                                       0x00010000,
+                                                       KERNELMAP_NOCACHE_SER,
+                                                       &mem_start);
+                        CyberRegs = (char *)kernel_map(board_addr +0x05000000,
+                                                       0x00010000,
+                                                       KERNELMAP_NOCACHE_SER,
+                                                       &mem_start);
+                        CyberMem = kernel_map(board_addr + 0x04800000,
+                                              0x00400000,
+                                              KERNELMAP_NOCACHE_SER,
+                                              &mem_start);
+                        printk("CV3D detected running in Z3 mode\n");
+                }
+	}
 
 	fbhw = &Cyber_switch;
 
@@ -954,9 +1319,9 @@
 	fbhw->encode_var(&cyberfb_default, &par);
 
 	do_fb_set_var(&cyberfb_default, 1);
-	cyberfb_get_var(&fb_display[0].var, -1, GET_FB_IDX(fb_info.node));
-	cyberfb_set_disp(-1);
-	do_install_cmap(0);
+	cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
+	cyberfb_set_disp(-1, &fb_info);
+	do_install_cmap(0, &fb_info);
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, CyberSize>>10);
@@ -968,17 +1333,17 @@
 }
 
 
-static int Cyberfb_switch(int con)
+static int Cyberfb_switch(int con, struct fb_info *info)
 {
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
 		fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
-			    fbhw->getcolreg);
+			    fbhw->getcolreg, info);
 
 	do_fb_set_var(&fb_display[con].var, 1);
 	currcon = con;
 	/* Install new colormap */
-	do_install_cmap(con);
+	do_install_cmap(con, info);
 	return(0);
 }
 
@@ -990,7 +1355,7 @@
  *    Since it's called by a kernel driver, no range checking is done.
  */
 
-static int Cyberfb_updatevar(int con)
+static int Cyberfb_updatevar(int con, struct fb_info *info)
 {
 	return(0);
 }
@@ -1000,7 +1365,7 @@
     *    Blank the display.
     */
 
-static void Cyberfb_blank(int blank)
+static void Cyberfb_blank(int blank, struct fb_info *info)
 {
 	fbhw->blank(blank);
 }
@@ -1014,10 +1379,14 @@
 {
 	int i;
 
-	for (i = 0; i < NUM_TOTAL_MODES; i++)
-		if (!strcmp(name, cyberfb_predefined[i].name))
+	for (i = 0; i < NUM_TOTAL_MODES; i++) {
+		if (!strcmp(name, cyberfb_predefined[i].name)) {
 			cyberfb_default = cyberfb_predefined[i].var;
 			return(i);
+		}
+	}
+	/* ++Andre: set cyberfb default mode */
+	cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
 	return(0);
 }
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/dnfb.c m68k-2.1.77/drivers/video/dnfb.c
--- /usr/src/m68k-2.1.77/drivers/video/dnfb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/dnfb.c	Fri Jan  9 01:20:34 1998
@@ -111,24 +111,29 @@
 
 /* frame buffer operations */
 
-static int dnfb_open(int fbidx);
-static int dnfb_release(int fbidx);
-static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
-static int dnfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int dnfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int dnfb_get_cmap(struct fb_cmap *cmap,int kspc,int con, int fbidx);
-static int dnfb_set_cmap(struct fb_cmap *cmap,int kspc,int con, int fbidx);
+static int dnfb_open(struct fb_info *info);
+static int dnfb_release(struct fb_info *info);
+static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			struct fb_info *info);
+static int dnfb_get_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info);
+static int dnfb_set_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info);
+static int dnfb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
+			 struct fb_info *info);
+static int dnfb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
+			 struct fb_info *info);
 static int dnfb_pan_display(struct fb_var_screeninfo *var, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int dnfb_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg, int con,
-		       int fbidx);
+		      unsigned int cmd, unsigned long arg, int con,
+		      struct fb_info *info);
 
-static int dnfbcon_switch(int con);
-static int dnfbcon_updatevar(int con);
-static void dnfbcon_blank(int blank);
+static int dnfbcon_switch(int con, struct fb_info *info);
+static int dnfbcon_updatevar(int con, struct fb_info *info);
+static void dnfbcon_blank(int blank, struct fb_info *info);
 
-static void dnfb_set_disp(int con);
+static void dnfb_set_disp(int con, struct fb_info *info);
 
 static struct display disp[MAX_NR_CONSOLES];
 static struct fb_info fb_info;
@@ -141,7 +146,7 @@
 
 static char dnfb_name[]="Apollo";
 
-static int dnfb_open(int fbidx)
+static int dnfb_open(struct fb_info *info)
 {
         /*
          * Nothing, only a usage count for the moment
@@ -151,13 +156,14 @@
         return(0);
 }
 
-static int dnfb_release(int fbidx)
+static int dnfb_release(struct fb_info *info)
 {
         MOD_DEC_USE_COUNT;
         return(0);
 }
 
-static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			struct fb_info *info)
 {
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	strcpy(fix->id,"Apollo Mono");
@@ -175,7 +181,8 @@
 
 }
         
-static int dnfb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int dnfb_get_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info)
 {
 	var->xres=1280;
 	var->yres=1024;
@@ -202,7 +209,8 @@
 
 }
 
-static int dnfb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int dnfb_set_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info)
 {
 	if(var->xres!=1280) 
 		return -EINVAL;
@@ -245,14 +253,16 @@
 
 }
 
-static int dnfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+static int dnfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			 struct fb_info *info)
 {
 	printk("get cmap not supported\n");
 
 	return -EINVAL;
 }
 
-static int dnfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+static int dnfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			 struct fb_info *info)
 {
 	printk("set cmap not supported\n");
 
@@ -260,7 +270,8 @@
 
 }
 
-static int dnfb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+static int dnfb_pan_display(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
 {
 	printk("panning not supported\n");
 
@@ -269,17 +280,17 @@
 }
 
 static int dnfb_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg, int con, int fbidx)
+		      unsigned int cmd, unsigned long arg, int con,
+		      struct fb_info *info)
 {
 	return -EINVAL;
 }
 
-static void dnfb_set_disp(int con)
+static void dnfb_set_disp(int con, struct fb_info *info)
 {
   struct fb_fix_screeninfo fix;
 
-  /* ### FN: Needs fixes later */
-  dnfb_get_fix(&fix, con, 0);
+  dnfb_get_fix(&fix, con, info);
   if(con==-1) 
     con=0;
 
@@ -325,16 +336,16 @@
         printk("apollo frame buffer alive and kicking !\n");
 
 	
-        dnfb_get_var(&disp[0].var, 0, GET_FB_IDX(fb_info.node));
+        dnfb_get_var(&disp[0].var, 0, &fb_info);
 
-	dnfb_set_disp(-1);
+	dnfb_set_disp(-1, &fb_info);
 
 	return mem_start;
 
 }	
 
 	
-static int dnfbcon_switch(int con)
+static int dnfbcon_switch(int con, struct fb_info *info)
 { 
 	currcon=con;
 	
@@ -342,12 +353,12 @@
 
 }
 
-static int dnfbcon_updatevar(int con)
+static int dnfbcon_updatevar(int con, struct fb_info *info)
 {
 	return 0;
 }
 
-static void dnfbcon_blank(int blank)
+static void dnfbcon_blank(int blank, struct fb_info *info)
 {
 	if(blank)  {
         	outb(0, AP_CONTROL_3A);
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcmap.c m68k-2.1.77/drivers/video/fbcmap.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcmap.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcmap.c	Fri Jan  9 01:20:34 1998
@@ -43,8 +43,8 @@
 };
 static u_short blue2[] = {
     0x0000, 0xaaaa
-};                                                  
- 
+};
+
 static u_short red4[] = {
     0x0000, 0xaaaa, 0x5555, 0xffff
 };
@@ -54,7 +54,7 @@
 static u_short blue4[] = {
     0x0000, 0xaaaa, 0x5555, 0xffff
 };
- 
+
 static u_short red8[] = {
     0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa
 };
@@ -64,7 +64,7 @@
 static u_short blue8[] = {
     0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa
 };
- 
+
 static u_short red16[] = {
     0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
     0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
@@ -83,10 +83,10 @@
 };
 static struct fb_cmap default_8_colors = {
     0, 8, red8, green8, blue8, NULL
-};                                  
+};
 static struct fb_cmap default_4_colors = {
     0, 4, red4, green4, blue4, NULL
-};             
+};
 static struct fb_cmap default_16_colors = {
     0, 16, red16, green16, blue16, NULL
 };
@@ -99,31 +99,31 @@
 int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
 {
     int size = len*sizeof(u_short);
-		    
+
     if (cmap->len != len) {
-	if (cmap->red)                                         
+	if (cmap->red)
 	    kfree(cmap->red);
 	if (cmap->green)
 	    kfree(cmap->green);
 	if (cmap->blue)
 	    kfree(cmap->blue);
 	if (cmap->transp)
-	    kfree(cmap->transp);            
-	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;    
-	cmap->len = 0;                          
-	if (!len) 
-	    return 0;                                      
+	    kfree(cmap->transp);
+	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
+	cmap->len = 0;
+	if (!len)
+	    return 0;
 	if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
 	    return -1;
-	if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))                 
+	if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
 	    return -1;
 	if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
-	    return -1;                  
-	if (transp) {                            
+	    return -1;
+	if (transp) {
 	    if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
-		return -1;                                      
-	} else                  
-	    cmap->transp = NULL;                                    
+		return -1;
+	} else
+	    cmap->transp = NULL;
     }
     cmap->start = 0;
     cmap->len = len;
@@ -150,12 +150,12 @@
 	size = from->len-fromoff;
     if (size < 0)
 	return;
-    size *= sizeof(u_short);                         
+    size *= sizeof(u_short);
     memcpy_fs(fsfromto, to->red+tooff, from->red+fromoff, size);
     memcpy_fs(fsfromto, to->green+tooff, from->green+fromoff, size);
     memcpy_fs(fsfromto, to->blue+tooff, from->blue+fromoff, size);
     if (from->transp && to->transp)
-	memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);                              
+	memcpy_fs(fsfromto, to->transp+tooff, from->transp+fromoff, size);
 }
 
 
@@ -164,7 +164,8 @@
      */
 
 int fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc,
-    	    	int (*getcolreg)(u_int, u_int *, u_int *, u_int *, u_int *))
+    	    	int (*getcolreg)(u_int, u_int *, u_int *, u_int *, u_int *,
+				 struct fb_info *), struct fb_info *info)
 {
     int i, start;
     u_short *red, *green, *blue, *transp;
@@ -178,7 +179,7 @@
     if (start < 0)
 	return -EINVAL;
     for (i = 0; i < cmap->len; i++) {
-	if (getcolreg(start++, &hred, &hgreen, &hblue, &htransp))
+	if (getcolreg(start++, &hred, &hgreen, &hblue, &htransp, info))
 	    return 0;
 	hred = CNVT_FROMHW(hred, var->red.length);
 	hgreen = CNVT_FROMHW(hgreen, var->green.length);
@@ -212,7 +213,8 @@
      */
 
 int fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc,
-    	    	int (*setcolreg)(u_int, u_int, u_int, u_int, u_int))
+    	    	int (*setcolreg)(u_int, u_int, u_int, u_int, u_int,
+				 struct fb_info *), struct fb_info *info)
 {
     int i, start;
     u_short *red, *green, *blue, *transp;
@@ -250,7 +252,7 @@
 	blue++;
 	if (transp)
 	    transp++;
-	if (setcolreg(start++, hred, hgreen, hblue, htransp))
+	if (setcolreg(start++, hred, hgreen, hblue, htransp, info))
 	    return 0;
     }
     return 0;
@@ -261,22 +263,15 @@
      *  Get the default colormap for a specific screen depth
      */
 
-struct fb_cmap *fb_default_cmap(int bpp)
+struct fb_cmap *fb_default_cmap(int len)
 {
-    switch (bpp) {                                                          
-	case 1:                                                       
-	    return &default_2_colors;
-	    break;
-	case 2:                                            
-	    return &default_4_colors;                             
-	    break;                                   
-	case 3:
-	    return &default_8_colors;                              
-	    break;
-	default:
-	    return &default_16_colors;
-	    break;                                                  
-    }
+    if (len <= 2)
+	return &default_2_colors;
+    if (len <= 4)
+	return &default_4_colors;
+    if (len <= 8)
+	return &default_8_colors;
+    return &default_16_colors;
 }
 
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-afb.c m68k-2.1.77/drivers/video/fbcon-afb.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-afb.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcon-afb.c	Fri Jan  9 01:20:34 1998
@@ -49,6 +49,8 @@
      *  Bitplanes à la Amiga
      */
 
+static u_char expand_table[1024];
+
 static int open_afb(struct display *p)
 {
     if (p->type != FB_TYPE_PLANES)
@@ -60,6 +62,16 @@
 	p->next_line = p->var.xres_virtual>>3;
     p->next_plane = p->var.yres_virtual*p->next_line;
     MOD_INC_USE_COUNT;
+    if (!expand_table[1023]) {
+	/* initialise the table */
+	u_short i;
+	for (i = 0; i < 256; i++) {
+	    expand_table[i] = 0;	/* bg = fg = 0 */
+	    expand_table[i+256] = i;	/* bg = 0, fg = 1 */
+	    expand_table[i+512] = ~i;	/* bg = 1, fg = 0 */
+	    expand_table[i+768] = 0xff;	/* bg = fg = 1 */
+	}
+    }
     return 0;
 }
 
@@ -72,44 +84,49 @@
 	              int height, int width)
 {
     u_char *src, *dest, *src0, *dest0;
-    u_int i, rows;
+    u_short i, j;
 
     if (sx == 0 && dx == 0 && width == p->next_line) {
 	src = p->screen_base+sy*p->fontheight*width;
 	dest = p->screen_base+dy*p->fontheight*width;
-	for (i = p->var.bits_per_pixel; i--;) {
+	i = p->var.bits_per_pixel;
+	do {
 	    mymemmove(dest, src, height*p->fontheight*width);
 	    src += p->next_plane;
 	    dest += p->next_plane;
-	}
+	} while (--i);
     } else if (dy <= sy) {
 	src0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
 	dest0 = p->screen_base+dy*p->fontheight*p->next_line+dx;
-	for (i = p->var.bits_per_pixel; i--;) {
+	i = p->var.bits_per_pixel;
+	do {
 	    src = src0;
 	    dest = dest0;
-	    for (rows = height*p->fontheight; rows--;) {
+	    j = height*p->fontheight;
+	    do {
 	        mymemmove(dest, src, width);
 	        src += p->next_line;
 	        dest += p->next_line;
-	    }
+	    } while (--j);
 	    src0 += p->next_plane;
 	    dest0 += p->next_plane;
-	}
+	} while (--i);
     } else {
 	src0 = p->screen_base+(sy+height)*p->fontheight*p->next_line+sx;
 	dest0 = p->screen_base+(dy+height)*p->fontheight*p->next_line+dx;
-	for (i = p->var.bits_per_pixel; i--;) {
+	i = p->var.bits_per_pixel;
+	do {
 	    src = src0;
 	    dest = dest0;
-	    for (rows = height*p->fontheight; rows--;) {
+	    j = height*p->fontheight;
+	    do {
 	        src -= p->next_line;
 	        dest -= p->next_line;
 	        mymemmove(dest, src, width);
-	    }
+	    } while (--j);
 	    src0 += p->next_plane;
 	    dest0 += p->next_plane;
-	}
+	} while (--i);
     }
 }
 
@@ -117,29 +134,33 @@
 	              int height, int width)
 {
     u_char *dest, *dest0;
-    u_int i, rows;
+    u_short i, j;
     int bg;
 
     dest0 = p->screen_base+sy*p->fontheight*p->next_line+sx;
 
     bg = attr_bgcol_ec(p,conp);
-    for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+    i = p->var.bits_per_pixel;
+    do {
 	dest = dest0;
-	for (rows = height*p->fontheight; rows--; dest += p->next_line)
+	j = height*p->fontheight;
+	do {
 	    if (bg & 1)
 	        mymemset(dest, width);
 	    else
 	        mymemclear(dest, width);
+	    dest += p->next_line;
+	} while (--j);
 	bg >>= 1;
-    }
+	dest0 += p->next_plane;
+    } while (--i);
 }
 
 static void putc_afb(struct vc_data *conp, struct display *p, int c, int yy,
 	             int xx)
 {
-    u_char *dest, *dest0, *cdat, *cdat0;
-    u_int rows, i;
-    u_char d;
+    u_char *dest, *dest0, *cdat, *cdat0, *expand;
+    u_short i, j;
     int fg, bg;
 
     c &= 0xff;
@@ -149,25 +170,24 @@
     fg = attr_fgcol(p,conp);
     bg = attr_bgcol(p,conp);
 
-    for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+    i = p->var.bits_per_pixel;
+    do {
 	dest = dest0;
 	cdat = cdat0;
-	for (rows = p->fontheight; rows--; dest += p->next_line) {
-	    d = *cdat++;
-	    if (bg & 1)
-	        if (fg & 1)
-	            *dest = 0xff;
-	        else
-	            *dest = ~d;
-	    else
-	        if (fg & 1)
-	            *dest = d;
-	        else
-	            *dest = 0x00;
-	}
+	expand = expand_table;
+	if (bg & 1)
+	    expand += 512;
+	if (fg & 1)
+	    expand += 256;
+	j = p->fontheight;
+	do {
+	    *dest = expand[*cdat++];
+	    dest += p->next_line;
+	} while (--j);
 	bg >>= 1;
 	fg >>= 1;
-    }
+	dest0 += p->next_plane;
+    } while (--i);
 }
 
     /*
@@ -178,11 +198,10 @@
 static void putcs_afb(struct vc_data *conp, struct display *p, const char *s,
 	              int count, int yy, int xx)
 {
-    u_char *dest, *dest0, *dest1;
+    u_char *dest, *dest0, *dest1, *expand;
     u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
-    u_int rows, i;
+    u_short i, j;
     u_char c1, c2, c3, c4;
-    u_long d;
     int fg0, bg0, fg, bg;
 
     dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
@@ -199,26 +218,25 @@
 	    fg = fg0;
 	    bg = bg0;
 
-	    for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
+	    i = p->var.bits_per_pixel;
+	    do {
 	        dest = dest1;
 	        cdat1 = cdat10;
-	        for (rows = p->fontheight; rows--; dest += p->next_line) {
-	            d = *cdat1++;
-	            if (bg & 1)
-	                if (fg & 1)
-	                    *dest = 0xff;
-	                else
-	                    *dest = ~d;
-	            else
-	                if (fg & 1)
-	                    *dest = d;
-	                else
-	                    *dest = 0x00;
-	        }
+		expand = expand_table;
+		if (bg & 1)
+		    expand += 512;
+		if (fg & 1)
+		    expand += 256;
+		j = p->fontheight;
+		do {
+		    *dest = expand[*cdat1++];
+		    dest += p->next_line;
+	        } while (--j);
 	        bg >>= 1;
 	        fg >>= 1;
-	    }
-	} else {	/* Fast version */
+		dest1 += p->next_plane;
+	    } while (--i);
+	} else {			/* Fast version */
 	    c1 = s[0];
 	    c2 = s[1];
 	    c3 = s[2];
@@ -232,28 +250,39 @@
 	    fg = fg0;
 	    bg = bg0;
 
-	    for (i = p->var.bits_per_pixel; i--; dest1 += p->next_plane) {
+	    i = p->var.bits_per_pixel;
+	    do {
 	        dest = dest1;
 	        cdat1 = cdat10;
 	        cdat2 = cdat20;
 	        cdat3 = cdat30;
 	        cdat4 = cdat40;
-	        for (rows = p->fontheight; rows--; dest += p->next_line) {
-	            d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
-	            if (bg & 1)
-	                if (fg & 1)
-	                    *(u_long *)dest = 0xffffffff;
-	                else
-	                    *(u_long *)dest = ~d;
-	            else
-	                if (fg & 1)
-	                    *(u_long *)dest = d;
-	                else
-	                    *(u_long *)dest = 0x00000000;
-	        }
+		expand = expand_table;
+		if (bg & 1)
+		    expand += 512;
+		if (fg & 1)
+		    expand += 256;
+		j = p->fontheight;
+	        do {
+#if defined(__BIG_ENDIAN)
+		    *(u32 *)dest = expand[*cdat1++]<<24 |
+				   expand[*cdat2++]<<16 |
+				   expand[*cdat3++]<<8 |
+				   expand[*cdat4++];
+#elif defined(__LITTLE_ENDIAN)
+		    *(u32 *)dest = expand[*cdat1++] |
+				   expand[*cdat2++]<<8 |
+				   expand[*cdat3++]<<16 |
+				   expand[*cdat4++]<<24;
+#else
+#error FIXME: No endianness??
+#endif
+		    dest += p->next_line;
+	        } while (--j);
 	        bg >>= 1;
 	        fg >>= 1;
-	    }
+		dest1 += p->next_plane;
+	    } while (--i);
 	    s += 4;
 	    dest0 += 4;
 	    xx += 4;
@@ -264,7 +293,7 @@
 static void rev_char_afb(struct display *p, int xx, int yy)
 {
     u_char *dest, *dest0;
-    u_int rows, i;
+    u_short i, j;
     int mask;
 
     dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
@@ -276,14 +305,19 @@
      *  inverting.
      */
 
-    for (i = p->var.bits_per_pixel; i--; dest0 += p->next_plane) {
+    i = p->var.bits_per_pixel;
+    do {
 	if (mask & 1) {
 	    dest = dest0;
-	    for (rows = p->fontheight; rows--; dest += p->next_line)
+	    j = p->fontheight;
+	    do {
 	        *dest = ~*dest;
+		dest += p->next_line;
+	    } while (--j);
 	}
 	mask >>= 1;
-    }
+	dest0 += p->next_plane;
+    } while (--i);
 }
 
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-aty.c m68k-2.1.77/drivers/video/fbcon-aty.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-aty.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-aty.c	Fri Jan  9 01:24:19 1998
@@ -0,0 +1,213 @@
+/*
+ *  linux/drivers/video/fbcon-aty.c -- Low level frame buffer operations for 8
+ *				       bpp packed pixels on ATI (accelerated)
+ *
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *
+ *  This driver is based on fbcon-cfb8.c and on fbcon-mach64.c 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"
+
+
+    /*
+     *  Prototypes
+     */
+
+static int open_aty(struct display *p);
+static void release_aty(void);
+static void bmove_aty(struct display *p, int sy, int sx, int dy, int dx,
+		      int height, int width);
+static void clear_aty(struct vc_data *conp, struct display *p, int sy, int sx,
+		      int height, int width);
+static void putc_aty(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_aty(struct vc_data *conp, struct display *p, const char *s,
+		      int count, int yy, int xx);
+static void rev_char_aty(struct display *p, int xx, int yy);
+
+
+    /*
+     *  Accelerated functions in atyfb.c
+     */
+
+extern void aty_waitblit(void);
+extern void aty_rectcopy(int srcx, int srcy, int dstx, int dsty, u_int width,
+			 u_int height);
+extern void aty_rectfill(int dstx, int dsty, u_int width, u_int height,
+			 u_int fcolor);
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch dispsw_aty = {
+    open_aty, release_aty, bmove_aty, clear_aty, putc_aty, putcs_aty,
+    rev_char_aty
+};
+
+
+    /*
+     *  8 bpp packed pixels
+     */
+
+static u32 nibbletab_aty[] = {
+#if defined(__BIG_ENDIAN)
+    0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+    0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, 
+    0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, 
+    0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000, 0xff000000, 0x00ff0000, 0xffff0000, 
+    0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00, 
+    0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, 
+    0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static int open_aty(struct display *p)
+{
+    printk("open_aty: probing...\n");
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 8 ||
+	(p->visual != FB_VISUAL_PSEUDOCOLOR &&
+	 p->visual != FB_VISUAL_STATIC_PSEUDOCOLOR) ||
+	p->var.accel != FB_ACCEL_ATY)
+	return -EINVAL;
+
+    printk("open_aty: using ATY acceleration\n");
+    p->next_line = p->var.xres_virtual;
+    p->next_plane = 0;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static void release_aty(void)
+{
+    MOD_DEC_USE_COUNT;
+}
+
+static void bmove_aty(struct display *p, int sy, int sx, int dy, int dx,
+		      int height, int width)
+{
+    sx *= p->fontwidth;
+    sy *= p->fontheight;
+    dx *= p->fontwidth;
+    dy *= p->fontheight;
+    width *= p->fontwidth;
+    height *= p->fontheight;
+
+    aty_rectcopy(sx, sy, dx, dy, width, height);
+}
+
+static void clear_aty(struct vc_data *conp, struct display *p, int sy, int sx,
+		      int height, int width)
+{
+    u32 bgx = attr_bgcol_ec(p, conp);
+    bgx |= (bgx << 8);
+    bgx |= (bgx << 16);
+
+    sx *= p->fontwidth;
+    sy *= p->fontheight;
+    width *= p->fontwidth;
+    height *= p->fontheight;
+
+    aty_rectfill(sx, sy, width, height, bgx);
+}
+
+static void putc_aty(struct vc_data *conp, struct display *p, int c, int yy,
+		     int xx)
+{
+    u_char *dest, *cdat;
+    int bytes = p->next_line, rows;
+    u32 eorx, fgx, bgx;
+
+    c &= 0xff;
+
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    cdat = 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;
+
+    aty_waitblit();
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	((u32 *)dest)[0] = (nibbletab_aty[*cdat >> 4] & eorx) ^ bgx;
+	((u32 *)dest)[1] = (nibbletab_aty[*cdat++ & 0xf] & eorx) ^ bgx;
+    }
+}
+
+static void putcs_aty(struct vc_data *conp, struct display *p, const char *s,
+		      int count, int yy, int xx)
+{
+    u_char *cdat, c, *dest, *dest0;
+    int rows, bytes = p->next_line;
+    u32 eorx, fgx, bgx;
+
+    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;
+
+    aty_waitblit();
+    while (count--) {
+	c = *s++;
+	cdat = p->fontdata + c * p->fontheight;
+
+	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+	    ((u32 *)dest)[0] = (nibbletab_aty[*cdat >> 4] & eorx) ^ bgx;
+	    ((u32 *)dest)[1] = (nibbletab_aty[*cdat++ & 0xf] & eorx) ^ bgx;
+	}
+	dest0+=8;
+    }
+}
+
+static void rev_char_aty(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) {
+	((u32 *)dest)[0] ^= 0x0f0f0f0f;
+	((u32 *)dest)[1] ^= 0x0f0f0f0f;
+    }
+}
+
+
+#ifdef MODULE
+int init_module(void)
+#else
+int fbcon_init_aty(void)
+#endif
+{
+    return(fbcon_register_driver(&dispsw_aty, 1));
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+    fbcon_unregister_driver(&dispsw_aty);
+}
+#endif /* MODULE */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb16.c m68k-2.1.77/drivers/video/fbcon-cfb16.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb16.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcon-cfb16.c	Fri Jan  9 01:20:44 1998
@@ -1,6 +1,6 @@
 /*
  *  linux/drivers/video/cfb16.c -- Low level frame buffer operations for 16 bpp
- *				   packed pixels
+ *				   truecolor packed pixels
  *
  *	Created 5 Apr 1997 by Geert Uytterhoeven
  *
@@ -50,15 +50,23 @@
      *  16 bpp packed pixels
      */
 
-u_short packed16_cmap[16];
+u16 cfb16_cmap[16];
 
-static u_long tab_cfb16[] = {
-    0x00000000,0x0000ffff,0xffff0000,0xffffffff
+static u32 tab_cfb16[] = {
+#if defined(__BIG_ENDIAN)
+    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
 };
 
 static int open_cfb16(struct display *p)
 {
-    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 16)
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 16 ||
+	(p->visual != FB_VISUAL_TRUECOLOR &&
+	 p->visual != FB_VISUAL_DIRECTCOLOR))
 	return -EINVAL;
 
     p->next_line = p->var.xres_virtual<<1;
@@ -76,7 +84,7 @@
 			int height, int width)
 {
     int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
-    u_char *src,*dst;
+    u_char *src, *dst;
 
     if (sx == 0 && dx == 0 && width * 16 == bytes)
 	mymemmove(p->screen_base + dy * linesize,
@@ -104,34 +112,33 @@
 static void clear_cfb16(struct vc_data *conp, struct display *p, int sy,
 			int sx, int height, int width)
 {
-    u_char *dest0,*dest;
-    int bytes=p->next_line,lines=height * p->fontheight, rows, i;
-    u_long bgx;
+    u_char *dest0, *dest;
+    int bytes = p->next_line, lines = height * p->fontheight, rows, i;
+    u32 bgx;
 
     dest = p->screen_base + sy * p->fontheight * bytes + sx * 16;
 
-    bgx = attr_bgcol_ec(p,conp);
-    bgx = packed16_cmap[bgx];
+    bgx = cfb16_cmap[attr_bgcol_ec(p, conp)];
     bgx |= (bgx << 16);
 
     if (sx == 0 && width * 16 == bytes)
 	for (i = 0 ; i < lines * width ; i++) {
-	    ((u_long *)dest)[0]=bgx;
-	    ((u_long *)dest)[1]=bgx;
-	    ((u_long *)dest)[2]=bgx;
-	    ((u_long *)dest)[3]=bgx;
-	    dest+=16;
+	    ((u32 *)dest)[0] = bgx;
+	    ((u32 *)dest)[1] = bgx;
+	    ((u32 *)dest)[2] = bgx;
+	    ((u32 *)dest)[3] = bgx;
+	    dest += 16;
 	}
     else {
-	dest0=dest;
+	dest0 = dest;
 	for (rows = lines; rows-- ; dest0 += bytes) {
-	    dest=dest0;
+	    dest = dest0;
 	    for (i = 0 ; i < width ; i++) {
-		((u_long *)dest)[0]=bgx;
-		((u_long *)dest)[1]=bgx;
-		((u_long *)dest)[2]=bgx;
-		((u_long *)dest)[3]=bgx;
-		dest+=16;
+		((u32 *)dest)[0] = bgx;
+		((u32 *)dest)[1] = bgx;
+		((u32 *)dest)[2] = bgx;
+		((u32 *)dest)[3] = bgx;
+		dest += 16;
 	    }
 	}
     }
@@ -140,28 +147,27 @@
 static void putc_cfb16(struct vc_data *conp, struct display *p, int c, int yy,
 		       int xx)
 {
-    u_char *dest,*cdat;
-    int bytes=p->next_line,rows;
-    ulong eorx,fgx,bgx;
+    u_char *dest, *cdat;
+    int bytes = p->next_line, rows;
+    u32 eorx, fgx, bgx;
 
     c &= 0xff;
 
     dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
     cdat = p->fontdata + c * p->fontheight;
 
-    fgx = attr_fgcol(p,conp);
-    fgx = packed16_cmap[fgx];
-    bgx = attr_bgcol(p,conp);
-    bgx = packed16_cmap[bgx];
+    fgx = cfb16_cmap[attr_fgcol(p, conp)];
+    bgx = cfb16_cmap[attr_bgcol(p, conp)];
     fgx |= (fgx << 16);
     bgx |= (bgx << 16);
     eorx = fgx ^ bgx;
 
     for (rows = p->fontheight ; rows-- ; dest += bytes) {
-	((u_long *)dest)[0]= (tab_cfb16[*cdat >> 6] & eorx) ^ bgx;
-	((u_long *)dest)[1]= (tab_cfb16[*cdat >> 4 & 0x3] & eorx) ^ bgx;
-	((u_long *)dest)[2]= (tab_cfb16[*cdat >> 2 & 0x3] & eorx) ^ bgx;
-	((u_long *)dest)[3]= (tab_cfb16[*cdat++ & 0x3] & eorx) ^ bgx;
+	u_char bits = *cdat++;
+	((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+	((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+	((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+	((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
     }
 }
 
@@ -169,14 +175,12 @@
 			int count, int yy, int xx)
 {
     u_char *cdat, c, *dest, *dest0;
-    int rows,bytes=p->next_line;
-    u_long eorx, fgx, bgx;
+    int rows, bytes = p->next_line;
+    u32 eorx, fgx, bgx;
 
     dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 16;
-    fgx = attr_fgcol(p,conp);
-    fgx = packed16_cmap[fgx];
-    bgx = attr_bgcol(p,conp);
-    bgx = packed16_cmap[bgx];
+    fgx = cfb16_cmap[attr_fgcol(p, conp)];
+    bgx = cfb16_cmap[attr_bgcol(p, conp)];
     fgx |= (fgx << 16);
     bgx |= (bgx << 16);
     eorx = fgx ^ bgx;
@@ -185,26 +189,27 @@
 	cdat = p->fontdata + c * p->fontheight;
 
 	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
-	    ((u_long *)dest)[0]= (tab_cfb16[*cdat >> 6] & eorx) ^ bgx;
-	    ((u_long *)dest)[1]= (tab_cfb16[*cdat >> 4 & 0x3] & eorx) ^ bgx;
-	    ((u_long *)dest)[2]= (tab_cfb16[*cdat >> 2 & 0x3] & eorx) ^ bgx;
-	    ((u_long *)dest)[3]= (tab_cfb16[*cdat++ & 0x3] & eorx) ^ bgx;
+	    u_char bits = *cdat++;
+	    ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+	    ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+	    ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+	    ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
 	}
-	dest0+=16;
+	dest0 += 16;
     }
 }
 
 static void rev_char_cfb16(struct display *p, int xx, int yy)
 {
     u_char *dest;
-    int bytes=p->next_line, rows;
+    int bytes = p->next_line, rows;
 
     dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
     for (rows = p->fontheight ; rows-- ; dest += bytes) {
-	((u_long *)dest)[0] ^= 0xffffffff;
-	((u_long *)dest)[1] ^= 0xffffffff;
-	((u_long *)dest)[2] ^= 0xffffffff;
-	((u_long *)dest)[3] ^= 0xffffffff;
+	((u32 *)dest)[0] ^= 0xffffffff;
+	((u32 *)dest)[1] ^= 0xffffffff;
+	((u32 *)dest)[2] ^= 0xffffffff;
+	((u32 *)dest)[3] ^= 0xffffffff;
     }
 }
 
@@ -230,4 +235,4 @@
      *  Visible symbols for modules
      */
 
-EXPORT_SYMBOL(packed16_cmap);
+EXPORT_SYMBOL(cfb16_cmap);
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb2.c m68k-2.1.77/drivers/video/fbcon-cfb2.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb2.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-cfb2.c	Fri Jan  9 01:24:23 1998
@@ -0,0 +1,328 @@
+/*
+ *  linux/drivers/video/cfb2.c -- Low level frame buffer operations for 8 bpp
+ *				  packed pixels
+ *
+ *	Created 26 Dec 1997 by Michael Schmitz
+ *	Based on 
+ *
+ *  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"
+
+
+    /*
+     *  Prototypes
+     */
+
+static int open_cfb2(struct display *p);
+static void release_cfb2(void);
+static void bmove_cfb2(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static void clear_cfb2(struct vc_data *conp, struct display *p, int sy,
+		       int sx, int height, int width);
+static void putc_cfb2(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_cfb2(struct vc_data *conp, struct display *p,
+		       const char *s, int count, int yy, int xx);
+static void rev_char_cfb2(struct display *p, int xx, int yy);
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch dispsw_cfb2 = {
+    open_cfb2, release_cfb2, bmove_cfb2, clear_cfb2, putc_cfb2, putcs_cfb2,
+    rev_char_cfb2
+};
+
+
+    /*
+     *  4 bpp packed pixels
+     */
+
+   /*
+    *		IFF the font is even pixel aligned (that is to say each
+    *		character start is a byte start in the pixel pairs). That
+    *		avoids us having to mask bytes and means we won't be here
+    *		all week. On a MacII that matters _lots_
+    */
+
+static u_short nibbletab_cfb2[]={
+0x0000,0x0003,0x000c,0x000f,
+0x0030,0x0033,0x003c,0x003f,
+0x00c0,0x00c3,0x00cc,0x00cf,
+0x00f0,0x00f3,0x00fc,0x00ff,
+
+0x0300,0x0303,0x030c,0x030f,
+0x0330,0x0333,0x033c,0x033f,
+0x03c0,0x03c3,0x03cc,0x03cf,
+0x03f0,0x03f3,0x03fc,0x03ff,
+
+0x0c00,0x0c03,0x0c0c,0x0c0f,
+0x0c30,0x0c33,0x0c3c,0x0c3f,
+0x0cc0,0x0cc3,0x0ccc,0x0ccf,
+0x0cf0,0x0cf3,0x0cfc,0x0cff,
+
+0x0f00,0x0f03,0x0f0c,0x000f,
+0x0f30,0x0f33,0x0f3c,0x003f,
+0x0fc0,0x0fc3,0x0fcc,0x00cf,
+0x0ff0,0x0ff3,0x0ffc,0x0fff,
+
+/* */
+0x3000,0x3003,0x300c,0x300f,
+0x3030,0x3033,0x303c,0x303f,
+0x30c0,0x30c3,0x30cc,0x30cf,
+0x30f0,0x30f3,0x30fc,0x30ff,
+
+0x3300,0x3303,0x330c,0x330f,
+0x3330,0x3333,0x333c,0x333f,
+0x33c0,0x33c3,0x33cc,0x33cf,
+0x33f0,0x33f3,0x33fc,0x33ff,
+
+0x3c00,0x3c03,0x3c0c,0x3c0f,
+0x3c30,0x3c33,0x3c3c,0x3c3f,
+0x3cc0,0x3cc3,0x3ccc,0x3ccf,
+0x3cf0,0x3cf3,0x3cfc,0x3cff,
+
+0x3f00,0x3f03,0x3f0c,0x3f0f,
+0x3f30,0x3f33,0x3f3c,0x3f3f,
+0x3fc0,0x3fc3,0x3fcc,0x3fcf,
+0x3ff0,0x3ff3,0x3ffc,0x3fff,
+
+/* */
+0xc000,0xc003,0xc00c,0xc00f,
+0xc030,0xc033,0xc03c,0xc03f,
+0xc0c0,0xc0c3,0xc0cc,0xc0cf,
+0xc0f0,0xc0f3,0xc0fc,0xc0ff,
+
+0xc300,0xc303,0xc30c,0xc30f,
+0xc330,0xc333,0xc33c,0xc33f,
+0xc3c0,0xc3c3,0xc3cc,0xc3cf,
+0xc3f0,0xc3f3,0xc3fc,0xc3ff,
+
+0xcc00,0xcc03,0xcc0c,0xcc0f,
+0xcc30,0xcc33,0xcc3c,0xcc3f,
+0xccc0,0xccc3,0xcccc,0xcccf,
+0xccf0,0xccf3,0xccfc,0xccff,
+
+0xcf00,0xcf03,0xcf0c,0xcf0f,
+0xcf30,0xcf33,0xcf3c,0xcf3f,
+0xcfc0,0xcfc3,0xcfcc,0xcfcf,
+0xcff0,0xcff3,0xcffc,0xcfff,
+
+/* */
+0xf000,0xf003,0xf00c,0xf00f,
+0xf030,0xf033,0xf03c,0xf03f,
+0xf0c0,0xf0c3,0xf0cc,0xf0cf,
+0xf0f0,0xf0f3,0xf0fc,0xf0ff,
+
+0xf300,0xf303,0xf30c,0xf30f,
+0xf330,0xf333,0xf33c,0xf33f,
+0xf3c0,0xf3c3,0xf3cc,0xf3cf,
+0xf3f0,0xf3f3,0xf3fc,0xf3ff,
+
+0xfc00,0xfc03,0xfc0c,0xfc0f,
+0xfc30,0xfc33,0xfc3c,0xfc3f,
+0xfcc0,0xfcc3,0xfccc,0xfccf,
+0xfcf0,0xfcf3,0xfcfc,0xfcff,
+
+0xff00,0xff03,0xff0c,0xff0f,
+0xff30,0xff33,0xff3c,0xff3f,
+0xffc0,0xffc3,0xffcc,0xffcf,
+0xfff0,0xfff3,0xfffc,0xffff};
+
+static int open_cfb2(struct display *p)
+{
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 2)
+	return -EINVAL;
+
+    p->next_line = p->var.xres_virtual>>2;
+    p->next_plane = 0;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static void release_cfb2(void)
+{
+    MOD_DEC_USE_COUNT;
+}
+
+static void bmove_cfb2(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+	u_char *src,*dst;
+
+	if (sx == 0 && dx == 0 && width * 2 == bytes) {
+		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 * 2;
+			dst = p->screen_base + dy * linesize + dx * 2;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 2);
+				src += bytes;
+				dst += bytes;
+			}
+		}
+		else {
+			src = p->screen_base + (sy+height) * linesize + sx * 2
+				- bytes;
+			dst = p->screen_base + (dy+height) * linesize + dx * 2
+				- bytes;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 2);
+				src -= bytes;
+				dst -= bytes;
+			}
+		}
+	}
+}
+
+static void clear_cfb2(struct vc_data *conp, struct display *p, int sy,
+                       int sx, int height, int width)
+{
+	u_char *dest0,*dest;
+	int bytes=p->next_line,lines=height * p->fontheight, rows, i;
+	u_long bgx;
+
+/*	if(p->screen_base!=0xFDD00020)
+		mac_boom(1);*/
+	dest = p->screen_base + sy * p->fontheight * bytes + sx * 2;
+
+	bgx=attr_bgcol_ec(p,conp);
+	bgx |= (bgx << 2);	/* expand the colour to 32bits */
+	bgx |= (bgx << 4);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+
+	if (sx == 0 && width * 2 == bytes) {
+		for (i = 0 ; i < lines * width ; i++) {
+			((u_long *)dest)[0]=bgx;
+			dest+=2;
+		}
+	} else {
+		dest0=dest;
+		for (rows = lines; rows-- ; dest0 += bytes) {
+			dest=dest0;
+			for (i = 0 ; i < width ; i++) {
+				/* memset ?? */
+				((u_long *)dest)[0]=bgx;
+				dest+=2;
+			}
+		}
+	}
+}
+
+static void putc_cfb2(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
+{
+	u_char *dest,*cdat;
+	int bytes=p->next_line,rows;
+	ulong eorx,fgx,bgx;
+
+	c &= 0xff;
+
+	dest = p->screen_base + yy * p->fontheight * bytes + xx * 4;
+	cdat = p->fontdata + c * p->fontheight;
+
+	fgx=3;/*attr_fgcol(p,conp)&0x0F;*/
+	bgx=attr_bgcol(p,conp)&0x0F;
+	fgx |= (fgx << 2);
+	fgx |= (fgx << 4);
+	fgx |= (fgx << 8);
+	bgx |= (bgx << 2);
+	bgx |= (bgx << 4);
+	bgx |= (bgx << 8);
+	eorx = fgx ^ bgx;
+
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_short *)dest)[0]=
+			(nibbletab_cfb2[*cdat >> 6] & eorx) ^ bgx;
+		((u_short *)dest)[1]=
+			(nibbletab_cfb2[(*cdat >> 4) & 0x3] & eorx) ^ bgx;
+		((u_short *)dest)[2]=
+			(nibbletab_cfb2[(*cdat >> 2) & 0x3] & eorx) ^ bgx;
+		((u_short *)dest)[4]=
+			(nibbletab_cfb2[*cdat++ & 0x3] & eorx) ^ bgx;
+	}
+}
+
+static void putcs_cfb2(struct vc_data *conp, struct display *p,
+                       const char *s, int count, int yy, int xx)
+{
+	u_char *cdat, c, *dest, *dest0;
+	int rows,bytes=p->next_line;
+	u_long eorx, fgx, bgx;
+
+	dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 2;
+	fgx=3/*attr_fgcol(p,conp)*/;
+	bgx=attr_bgcol(p,conp);
+	fgx |= (fgx << 2);
+	fgx |= (fgx << 4);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 2);
+	bgx |= (bgx << 4);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+	while (count--) {
+		c = *s++;
+		cdat = p->fontdata + c * p->fontheight;
+
+		for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			((u_short *)dest)[0]=
+			(nibbletab_cfb2[*cdat >> 6] & eorx) ^ bgx;
+			((u_short *)dest)[1]=
+				(nibbletab_cfb2[(*cdat >> 4) & 0x3] & eorx) ^ bgx;
+			((u_short *)dest)[2]=
+				(nibbletab_cfb2[(*cdat >> 2) & 0x3] & eorx) ^ bgx;
+			((u_short *)dest)[1]=
+			(nibbletab_cfb2[*cdat++ & 0x3] & eorx) ^ bgx;
+		}
+		dest0+=2;
+	}
+}
+
+static void rev_char_cfb2(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 * 2;
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0] ^= 0x33333333;
+	}
+}
+
+#ifdef MODULE
+int init_module(void)
+#else
+int fbcon_init_cfb2(void)
+#endif
+{
+    return(fbcon_register_driver(&dispsw_cfb2, 0));
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+    fbcon_unregister_driver(&dispsw_cfb2);
+}
+#endif /* MODULE */
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb32.c m68k-2.1.77/drivers/video/fbcon-cfb32.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb32.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-cfb32.c	Fri Jan  9 01:24:26 1998
@@ -0,0 +1,243 @@
+/*
+ *  linux/drivers/video/cfb32.c -- Low level frame buffer operations for 32 bpp
+ *				   truecolor packed pixels
+ *
+ *	Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/fb.h>
+
+#include "fbcon.h"
+
+
+    /*
+     *  Prototypes
+     */
+
+static int open_cfb32(struct display *p);
+static void release_cfb32(void);
+static void bmove_cfb32(struct display *p, int sy, int sx, int dy, int dx,
+			int height, int width);
+static void clear_cfb32(struct vc_data *conp, struct display *p, int sy,
+			int sx, int height, int width);
+static void putc_cfb32(struct vc_data *conp, struct display *p, int c,
+		       int yy, int xx);
+static void putcs_cfb32(struct vc_data *conp, struct display *p,
+			const char *s, int count, int yy, int xx);
+static void rev_char_cfb32(struct display *p, int xx, int yy);
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch dispsw_cfb32 = {
+    open_cfb32, release_cfb32, bmove_cfb32, clear_cfb32, putc_cfb32,
+    putcs_cfb32, rev_char_cfb32
+};
+
+
+    /*
+     *  32 bpp packed pixels
+     */
+
+u32 cfb32_cmap[16];
+
+static int open_cfb32(struct display *p)
+{
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 32 ||
+	(p->visual != FB_VISUAL_TRUECOLOR &&
+	 p->visual != FB_VISUAL_DIRECTCOLOR))
+	return -EINVAL;
+
+    p->next_line = p->var.xres_virtual<<2;
+    p->next_plane = 0;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static void release_cfb32(void)
+{
+    MOD_DEC_USE_COUNT;
+}
+
+static void bmove_cfb32(struct display *p, int sy, int sx, int dy, int dx,
+			int height, int width)
+{
+    int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+    u_char *src, *dst;
+
+    if (sx == 0 && dx == 0 && width * 32 == bytes)
+	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 * 32;
+	dst = p->screen_base + dy * linesize + dx * 32;
+	for (rows = height * p->fontheight ; rows-- ;) {
+	    mymemmove(dst, src, width * 32);
+	    src += bytes;
+	    dst += bytes;
+	}
+    } else {
+	src = p->screen_base + (sy+height) * linesize + sx * 32 - bytes;
+	dst = p->screen_base + (dy+height) * linesize + dx * 32 - bytes;
+	for (rows = height * p->fontheight ; rows-- ;) {
+	    mymemmove(dst, src, width * 32);
+	    src -= bytes;
+	    dst -= bytes;
+	}
+    }
+}
+
+static void clear_cfb32(struct vc_data *conp, struct display *p, int sy,
+			int sx, int height, int width)
+{
+    u_char *dest0, *dest;
+    int bytes = p->next_line, lines = height * p->fontheight, rows, i;
+    u32 bgx;
+
+    dest = p->screen_base + sy * p->fontheight * bytes + sx * 32;
+
+    bgx = cfb32_cmap[attr_bgcol_ec(p, conp)];
+
+    if (sx == 0 && width * 32 == bytes)
+	for (i = 0 ; i < lines * width ; i++) {
+	    ((u32 *)dest)[0] = bgx;
+	    ((u32 *)dest)[1] = bgx;
+	    ((u32 *)dest)[2] = bgx;
+	    ((u32 *)dest)[3] = bgx;
+	    ((u32 *)dest)[4] = bgx;
+	    ((u32 *)dest)[5] = bgx;
+	    ((u32 *)dest)[6] = bgx;
+	    ((u32 *)dest)[7] = bgx;
+	    dest += 32;
+	}
+    else {
+	dest0 = dest;
+	for (rows = lines; rows-- ; dest0 += bytes) {
+	    dest = dest0;
+	    for (i = 0 ; i < width ; i++) {
+		((u32 *)dest)[0] = bgx;
+		((u32 *)dest)[1] = bgx;
+		((u32 *)dest)[2] = bgx;
+		((u32 *)dest)[3] = bgx;
+		((u32 *)dest)[4] = bgx;
+		((u32 *)dest)[5] = bgx;
+		((u32 *)dest)[6] = bgx;
+		((u32 *)dest)[7] = bgx;
+		dest += 32;
+	    }
+	}
+    }
+}
+
+static void putc_cfb32(struct vc_data *conp, struct display *p, int c, int yy,
+		       int xx)
+{
+    u_char *dest, *cdat;
+    int bytes = p->next_line, rows;
+    u32 eorx, fgx, bgx;
+
+    c &= 0xff;
+
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 32;
+    cdat = p->fontdata + c * p->fontheight;
+
+    fgx = cfb32_cmap[attr_fgcol(p, conp)];
+    bgx = cfb32_cmap[attr_bgcol(p, conp)];
+    eorx = fgx ^ bgx;
+
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	u_char bits = *cdat++;
+	((u32 *)dest)[0] = (-(bits >> 7) & eorx) ^ bgx;
+	((u32 *)dest)[1] = (-(bits >> 6 & 1) & eorx) ^ bgx;
+	((u32 *)dest)[2] = (-(bits >> 5 & 1) & eorx) ^ bgx;
+	((u32 *)dest)[3] = (-(bits >> 4 & 1) & eorx) ^ bgx;
+	((u32 *)dest)[4] = (-(bits >> 3 & 1) & eorx) ^ bgx;
+	((u32 *)dest)[5] = (-(bits >> 2 & 1) & eorx) ^ bgx;
+	((u32 *)dest)[6] = (-(bits >> 1 & 1) & eorx) ^ bgx;
+	((u32 *)dest)[7] = (-(bits & 1) & eorx) ^ bgx;
+    }
+}
+
+static void putcs_cfb32(struct vc_data *conp, struct display *p, const char *s,
+			int count, int yy, int xx)
+{
+    u_char *cdat, c, *dest, *dest0;
+    int rows, bytes = p->next_line;
+    u32 eorx, fgx, bgx;
+
+    dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 32;
+    fgx = cfb32_cmap[attr_fgcol(p, conp)];
+    bgx = cfb32_cmap[attr_bgcol(p, conp)];
+    eorx = fgx ^ bgx;
+    while (count--) {
+	c = *s++;
+	cdat = p->fontdata + c * p->fontheight;
+
+	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+	    u_char bits = *cdat++;
+	    ((u32 *)dest)[0] = (-(bits >> 7) & eorx) ^ bgx;
+	    ((u32 *)dest)[1] = (-(bits >> 6 & 1) & eorx) ^ bgx;
+	    ((u32 *)dest)[2] = (-(bits >> 5 & 1) & eorx) ^ bgx;
+	    ((u32 *)dest)[3] = (-(bits >> 4 & 1) & eorx) ^ bgx;
+	    ((u32 *)dest)[4] = (-(bits >> 3 & 1) & eorx) ^ bgx;
+	    ((u32 *)dest)[5] = (-(bits >> 2 & 1) & eorx) ^ bgx;
+	    ((u32 *)dest)[6] = (-(bits >> 1 & 1) & eorx) ^ bgx;
+	    ((u32 *)dest)[7] = (-(bits & 1) & eorx) ^ bgx;
+	}
+	dest0 += 32;
+    }
+}
+
+static void rev_char_cfb32(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 * 32;
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	((u32 *)dest)[0] ^= 0xffffffff;
+	((u32 *)dest)[1] ^= 0xffffffff;
+	((u32 *)dest)[2] ^= 0xffffffff;
+	((u32 *)dest)[3] ^= 0xffffffff;
+	((u32 *)dest)[4] ^= 0xffffffff;
+	((u32 *)dest)[5] ^= 0xffffffff;
+	((u32 *)dest)[6] ^= 0xffffffff;
+	((u32 *)dest)[7] ^= 0xffffffff;
+    }
+}
+
+
+#ifdef MODULE
+int init_module(void)
+#else
+int fbcon_init_cfb32(void)
+#endif
+{
+    return(fbcon_register_driver(&dispsw_cfb32, 0));
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+    fbcon_unregister_driver(&dispsw_cfb32);
+}
+#endif /* MODULE */
+
+
+    /*
+     *  Visible symbols for modules
+     */
+
+EXPORT_SYMBOL(cfb32_cmap);
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb4.c m68k-2.1.77/drivers/video/fbcon-cfb4.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb4.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-cfb4.c	Fri Jan  9 01:24:29 1998
@@ -0,0 +1,237 @@
+/*
+ *  linux/drivers/video/cfb4.c -- Low level frame buffer operations for 4 bpp
+ *				  packed pixels
+ *
+ *	Created 26 Dec 1997 by Michael Schmitz
+ *	Based on the old macfb.c 4bpp code by Alan Cox
+ *
+ *  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"
+
+
+    /*
+     *  Prototypes
+     */
+
+static int open_cfb4(struct display *p);
+static void release_cfb4(void);
+static void bmove_cfb4(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static void clear_cfb4(struct vc_data *conp, struct display *p, int sy,
+		       int sx, int height, int width);
+static void putc_cfb4(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_cfb4(struct vc_data *conp, struct display *p,
+		       const char *s, int count, int yy, int xx);
+static void rev_char_cfb4(struct display *p, int xx, int yy);
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch dispsw_cfb4 = {
+    open_cfb4, release_cfb4, bmove_cfb4, clear_cfb4, putc_cfb4, putcs_cfb4,
+    rev_char_cfb4
+};
+
+
+    /*
+     *  4 bpp packed pixels
+     */
+
+   /*
+    *		IFF the font is even pixel aligned (that is to say each
+    *		character start is a byte start in the pixel pairs). That
+    *		avoids us having to mask bytes and means we won't be here
+    *		all week. On a MacII that matters _lots_
+    */
+
+static u_short nibbletab_cfb4[]={
+0x0000,0x000f,0x00f0,0x00ff,
+0x0f00,0x0f0f,0x0ff0,0x0fff,
+0xf000,0xf00f,0xf0f0,0xf0ff,
+0xff00,0xff0f,0xfff0,0xffff};
+
+static int open_cfb4(struct display *p)
+{
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 4)
+	return -EINVAL;
+
+    p->next_line = p->var.xres_virtual>>1;
+    p->next_plane = 0;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static void release_cfb4(void)
+{
+    MOD_DEC_USE_COUNT;
+}
+
+static void bmove_cfb4(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
+	u_char *src,*dst;
+
+	if (sx == 0 && dx == 0 && width * 4 == bytes) {
+		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 * 4;
+			dst = p->screen_base + dy * linesize + dx * 4;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 4);
+				src += bytes;
+				dst += bytes;
+			}
+		}
+		else {
+			src = p->screen_base + (sy+height) * linesize + sx * 4
+				- bytes;
+			dst = p->screen_base + (dy+height) * linesize + dx * 4
+				- bytes;
+			for (rows = height * p->fontheight ; rows-- ;) {
+				mymemmove(dst, src, width * 4);
+				src -= bytes;
+				dst -= bytes;
+			}
+		}
+	}
+}
+
+static void clear_cfb4(struct vc_data *conp, struct display *p, int sy,
+                       int sx, int height, int width)
+{
+	u_char *dest0,*dest;
+	int bytes=p->next_line,lines=height * p->fontheight, rows, i;
+	u_long bgx;
+
+/*	if(p->screen_base!=0xFDD00020)
+		mac_boom(1);*/
+	dest = p->screen_base + sy * p->fontheight * bytes + sx * 4;
+
+	bgx=attr_bgcol_ec(p,conp);
+	bgx |= (bgx << 4);	/* expand the colour to 32bits */
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+
+	if (sx == 0 && width * 4 == bytes) {
+		for (i = 0 ; i < lines * width ; i++) {
+			((u_long *)dest)[0]=bgx;
+			dest+=4;
+		}
+	} else {
+		dest0=dest;
+		for (rows = lines; rows-- ; dest0 += bytes) {
+			dest=dest0;
+			for (i = 0 ; i < width ; i++) {
+				/* memset ?? */
+				((u_long *)dest)[0]=bgx;
+				dest+=4;
+			}
+		}
+	}
+}
+
+static void putc_cfb4(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
+{
+	u_char *dest,*cdat;
+	int bytes=p->next_line,rows;
+	ulong eorx,fgx,bgx;
+
+	c &= 0xff;
+
+	dest = p->screen_base + yy * p->fontheight * bytes + xx * 4;
+	cdat = p->fontdata + c * p->fontheight;
+
+	fgx=15;/*attr_fgcol(p,conp)&0x0F;*/
+	bgx=attr_bgcol(p,conp)&0x0F;
+	fgx |= (fgx << 4);
+	fgx |= (fgx << 8);
+	bgx |= (bgx << 4);
+	bgx |= (bgx << 8);
+	eorx = fgx ^ bgx;
+
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_short *)dest)[0]=
+			(nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx;
+		((u_short *)dest)[1]=
+			(nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx;
+	}
+}
+
+static void putcs_cfb4(struct vc_data *conp, struct display *p,
+                       const char *s, int count, int yy, int xx)
+{
+	u_char *cdat, c, *dest, *dest0;
+	int rows,bytes=p->next_line;
+	u_long eorx, fgx, bgx;
+
+	dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 4;
+	fgx=15/*attr_fgcol(p,conp)*/;
+	bgx=attr_bgcol(p,conp);
+	fgx |= (fgx << 4);
+	fgx |= (fgx << 8);
+	fgx |= (fgx << 16);
+	bgx |= (bgx << 4);
+	bgx |= (bgx << 8);
+	bgx |= (bgx << 16);
+	eorx = fgx ^ bgx;
+	while (count--) {
+		c = *s++;
+		cdat = p->fontdata + c * p->fontheight;
+
+		for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+			((u_short *)dest)[0]=
+			(nibbletab_cfb4[*cdat >> 4] & eorx) ^ bgx;
+			((u_short *)dest)[1]=
+			(nibbletab_cfb4[*cdat++ & 0xf] & eorx) ^ bgx;
+		}
+		dest0+=4;
+	}
+}
+
+static void rev_char_cfb4(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 * 4;
+	for (rows = p->fontheight ; rows-- ; dest += bytes) {
+		((u_long *)dest)[0] ^= 0x0f0f0f0f;
+	}
+}
+
+#ifdef MODULE
+int init_module(void)
+#else
+int fbcon_init_cfb4(void)
+#endif
+{
+    return(fbcon_register_driver(&dispsw_cfb4, 0));
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+    fbcon_unregister_driver(&dispsw_cfb4);
+}
+#endif /* MODULE */
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb8.c m68k-2.1.77/drivers/video/fbcon-cfb8.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-cfb8.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcon-cfb8.c	Fri Jan  9 01:21:07 1998
@@ -50,16 +50,27 @@
      *  8 bpp packed pixels
      */
 
-static u_long nibbletab_cfb8[] = {
+static u32 nibbletab_cfb8[] = {
+#if defined(__BIG_ENDIAN)
     0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
     0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
     0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
     0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000,0xff000000,0x00ff0000,0xffff0000,
+    0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+    0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+    0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
 };
 
 static int open_cfb8(struct display *p)
 {
-    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 8)
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->var.bits_per_pixel != 8 ||
+	(p->visual != FB_VISUAL_PSEUDOCOLOR &&
+	 p->visual != FB_VISUAL_STATIC_PSEUDOCOLOR))
 	return -EINVAL;
 
     p->next_line = p->var.xres_virtual;
@@ -107,7 +118,7 @@
 {
     u_char *dest0,*dest;
     int bytes=p->next_line,lines=height * p->fontheight, rows, i;
-    u_long bgx;
+    u32 bgx;
 
     dest = p->screen_base + sy * p->fontheight * bytes + sx * 8;
 
@@ -117,8 +128,8 @@
 
     if (sx == 0 && width * 8 == bytes)
 	for (i = 0 ; i < lines * width ; i++) {
-	    ((u_long *)dest)[0]=bgx;
-	    ((u_long *)dest)[1]=bgx;
+	    ((u32 *)dest)[0]=bgx;
+	    ((u32 *)dest)[1]=bgx;
 	    dest+=8;
 	}
     else {
@@ -126,8 +137,8 @@
 	for (rows = lines; rows-- ; dest0 += bytes) {
 	    dest=dest0;
 	    for (i = 0 ; i < width ; i++) {
-		((u_long *)dest)[0]=bgx;
-		((u_long *)dest)[1]=bgx;
+		((u32 *)dest)[0]=bgx;
+		((u32 *)dest)[1]=bgx;
 		dest+=8;
 	    }
 	}
@@ -139,7 +150,7 @@
 {
     u_char *dest,*cdat;
     int bytes=p->next_line,rows;
-    ulong eorx,fgx,bgx;
+    u32 eorx,fgx,bgx;
 
     c &= 0xff;
 
@@ -155,8 +166,8 @@
     eorx = fgx ^ bgx;
 
     for (rows = p->fontheight ; rows-- ; dest += bytes) {
-	((u_long *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
-	((u_long *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
+	((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+	((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
     }
 }
 
@@ -165,7 +176,7 @@
 {
     u_char *cdat, c, *dest, *dest0;
     int rows,bytes=p->next_line;
-    u_long eorx, fgx, bgx;
+    u32 eorx, fgx, bgx;
 
     dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8;
     fgx=attr_fgcol(p,conp);
@@ -180,9 +191,8 @@
 	cdat = p->fontdata + c * p->fontheight;
 
 	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
-	    ((u_long *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
-	    ((u_long *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^
-				 bgx;
+	    ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+	    ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
 	}
 	dest0+=8;
     }
@@ -195,8 +205,8 @@
 
     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;
+	((u32 *)dest)[0] ^= 0x0f0f0f0f;
+	((u32 *)dest)[1] ^= 0x0f0f0f0f;
     }
 }
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-cyber.c m68k-2.1.77/drivers/video/fbcon-cyber.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-cyber.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcon-cyber.c	Fri Jan  9 01:21:07 1998
@@ -67,6 +67,22 @@
      *  CyberVision64 (accelerated)
      */
 
+static u32 nibbletab_cfb8[] = {
+#if defined(__BIG_ENDIAN)
+    0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+    0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+    0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+    0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000,0xff000000,0x00ff0000,0xffff0000,
+    0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+    0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+    0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
 static int open_cyber(struct display *p)
 {
     if (p->type != FB_TYPE_PACKED_PIXELS ||
@@ -111,80 +127,52 @@
 static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy,
 	               int xx)
 {
-    u_char *dest, *cdat;
-    u_long tmp;
-    u_int rows, revs, underl;
-    u_char d;
-    u_char fg, bg;
+    u_char *dest,*cdat;
+    int bytes=p->next_line,rows;
+    u32 eorx,fgx,bgx;
 
     c &= 0xff;
 
-    dest = p->screen_base+yy*p->fontheight*p->next_line+8*xx;
-    cdat = p->fontdata+(c*p->fontheight);
-    fg = p->fgcol;
-    bg = p->bgcol;
-    revs = conp->vc_reverse;
-    underl = conp->vc_underline;
-
-    Cyber_WaitBlit();
-    for (rows = p->fontheight; rows--; dest += p->next_line) {
-	d = *cdat++;
-
-	if (underl && !rows)
-	    d = 0xff;
-	if (revs)
-	    d = ~d;
-
-	tmp =  ((d & 0x80) ? fg : bg) << 24;
-	tmp |= ((d & 0x40) ? fg : bg) << 16;
-	tmp |= ((d & 0x20) ? fg : bg) << 8;
-	tmp |= ((d & 0x10) ? fg : bg);
-	*((u_long*) dest) = tmp;
-	tmp =  ((d & 0x8) ? fg : bg) << 24;
-	tmp |= ((d & 0x4) ? fg : bg) << 16;
-	tmp |= ((d & 0x2) ? fg : bg) << 8;
-	tmp |= ((d & 0x1) ? fg : bg);
-	*((u_long*) dest + 1) = tmp;
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    cdat = 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;
+
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+	((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
     }
 }
 
 static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
 	                int count, int yy, int xx)
 {
-    u_char *dest, *dest0, *cdat;
-    u_long tmp;
-    u_int rows, underl;
-    u_char c, d;
-    u_char fg, bg;
-
-    dest0 = p->screen_base+yy*p->fontheight*p->next_line+8*xx;
-    fg = p->fgcol;
-    bg = p->bgcol;
-    underl = conp->vc_underline;
-
-    Cyber_WaitBlit();
+    u_char *cdat, c, *dest, *dest0;
+    int rows,bytes=p->next_line;
+    u32 eorx, fgx, bgx;
+
+    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;
     while (count--) {
 	c = *s++;
-	dest = dest0;
-	dest0 += 8;
-	cdat = p->fontdata+(c*p->fontheight);
-	for (rows = p->fontheight; rows--; dest += p->next_line) {
-	    d = *cdat++;
-
-	    if (underl && !rows)
-		d = 0xff;
-
-	    tmp =  ((d & 0x80) ? fg : bg) << 24;
-	    tmp |= ((d & 0x40) ? fg : bg) << 16;
-	    tmp |= ((d & 0x20) ? fg : bg) << 8;
-	    tmp |= ((d & 0x10) ? fg : bg);
-	    *((u_long*) dest) = tmp;
-	    tmp =  ((d & 0x8) ? fg : bg) << 24;
-	    tmp |= ((d & 0x4) ? fg : bg) << 16;
-	    tmp |= ((d & 0x2) ? fg : bg) << 8;
-	    tmp |= ((d & 0x1) ? fg : bg);
-	    *((u_long*) dest + 1) = tmp;
+	cdat = p->fontdata + c * p->fontheight;
+	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+	    ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+	    ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
 	}
+	dest0+=8;
     }
 }
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-ilbm.c m68k-2.1.77/drivers/video/fbcon-ilbm.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-ilbm.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcon-ilbm.c	Fri Jan  9 01:21:07 1998
@@ -188,7 +188,7 @@
     u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
     u_int rows, i;
     u_char c1, c2, c3, c4;
-    u_long d;
+    u32 d;
     int fg0, bg0, fg, bg;
 
     dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
@@ -233,20 +233,26 @@
 	    cdat3 = p->fontdata+c3*p->fontheight;
 	    cdat4 = p->fontdata+c4*p->fontheight;
 	    for (rows = p->fontheight; rows--;) {
+#if defined(__BIG_ENDIAN)
 		d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
+#elif defined(__LITTLE_ENDIAN)
+		d = *cdat1++ | *cdat2++<<8 | *cdat3++<<16 | *cdat4++<<32);
+#else
+#error FIXME: No endianness??
+#endif
 		fg = fg0;
 		bg = bg0;
 		for (i = p->var.bits_per_pixel; i--; dest += p->next_plane) {
 		    if (bg & 1)
 			if (fg & 1)
-			    *(u_long *)dest = 0xffffffff;
+			    *(u32 *)dest = 0xffffffff;
 			else
-			    *(u_long *)dest = ~d;
+			    *(u32 *)dest = ~d;
 		    else
 			if (fg & 1)
-			    *(u_long *)dest = d;
+			    *(u32 *)dest = d;
 			else
-			    *(u_long *)dest = 0x00000000;
+			    *(u32 *)dest = 0x00000000;
 		    bg >>= 1;
 		    fg >>= 1;
 		}
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-mac.c m68k-2.1.77/drivers/video/fbcon-mac.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-mac.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-mac.c	Fri Jan  9 01:24:33 1998
@@ -0,0 +1,538 @@
+/*
+ *  linux/drivers/video/fbcon-mac.c -- Low level frame buffer operations for 
+ *				       x bpp packed pixels, font width != 8
+ *
+ *	Created 26 Dec 1997 by Michael Schmitz
+ *	Based on the old macfb.c 6x11 code by Randy Thelen
+ *
+ *	This driver is significantly slower than the 8bit font drivers 
+ *	and would probably benefit from splitting into drivers for each depth.
+ *
+ *  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
+ */
+
+#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 <linux/delay.h>
+
+#include "fbcon.h"
+
+
+    /*
+     *  Prototypes
+     */
+
+static int open_mac(struct display *p);
+static void release_mac(void);
+static void bmove_mac(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static void clear_mac(struct vc_data *conp, struct display *p, int sy,
+		       int sx, int height, int width);
+static void putc_mac(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_mac(struct vc_data *conp, struct display *p,
+		       const char *s, int count, int yy, int xx);
+static void rev_char_mac(struct display *p, int xx, int yy);
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch dispsw_mac = {
+    open_mac, release_mac, bmove_mac, clear_mac, putc_mac, putcs_mac,
+    rev_char_mac
+};
+
+
+    /*
+     *  variable bpp packed pixels
+     */
+
+static int open_mac(struct display *p)
+{
+    if (p->type != FB_TYPE_PACKED_PIXELS || p->fontwidth == 8)
+	return -EINVAL;
+
+    if (p->line_length)
+	p->next_line = p->line_length;
+    else
+    	p->next_line = p->var.xres_virtual>>3;
+    p->next_plane = 0;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static void release_mac(void)
+{
+    MOD_DEC_USE_COUNT;
+}
+
+   /*
+    *    Macintosh
+    */
+#define PIXEL_BLACK_MAC          0
+#define PIXEL_WHITE_MAC          1
+#define PIXEL_INVERT_MAC         2
+
+static void bmove_mac(struct display *p, int sy, int sx, int dy, int dx,
+                       int height, int width)
+{
+   int i, j;
+   u_char *dest, *src;
+   int l,r,t,b,w,lo,s;
+   int dl,dr,dt,db,dw,dlo;
+   int move_up;
+
+   src = (u_char *) (p->screen_base + sy * p->fontheight * p->next_line);
+   dest = (u_char *) (p->screen_base + dy * p->fontheight * p->next_line);
+
+   if( sx == 0 && width == p->conp->vc_cols) {
+     s = height * p->fontheight * p->next_line;
+     mymemmove(dest, src, s);
+     return;
+   }
+   
+   l = sx * p->fontwidth;
+   r = l + width * p->fontwidth;
+   t = sy * p->fontheight;
+   b = t + height * p->fontheight;
+
+   dl = dx * p->fontwidth;
+   dr = dl + width * p->fontwidth;
+   dt = dy * p->fontheight;
+   db = dt + height * p->fontheight;
+
+   /* w is the # pixels between two long-aligned points, left and right */
+   w = (r&~31) - ((l+31)&~31);
+   dw = (dr&~31) - ((dl+31)&~31);
+   /* lo is the # pixels between the left edge and a long-aligned left pixel */
+   lo = ((l+31)&~31) - l;
+   dlo = ((dl+31)&~31) - dl;
+   
+   /* if dx != sx then, logic has to align the left and right edges for fast moves */
+   if (lo != dlo) {
+     lo = ((l+7)&~7) - l;
+     dlo = ((dl+7)&~7) - dl;
+     w = (r&~7) - ((l+7)&~7);
+     dw = (dr&~7) - ((dl+7)&~7);
+     if (lo != dlo) {
+       char err_str[256];
+       unsigned long cnt;
+       sprintf( err_str, "ERROR: Shift algorithm: sx=%d,sy=%d,dx=%d,dy=%d,w=%d,h=%d,bpp=%d",
+		sx,sy,dx,dy,width,height,p->var.bits_per_pixel);
+       putcs_mac(p->conp, p, err_str, strlen(err_str), 0, 0);
+       /* pause for the user */
+       for(cnt = 0; cnt < 50000; cnt++)
+		udelay(100);
+       return;
+     }
+   }
+
+   s = 0;
+   switch (p->var.bits_per_pixel) {
+   case 1:
+     s = w >> 3;
+     src += lo >> 3;
+     dest += lo >> 3;
+     break;
+   case 2:
+     s = w >> 2;
+     src += lo >> 2;
+     dest += lo >> 2;
+     break;
+   case 4:
+     s = w >> 1;
+     src += lo >> 1;
+     dest += lo >> 1;
+     break;
+   case 8:
+     s = w;
+     src += lo;
+     dest += lo;
+     break;
+   case 16:
+     s = w << 1;
+     src += lo << 1;
+     dest += lo << 1;
+     break;
+   case 32:
+     s = w << 2;
+     src += lo << 2;
+     dest += lo << 2;
+     break;
+   }
+
+   if (sy <= sx) {
+     i = b;
+     move_up = 0;
+     src += height * p->fontheight;
+     dest += height * p->fontheight;
+   } else {
+     i = t;
+     move_up = 1;
+   }
+
+   while (1) {
+     for (i = t; i < b; i++) {
+       j = l;
+
+       for (; j & 31 && j < r; j++)
+	 plot_pixel_mac(p, get_pixel_mac(p, j+(dx-sx), i+(dy-sy)), j, i);
+
+       if (j < r) {
+	 mymemmove(dest, src, s);
+	 if (move_up) {
+	   dest += p->next_line;
+	   src += p->next_line;
+	 } else {
+	   dest -= p->next_line;
+	   src -= p->next_line;
+	 }
+	 j += w;
+       }
+     
+       for (; j < r; j++)
+	 plot_pixel_mac(p, get_pixel_mac(p, j+(dx-sx), i+(dy-sy)), j, i);
+     }
+
+     if (move_up) {
+       i++;
+       if (i >= b)
+	 break;
+     } else {
+       i--;
+       if (i < t)
+	 break;
+     }
+   }
+}
+
+
+static void clear_mac(struct vc_data *conp, struct display *p, int sy, int sx,
+                       int height, int width)
+{
+   int pixel;
+   int i, j;
+   int inverse;
+   u_char *dest;
+   int l,r,t,b,w,lo,s;
+
+   inverse = attr_reverse(p,conp);
+   pixel = inverse ? PIXEL_WHITE_MAC : PIXEL_BLACK_MAC;
+   dest = (u_char *) (p->screen_base + sy * p->fontheight * p->next_line);
+
+   if( sx == 0 && width == p->conp->vc_cols) {
+     s = height * p->fontheight * p->next_line;
+     if (inverse)
+       mymemclear(dest, s);
+     else
+       mymemset(dest, s);
+   }
+   
+   l = sx * p->fontwidth;
+   r = l + width * p->fontwidth;
+   t = sy * p->fontheight;
+   b = t + height * p->fontheight;
+   /* w is the # pixels between two long-aligned points, left and right */
+   w = (r&~31) - ((l+31)&~31);
+   /* lo is the # pixels between the left edge and a long-aligned left pixel */
+   lo = ((l+31)&~31) - l;
+   s = 0;
+   switch (p->var.bits_per_pixel) {
+   case 1:
+     s = w >> 3;
+     dest += lo >> 3;
+     break;
+   case 2:
+     s = w >> 2;
+     dest += lo >> 2;
+     break;
+   case 4:
+     s = w >> 1;
+     dest += lo >> 1;
+     break;
+   case 8:
+     s = w;
+     dest += lo;
+     break;
+   case 16:
+     s = w << 1;
+     dest += lo << 1;
+     break;
+   case 32:
+     s = w << 2;
+     dest += lo << 2;
+     break;
+   }
+
+   for (i = t; i < b; i++) {
+     j = l;
+
+     for (; j & 31 && j < r; j++)
+       plot_pixel_mac(p, pixel, j, i);
+
+     if (j < r) {
+       if (PIXEL_WHITE_MAC == pixel)
+	 mymemclear(dest, s);
+       else
+	 mymemset(dest, s);
+       dest += p->next_line;
+       j += w;
+     }
+     
+     for (; j < r; j++)
+       plot_pixel_mac(p, pixel, j, i);
+   }
+}
+
+
+static void putc_mac(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
+{
+   u_char *cdat;
+   u_int rows, bold, ch_reverse, ch_underline;
+   u_char d;
+   int j;
+
+   c &= 0xff;
+
+   cdat = p->fontdata+c*p->fontheight;
+   bold = attr_bold(p,conp);
+   ch_reverse = attr_reverse(p,conp);
+   ch_underline = attr_underline(p,conp);
+
+   for (rows = 0; rows < p->fontheight; rows++) {
+      d = *cdat++;
+      if (!conp->vc_can_do_color) {
+	if (ch_underline && rows == (p->fontheight-2))
+	  d = 0xff;
+	else if (bold)
+	  d |= d>>1;
+	if (ch_reverse)
+	  d = ~d;
+      }
+      for (j = 0; j < p->fontwidth; j++) {
+	plot_pixel_mac(p, (d & 0x80) >> 7, (xx*p->fontwidth) + j, (yy*p->fontheight) + rows);
+	d <<= 1;
+      }
+   }
+}
+
+
+static void putcs_mac(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int yy, int xx)
+{
+   u_char c;
+
+   while (count--) {
+      c = *s++;
+      putc_mac(conp, p, c, yy, xx++);
+   }
+}
+
+
+static void rev_char_mac(struct display *p, int xx, int yy)
+{
+   u_int rows, j;
+
+   for (rows = 0; rows < p->fontheight; rows++) {
+     for (j = 0; j < p->fontwidth; j++) {
+       plot_pixel_mac (p, PIXEL_INVERT_MAC, (xx*p->fontwidth)+j, (yy*p->fontheight)+rows);
+     }
+   }
+}
+
+/*
+ * plot_pixel_mac
+ *
+ * bw == 0 = black
+ *       1 = white
+ *       2 = invert
+ */
+static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y)
+{
+  u_char *dest, bit;
+  u_short *dest16, pix16;
+  u_long *dest32, pix32;
+
+  if (pixel_x < 0 || pixel_y < 0 || pixel_x >= 832 || pixel_y >= 624) {
+    int cnt;
+    printk ("ERROR: pixel_x == %d, pixel_y == %d", pixel_x, pixel_y);
+    for(cnt = 0; cnt < 100000; cnt++)
+        udelay(100);
+    return;
+  }
+
+  switch (p->var.bits_per_pixel) {
+  case 1:
+    dest = (u_char *) ((pixel_x >> 3) + p->screen_base + pixel_y * p->next_line);
+    bit = 0x80 >> (pixel_x & 7);
+    switch (bw) {
+    case PIXEL_BLACK_MAC:
+      *dest |= bit;
+      break;
+    case PIXEL_WHITE_MAC:
+      *dest &= ~bit;
+      break;
+    case PIXEL_INVERT_MAC:
+      *dest ^= bit;
+      break;
+    default:
+      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+    }
+    break;
+
+  case 2:
+    dest = (u_char *) ((pixel_x >> 2) + p->screen_base + pixel_y * p->next_line);
+    bit = 0xC0 >> ((pixel_x & 3) << 1);
+    switch (bw) {
+    case PIXEL_BLACK_MAC:
+      *dest |= bit;
+      break;
+    case PIXEL_WHITE_MAC:
+      *dest &= ~bit;
+      break;
+    case PIXEL_INVERT_MAC:
+      *dest ^= bit;
+      break;
+    default:
+      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+    }
+    break;
+
+  case 4:
+    dest = (u_char *) ((pixel_x / 2) + p->screen_base + pixel_y * p->next_line);
+    bit = 0xF0 >> ((pixel_x & 1) << 2);
+    switch (bw) {
+    case PIXEL_BLACK_MAC:
+      *dest |= bit;
+      break;
+    case PIXEL_WHITE_MAC:
+      *dest &= ~bit;
+      break;
+    case PIXEL_INVERT_MAC:
+      *dest ^= bit;
+      break;
+    default:
+      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+    }
+    break;
+
+  case 8:
+    dest = (u_char *) (pixel_x + p->screen_base + pixel_y * p->next_line);
+    bit = 0xFF;
+    switch (bw) {
+    case PIXEL_BLACK_MAC:
+      *dest |= bit;
+      break;
+    case PIXEL_WHITE_MAC:
+      *dest &= ~bit;
+      break;
+    case PIXEL_INVERT_MAC:
+      *dest ^= bit;
+      break;
+    default:
+      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+    }
+    break;
+
+  case 16:
+    dest16 = (u_short *) ((pixel_x *2) + p->screen_base + pixel_y * p->next_line);
+    pix16 = 0xFFFF;
+    switch (bw) {
+    case PIXEL_BLACK_MAC:
+      *dest16 = ~pix16;
+      break;
+    case PIXEL_WHITE_MAC:
+      *dest16 = pix16;
+      break;
+    case PIXEL_INVERT_MAC:
+      *dest16 ^= pix16;
+      break;
+    default:
+      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+    }
+    break;
+
+  case 32:
+    dest32 = (u_long *) ((pixel_x *4) + p->screen_base + pixel_y * p->next_line);
+    pix32 = 0xFFFFFFFF;
+    switch (bw) {
+    case PIXEL_BLACK_MAC:
+      *dest32 = ~pix32;
+      break;
+    case PIXEL_WHITE_MAC:
+      *dest32 = pix32;
+      break;
+    case PIXEL_INVERT_MAC:
+      *dest32 ^= pix32;
+      break;
+    default:
+      printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+    }
+    break;
+  }
+}
+
+static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y)
+{
+  u_char *dest, bit;
+  u_short *dest16;
+  u_long *dest32;
+  u_char pixel;
+
+  switch (p->var.bits_per_pixel) {
+  case 1:
+    dest = (u_char *) ((pixel_x / 8) + p->screen_base + pixel_y * p->next_line);
+    bit = 0x80 >> (pixel_x & 7);
+    pixel = *dest & bit;
+    break;
+  case 2:
+    dest = (u_char *) ((pixel_x / 4) + p->screen_base + pixel_y * p->next_line);
+    bit = 0xC0 >> (pixel_x & 3);
+    pixel = *dest & bit;
+    break;
+  case 4:
+    dest = (u_char *) ((pixel_x / 2) + p->screen_base + pixel_y * p->next_line);
+    bit = 0xF0 >> (pixel_x & 1);
+    pixel = *dest & bit;
+    break;
+  case 8:
+    dest = (u_char *) (pixel_x + p->screen_base + pixel_y * p->next_line);
+    pixel = *dest;
+    break;
+  case 16:
+    dest16 = (u_short *) ((pixel_x *2) + p->screen_base + pixel_y * p->next_line);
+    pixel = *dest16 ? 1 : 0;
+    break;
+  case 32:
+    dest32 = (u_long *) ((pixel_x *4) + p->screen_base + pixel_y * p->next_line);
+    pixel = *dest32 ? 1 : 0;
+    break;
+  }
+
+  return pixel ? PIXEL_BLACK_MAC : PIXEL_WHITE_MAC;
+}
+
+#ifdef MODULE
+int init_module(void)
+#else
+int fbcon_init_mac(void)
+#endif
+{
+    return(fbcon_register_driver(&dispsw_mac, 0));
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+    fbcon_unregister_driver(&dispsw_mac);
+}
+#endif /* MODULE */
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-mach64.c m68k-2.1.77/drivers/video/fbcon-mach64.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-mach64.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-mach64.c	Fri Jan  9 01:24:36 1998
@@ -0,0 +1,529 @@
+/*
+ *  linux/drivers/video/fbcon-mach64.c -- Low level frame buffer operations for 
+ *					  Ati Mach64 (accelerated)
+ *
+ *	Created 20 Jun 1997 by Bernd Harries
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/fb.h>
+
+#include "fbcon.h"
+#include "fbcon-mach64.h"
+#include "mach64fb.h"
+
+/*============================================================================*/
+/* Defines */
+
+#define  _USE_HW_ACCEL_BLT_
+#define  _USE_HW_ACCEL_FILL_
+
+
+#ifdef  BHA_DEBUG
+
+#define  FuncId       if(mach64_debug & 0x00000100) printk
+#define  FuncDone     if(mach64_debug & 0x00000200) printk
+#define  CFuncId      if(mach64_debug & 0x00000400) printk
+#define  CFuncDone    if(mach64_debug & 0x00000800) printk
+
+
+/* Busy */
+#define  Bprint       if(mach64_debug & 0x01000000) printk
+/* Debug */
+#define  Dprint       if(mach64_debug & 0x00800000) printk
+
+/* Message */
+#define  Mprint       if(mach64_debug & 0x00004000) printk
+/* Info */
+#define  Iprint       if(mach64_debug & 0x00008000) printk
+/* Warn */
+#define  Wprint       if(mach64_debug & 0x00010000) printk
+/* Error */
+#define  Eprint       if(mach64_debug & 0x00020000) printk
+/* Fatal */
+#define  Fprint       if(mach64_debug & 0x00040000) printk
+/* Panic */
+#define  Pprint       if(mach64_debug & 0x00040000) printk
+
+#else
+
+#define  FuncId
+#define  FuncDone
+#define  CFuncId
+#define  CFuncDone
+
+#endif  /* BHA_DEBUG*/
+
+/*============================================================================*/
+/* Types */
+
+/*============================================================================*/
+/* Extern Functions*/
+
+
+
+/*============================================================================*/
+/* Intern Functions*/
+
+    /*
+     *  Prototypes
+     */
+
+int fbcon_init_mach64(void);
+
+static int open_mach64(struct display *p);
+static void release_mach64(void);
+static void bmove_mach64(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width);
+static void clear_mach64(struct vc_data *conp, struct display *p, int sy,
+		       int sx, int height, int width);
+static void putc_mach64(struct vc_data *conp, struct display *p, int c, int yy,
+		      int xx);
+static void putcs_mach64(struct vc_data *conp, struct display *p,
+		       const char *s, int count, int yy, int xx);
+static void rev_char_mach64(struct display *p, int xx, int yy);
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Intern Variables */
+
+/*--------------------------------------------------------------------------*/
+/* BSS */
+
+/*--------------------------------------------------------------------------*/
+/* Data */
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch    dispsw_mach64 = 
+{
+  open_mach64,
+  release_mach64,
+  bmove_mach64,
+  clear_mach64,
+  putc_mach64,
+  putcs_mach64,
+  rev_char_mach64
+};
+
+
+    /*
+     *  8 bpp packed pixels => 4 pixel / 32 Bit => 1/2 FontByte 
+     */
+
+static u_int nibbletab_mach64[16] = 
+{
+#if defined(__BIG_ENDIAN)
+  0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+  0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+  0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+  0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+  0x00000000,0xff000000,0x00ff0000,0xffff0000,
+  0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+  0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+  0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+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++;
+    *((u32 *)dest_p) = (nibbletab_mach64[cdat >> 4] & eorx) ^ bgx;
+    ((u32 *)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++;
+      *((u32 *)dest_p) = (nibbletab_mach64[cdat >> 4] & eorx) ^ bgx;
+      ((u32 *)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) {
+	((u32 *)dest)[0] ^= 0x0f0f0f0f;
+	((u32 *)dest)[1] ^= 0x0f0f0f0f;
+    }
+}
+/*endproc rev_char_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef MODULE
+int 
+init_module(void)
+#else
+int 
+fbcon_init_mach64(void)
+#endif
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("fbcon_init_mach64() \n");
+  /* We want to be added to the list of accelerated drivers */
+  return(fbcon_register_driver(&dispsw_mach64, 1));
+}
+/*endproc fbcon_init_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef MODULE
+void 
+cleanup_module(void)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  FuncId("cleanup_module() \n");
+    fbcon_unregister_driver(&dispsw_mach64);
+}
+/*endproc cleanup_mach64() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+#endif /* MODULE */
+/*============================================================================*/
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+  static char
+  rcs_id_c[] =
+    "@(#) Linux-m68k: 1997 10 05 14:53:32 BHA: fbcon-mach64.c ";
+
+  static char
+  rcs_id_h[] = FBCON_MACH64_H_ID;
+
+/*============================================================================*/
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-mach64.h m68k-2.1.77/drivers/video/fbcon-mach64.h
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-mach64.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-mach64.h	Fri Jan  9 01:24:41 1998
@@ -0,0 +1,31 @@
+
+
+#ifndef _FBCON_MACH64_H_LOADED_
+#define _FBCON_MACH64_H_LOADED_
+
+
+
+
+
+
+
+/*============================================================================*/
+	/*
+	 * Support for Graphics Boards
+	 */
+
+#ifdef CONFIG_FBCON_MACH64			/* ATI Mach 64 */
+
+int fbcon_init_mach64(void);
+
+#endif /* CONFIG_FBCON_MACH64 */	
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define FBCON_MACH64_H_ID \
+  "@(#) Linux-m68k: 1997 06 25 17:34:18 BHA: fbcon-mach64.h "
+
+/*============================================================================*/
+
+#endif /* _FBCON_MACH64_H_LOADED_ */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-retz3.c m68k-2.1.77/drivers/video/fbcon-retz3.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-retz3.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fbcon-retz3.c	Fri Jan  9 01:22:03 1998
@@ -50,7 +50,7 @@
 #define Z3BLTset		0xf0
 
 
-/*
+    /*
      *  `switch' for the low level operations
      */
 
@@ -60,10 +60,26 @@
 };
 
 
-/*
+    /*
      *  RetinaZ3 (accelerated)
      */
 
+static u32 nibbletab_cfb8[] = {
+#if defined(__BIG_ENDIAN)
+    0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+    0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+    0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+    0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+    0x00000000,0xff000000,0x00ff0000,0xffff0000,
+    0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+    0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+    0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
 static int open_retz3(struct display *p)
 {
 	if (p->type != FB_TYPE_PACKED_PIXELS ||
@@ -125,122 +141,68 @@
 		     col);
 }
 
-static void putc_retz3(struct vc_data *conp, struct display *p,
-		       int c, int ypos, int xpos)
+static void putc_retz3(struct vc_data *conp, struct display *p, int c, int yy,
+		       int xx)
 {
-	unsigned char *dest, *cdat;
-	unsigned long tmp;
-	unsigned int rows, revs, underl;
-	unsigned char d;
-	unsigned char fg, bg;
-
-	c &= 0xff;
-
-	dest = p->screen_base + ypos * p->fontheight * p->next_line +
-	        xpos*p->fontwidth;
+    u_char *dest,*cdat;
+    int bytes=p->next_line,rows;
+    u32 eorx,fgx,bgx;
+
+    c &= 0xff;
+
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    cdat = 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;
+
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+	((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+	((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
+    }
+}
+
+static void putcs_retz3(struct vc_data *conp, struct display *p, const char *s,
+			int count, int yy, int xx)
+{
+    u_char *cdat, c, *dest, *dest0;
+    int rows,bytes=p->next_line;
+    u32 eorx, fgx, bgx;
+
+    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;
+    while (count--) {
+	c = *s++;
 	cdat = p->fontdata + c * p->fontheight;
-
-	fg = p->fgcol;
-	bg = p->bgcol;
-	revs = conp->vc_reverse;
-	underl = conp->vc_underline;
-
-	for (rows = p->fontheight; rows--; dest += p->next_line) {
-		d = *cdat++;
-
-		if (underl && !rows)
-			d = 0xff;
-		if (revs)
-			d = ~d;
-
-		tmp =  ((d & 0x80) ? fg : bg) << 24;
-		tmp |= ((d & 0x40) ? fg : bg) << 16;
-		tmp |= ((d & 0x20) ? fg : bg) << 8;
-		tmp |= ((d & 0x10) ? fg : bg);
-		*((unsigned long*) dest) = tmp;
-		tmp =  ((d & 0x8) ? fg : bg) << 24;
-		tmp |= ((d & 0x4) ? fg : bg) << 16;
-		tmp |= ((d & 0x2) ? fg : bg) << 8;
-		tmp |= ((d & 0x1) ? fg : bg);
-		*((unsigned long*) dest + 1) = tmp;
-	}
-}
-
-static void putcs_retz3(struct vc_data *conp, struct display *p,
-			const char *s, int count, int ypos, int xpos)
-{
-	unsigned char *dest, *dest0, *cdat;
-	unsigned long tmp;
-	unsigned int rows, revs, underl;
-	unsigned char c, d;
-	unsigned char fg, bg;
-
-	dest0 = p->screen_base + ypos * p->fontheight * p->next_line
-		+ xpos * p->fontwidth;
-
-	fg = p->fgcol;
-	bg = p->bgcol;
-	revs = conp->vc_reverse;
-	underl = conp->vc_underline;
-
-	while (count--) {
-		c = *s++;
-		dest = dest0;
-		dest0 += 8;
-
-		cdat = p->fontdata + c * p->fontheight;
-		for (rows = p->fontheight; rows--; dest += p->next_line) {
-			d = *cdat++;
-
-			if (underl && !rows)
-				d = 0xff;
-			if (revs)
-				d = ~d;
-
-			tmp =  ((d & 0x80) ? fg : bg) << 24;
-			tmp |= ((d & 0x40) ? fg : bg) << 16;
-			tmp |= ((d & 0x20) ? fg : bg) << 8;
-			tmp |= ((d & 0x10) ? fg : bg);
-			*((unsigned long*) dest) = tmp;
-			tmp =  ((d & 0x8) ? fg : bg) << 24;
-			tmp |= ((d & 0x4) ? fg : bg) << 16;
-			tmp |= ((d & 0x2) ? fg : bg) << 8;
-			tmp |= ((d & 0x1) ? fg : bg);
-			*((unsigned long*) dest + 1) = tmp;
-		}
+	for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+	    ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+	    ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
 	}
+	dest0+=8;
+    }
 }
 
-static void rev_char_retz3(struct display *p, int xpos, int ypos)
+static void rev_char_retz3(struct display *p, int xx, int yy)
 {
-	unsigned char *dest;
-	int bytes=p->next_line, rows;
-	unsigned int bpp, mask;
-
-	bpp = p->var.bits_per_pixel;
-
-	switch (bpp){
-	case 8:
-		mask = 0x0f0f0f0f;
-		break;
-	case 16:
-		mask = 0xffffffff;
-		break;
-	case 24:
-		mask = 0xffffffff; /* ??? */
-		break;
-	default:
-		printk("illegal depth for rev_char_retz3(), bpp = %i\n", bpp);
-		return;
-	}
-
-	dest = p->screen_base + ypos * p->fontheight * bytes +
-		xpos * p->fontwidth;
+    u_char *dest;
+    int bytes=p->next_line, rows;
 
-	for (rows = p->fontheight ; rows-- ; dest += bytes) {
-		((unsigned long *)dest)[0] ^= mask;
-		((unsigned long *)dest)[1] ^= mask;
-	}
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+        ((u32 *)dest)[0] ^= 0x0f0f0f0f;
+        ((u32 *)dest)[1] ^= 0x0f0f0f0f;
+    }
 }
 
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon-virge.c m68k-2.1.77/drivers/video/fbcon-virge.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon-virge.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbcon-virge.c	Fri Jan  9 01:24:45 1998
@@ -0,0 +1,225 @@
+/*
+ *  linux/drivers/video/fbcon-virge.c -- Low level frame buffer operations
+ *			     for the CyberVision64/3D (accelerated)
+ *
+ *	Created 28 Dec 1997 by Andre Heynatz
+ *
+ *      based on fbcon-cyber.c (same dir) and fbcon.c from Linux 2.0.31pre3
+ *      (both written by Geert Uytterhoeven and others)
+ *
+ *  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.
+ */
+
+#define FBCONVIRGEDEBUG
+
+#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 "s3blit.h"
+
+#ifdef FBCONVIRGEDEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+    /*
+     *  Prototypes
+     */
+
+static int open_cyber3d(struct display *p);
+static void release_cyber3d(void);
+static void bmove_cyber3d(struct display *p, int sy, int sx, int dy, int dx,
+	                int height, int width);
+static void clear_cyber3d(struct vc_data *conp, struct display *p, int sy, int sx,
+	                int height, int width);
+/* TODO:
+static void putc_cyber3d(struct vc_data *conp, struct display *p, int c, int yy,
+	               int xx);
+static void putcs_cyber3d(struct vc_data *conp, struct display *p, const char *s,
+	                int count, int yy, int xx);
+static void rev_char_cyber3d(struct display *p, int xx, int yy);
+*/
+/* prototypes for cfb8 functions, can be done without replicating code,
+   remove them if they are replaced by native functions */
+
+static void putc_cfb8(struct vc_data *conp, struct display *p, int c, int yy,
+                       int xx);
+static void putcs_cfb8(struct vc_data *conp, struct display *p, const char *s,
+                        int count, int yy, int xx);
+static void rev_char_cfb8(struct display *p, int xx, int yy);
+
+    /*
+     *  Acceleration functions in cyberfb.c
+     */
+
+extern void Cyber3D_WaitQueue(unsigned short fifo);
+extern void Cyber_WaitBlit(void);
+extern void Cyber3D_BitBLT(unsigned short curx, unsigned short cury,
+			 unsigned short destx, unsigned short desty,
+			 unsigned short width, unsigned short height,
+			 unsigned short mode);
+extern void Cyber3D_RectFill(unsigned short xx, unsigned short yy,
+			   unsigned short width, unsigned short height,
+			     /* unsigned short mode, */ unsigned short fillcolor);
+extern void Cyber_MoveCursor(unsigned short xx, unsigned short yy);
+
+
+    /*
+     *  `switch' for the low level operations
+     */
+
+static struct display_switch dispsw_cyber3d = {
+   open_cyber3d, release_cyber3d, bmove_cyber3d, clear_cyber3d, putc_cfb8,
+   putcs_cfb8, rev_char_cfb8
+};
+
+    /*
+     *  CyberVision64/3D (accelerated)
+     */
+
+static int open_cyber3d(struct display *p)
+{
+    if (p->type != FB_TYPE_PACKED_PIXELS ||
+        p->var.accel != FB_ACCEL_CYBERVISION3D) {
+        DPRINTK("accelerated driver not wanted\n");
+        return -EINVAL;
+    }
+    p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
+    p->next_plane = 0;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static void release_cyber3d(void)
+{
+    MOD_DEC_USE_COUNT;
+}
+
+static void bmove_cyber3d(struct display *p, int sy, int sx, int dy, int dx,
+	                int height, int width)
+{
+        sx *= 8; dx *= 8; width *= 8;
+        Cyber3D_BitBLT((u_short)sx, (u_short)(sy*p->fontheight), (u_short)dx,
+                       (u_short)(dy*p->fontheight), (u_short)width,
+                       (u_short)(height*p->fontheight), (u_short)S3_NEW);
+}
+
+static void clear_cyber3d(struct vc_data *conp, struct display *p,
+                          int sy, int sx, int height, int width)
+{
+        unsigned char bg;
+
+        sx *= 8; width *= 8;
+        bg = attr_bgcol_ec(p,conp);
+        Cyber3D_RectFill((u_short)sx, (u_short)(sy*p->fontheight),
+                         (u_short)width, (u_short)(height*p->fontheight),
+                         (u_short)bg);
+}
+
+/* the following structures are copies from fbcon-cfb8.c
+   remove them if there are no functions from fbcon-cfb8 left */
+
+static u_long nibbletab_cfb8[] = {
+    0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+    0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+    0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+    0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+};
+
+/* the following functions are copies from fbcon-cfb8.c
+   TODO: rewrite them for the Cybervision64/3D
+*/
+
+static void putc_cfb8(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
+{
+    u_char *dest,*cdat;
+    int bytes=p->next_line,rows;
+    ulong eorx,fgx,bgx;
+
+    c &= 0xff;
+
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    cdat = 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;
+
+    for (rows = p->fontheight ; rows-- ; dest += bytes) {
+        ((u_long *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+        ((u_long *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
+    }
+}
+
+static void putcs_cfb8(struct vc_data *conp, struct display *p, const char *s,
+                       int count, int yy, int xx)
+{
+    u_char *cdat, c, *dest, *dest0;
+    int rows,bytes=p->next_line;
+    u_long eorx, fgx, bgx;
+
+    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;
+    while (count--) {
+        c = *s++;
+        cdat = p->fontdata + c * p->fontheight;
+
+        for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+            ((u_long *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+            ((u_long *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^
+                                 bgx;
+        }
+        dest0+=8;
+    }
+}
+
+static void rev_char_cfb8(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;
+    }
+}
+
+
+#ifdef MODULE
+int init_module(void)
+#else
+int fbcon_init_cyber3d(void)
+#endif
+{
+     DPRINTK("registering accelerated driver\n");
+     return(fbcon_register_driver(&dispsw_cyber3d, 1));
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+    fbcon_unregister_driver(&dispsw_cyber3d);
+}
+#endif /* MODULE */
+
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbcon.c m68k-2.1.77/drivers/video/fbcon.c
--- /usr/src/m68k-2.1.77/drivers/video/fbcon.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/fbcon.c	Fri Jan  9 01:22:14 1998
@@ -41,7 +41,10 @@
  *    - accelerated:
  *
  *	  o cyber	 CyberVision64 packed pixels (accelerated)
+ *        o virge        CyberVision64/3D packed pixels (accelerated)
  *	  o retz3	 Retina Z3 packed pixels (accelerated)
+ *	  o mach64	 ATI Mach 64 packed pixels (accelerated)
+ *	  o aty		 ATI Mach 64 packed pixels (accelerated)
  *
  *  To do:
  *
@@ -55,6 +58,8 @@
  *  more details.
  */
 
+#define FBCONDEBUG
+
 #define SUPPORT_SCROLLBACK	0
 #define FLASHING_CURSOR		1
 
@@ -64,6 +69,7 @@
 #include <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
+#include <linux/delay.h>	/* MSch: for IRQ probe */
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/string.h>
@@ -87,6 +93,9 @@
 #ifdef CONFIG_ATARI
 #include <asm/atariints.h>
 #endif
+#ifdef CONFIG_MAC
+#include <asm/macints.h>
+#endif
 #ifdef __mc68000__
 #include <asm/machdep.h>
 #include <asm/setup.h>
@@ -96,6 +105,11 @@
 #include "fbcon.h"
 #include "font.h"
 
+#ifdef FBCONDEBUG
+#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
 
 struct display fb_display[MAX_NR_CONSOLES];
 
@@ -111,6 +125,7 @@
 /* # VBL ints between cursor state changes */
 #define AMIGA_CURSOR_BLINK_RATE		(20)
 #define ATARI_CURSOR_BLINK_RATE		(42)
+#define MAC_CURSOR_BLINK_RATE		(32)
 #define DEFAULT_CURSOR_BLINK_RATE	(20)
 
 static int vbl_cursor_cnt = 0;
@@ -202,6 +217,19 @@
 static int fbcon_show_logo(void);
 
 #if FLASHING_CURSOR
+
+#ifdef CONFIG_MAC
+/*
+ * On the Macintoy, there may or may not be a working VBL int. We need to prob
+ */
+static int vbl_detected = 0;
+
+static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
+{
+      vbl_detected++;
+}
+#endif
+
 static void cursor_timer_handler(unsigned long dev_addr);
 
 static struct timer_list cursor_timer = {
@@ -211,7 +239,7 @@
 static void cursor_timer_handler(unsigned long dev_addr)
 {
       fbcon_vbl_handler(0, NULL, NULL);
-      cursor_timer.expires = jiffies+2;
+      cursor_timer.expires = jiffies+HZ/50;
       cursor_timer.data = 0;
       cursor_timer.next = cursor_timer.next = NULL;
       add_timer(&cursor_timer);
@@ -242,6 +270,12 @@
 #ifdef CONFIG_FBCON_IPLAN2P8
 extern int fbcon_init_iplan2p8(void);
 #endif
+#ifdef CONFIG_FBCON_CFB2
+extern int fbcon_init_cfb2(void);
+#endif
+#ifdef CONFIG_FBCON_CFB4
+extern int fbcon_init_cfb4(void);
+#endif
 #ifdef CONFIG_FBCON_CFB8
 extern int fbcon_init_cfb8(void);
 #endif
@@ -257,9 +291,27 @@
 #ifdef CONFIG_FBCON_CYBER
 extern int fbcon_init_cyber(void);
 #endif
+#ifdef CONFIG_FBCON_VIRGE
+extern int fbcon_init_cyber3d(void);
+#endif
+#ifdef CONFIG_FBCON_VIRGE
+extern int fbcon_init_cyber3d(void);
+#endif
 #ifdef CONFIG_FBCON_RETINAZ3
 extern int fbcon_init_retz3(void);
 #endif
+#ifdef CONFIG_FBCON_MACH64
+extern int fbcon_init_mach64(void);
+#endif
+#ifdef CONFIG_FBCON_TRIO
+extern int fbcon_init_trio(void);
+#endif
+#ifdef CONFIG_FBCON_ATY
+extern int fbcon_init_aty(void);
+#endif
+#ifdef CONFIG_FBCON_MAC
+extern int fbcon_init_mac(void);
+#endif
 
 __initfunc(static unsigned long fbcon_startup(unsigned long kmem_start,
 					      const char **display_desc))
@@ -269,9 +321,10 @@
     /* Probe all frame buffer devices */
     kmem_start = probe_framebuffers(kmem_start);
 
-    if (!num_registered_fb)
+    if (!num_registered_fb) {
+            DPRINTK("no framebuffer registered\n");
 	    return kmem_start;
-
+    }
     /* Initialize all built-in low level drivers */
 #ifdef CONFIG_FBCON_RETINAZ3
     fbcon_init_retz3();
@@ -294,6 +347,12 @@
 #ifdef CONFIG_FBCON_AFB
     fbcon_init_afb();
 #endif
+#ifdef CONFIG_FBCON_CFB2
+    fbcon_init_cfb2();
+#endif
+#ifdef CONFIG_FBCON_CFB4
+    fbcon_init_cfb4();
+#endif
 #ifdef CONFIG_FBCON_CFB8
     fbcon_init_cfb8();
 #endif
@@ -309,6 +368,24 @@
 #ifdef CONFIG_FBCON_CYBER
     fbcon_init_cyber();
 #endif
+#ifdef CONFIG_FBCON_VIRGE
+    fbcon_init_cyber3d();
+#endif
+#ifdef CONFIG_FBCON_VIRGE
+    fbcon_init_cyber3d();
+#endif
+#ifdef CONFIG_FBCON_MACH64
+    fbcon_init_mach64();
+#endif
+#ifdef CONFIG_FBCON_TRIO
+    fbcon_init_trio();
+#endif
+#ifdef CONFIG_FBCON_ATY
+    fbcon_init_aty();
+#endif
+#ifdef CONFIG_FBCON_MAC
+    fbcon_init_mac();
+#endif
 
     *display_desc = "frame buffer device";
 
@@ -326,9 +403,49 @@
 			     "console/cursor", fbcon_vbl_handler);
     }
 #endif /* CONFIG_ATARI */
+
+#ifdef CONFIG_MAC
+    /*
+     * On a Macintoy, the VBL interrupt may or may not be active. 
+     * As interrupt based cursor is more reliable and race free, we 
+     * probe for VBL interrupts.
+     */
+    if (MACH_IS_MAC) {
+       int ct = 0;
+       /*
+        * Probe for VBL: set temp. handler ...
+        */
+       irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,
+                            "console/cursor", fbcon_vbl_detect);
+       /*
+        * ... and spin for 20 ms ...
+        */
+       while (!vbl_detected && ++ct<1000)
+          udelay(20);
+ 
+       if(ct==1000)
+          printk("fbcon_startup: No VBL detected, using timer based cursor.\n");
+ 
+       if (vbl_detected) {
+         /*
+          * interrupt based cursor ok
+          */
+          cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
+          irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,
+                               "console/cursor", fbcon_vbl_handler);
+       } else {
+          /*
+           * VBL not detected: fall through, use timer based cursor
+           */
+           irqres = 1;
+	   /* free interrupt here ?? */
+       }
+    }
+#endif /* CONFIG_MAC */
+
     if (irqres) {
 	cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-	cursor_timer.expires = jiffies+2;
+	cursor_timer.expires = jiffies+HZ/50;
 	cursor_timer.data = 0;
 	cursor_timer.next = cursor_timer.prev = NULL;
 	add_timer(&cursor_timer);
@@ -351,6 +468,11 @@
 
     info->changevar = &fbcon_changevar;
     fb_display[unit] = *(info->disp);	/* copy from default */
+    DPRINTK("mode:   %s\n",info->modename);
+    DPRINTK("visual: %d\n",fb_display[unit].visual);
+    DPRINTK("res:    %dx%d-%d\n",fb_display[unit].var.xres,
+	                     fb_display[unit].var.yres,
+	                     fb_display[unit].var.bits_per_pixel);
     fb_display[unit].conp = conp;
     fb_display[unit].fb_info = info;
     fbcon_setup(unit, 1, 1);
@@ -405,7 +527,7 @@
 		      &p->fontdata) || p->fontwidth != 8)
 	getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
 		       &p->fontheight, &p->fontdata);
-    if (p->fontwidth != 8) {
+    if (p->fontwidth != 8 && !MACH_IS_MAC) {
 	/* ++Geert: changed from panic() to `correct and continue' */
 	printk(KERN_ERR "fbcon_setup: No support for fontwidth != 8");
 	p->fontwidth = 8;
@@ -614,7 +736,7 @@
     p->var.xoffset = 0;
     p->var.yoffset = p->yscroll*p->fontheight;
     p->var.vmode |= FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit);
+    p->fb_info->updatevar(unit, p->fb_info);
 #if SUPPORT_SCROLLBACK
     scrollback_max += count;
     if (scrollback_max > p->vrows-conp->vc_rows)
@@ -637,7 +759,7 @@
     p->var.xoffset = 0;
     p->var.yoffset = p->yscroll*p->fontheight;
     p->var.vmode |= FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit);
+    p->fb_info->updatevar(unit, p->fb_info);
 #if SUPPORT_SCROLLBACK
     scrollback_max -= count;
     if (scrollback_max < 0)
@@ -659,7 +781,7 @@
     p->var.xoffset = 0;
     p->var.yoffset = p->yscroll*p->fontheight;
     p->var.vmode &= ~FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit);
+    p->fb_info->updatevar(unit, p->fb_info);
 }
 
 
@@ -675,7 +797,7 @@
     p->var.xoffset = 0;
     p->var.yoffset = p->yscroll*p->fontheight;
     p->var.vmode &= ~FB_VMODE_YWRAP;
-    p->fb_info->updatevar(unit);
+    p->fb_info->updatevar(unit, p->fb_info);
 }
 
 
@@ -885,7 +1007,7 @@
     struct fb_info *info = p->fb_info;
 
     if (info && info->switch_con)
-	(*info->switch_con)(conp->vc_num);
+	(*info->switch_con)(conp->vc_num, info);
 #if SUPPORT_SCROLLBACK
     scrollback_max = 0;
     scrollback_current = 0;
@@ -897,6 +1019,7 @@
 static int fbcon_blank(int blank)
 {
     struct display *p = &fb_display[fg_console];
+    struct fb_info *info = p->fb_info;
 
     fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
 
@@ -916,7 +1039,7 @@
 	    return(1);
 	}
     }
-    (*p->fb_info->blank)(blank);
+    (*info->blank)(blank, info);
     return(0);
 }
 
@@ -1069,8 +1192,7 @@
     palette_cmap.len = 1<<p->var.bits_per_pixel;
     if (palette_cmap.len > 16)
 	palette_cmap.len = 16;
-    return(p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit,
-					  con2fb_map[unit]));
+    return p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit, p->fb_info);
 }
 
 static int fbcon_scrolldelta(int lines)
@@ -1101,7 +1223,7 @@
     p->var.vmode |= FB_VMODE_YWRAP;
     p->var.xoffset = 0;
     p->var.yoffset = offset*p->fontheight;
-    p->fb_info->updatevar(unit);
+    p->fb_info->updatevar(unit, p->fb_info);
 #else
     return -ENOSYS;
 #endif
@@ -1159,7 +1281,7 @@
 		palette_cmap.blue[j]  = (blue[i+j] << 8) | blue[i+j];
 	    }
 	    p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
-					   con2fb_map[fg_console]);
+					   p->fb_info);
 	}
 	fb_display[fg_console].cmap.len = old_cmap_len;
     }
@@ -1177,12 +1299,13 @@
 	logo_depth = 1;
     }
 
-#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CYBER) || \
-    defined(CONFIG_FBCON_RETINAZ3)
+#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
+    defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FBCON_CYBER) || \
+    defined(CONFIG_FBCON_VIRGE) || 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! */
+	unsigned int 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;
@@ -1212,7 +1335,8 @@
     }
 #endif
 #if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CYBER) || \
-    defined(CONFIG_FBCON_RETINAZ3)
+    defined(CONFIG_FBCON_VIRGE) || defined(CONFIG_FBCON_RETINAZ3)
+
     if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {
 	/* depth 8 or more, packed, with color registers */
 		
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fbgen.c m68k-2.1.77/drivers/video/fbgen.c
--- /usr/src/m68k-2.1.77/drivers/video/fbgen.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/fbgen.c	Fri Jan  9 01:24:49 1998
@@ -0,0 +1,384 @@
+/*
+ * linux/drivers/video/fbgen.c -- Generic routines for frame buffer devices
+ *
+ *  Created 3 Jan 1998 by Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+
+#include <asm/uaccess.h>
+
+
+
+static int currcon = 0;
+
+static struct display disp;
+
+
+    /*
+     *  `Generic' versions of the frame buffer device operations
+     */
+
+extern int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info);
+extern int fbgen_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+extern int fbgen_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info);
+extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info);
+extern int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info);
+extern int fbgen_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info);
+
+
+    /*
+     *  Helper functions
+     */
+
+int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
+		     struct fb_info_gen *info);
+void fbgen_set_disp(int con, struct fb_info_gen *info);
+void fbgen_install_cmap(int con, struct fb_info_gen *info);
+int fbgen_update_var(int con, struct fb_info *info);
+int fbgen_switch(int con, struct fb_info *info);
+void fbgen_blank(int blank, struct fb_info *info);
+
+
+/* ---- `Generic' versions of the frame buffer device operations ----------- */
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+
+int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+    char par[info2->parsize];
+
+    if (con == -1)
+	fbhw->get_par(&par, info2);
+    else {
+	int err;
+
+	if ((err = fbhw->decode_var(&fb_display[con].var, &par, info2)))
+	    return err;
+    }
+    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+    return fbhw->encode_fix(fix, &par, info2);
+}
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+int fbgen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+    char par[info2->parsize];
+
+    if (con == -1) {
+	fbhw->get_par(&par, info2);
+	fbhw->encode_var(var, &par, info2);
+    } else
+	*var = fb_display[con].var;
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+int fbgen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    int err;
+    int oldxres, oldyres, oldbpp, oldxres_virtual, oldyres_virtual, oldyoffset;
+
+    if ((err = fbgen_do_set_var(var, con == currcon, info2)))
+	return err;
+    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+	oldxres = fb_display[con].var.xres;
+	oldyres = fb_display[con].var.yres;
+	oldxres_virtual = fb_display[con].var.xres_virtual;
+	oldyres_virtual = fb_display[con].var.yres_virtual;
+	oldbpp = fb_display[con].var.bits_per_pixel;
+	oldyoffset = fb_display[con].var.yoffset;
+	fb_display[con].var = *var;
+	if (oldxres != var->xres || oldyres != var->yres ||
+	    oldxres_virtual != var->xres_virtual ||
+	    oldyres_virtual != var->yres_virtual ||
+	    oldbpp != var->bits_per_pixel ||
+	    oldyoffset != var->yoffset) {
+	    fbgen_set_disp(con, info2);
+	    if (info->changevar)
+		(*info->changevar)(con);
+	    if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
+		return err;
+	    fbgen_install_cmap(con, info2);
+	}
+    }
+    var->activate = 0;
+    return 0;
+}
+
+
+    /*
+     *  Get the Colormap
+     */
+
+int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+		   struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+
+    if (con == currcon)			/* current console ? */
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, fbhw->getcolreg,
+			   info);
+    else
+	if (fb_display[con].cmap.len)	/* non default colormap ? */
+	    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	else
+	    fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+			 cmap, kspc ? 0 : 2);
+    return 0;
+}
+
+
+    /*
+     *  Set the Colormap
+     */
+
+int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+		   struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+    int err;
+
+    if (!fb_display[con].cmap.len) {	/* no colormap allocated ? */
+	if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+				 1 << fb_display[con].var.bits_per_pixel, 0)))
+	    return err;
+    }
+    if (con == currcon)			/* current console ? */
+	return fb_set_cmap(cmap, &fb_display[con].var, kspc, fbhw->setcolreg,
+			   info);
+    else
+	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+    return 0;
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+     */
+
+int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
+		      struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+    int xoffset = var->xoffset;
+    int yoffset = var->yoffset;
+    int err;
+
+    if (xoffset < 0 ||
+	xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
+	yoffset < 0 ||
+	yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+	return -EINVAL;
+    if (con == currcon) {
+	if (fbhw->pan_display) {
+	    if ((err = fbhw->pan_display(var, info2)))
+		return err;
+	} else
+	    return -EINVAL;
+    }
+    fb_display[con].var.xoffset = var->xoffset;
+    fb_display[con].var.yoffset = var->yoffset;
+    if (var->vmode & FB_VMODE_YWRAP)
+	fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+    else
+	fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+
+    return 0;
+}
+
+
+    /*
+     *  Frame Buffer Specific ioctls
+     */
+
+int fbgen_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		unsigned long arg, int con, struct fb_info *info)
+{
+    return -EINVAL;
+}
+
+
+/* ---- Helper functions --------------------------------------------------- */
+
+
+    /*
+     *  Change the video mode
+     */
+
+int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
+		     struct fb_info_gen *info)
+{
+    struct fbgen_hwswitch *fbhw = info->fbhw;
+    int err, activate;
+    char par[info->parsize];
+
+    if ((err = fbhw->decode_var(var, &par, info)))
+	return err;
+    activate = var->activate;
+    if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive)
+	fbhw->set_par(&par, info);
+    fbhw->encode_var(var, &par, info);
+    var->activate = activate;
+    return 0;
+}
+
+
+    /*
+     *  Set the display parameters for a video mode
+     */
+
+void fbgen_set_disp(int con, struct fb_info_gen *info)
+{
+    struct fb_fix_screeninfo fix;
+    struct display *display;
+
+    if (con >= 0)
+	display = &fb_display[con];
+    else
+	display = &disp;	/* used during initialization */
+
+    fbgen_get_fix(&fix, con, &info->info);
+    if (con == -1)
+	con = 0;
+
+    display->screen_base = fix.smem_start;
+    display->visual = fix.visual;
+    display->type = fix.type;
+    display->type_aux = fix.type_aux;
+    display->ypanstep = fix.ypanstep;
+    display->ywrapstep = fix.ywrapstep;
+    display->line_length = fix.line_length;
+    if (info->fbhw->blank || fix.visual == FB_VISUAL_PSEUDOCOLOR ||
+	fix.visual == FB_VISUAL_DIRECTCOLOR)
+	display->can_soft_blank = 1;
+    else
+	display->can_soft_blank = 0;
+#if 0 /* FIXME: generic inverse is not supported yet */
+    display->inverse = (fix.visual == FB_VISUAL_MONO01 ? !inverse : inverse);
+#else
+    display->inverse = fix.visual == FB_VISUAL_MONO01;
+#endif
+}
+
+
+    /*
+     *  Install the current colormap
+     */
+
+void fbgen_install_cmap(int con, struct fb_info_gen *info)
+{
+    struct fbgen_hwswitch *fbhw = info->fbhw;
+    if (con != currcon)
+	return;
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+		    fbhw->setcolreg, &info->info);
+    else
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		    &fb_display[con].var, 1, fbhw->setcolreg, &info->info);
+}
+
+
+    /*
+     *  Update the `var' structure (called by fbcon.c)
+     */
+
+int fbgen_update_var(int con, struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+    int err;
+
+    if (fbhw->pan_display) {
+        if ((err = fbhw->pan_display(&fb_display[con].var, info2)))
+            return err;
+    }
+    return 0;
+}
+
+
+    /*
+     *  Switch to a different virtual console
+     */
+
+int fbgen_switch(int con, struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+
+    /* Do we have to save the colormap ? */
+    if (fb_display[currcon].cmap.len)
+	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+		    fbhw->getcolreg, &info2->info);
+    fbgen_do_set_var(&fb_display[con].var, 1, info2);
+    currcon = con;
+    /* Install new colormap */
+    fbgen_install_cmap(con, info2);
+    return 0;
+}
+
+
+    /*
+     *  Blank the screen
+     */
+
+void fbgen_blank(int blank, struct fb_info *info)
+{
+    struct fb_info_gen *info2 = (struct fb_info_gen *)info;
+    struct fbgen_hwswitch *fbhw = info2->fbhw;
+    u16 black[16];
+    struct fb_cmap cmap;
+
+    if (fbhw->blank && !fbhw->blank(blank, info2))
+	return;
+    if (blank) {
+	memset(black, 0, 16*sizeof(u16));
+	cmap.red = black;
+	cmap.green = black;
+	cmap.blue = black;
+	cmap.transp = NULL;
+	cmap.start = 0;
+	cmap.len = 16;
+	fb_set_cmap(&cmap, &fb_display[currcon].var, 1, fbhw->setcolreg, info);
+    } else
+	fbgen_install_cmap(currcon, info2);
+}
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/font_6x11.c m68k-2.1.77/drivers/video/font_6x11.c
--- /usr/src/m68k-2.1.77/drivers/video/font_6x11.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/font_6x11.c	Fri Jan  9 01:24:55 1998
@@ -0,0 +1,3345 @@
+/**********************************************/
+/*                                            */
+/*       Font file generated by rthelen       */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX (11*256)
+
+char fontname_6x11[] = "ProFont6x11";
+
+int  fontheight_6x11 = 11;
+int  fontwidth_6x11  = 6;
+
+unsigned char fontdata_6x11[FONTDATAMAX] = {
+
+	/* 0 0x00 '^A' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 1 0x01 '^B' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 2 0x02 '^C' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 3 0x03 '^D' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 4 0x04 '^E' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 5 0x05 '^F' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 6 0x06 '^G' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 7 0x07 '^H' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 8 0x08 '^I' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 9 0x09 '^J' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 10 0x0a '^K' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 11 0x0b '^L' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 12 0x0c '^M' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 13 0x0d '^N' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 14 0x0e '^O' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 15 0x0f '^P' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 16 0x10 '^Q' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 17 0x11 '^R' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 18 0x12 '^S' */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 19 0x13 '^T' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x7c, /* 0     00 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 20 0x14 '^U' */
+	0x18, /* 000  000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x78, /* 0    000 */
+	0x78, /* 0    000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 21 0x15 '^V' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 22 0x16 '^W' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 23 0x17 '^X' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 24 0x18 '^Y' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 25 0x19 '^Z' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 26 0x1a '^[' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 27 0x1b '^\' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 28 0x1c '^]' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 29 0x1d '^^' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 30 0x1e '^_' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 31 0x1f '^`' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 33 0x21 '!' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 34 0x22 '"' */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 35 0x23 '#' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 36 0x24 '$' */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x50, /* 0 0 0000 */
+	0x38, /* 00   000 */
+	0x14, /* 000 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x54, /* 0 0 0 00 */
+	0x58, /* 0 0  000 */
+	0x28, /* 00 0 000 */
+	0x34, /* 00  0 00 */
+	0x54, /* 0 0 0 00 */
+	0x48, /* 0 00 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 38 0x26 '&' */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x48, /* 0 00 000 */
+	0x50, /* 0 0 0000 */
+	0x20, /* 00 00000 */
+	0x54, /* 0 0 0 00 */
+	0x48, /* 0 00 000 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 39 0x27 ''' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 40 0x28 '(' */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 41 0x29 ')' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 47 0x2f '/' */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+
+	/* 48 0x30 '0' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 49 0x31 '1' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x18, /* 000  000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 50 0x32 '2' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 51 0x33 '3' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x04, /* 00000 00 */
+	0x18, /* 000  000 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 52 0x34 '4' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x18, /* 000  000 */
+	0x28, /* 00 0 000 */
+	0x48, /* 0 00 000 */
+	0x7c, /* 0     00 */
+	0x08, /* 0000 000 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 53 0x35 '5' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 54 0x36 '6' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 55 0x37 '7' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 56 0x38 '8' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 57 0x39 '9' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x30, /* 00  0000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 60 0x3c '<' */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 62 0x3e '>' */
+	0x00, /* 00000000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 63 0x3f '?' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 64 0x40 '@' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x74, /* 0   0 00 */
+	0x54, /* 0 0 0 00 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 65 0x41 'A' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 66 0x42 'B' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 67 0x43 'C' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 68 0x44 'D' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 69 0x45 'E' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 70 0x46 'F' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 71 0x47 'G' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x4c, /* 0 00  00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 72 0x48 'H' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 73 0x49 'I' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x48, /* 0 00 000 */
+	0x50, /* 0 0 0000 */
+	0x60, /* 0  00000 */
+	0x50, /* 0 0 0000 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x6c, /* 0  0  00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x64, /* 0  00 00 */
+	0x54, /* 0 0 0 00 */
+	0x4c, /* 0 00  00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 80 0x50 'P' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 82 0x52 'R' */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 83 0x53 'S' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x38, /* 00   000 */
+	0x04, /* 00000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 84 0x54 'T' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 85 0x55 'U' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 86 0x56 'V' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 87 0x57 'W' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x6c, /* 0  0  00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 88 0x58 'X' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 91 0x5b '[' */
+	0x0c, /* 0000  00 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x0c, /* 0000  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 92 0x5c '\' */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x02, /* 000000 0 */
+	0x02, /* 000000 0 */
+	0x00, /* 00000000 */
+
+	/* 93 0x5d ']' */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x30, /* 00  0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 94 0x5e '^' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 0      0 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 96 0x60 '`' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 98 0x62 'b' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 100 0x64 'd' */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 102 0x66 'f' */
+	0x00, /* 00000000 */
+	0x0c, /* 0000  00 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+
+	/* 104 0x68 'h' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 105 0x69 'i' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x60, /* 0  00000 */
+	0x00, /* 00000000 */
+
+	/* 107 0x6b 'k' */
+	0x00, /* 00000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x48, /* 0 00 000 */
+	0x50, /* 0 0 0000 */
+	0x70, /* 0   0000 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, /* 00000000 */
+	0x30, /* 00  0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x58, /* 0 0  000 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x78, /* 0    000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x58, /* 0 0  000 */
+	0x64, /* 0  00 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x40, /* 0 000000 */
+	0x38, /* 00   000 */
+	0x04, /* 00000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 116 0x74 't' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x0c, /* 0000  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 123 0x7b '{' */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+
+	/* 124 0x7c '|' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 125 0x7d '}' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 126 0x7e '~' */
+	0x00, /* 00000000 */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 127 0x7f '^?' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 128 0x80 '\200' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 129 0x81 '\201' */
+	0x28, /* 00 0 000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 130 0x82 '\202' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 131 0x83 '\203' */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x78, /* 0    000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 132 0x84 '\204' */
+	0x58, /* 0 0  000 */
+	0x44, /* 0 000 00 */
+	0x64, /* 0  00 00 */
+	0x54, /* 0 0 0 00 */
+	0x4c, /* 0 00  00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 133 0x85 '\205' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 134 0x86 '\206' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 135 0x87 '\207' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 136 0x88 '\210' */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 137 0x89 '\211' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 138 0x8a '\212' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 139 0x8b '\213' */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 140 0x8c '\214' */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x3c, /* 00    00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 141 0x8d '\215' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+
+	/* 142 0x8e '\216' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 143 0x8f '\217' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 144 0x90 '\220' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 145 0x91 '\221' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x40, /* 0 000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 146 0x92 '\222' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 147 0x93 '\223' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 148 0x94 '\224' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 149 0x95 '\225' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 150 0x96 '\226' */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x58, /* 0 0  000 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 151 0x97 '\227' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 152 0x98 '\230' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 153 0x99 '\231' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 154 0x9a '\232' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 155 0x9b '\233' */
+	0x34, /* 00  0 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 156 0x9c '\234' */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 157 0x9d '\235' */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 158 0x9e '\236' */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 159 0x9f '\237' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x34, /* 00  0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 160 0xa0 '\240' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 161 0xa1 '\241' */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 162 0xa2 '\242' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x50, /* 0 0 0000 */
+	0x54, /* 0 0 0 00 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 163 0xa3 '\243' */
+	0x30, /* 00  0000 */
+	0x48, /* 0 00 000 */
+	0x40, /* 0 000000 */
+	0x70, /* 0   0000 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x78, /* 0    000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 164 0xa4 '\244' */
+	0x44, /* 0 000 00 */
+	0x24, /* 00 00 00 */
+	0x50, /* 0 0 0000 */
+	0x48, /* 0 00 000 */
+	0x24, /* 00 00 00 */
+	0x14, /* 000 0 00 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 165 0xa5 '\245' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x7c, /* 0     00 */
+	0x7c, /* 0     00 */
+	0x7c, /* 0     00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 166 0xa6 '\246' */
+	0x3c, /* 00    00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x54, /* 0 0 0 00 */
+	0x3c, /* 00    00 */
+	0x14, /* 000 0 00 */
+	0x14, /* 000 0 00 */
+	0x14, /* 000 0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 167 0xa7 '\247' */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x44, /* 0 000 00 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x58, /* 0 0  000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 168 0xa8 '\250' */
+	0x00, /* 00000000 */
+	0x70, /* 0   0000 */
+	0x08, /* 0000 000 */
+	0x64, /* 0  00 00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x58, /* 0 0  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 169 0xa9 '\251' */
+	0x00, /* 00000000 */
+	0x70, /* 0   0000 */
+	0x08, /* 0000 000 */
+	0x34, /* 00  0 00 */
+	0x44, /* 0 000 00 */
+	0x34, /* 00  0 00 */
+	0x08, /* 0000 000 */
+	0x70, /* 0   0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 170 0xaa '\252' */
+	0x00, /* 00000000 */
+	0x7a, /* 0    0 0 */
+	0x2e, /* 00 0   0 */
+	0x2e, /* 00 0   0 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 171 0xab '\253' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 172 0xac '\254' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 173 0xad '\255' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 174 0xae '\256' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x78, /* 0    000 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x5c, /* 0 0   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 175 0xaf '\257' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x4c, /* 0 00  00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 176 0xb0 '\260' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x6c, /* 0  0  00 */
+	0x54, /* 0 0 0 00 */
+	0x6c, /* 0  0  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 177 0xb1 '\261' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 178 0xb2 '\262' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 179 0xb3 '\263' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x04, /* 00000 00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 180 0xb4 '\264' */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x7c, /* 0     00 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 181 0xb5 '\265' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x74, /* 0   0 00 */
+	0x40, /* 0 000000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+
+	/* 182 0xb6 '\266' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x0c, /* 0000  00 */
+	0x14, /* 000 0 00 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 183 0xb7 '\267' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x24, /* 00 00 00 */
+	0x10, /* 000 0000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x24, /* 00 00 00 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 184 0xb8 '\270' */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 185 0xb9 '\271' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 186 0xba '\272' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x60, /* 0  00000 */
+	0x00, /* 00000000 */
+
+	/* 187 0xbb '\273' */
+	0x00, /* 00000000 */
+	0x1c, /* 000   00 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x1c, /* 000   00 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 188 0xbc '\274' */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 189 0xbd '\275' */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x6c, /* 0  0  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 190 0xbe '\276' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x54, /* 0 0 0 00 */
+	0x5c, /* 0 0   00 */
+	0x50, /* 0 0 0000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 191 0xbf '\277' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x4c, /* 0 00  00 */
+	0x54, /* 0 0 0 00 */
+	0x64, /* 0  00 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 192 0xc0 '\300' */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x20, /* 00 00000 */
+	0x40, /* 0 000000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 193 0xc1 '\301' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x08, /* 0000 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 194 0xc2 '\302' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x04, /* 00000 00 */
+	0x04, /* 00000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 195 0xc3 '\303' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x0c, /* 0000  00 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x50, /* 0 0 0000 */
+	0x20, /* 00 00000 */
+	0x20, /* 00 00000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 196 0xc4 '\304' */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x60, /* 0  00000 */
+	0x00, /* 00000000 */
+
+	/* 197 0xc5 '\305' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x40, /* 0 000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 198 0xc6 '\306' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 199 0xc7 '\307' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x24, /* 00 00 00 */
+	0x48, /* 0 00 000 */
+	0x48, /* 0 00 000 */
+	0x24, /* 00 00 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 200 0xc8 '\310' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x48, /* 0 00 000 */
+	0x24, /* 00 00 00 */
+	0x24, /* 00 00 00 */
+	0x48, /* 0 00 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 201 0xc9 '\311' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x54, /* 0 0 0 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 202 0xca '\312' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 203 0xcb '\313' */
+	0x10, /* 000 0000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 204 0xcc '\314' */
+	0x58, /* 0 0  000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x7c, /* 0     00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 205 0xcd '\315' */
+	0x58, /* 0 0  000 */
+	0x38, /* 00   000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 206 0xce '\316' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x58, /* 0 0  000 */
+	0x50, /* 0 0 0000 */
+	0x50, /* 0 0 0000 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 207 0xcf '\317' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x54, /* 0 0 0 00 */
+	0x5c, /* 0 0   00 */
+	0x50, /* 0 0 0000 */
+	0x2c, /* 00 0  00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 208 0xd0 '\320' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 209 0xd1 '\321' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 0      0 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 210 0xd2 '\322' */
+	0x00, /* 00000000 */
+	0x14, /* 000 0 00 */
+	0x28, /* 00 0 000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 211 0xd3 '\323' */
+	0x00, /* 00000000 */
+	0x14, /* 000 0 00 */
+	0x14, /* 000 0 00 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 212 0xd4 '\324' */
+	0x00, /* 00000000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x18, /* 000  000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 213 0xd5 '\325' */
+	0x00, /* 00000000 */
+	0x18, /* 000  000 */
+	0x08, /* 0000 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 214 0xd6 '\326' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x7c, /* 0     00 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 215 0xd7 '\327' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x10, /* 000 0000 */
+	0x28, /* 00 0 000 */
+	0x44, /* 0 000 00 */
+	0x28, /* 00 0 000 */
+	0x10, /* 000 0000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 216 0xd8 '\330' */
+	0x00, /* 00000000 */
+	0x28, /* 00 0 000 */
+	0x00, /* 00000000 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x44, /* 0 000 00 */
+	0x3c, /* 00    00 */
+	0x04, /* 00000 00 */
+	0x38, /* 00   000 */
+	0x00, /* 00000000 */
+
+	/* 217 0xd9 '\331' */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x7e, /* 0      0 */
+	0x00, /* 00000000 */
+	0x7e, /* 0      0 */
+	0x00, /* 00000000 */
+	0x7e, /* 0      0 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 218 0xda '\332' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 219 0xdb '\333' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 220 0xdc '\334' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 221 0xdd '\335' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 222 0xde '\336' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 223 0xdf '\337' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 224 0xe0 '\340' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 225 0xe1 '\341' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 226 0xe2 '\342' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 227 0xe3 '\343' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 228 0xe4 '\344' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 229 0xe5 '\345' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 230 0xe6 '\346' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 231 0xe7 '\347' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 232 0xe8 '\350' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 233 0xe9 '\351' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 234 0xea '\352' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 235 0xeb '\353' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 236 0xec '\354' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 237 0xed '\355' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 238 0xee '\356' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 239 0xef '\357' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 240 0xf0 '\360' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 241 0xf1 '\361' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 242 0xf2 '\362' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 243 0xf3 '\363' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 244 0xf4 '\364' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 245 0xf5 '\365' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 246 0xf6 '\366' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 247 0xf7 '\367' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 248 0xf8 '\370' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 249 0xf9 '\371' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 250 0xfa '\372' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 251 0xfb '\373' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 252 0xfc '\374' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 253 0xfd '\375' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 254 0xfe '\376' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+	/* 255 0xff '\377' */
+	0x00, /* 00000000 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x3c, /* 00    00 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+	0x00, /* 00000000 */
+
+};
+
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/fonts.c m68k-2.1.77/drivers/video/fonts.c
--- /usr/src/m68k-2.1.77/drivers/video/fonts.c	Wed Dec  3 21:12:27 1997
+++ m68k-2.1.77/drivers/video/fonts.c	Fri Jan  9 01:22:32 1998
@@ -9,6 +9,7 @@
  */
 
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #ifdef __mc68000__
@@ -36,6 +37,11 @@
 extern int fontwidth_pearl8x8, fontheight_pearl8x8;
 extern u_char fontdata_pearl8x8[];
 
+/* VGA6x11 */
+extern char fontname_6x11[];
+extern int fontwidth_6x11, fontheight_6x11;
+extern u_char fontdata_6x11[];
+
 
    /*
     *    Font Descriptor Array
@@ -51,12 +57,14 @@
 #define VGA8x8_IDX	0
 #define VGA8x16_IDX	1
 #define PEARL8x8_IDX	2
+#define VGA6x11_IDX	3
 
 static struct softfontdesc softfonts[] = {
    { fontname_8x8, &fontwidth_8x8, &fontheight_8x8, fontdata_8x8 },
    { fontname_8x16, &fontwidth_8x16, &fontheight_8x16, fontdata_8x16 },
    { fontname_pearl8x8, &fontwidth_pearl8x8, &fontheight_pearl8x8,
      fontdata_pearl8x8 },
+   { fontname_6x11, &fontwidth_6x11, &fontheight_6x11, fontdata_6x11 },
 };
 
 static unsigned int numsoftfonts = sizeof(softfonts)/sizeof(*softfonts);
@@ -101,6 +109,16 @@
 #endif
     } else
 	i = VGA8x16_IDX;
+
+#if defined(CONFIG_MAC)
+    if (MACH_IS_MAC) {
+#if 0  /* MSch: removed until 6x11 is debugged */
+        i = VGA6x11_IDX;   /* I added this for fun ... I like 6x11 */
+#endif
+       if (xres < 640)
+           i = VGA6x11_IDX;
+    }
+#endif
 
     if (name)
 	*name = softfonts[i].name;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/macfb.c m68k-2.1.77/drivers/video/macfb.c
--- /usr/src/m68k-2.1.77/drivers/video/macfb.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/macfb.c	Fri Jan  9 01:24:58 1998
@@ -0,0 +1,423 @@
+/*
+ *	We've been given MAC frame buffer info by the booter. Now go set it up
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.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/nubus.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/bootinfo.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/macintosh.h>
+#include <linux/fb.h>
+
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+static struct fb_var_screeninfo macfb_defined={
+	0,0,0,0,	/* W,H, W, H (virtual) load xres,xres_virtual*/
+	0,0,		/* virtual -> visible no offset */
+	8,		/* depth -> load bits_per_pixel */
+	0,		/* greyscale ? */
+	{0,0,0},	/* R */
+	{0,0,0},	/* G */
+	{0,0,0},	/* B */
+	{0,0,0},	/* transparency */
+	0,		/* standard pixel format */
+	FB_ACTIVATE_NOW,
+	274,195,	/* 14" monitor *Mikael Nykvist's anyway* */
+	FB_ACCEL_NONE,	/* The only way to accelerate a mac is .. */
+	0L,0L,0L,0L,0L,
+	0L,0L,0,	/* No sync info */
+	FB_VMODE_NONINTERLACED,
+	{0,0,0,0,0,0}
+};
+
+#define NUM_TOTAL_MODES		1
+#define NUM_PREDEF_MODES	1
+
+static struct display disp;
+static struct fb_info fb_info;
+
+static int inverse = 0;
+
+struct macfb_par
+{
+	void *unused;
+};
+
+static int currcon = 0;
+static int current_par_valid = 0;
+struct macfb_par current_par;
+
+static int mac_xres,mac_yres,mac_depth, mac_xbytes, mac_vxres;
+static unsigned long mac_videobase;
+static unsigned long mac_videosize;
+
+	/*
+	 * Open/Release the frame buffer device
+	 */
+
+static int macfb_open(struct fb_info *info)
+{
+	/*
+	 * Nothing, only a usage count for the moment
+	 */
+	MOD_INC_USE_COUNT;
+	return(0);
+}
+
+static int macfb_release(struct fb_info *info)
+{
+	MOD_DEC_USE_COUNT;
+	return(0);
+}
+
+static void macfb_encode_var(struct fb_var_screeninfo *var, 
+				struct macfb_par *par)
+{
+	int i=0;
+	var->xres=mac_xres;
+	var->yres=mac_yres;
+	var->xres_virtual=mac_vxres;
+	var->yres_virtual=var->yres;
+	var->xoffset=0;
+	var->yoffset=0;
+	var->bits_per_pixel = mac_depth;
+	var->grayscale=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=0;
+	var->vmode=FB_VMODE_NONINTERLACED;
+	var->pixclock=0;
+	var->sync=0;
+	var->left_margin=0;
+	var->right_margin=0;
+	var->upper_margin=0;
+	var->lower_margin=0;
+	var->hsync_len=0;
+	var->vsync_len=0;
+	for(i=0;i<arraysize(var->reserved);i++)
+		var->reserved[i]=0;
+	return;
+}
+
+
+static void macfb_get_par(struct macfb_par *par)
+{
+	*par=current_par;
+}
+
+static void macfb_set_par(struct macfb_par *par)
+{
+	current_par_valid=1;
+}
+
+static int fb_update_var(int con, struct fb_info *info)
+{
+	return 0;
+}
+
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+{
+	struct macfb_par par;
+	
+	macfb_get_par(&par);
+	macfb_encode_var(var, &par);
+	return 0;
+}
+
+extern int console_loglevel;
+
+static void macfb_encode_fix(struct fb_fix_screeninfo *fix, 
+				struct macfb_par *par)
+{
+	int i;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id,"Macintosh");
+
+	/*
+	 * X works, but screen wraps ... 
+	 */
+	fix->smem_start=(char *)(mac_videobase&PAGE_MASK);
+	fix->smem_offset=(mac_videobase&~PAGE_MASK);
+	fix->smem_len=PAGE_ALIGN(mac_videosize);
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	fix->xpanstep=0;
+	fix->ypanstep=0;
+	fix->ywrapstep=0;
+	fix->line_length=mac_xbytes;
+	return;
+}
+
+static int macfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
+{
+	struct macfb_par par;
+	macfb_get_par(&par);
+	macfb_encode_fix(fix, &par);
+	return 0;
+}
+
+static int macfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	struct macfb_par par;
+	if(con==-1)
+	{
+		macfb_get_par(&par);
+		macfb_encode_var(var, &par);
+	}
+	else
+		*var=fb_display[con].var;
+	return 0;
+}
+
+static void macfb_set_disp(int con)
+{
+	struct fb_fix_screeninfo fix;
+	struct display *display;
+	
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = &disp;	/* used during initialization */
+
+	macfb_get_fix(&fix, con, 0);
+
+	display->screen_base = (u_char *)(fix.smem_start+fix.smem_offset);
+	display->visual = fix.visual;
+	display->type = fix.type;
+	display->type_aux = fix.type_aux;
+	display->ypanstep = fix.ypanstep;
+	display->ywrapstep = fix.ywrapstep;
+	display->line_length = fix.line_length;
+	display->next_line = fix.line_length;
+	display->can_soft_blank = 0;
+	display->inverse = inverse;
+
+}
+
+static int macfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	int err;
+	
+	if ((err=do_fb_set_var(var, 1)))
+		return err;
+	return 0;
+}
+
+static int macfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+	printk("macfb_get_cmap: not supported!\n");
+#if 0
+	/* interferes with X11 */
+	if (console_loglevel < 7)
+		return -EINVAL;
+	if (con == currcon) /* current console? */
+		return fb_get_cmap(cmap, &fb_display[con].var, kspc, 0 /*offb_getcolreg*/, info);
+	else if (fb_display[con].cmap.len) /* non default colormap? */
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		     cmap, kspc ? 0 : 2);
+#endif
+	return 0;
+
+}
+
+static int macfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+	printk("macfb_set_cmap: not supported!\n");
+#if 0
+	if (console_loglevel < 7)
+		return -EINVAL;
+	if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+		if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+				 1<<fb_display[con].var.bits_per_pixel, 0)))
+		return err;
+	}
+	if (con == currcon)			/* current console? */
+		return fb_set_cmap(cmap, &fb_display[con].var, kspc, 1 /*offb_setcolreg*/, info);
+	else
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+#endif
+	return 0;
+}
+
+static int macfb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info)
+{
+	/* no panning */
+	printk("macfb_pan: not supported!\n");
+	return -EINVAL;
+}
+
+static int macfb_ioctl(struct inode *inode, struct file *file, 
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info)
+{
+	printk("macfb_ioctl: not supported!\n");
+	return -EINVAL;
+}
+
+static struct fb_ops macfb_ops = {
+	macfb_open,
+	macfb_release,
+	macfb_get_fix,
+	macfb_get_var,
+	macfb_set_var,
+	macfb_get_cmap,
+	macfb_set_cmap,
+	macfb_pan_display,
+	macfb_ioctl
+};
+
+void macfb_setup(char *options, int *ints)
+{
+    char *this_opt;
+    int temp;
+
+    fb_info.fontname[0] = '\0';
+
+    if (!options || !*options)
+		return;
+     
+    for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+	if (!*this_opt) continue;
+
+	if (! strcmp(this_opt, "inverse"))
+		inverse=1;
+	else if (!strncmp(this_opt, "font:", 5)) {
+	   strcpy(fb_info.fontname, this_opt+5);
+	   printk("macfb_setup: option %s\n", this_opt);
+	}
+    }
+}
+
+static int macfb_switch(int con, struct fb_info *info)
+{
+	do_fb_set_var(&fb_display[con].var,1);
+	currcon=con;
+	return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void macfb_blank(int blank, struct fb_info *info)
+{
+	/* Not supported */
+}
+
+/*
+ *	Nubus call back. This will give us our board identity and also
+ *	other useful info we need later
+ */
+ 
+static int nubus_video_card(struct nubus_device_specifier *ns, int slot, struct nubus_type *nt)
+{
+	if(nt->category==NUBUS_CAT_DISPLAY)
+		return 0;
+	/* Claim all video cards. We dont yet do driver specifics tho. */
+	return -ENODEV;
+}
+
+static struct nubus_device_specifier nb_video={
+	nubus_video_card,
+	NULL
+};
+
+__initfunc(unsigned long macfb_init(unsigned long mem_start))
+{
+	/* nubus_remap the video .. */
+	int err;
+
+	if (!MACH_IS_MAC) 
+		return mem_start;
+
+	mac_xres=mac_bi_data.dimensions&0xFFFF;
+	mac_yres=(mac_bi_data.dimensions&0xFFFF0000)>>16;
+	mac_depth=mac_bi_data.videodepth;
+	mac_xbytes=mac_bi_data.videorow;
+	mac_vxres = (mac_xbytes/mac_depth)*8;
+	mac_videosize=mac_xbytes*mac_yres;
+	mac_videobase=mac_bi_data.videoaddr;
+
+	printk("macfb_init: xres %d yres %d bpp %d addr %x size %d \n",
+		mac_xres, mac_yres, mac_depth, mac_videobase, mac_videosize);
+
+	mac_debugging_penguin(4);
+	
+	/*
+	 *	Fill in the available video resolution
+	 */
+	 
+	 macfb_defined.xres=mac_xres;
+	 macfb_defined.yres=mac_yres;
+	 macfb_defined.xres_virtual=mac_vxres;
+	 macfb_defined.yres_virtual=mac_yres;
+	 macfb_defined.bits_per_pixel=mac_depth;
+	 
+	 
+	/*
+	 *	Let there be consoles..
+	 */
+	strcpy(fb_info.modename, "Macintosh Builtin ");
+	fb_info.changevar = NULL;
+	fb_info.node = -1;
+	fb_info.fbops = &macfb_ops;
+	fb_info.disp=&disp;
+	fb_info.switch_con=&macfb_switch;
+	fb_info.updatevar=&fb_update_var;
+	fb_info.blank=&macfb_blank;
+	do_fb_set_var(&macfb_defined,1);
+
+	err=register_framebuffer(&fb_info);
+	if(err<0)
+	{
+		mac_boom(6);
+		return NULL;
+	}
+
+	macfb_get_var(&disp.var, -1, &fb_info));
+	macfb_set_disp(-1);
+	
+	/*
+	 *	Register the nubus hook
+	 */
+	 
+	register_nubus_device(&nb_video);
+	
+	return mem_start;
+}
+
+#if 0
+/*
+ * These two auxiliary debug functions should go away ASAP. Only usage: 
+ * before the console output is up (after head.S come some other crucial
+ * setup routines :-) 
+ *
+ * Now in debug.c ...
+ */
+#endif
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/mach64fb.c m68k-2.1.77/drivers/video/mach64fb.c
--- /usr/src/m68k-2.1.77/drivers/video/mach64fb.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/mach64fb.c	Fri Jan  9 01:25:04 1998
@@ -0,0 +1,2519 @@
+/*
+ * linux/drivers/video/mach64fb.c -- Low level implementation of the
+ *                                   ATI Mach64 frame buffer device
+ *
+ *    Copyright (C) 1997 Bernd Harries
+ *
+ *
+ * This file is based on the Atari frame buffer device (atafb.c):
+ *
+ *  Copyright (C) 1994 Martin Schaller & Roman Hodek
+ *  
+ *
+ * and the Amiga frame buffer device (amifb.c):
+ *
+ *    Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ * History:
+ *   - 09 Aug 97: Original version by Bernd Harries
+ *   - 27 Aug 97: Extra Parameter for GUIreg-Base for Panther 64
+ *   - 03 Oct 97: Minor changes by Bernd Harries
+ *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*============================================================================*/
+/* Includes */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/zorro.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+
+#include "mach64regs.h"
+
+#include "mach64fb.h"
+
+
+unsigned long mach64fb_init(unsigned long mem_start);
+void mach64fb_setup(char *options, int *ints);
+
+/*============================================================================*/
+/* Defines */
+
+#define _NOT_MAP_768K_IO_
+
+#define _MAP_GUIREGS_0BFC00_
+
+
+#define _NOT_DUMP_IO_REGS_
+
+#define _NOT_DUMP_GUIREGS_0BFC00_
+
+#define _NOT_DUMP_GUIREGS_3FFC00_
+
+#define _NOT_DUMP_KMAP_RANGE_
+
+
+#ifdef MULTI_MACH
+
+#define MACH_MAX 8
+
+#define DECLARE_STATIC_UINT08___MN_  static unsigned char          m64_num;
+#define DECLARE_UINT08___MN_         unsigned char m64_num;
+#define ARG_UINT08___MN_             unsigned char m64_num
+#define ADD_ARG_UINT08___MN_         , unsigned char m64_num
+
+#define _ARRAY_       [MACH_MAX]
+#define __MN__        [m64_num]
+#define _MN_           m64_num
+#define _INC_MN_       m64_num++
+#define _ARG_MN_       m64_num
+#define _ADD_ARG_MN_   , m64_num
+
+#else      /*---------------------*/
+
+#define DECLARE_STATIC_UINT08___MN_
+#define DECLARE_UINT08___MN_
+#define ARG_UINT08___MN_           void
+#define ADD_ARG_UINT08___MN_
+
+#define _ARRAY_    
+#define __MN__         
+#define _MN_           0
+#define _INC_MN_       
+#define _ARG_MN_       
+#define _ADD_ARG_MN_   
+
+#endif     /* MULTI_MACH */
+
+/*--------------------------------------------------------------------------*/
+  
+#define MACH_MAX 8
+#define arraysize(x)    (sizeof(x)/sizeof(*(x)))
+
+#define  FuncId       if(mach64fb_debug & 0x00000100) printk
+#define  FuncDone     if(mach64fb_debug & 0x00000200) printk
+#define  CFuncId      if(mach64fb_debug & 0x00000400) printk
+#define  CFuncDone    if(mach64fb_debug & 0x00000800) printk
+#define  OFuncId      if(mach64fb_debug & 0x00001000) printk
+#define  OFuncDone    if(mach64fb_debug & 0x00002000) printk
+
+
+/* Busy */
+#define  Bprint       if(mach64fb_debug & 0x01000000) printk
+/* Debug */
+#define  Dprint       if(mach64fb_debug & 0x00800000) printk
+
+/* Message */
+#define  Mprint       if(mach64fb_debug & 0x00004000) printk
+/* Info */
+#define  Iprint       if(mach64fb_debug & 0x00008000) printk
+/* Warn */
+#define  Wprint       if(mach64fb_debug & 0x00010000) printk
+/* Error */
+#define  Eprint       if(mach64fb_debug & 0x00020000) printk
+/* Fatal */
+#define  Fprint       if(mach64fb_debug & 0x00040000) printk
+/* Panic */
+#define  Pprint       if(mach64fb_debug & 0x00080000) printk
+
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * This Fragment is for learning and for future expansion so far:
+ *
+ * Byte swaping is probably not needed on Alpha CPUs but The IO is memory
+ * mapped anyway and writing data < 32 bit is impossible on the actual
+ * CPUs unless the board has a sparse space. 
+ *
+ * The DEC Alpha CPUs have write buffers that hold data to be written
+ * to memory. The data is NOT necessarily written to memory immediately
+ * after the instruction.
+ * Darum: The machine instruction MB (memory barrier, wbflush on Mips CPUs) 
+ * has to be executed to force the flush of these buffers, or a write
+ * instruction at least $1000 bytes apart from the access to be flushed 
+ * (may be more in future CPUs) has to follow. This can be done by using
+ * mirrored registers if available. The Mach64 GUI registers are all within
+ * 1 $1000 byte area and are not always mirrored. => MB instruction. 
+ *
+ */
+
+#ifdef __alpha__
+
+#define barrier() __asm__ __volatile__("mb": : :"memory")
+
+#else /* __alpha__ */
+
+#ifdef __mips
+
+#define barrier() __asm__ __volatile__ ("wbflush": : :"memory")
+
+#else
+/*
+#define barrier()  / * Serialized Nocaching => Not used on 680x0 today  * /
+*/
+#endif /* __mips__ */
+#endif /* __alpha__ */
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef _MAP_768K_IO_
+
+#define OUTB(port,val) \
+  *((unsigned volatile char *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )) = (val)
+
+#define INB(port) \
+  (*((unsigned volatile char *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )))
+
+/*
+#define OUTL(port,val) \
+  *((unsigned volatile int *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )) = (val)
+
+#define INL(port) \
+  (*((unsigned volatile int *) ((port) + 0x00080000 + virt_vgaiobase __MN__  )))
+*/
+
+#else
+
+#define OUTB(port,val) \
+  *((unsigned volatile char *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+#define INB(port) \
+  (*((unsigned volatile char *) ((port) + virt_vgaiobase __MN__  )))
+
+/*
+#define OUTL(port,val) \
+  *((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+#define INL(port) \
+  (*((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )))
+*/
+
+#endif  /* _MAP_768K_IO_ */
+
+#define DACDelay                    \
+  do {                              \
+    unsigned char tmp = INB(0x3da); \
+    tmp = INB(0x3da);               \
+  } while (0)
+
+/*============================================================================*/
+
+/*
+#define regwr(port, val) \
+  *((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )) = (val)
+
+
+#define regrd(port) \
+  (*((unsigned volatile int *) ((port) + virt_vgaiobase __MN__  )))
+*/
+
+/*============================================================================*/
+/* Types */
+
+struct mach64fb_par
+{
+   int xres;
+   int yres;
+   int bpp;
+};
+
+/*============================================================================*/
+/* Extern Functions*/
+
+
+
+/*============================================================================*/
+/* Intern Functions*/
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Interface to the low level console driver exported with fb_info
+    */
+
+static int  Mach64fb_switch(int con, struct fb_info *info);
+static int  Mach64fb_updatevar(int con, struct fb_info *info);
+static void Mach64fb_blank(int blank, struct fb_info *info);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Interface fb_ops used by the world exported with fb_info.fb_ops
+    */
+
+static int M64_op_open(struct fb_info *info);
+static int M64_op_release(struct fb_info *info);
+static int M64_op_get_fix(struct fb_fix_screeninfo * fix, int con,
+			  struct fb_info *info);
+static int M64_op_get_var(struct fb_var_screeninfo * var, int con,
+			  struct fb_info *info);
+static int M64_op_set_var(struct fb_var_screeninfo * var, int con,
+			  struct fb_info *info);
+static int M64_op_get_cmap(struct fb_cmap * cmap, int kspc, int con,
+			   struct fb_info *info);
+static int M64_op_set_cmap(struct fb_cmap * cmap, int kspc, int con,
+			   struct fb_info *info);
+static int M64_op_pan_display(struct fb_var_screeninfo * var, int con,
+			      struct fb_info *info);
+
+static int 
+M64_op_ioctl(
+  struct inode * inode,
+  struct file *file,
+  u_int cmd,
+  u_long arg,
+  int con,
+  struct fb_info *info);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *   Internal Routines
+    */
+
+static int 
+do_fb_set_var(struct fb_var_screeninfo * var, int isactive);
+
+static void 
+do_install_cmap(int con, struct fb_info *info);
+
+static void 
+mach64fb_set_disp(int con, struct fb_info *info);
+
+static int 
+get_video_mode(const char * name);
+
+static int 
+store_video_par(char* videopar  ADD_ARG_UINT08___MN_ );
+
+static char * 
+strtoke(char * s,const char * ct);
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *   Hardware Specific Routines
+    */
+
+static int 
+M64_hw_init( ARG_UINT08___MN_ );
+
+static int 
+M64_hw_encode_fix(struct fb_fix_screeninfo * fix, struct mach64fb_par * par);
+
+static int 
+M64_hw_decode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+
+static int 
+M64_hw_encode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+
+static void 
+M64_hw_get_par(struct mach64fb_par * par);
+
+static void 
+M64_hw_set_par(struct mach64fb_par * par);
+
+static int 
+M64_hw_getcolreg(
+  u_int regno,
+  u_int * red,
+  u_int * green,
+  u_int * blue,
+  u_int * transp,
+  struct fb_info *info);
+
+static int 
+M64_hw_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp,
+				 struct fb_info *info);
+
+static void 
+M64_hw_blank(int blank);
+
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Intern Variables */
+
+/*--------------------------------------------------------------------------*/
+/* BSS */
+
+
+static unsigned long            phys_vmembase _ARRAY_ ;
+static unsigned long            phys_size _ARRAY_ ;
+static unsigned long            phys_vgaiobase _ARRAY_ ;
+static unsigned long            phys_guiregbase _ARRAY_ ;
+
+static unsigned long            virt_vmembase _ARRAY_ ;
+static unsigned long            virt_size _ARRAY_ ;
+static unsigned long            virt_vgaiobase _ARRAY_ ;
+static unsigned long            virt_guiregbase _ARRAY_ ;
+
+static unsigned int             mach64_xres _ARRAY_ ;
+static unsigned int             mach64_yres _ARRAY_ ;
+static unsigned int             mach64_depth _ARRAY_ ;
+
+
+static struct mach64fb_par     current_par _ARRAY_ ;
+static struct display           m_disp _ARRAY_ ;
+static struct fb_info           fb_info _ARRAY_ ;
+
+static u_short                  mach64_colormap  _ARRAY_ [256][4];
+
+static u_int                    mach64_key;
+static u_int                    mach64_bitspercol _ARRAY_ ;
+
+static int                      currcon;
+
+
+static u_short                  mach64_inverse _ARRAY_ ;
+static short int                mach64_pmode _ARRAY_ ;
+static short int                mach64_mode _ARRAY_ ;   /* 0..31 */
+static short int                mach64_use_accel _ARRAY_ ;
+static char                     current_par_valid _ARRAY_ ;
+
+static unsigned char            mach64_count;
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Switch for Chipset Independency
+    */
+
+static struct fb_hwswitch
+{
+
+  /* Initialisation */
+
+  int (*init)( ARG_UINT08___MN_ );
+
+  /* Display Control */
+
+  int (*encode_fix)(struct fb_fix_screeninfo * fix, struct mach64fb_par * par);
+  int (*decode_var)(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+  int (*encode_var)(struct fb_var_screeninfo * var, struct mach64fb_par * par);
+  void (*get_par)(struct mach64fb_par * par );
+  void (*set_par)(struct mach64fb_par * par );
+  int (*getcolreg)(u_int regno, u_int * red, u_int * green, u_int * blue,
+    u_int * transp, struct fb_info *info);
+  int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
+    u_int transp, struct fb_info *info);
+  void (*blank)(int blank);
+  void (*set_screen_base)( unsigned long s_base );
+  int  (*pan_display)( struct fb_var_screeninfo * var);
+} 
+* fbhws_ptr;
+
+
+/*--------------------------------------------------------------------------*/
+/* Data */
+
+
+/* -------------- local Interfaces to hardware functions ---------------- */
+
+/* see XGCValues GCFunction */
+int 
+mach64alu[16] =
+{
+    MIX_0,
+    MIX_AND,
+    MIX_SRC_AND_NOT_DST,
+    MIX_SRC,
+    MIX_NOT_SRC_AND_DST,
+    MIX_DST,
+    MIX_XOR,
+    MIX_OR,
+    MIX_NOR,
+    MIX_XNOR,
+    MIX_NOT_DST,
+    MIX_SRC_OR_NOT_DST,
+    MIX_NOT_SRC,
+    MIX_NOT_SRC_OR_DST,
+    MIX_NAND,
+    MIX_1
+};
+
+static struct fb_hwswitch 
+mach64_switch = 
+{
+  M64_hw_init,
+  M64_hw_encode_fix,
+  M64_hw_decode_var,
+  M64_hw_encode_var,
+  NULL,                    /* M64_hw_get_par, */
+  NULL,                    /* M64_hw_set_par, */
+  M64_hw_getcolreg,
+  M64_hw_setcolreg,
+  M64_hw_blank,
+  NULL,
+  NULL
+};
+
+/* ------ Interfaces to hardware functions to export with fb_info  ------ */
+
+static struct fb_ops 
+mach64fb_ops =
+{
+  M64_op_open,
+  M64_op_release,
+  M64_op_get_fix,
+  M64_op_get_var,
+  M64_op_set_var,
+  M64_op_get_cmap,
+  M64_op_set_cmap,
+  M64_op_pan_display,
+  M64_op_ioctl
+};
+
+static  unsigned int    mach64fb_debug = 0x018FCF00;
+
+   /*
+    *    Frame Buffer Name
+    */
+
+static char     mach64fb_name[16] = "ATI Mach64 ";
+
+
+   /*
+    *    Ati Mach64 Graphics Board
+    */
+
+#define M64_8_WIDTH 1152
+#define M64_8_HEIGHT 912
+#define M64_8_PIXCLOCK 12500    /* ++Geert: Just a guess */
+
+#define M64_16_WIDTH 800
+#define M64_16_HEIGHT 600
+#define M64_16_PIXCLOCK 25000   /* ++Geert: Just a guess */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Predefined Video Mode Names
+    */
+/*--------------------------------------------------------------------------*/
+
+static char *                   fb_var_names[] =
+{
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   "autodetect",
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   "Mach64_8",            /* Mach64 8 bpp */
+   "Mach64_16",           /* Mach64 16 bpp */
+};
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Predefined Video Mode Definitions
+    */
+/*--------------------------------------------------------------------------*/
+
+static struct fb_var_screeninfo mach64fb_predefined[] = 
+{
+
+   /*
+    *    Autodetect (Default) Video Mode
+    */
+
+   { 0, },
+
+   /*
+    *    Predefined Video Modes
+    */
+    
+   {
+      /* Cybervision 8 bpp */
+      M64_8_WIDTH, M64_8_HEIGHT, M64_8_WIDTH, M64_8_HEIGHT, 0, 0, 8, 0,
+      {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+      0, 0, -1, -1, FB_ACCEL_NONE, M64_8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+   }, {
+      /* Cybervision 16 bpp */
+      M64_16_WIDTH, M64_16_HEIGHT, M64_16_WIDTH, M64_16_HEIGHT, 0, 0, 16, 0,
+      {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+      0, 0, -1, -1, FB_ACCEL_NONE, M64_16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+      FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+   },
+};
+
+
+#define NUM_TOTAL_MODES    arraysize(mach64fb_predefined)
+#define NUM_PREDEF_MODES   (3)
+
+
+   /*
+    *    Some default modes
+    */
+
+#define M64_8_DEFMODE     (1)
+#define M64_16_DEFMODE    (2)
+
+
+
+/*============================================================================*/
+/*============================================================================*/
+/* Functions */
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*============================================================================*/
+
+__inline__ void 
+regwr(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regrd(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwrb(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x003FFC00 + virt_vmembase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+
+#ifdef _MAP_768K_IO_
+
+__inline__ void
+OUTL(unsigned int port, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + 0x00080000 + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+INL(unsigned int port)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + 0x00080000 + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regw(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regr(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwB(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0003FC00 + virt_vgaiobase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+#else
+
+__inline__ void 
+OUTL(unsigned int port, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + virt_vgaiobase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+INL(unsigned int port)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((port) + virt_vgaiobase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+
+
+__inline__ void 
+regw(unsigned int regindex, unsigned long regdata)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  lword = (regdata >> 16) | (regdata << 16);
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  *((unsigned volatile int*)(appaddr)) = lword;
+  barrier();
+}
+/*============================================================================*/
+
+__inline__ unsigned int
+regr(unsigned int regindex)
+{
+  register unsigned long        appaddr;
+  register u_int                lword;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  lword = (*((unsigned volatile int*)(appaddr)));
+
+  lword = (lword >> 16) | (lword << 16);     /* swap words */
+  lword = ((lword >> 8) & 0x00FF00FF) | ((lword << 8) & 0xFF00FF00);
+
+  return(lword);
+}
+/*============================================================================*/
+
+__inline__ void 
+regwB(unsigned int regindex, unsigned char regdata)
+{
+  register unsigned long        appaddr;
+  /*--------------------------------------------------------------------------*/
+  /* calculate aperture address */
+  appaddr = ((regindex) + 0x0000FC00 + virt_guiregbase __MN__  );
+
+  *(char *)appaddr = regdata;
+  barrier();
+}
+/*============================================================================*/
+
+#endif  /* _MAP_768K_IO_ */
+
+
+/*============================================================================*/
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_open(struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_open(%p) \n", info);
+  /*
+   * Nothing, only a usage count for the moment
+   */
+
+  MOD_INC_USE_COUNT;
+
+  return(0);
+}
+/*endproc M64_op_open() */
+
+/*============================================================================*/
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_release(struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("M64_op_release() \n");
+  MOD_DEC_USE_COUNT;
+  return(0);
+}
+/*endproc M64_op_release() */
+
+/*============================================================================*/
+
+
+/* -------------------- Hardware specific routines ------------------------ */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Initialization
+    *
+    *    Set the default video mode for this chipset. If a video mode was
+    *    specified on the command line, it will override the default mode.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_init( ARG_UINT08___MN_ )
+
+/*--------------------------------------------------------------------------*/
+{
+  struct fb_var_screeninfo *    var_ptr = &mach64fb_predefined[0];
+  struct mach64fb_par          dummy_par;
+
+  unsigned long                 board_addr;
+  u_int *                       u32_ptr;
+  u_int                         read_val;
+  int                           n;
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("M64_hw_init() \n");
+
+  if(mach64_mode __MN__   == -1)
+  {
+    mach64_mode __MN__   = M64_8_DEFMODE;
+  }
+  /*endif*/
+
+  board_addr = virt_vmembase __MN__  ;
+  for (i = 0; i < 256; i++)
+  {
+    mach64_colormap  __MN__  [i][0] = i;
+    mach64_colormap  __MN__  [i][1] = i;
+    mach64_colormap  __MN__  [i][2] = i;
+    mach64_colormap  __MN__  [i][3] = 0;
+  }
+
+#ifdef _DUMP_IO_REGS_
+  u32_ptr = (u_int *)(0x000002EC + virt_vgaiobase __MN__ );
+  n = 0;
+  while(n < 0x20)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    Dprint("%08X ", INL(0x02EC + (n << 10)) );  n++;
+    u32_ptr += 0x0400;
+  }
+  /*endwhile*/
+  Dprint("\n" );
+#endif
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+  read_val = regr(GEN_TEST_CNTL);
+  if(0)
+  {
+    regw(GEN_TEST_CNTL, read_val | 0x0200);
+  }
+  else
+  {
+    regw(GEN_TEST_CNTL, read_val & ~0x0200);
+  }
+  /*endif*/
+
+  WaitQueue(13);
+  regw(SRC_OFF_PITCH, (mach64_xres __MN__  << 19));
+  regw(DST_OFF_PITCH, (mach64_xres __MN__  << 19));
+  regw(SC_LEFT_RIGHT, (mach64_xres __MN__  -1) << 16);
+  regw(SC_TOP_BOTTOM, (mach64_yres __MN__  -1) << 16);
+
+  regw(DP_BKGD_CLR, 0x00000000);
+  regw(DP_FRGD_CLR, 0x00000001);
+
+  regw(DP_WRITE_MASK, 0x000000FF  /* pGC->planemask */ );
+  regw(DP_PIX_WIDTH, BYTE_ORDER_MSB_TO_LSB | HOST_8BPP | SRC_8BPP | DST_8BPP);
+  regw(DP_MIX, FRGD_MIX_S | BKGD_MIX_D);
+  regw(DP_SRC, FRGD_SRC_BLIT | BKGD_SRC_BKGD_CLR);
+
+  regw(CLR_CMP_CNTL, 0x00000000);
+  regw(CLR_CMP_CLR, 0x00000000);
+
+  regw(GUI_TRAJ_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+
+
+#ifdef  _DUMP_GUIREGS_0BFC00_
+
+#ifdef _MAP_768K_IO_
+  u32_ptr = (u_int *)(0x0003FC00 + virt_vgaiobase __MN__ );
+#else
+  u32_ptr = (u_int *)(0x0000FC00 + virt_guiregbase __MN__ );
+#endif
+  n = 0;
+  while(n < 0x100)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    Dprint("%08X ", regr(n << 2) );  n++;
+    u32_ptr += 4;
+  }
+  /*endwhile*/
+  Dprint("\n" );
+#endif
+
+#ifdef  _DUMP_GUIREGS_3FFC00_
+  u32_ptr = (u_int *)(0x003FFC00 + virt_vmembase __MN__ );
+  n = 0;
+  while(n < 0x100)
+  {
+    Dprint("\n%08X: ", u32_ptr);
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    Dprint("%08lX ", regrd(n << 2) );  n++;
+    u32_ptr += 4;
+  }
+  /*endwhile*/
+
+  Dprint("\n" );
+#endif
+
+
+
+  dummy_par.xres = mach64_xres __MN__  ;
+  dummy_par.yres = mach64_yres __MN__  ;
+  dummy_par.bpp = mach64_depth __MN__  ;
+  M64_hw_encode_var(var_ptr, &dummy_par);
+
+  mach64fb_debug = 0x018FC100;
+
+  M64_hw_setcolreg (255, 56, 100, 160, 0, NULL /* unused */);
+  M64_hw_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);
+
+  FuncDone("M64_hw_init() done.\n");
+  return(1);    /* detected_mode */
+}
+/*endproc M64_hw_init() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    This function should fill in the `fix' structure based on the
+    *    values in the `par' structure.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_encode_fix(struct fb_fix_screeninfo * fix, struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_encode_fix() \n");
+
+  strcpy(fix->id, mach64fb_name);
+  fix->id[15] =  _MN_ ;
+  fix->smem_start = (caddr_t) virt_vmembase __MN__  ;
+
+  /* aufrunden */
+  fix->smem_len = (phys_size __MN__   + PAGE_SIZE - 0x00200001) & PAGE_MASK;
+
+  if(mach64_depth __MN__   == 1)
+  {
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    /* The letters 'n' and 'i' in the "video=Mach64:" stand
+     * for "normal" and "inverted", rsp., in the monochrome case */
+    fix->visual =
+      (mach64_pmode __MN__   == FB_TYPE_INTERLEAVED_PLANES ||
+      mach64_pmode __MN__   == FB_TYPE_PACKED_PIXELS) ?
+      FB_VISUAL_MONO10 : FB_VISUAL_MONO01;
+  }
+  else   /* depth > 1 */
+  {
+    switch(mach64_pmode __MN__  )
+    {
+      /* All visuals are STATIC, because we don't know how to change
+       * colors :-(
+       */
+      case -1:              /* truecolor */
+        fix->type = FB_TYPE_PACKED_PIXELS;
+        fix->visual = FB_VISUAL_TRUECOLOR;
+        break;
+      case FB_TYPE_PACKED_PIXELS:
+        fix->type = FB_TYPE_PACKED_PIXELS;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+      case FB_TYPE_PLANES:
+        fix->type = FB_TYPE_PLANES;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+      case FB_TYPE_INTERLEAVED_PLANES:
+        fix->type = FB_TYPE_INTERLEAVED_PLANES;
+        fix->type_aux = 2;
+        fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+        break;
+    }
+    /*endswitch*/
+  }
+  /*endif*/
+  fix->xpanstep = 0;
+  fix->ypanstep = 0;
+  fix->ywrapstep = 0;
+  fix->line_length = 0;
+
+  for(i = 0; i < arraysize(fix->reserved); i++)
+    fix->reserved[i] = 0;
+
+  CFuncId("M64_hw_encode_fix() done. \n");
+  return(0);
+}
+/*endproc _encode_fix() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the video params out of `var'. If a value doesn't fit, round
+    *    it up, if it's too big, return -EINVAL.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_decode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_decode_var() \n");
+
+  par->xres = var->xres;
+  par->yres = var->yres;
+  par->bpp = var->bits_per_pixel;
+
+  return(0);
+}
+/*endproc _decode_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Fill the `var' structure based on the values in `par' and maybe
+    *    other values read out of the hardware.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_encode_var(struct fb_var_screeninfo * var, struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int                           i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_encode_var() \n");
+
+  var->xres = par->xres;
+  var->yres = par->yres;
+  var->xres_virtual = par->xres;
+  var->yres_virtual = par->yres;
+  var->xoffset = 0;
+  var->yoffset = 0;
+
+  var->bits_per_pixel = par->bpp;
+  var->grayscale = 0;
+
+  if(par->bpp == 8)
+  {
+    var->red.offset = 0;
+    var->red.length =
+      (virt_vgaiobase __MN__   ? mach64_bitspercol __MN__  : 0);
+    var->red.msb_right = 0;
+    var->blue = var->green = var->red;
+  }
+  else
+  {
+    var->red.offset = 11;
+    var->red.length = 5;
+    var->red.msb_right = 0;
+    var->green.offset = 5;
+    var->green.length = 6;
+    var->green.msb_right = 0;
+    var->blue.offset = 0;
+    var->blue.length = 5;
+    var->blue.msb_right = 0;
+  }
+  var->transp.offset = 0;
+  var->transp.length = 0;
+  var->transp.msb_right = 0;
+
+  var->nonstd = 0;
+  var->activate = 0;
+
+  var->height = -1;
+  var->width = -1;
+  var->accel = mach64_use_accel __MN__  ;
+  var->vmode = FB_VMODE_NONINTERLACED;
+
+  /* Dummy values */
+
+  if (par->bpp == 8)
+    var->pixclock = M64_8_PIXCLOCK;
+  else
+    var->pixclock = M64_16_PIXCLOCK;
+  var->sync = 0;
+  var->left_margin = 64;
+  var->right_margin = 96;
+  var->upper_margin = 35;
+  var->lower_margin = 12;
+  var->hsync_len = 112;
+  var->vsync_len = 2;
+
+  for(i = 0; i < arraysize(var->reserved); i++)
+    var->reserved[i] = 0;
+
+  return(0);
+}
+/*endproc _encode_var() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Set a single color register. The values supplied are already
+    *    rounded down to the hardware's capabilities (according to the
+    *    entries in the var structure). Return != 0 for invalid regno.
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_hw_setcolreg(u_int regno,
+  u_int red,
+  u_int green,
+  u_int blue,
+  u_int transp,
+  struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  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,
+  struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_hw_getcolreg() \n");
+
+  if(regno >= 256)  return (1);
+
+  *red    = mach64_colormap  __MN__  [regno][0];
+  *green  = mach64_colormap  __MN__  [regno][1];
+  *blue   = mach64_colormap  __MN__  [regno][2];
+  *transp = mach64_colormap  __MN__  [regno][3];
+
+  /*
+  OUTB(0x3c7, regno);
+  DACDelay;
+  *red = INB(0x3c9) & colmask;
+  DACDelay;
+  *green = INB(0x3c9) & colmask;
+  DACDelay;
+  *blue = INB(0x3c9) & colmask;
+  DACDelay;
+  */
+	    
+  return (0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    (Un)Blank the screen: Set all colors = RGB 000 or back
+    */
+/*--------------------------------------------------------------------------*/
+
+void 
+M64_hw_blank(int blank)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int regno;
+
+  unsigned short                colmask;
+  unsigned short                colshift;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_blank() \n");
+
+  if(blank)
+  {
+    for(regno = 0; regno < 256; regno++)
+    {
+      OUTB(0x3c8, regno);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+      OUTB(0x3c9, 0);
+      DACDelay;
+
+    }
+    /*nexxt regno*/
+  }
+  else
+  {
+    colmask = (1 << mach64_bitspercol __MN__  ) - 1;
+    colshift = 8 - mach64_bitspercol __MN__  ;
+    for (regno = 0; regno < 256; regno++)
+    {
+      OUTB(0x3c8, regno);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][0] >> colshift) & colmask);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][1] >> colshift) & colmask);
+      DACDelay;
+      OUTB(0x3c9, (mach64_colormap  __MN__  [regno][2] >> colshift) & colmask);
+    }
+    /*nexxt regno*/
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We are waiting for "fifo" FIFO-slots empty
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_WaitQueue (u_short fifo)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_WaitQueue() \n");
+
+  WaitQueue(16);
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We are waiting for Hardware (Graphics Engine) not busy
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_WaitBlit (void)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_WaitBlit() \n");
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * BitBLT - Through the Plane
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_BitBLT (
+  int     xSrc,
+  int     ySrc,
+  int     xDst,
+  int     yDst,
+  u_int   wSrc,
+  u_int   hSrc,
+  u_short mode)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  u_int                         direction;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("BB(%03X,%03X,%03X,%03X,%03X,%03X,%X) ",
+    xSrc, ySrc, xDst, yDst, wSrc, hSrc, mode);
+  /* Set drawing direction */
+  /* -Y, X maj, -X (default) */
+
+#if 1
+
+  direction = 0;
+
+  if(ySrc < yDst)
+  {
+    yDst += hSrc - 1;
+    ySrc += hSrc - 1;
+  }
+  else
+  {
+    direction |= DST_Y_TOP_TO_BOTTOM;
+  }
+  /*endif*/
+  if(xSrc < xDst)
+  {
+    xDst += wSrc - 1;
+    xSrc += wSrc - 1;
+  }
+  else
+  {
+    direction |= DST_X_LEFT_TO_RIGHT;
+  }
+  /*endif*/
+
+
+  WaitQueue(4);
+  regw(DP_WRITE_MASK, 0x000000FF          /* pGC->planemask */ );
+  regw(DP_MIX, (mach64alu[mode] << 16) |  MIX_DST);
+  regw(DP_SRC, FRGD_SRC_BLIT);
+
+  regw(GUI_TRAJ_CNTL, direction);
+
+/*
+  MACH64_BIT_BLT(xSrc, ySrc, xDst, yDst, wSrc, hSrc, direction);
+*/
+    WaitQueue(4);
+    regw(SRC_Y_X, (((xSrc) << 16) | (ySrc) ));
+    regw(SRC_WIDTH1, (wSrc));
+    regw(DST_Y_X, (((xDst) << 16) | (yDst) ));
+    regw(DST_HEIGHT_WIDTH, (((wSrc) << 16) | (hSrc) ));
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+  /*
+   * Make sure that the destination trajectory is correctly set
+   * for subsequent calls.  MACH64_BIT_BLT is the only function that
+   * currently changes the destination trajectory from L->R and T->B.
+   */
+  regw(DST_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+
+#endif
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * Rectangle Fill Solid
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_RectFill(
+  int     x,
+  int     y,
+  u_int   wSrc,
+  u_int   hSrc,
+  u_int   mode,
+  u_int   color)
+
+/*--------------------------------------------------------------------------*/
+{
+
+#if 1
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("RF(%03X,%03X,%03X,%03X,%X) ",
+    x, y, wSrc, hSrc, mode);
+
+  WaitQueue(5);
+  regw(DP_FRGD_CLR, color              /* pGC->fgPixel */ );
+  regw(DP_WRITE_MASK, 0x000000FF       /* pGC->planemask */ );
+  regw(DP_MIX, (mach64alu[mode] << 16) | MIX_DST);
+  regw(DP_SRC, FRGD_SRC_FRGD_CLR);
+
+  regw(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+
+  if ((wSrc > 0) && (hSrc > 0))
+  {
+    /* Bprint("q\n"); */
+    WaitQueue(2);
+    regw(DST_Y_X, (((u_int)x << 16) | ((u_int)y & 0x0000ffff)));
+    regw(DST_HEIGHT_WIDTH, (((u_int)wSrc << 16) | hSrc));
+  }
+
+  WaitIdleEmpty(); /* Make sure that all commands have finished */
+
+#endif
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+/*
+ * Move cursor to x, y
+ */
+/*--------------------------------------------------------------------------*/
+
+void 
+Mach64_MoveCursor (u_short x, u_short y)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64_MoveCursor() \n");
+
+
+  return;
+}
+/*endproc Mach64_MoveCursor()*/
+
+/*============================================================================*/
+
+
+/* -------------------- Generic routines ------------------------------------ */
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Fill the hardware's `par' structure.
+    */
+/*--------------------------------------------------------------------------*/
+
+static void 
+M64_hw_get_par(struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_get_par() \n");
+  if(current_par_valid __MN__  )
+  {
+    *par = current_par __MN__  ;
+  }
+  else    /* use a default, initialize */
+  {
+    fbhws_ptr->decode_var(
+      &mach64fb_predefined[mach64_mode __MN__  ],
+      par);
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+M64_hw_set_par(struct mach64fb_par * par)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_hw_set_par() \n");
+  current_par __MN__   = *par;
+  current_par_valid __MN__   = 1;
+
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+do_fb_set_var(struct fb_var_screeninfo * var, int isactive)
+
+/*--------------------------------------------------------------------------*/
+{
+  int                           err, activate;
+  struct mach64fb_par          par;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("do_fb_set_var() \n");
+  if((err = fbhws_ptr->decode_var(var, &par)))
+    return(err);
+  activate = var->activate;
+  if((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
+  {
+    M64_hw_set_par(&par);
+  }
+  /*endif*/
+  fbhws_ptr->encode_var(var, &par);
+  var->activate = activate;
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+do_install_cmap(int con, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  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,
+      info);
+  }
+  else
+  {
+    fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+      &fb_display[con].var,
+      1,
+      fbhws_ptr->setcolreg,
+      info);
+  }
+  /*endif*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the Fixed Part of the Display
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_fix(struct fb_fix_screeninfo * fix, int con, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  struct mach64fb_par          par;
+  int                           status = 0;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_get_fix() \n");
+  if (con == -1)
+  {
+    M64_hw_get_par(&par);
+  }
+  else
+  {
+    status = fbhws_ptr->decode_var(&fb_display[con].var, &par);
+  }
+  /*endif*/
+  return(status ? status : fbhws_ptr->encode_fix(fix, &par));
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get the User Defined Part of the Display
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  struct mach64fb_par          par;
+  int                           status = 0;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_get_var() \n");
+  if(con == -1)
+  {
+    M64_hw_get_par(&par);
+    status = fbhws_ptr->encode_var(var, &par);
+  }
+  else
+  {
+    *var = fb_display[con].var;
+  }
+  /*endif*/
+  return(status);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static void 
+mach64fb_set_disp(int con, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  struct display *              disp_p;
+  struct fb_fix_screeninfo      fix;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("mach64fb_set_disp() \n");
+
+  if(con >= 0)
+    disp_p = &fb_display[con];
+  else
+    disp_p = &m_disp __MN__  ;  	/* used during initialization */
+
+  M64_op_get_fix(&fix, con, info);
+
+  if(con == -1)  con = 0;
+
+  disp_p->screen_base = (u_char *)fix.smem_start;
+  disp_p->visual = fix.visual;
+  disp_p->type = fix.type;
+  disp_p->type_aux = fix.type_aux;
+  disp_p->ypanstep = fix.ypanstep;
+  disp_p->ywrapstep = fix.ywrapstep;
+  disp_p->line_length = fix.line_length;
+  if(fix.visual != FB_VISUAL_PSEUDOCOLOR && fix.visual != FB_VISUAL_DIRECTCOLOR)
+  {
+    disp_p->can_soft_blank = 0;                   /* aus atari_ */
+  }
+  else
+  {
+    disp_p->can_soft_blank = 1;
+  }
+  /*endif*/
+
+  disp_p->can_soft_blank = 1;                       /* aus Cyber_ */
+  disp_p->inverse = mach64_inverse __MN__  ;
+
+  return;
+}
+/*endproc mach64fb_set_disp() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+  /*
+   *    Set the User Defined Part of the Display
+   */
+/*--------------------------------------------------------------------------*/
+
+static int 
+M64_op_set_var(struct fb_var_screeninfo * var, int con, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+  int       err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_set_var() \n");
+
+  if((err = do_fb_set_var(var, con == currcon)))
+    return(err);
+  if((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+  {
+    oldxres = fb_display[con].var.xres;
+    oldyres = fb_display[con].var.yres;
+    oldvxres = fb_display[con].var.xres_virtual;
+    oldvyres = fb_display[con].var.yres_virtual;
+    oldbpp = fb_display[con].var.bits_per_pixel;
+    fb_display[con].var = *var;
+    if(oldxres != var->xres || oldyres != var->yres ||
+      oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+      oldbpp != var->bits_per_pixel)
+    {
+      mach64fb_set_disp(con, info);
+      (*fb_info __MN__  .changevar)(con);
+      fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
+      do_install_cmap(con, info);
+    }
+  }
+  /*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, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  OFuncId("M64_op_get_cmap() \n");
+
+  if(con == currcon) /* current console? */
+  {
+    return(fb_get_cmap(cmap, &fb_display[con].var, kspc, fbhws_ptr->getcolreg,
+		       info));
+  }
+  else if(fb_display[con].cmap.len) /* non default colormap? */
+  {
+    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+  }
+  else
+  {
+    fb_copy_cmap(fb_default_cmap(1<<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, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  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,
+		       info));
+  }
+  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,
+		   struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  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,
+  struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("M64_op_ioctl($%08X %d) \n", cmd, con);
+  switch (cmd)
+  {
+
+#ifdef FBCMD_GET_CURRENTPAR
+    case FBCMD_GET_CURRENTPAR:
+    {
+      if (copy_to_user((void *)arg, (void *)&current_par __MN__  ,
+         sizeof(struct mach64fb_par)))
+        return -EFAULT;
+      return 0;
+    }
+    /*endcase*/
+#endif
+
+#ifdef FBCMD_SET_CURRENTPAR
+    case FBCMD_SET_CURRENTPAR:
+    {
+
+      if (copy_from_user((void *)&current_par __MN__  , (void *)arg,
+        sizeof(struct mach64fb_par)))
+        return -EFAULT;
+      M64_hw_set_par(&current_par __MN__  );
+      return 0;
+    }
+    /*endcase*/
+#endif
+
+  }
+  /*endswitch*/
+  return(-EINVAL);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+int 
+Mach64_probe(void)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("Mach64_probe() \n");
+  mach64_key = 0;
+  return(mach64_key);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+__initfunc(
+void 
+mach64fb_setup(char * options, int * ints)
+)
+/*--------------------------------------------------------------------------*/
+{
+  DECLARE_STATIC_UINT08___MN_ 
+
+  char *        this_opt;
+  char          mach64_str[80];
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("mach64fb_setup() '%s'\n", options);
+
+  fb_info __MN__  .fontname[0] = '\0';
+
+  if(!options || !*options)  return;
+
+  for(this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
+  {
+    if (!strcmp(this_opt, "inverse"))
+    {
+      mach64_inverse __MN__   = 1;
+      fb_invert_cmaps();
+    }
+    else if (!strncmp(this_opt, "font:", 5))
+    {
+      strcpy(fb_info __MN__  .fontname, this_opt + 5);
+    }
+    else if (!strncmp(this_opt,"Mach64:", 7))
+    {
+      strncpy(mach64_str, this_opt + 7, 80);
+      store_video_par(mach64_str  _ADD_ARG_MN_ );
+      _INC_MN_ ;
+      mach64_count =  _MN_ ;
+    }
+    else
+    {
+      mach64_mode __MN__   = get_video_mode(this_opt);
+    }
+    /*endif*/
+  }
+  /*next this_opt*/
+
+  return;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+store_video_par(char* video_str ADD_ARG_UINT08___MN_ )
+
+/*--------------------------------------------------------------------------*/
+{
+  char *                        p;
+  unsigned  long                sm_addr, sm_size;
+
+  int                           xres, yres, depth;
+  short int                     pmode;
+  short int                     use_accel;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("store_video_par(%d) \n",  _MN_ );
+  /* Format is: <xres>;<yres>;<depth>;<plane organ.>;
+   *            <screen mem addr>
+   *        [;<screen mem length>[;<vgaiobase>[;<colorreg-type>]]]
+   */
+
+  use_accel = 0;
+  if (!(p = strtoke(video_str, ";")) || !*p)  goto mach64_invalid;
+  xres = simple_strtoul(p, NULL, 10);
+  if (xres <= 0)  goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  yres = simple_strtoul(p, NULL, 10);
+  if (yres <= 0) goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  depth = simple_strtoul(p, NULL, 10);
+  if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
+      depth != 16 && depth != 24)  goto mach64_invalid;
+
+  if (!(p = strtoke(NULL, ";")) || !*p)  goto mach64_invalid;
+  if (*p == 'i')
+    pmode = FB_TYPE_INTERLEAVED_PLANES;
+  else if (*p == 'p')
+    pmode = FB_TYPE_PACKED_PIXELS;
+  else if (*p == 'n')
+    pmode = FB_TYPE_PLANES;
+  else if (*p == 't')
+    pmode = -1; /* true color */
+  else
+    goto mach64_invalid;
+
+
+  if (!(p = strtoke(NULL, ";")) ||!*p)  goto mach64_invalid;
+  sm_addr = simple_strtoul(p, NULL, 0);
+
+  if (!(p = strtoke(NULL, ";")) ||!*p)
+    sm_size = xres * yres * depth / 8;
+  else
+    sm_size = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+    phys_vgaiobase __MN__   = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+  {
+    mach64_bitspercol __MN__   = simple_strtoul(p, NULL, 0);
+    if (mach64_bitspercol __MN__   > 8)
+      mach64_bitspercol __MN__   = 8;
+    else if (mach64_bitspercol __MN__   < 1)
+      mach64_bitspercol __MN__   = 1;
+  }
+  /*endif*/
+
+  if ((p = strtoke(NULL, ";")) && *p)
+    phys_guiregbase __MN__   = simple_strtoul(p, NULL, 0);
+
+  if ((p = strtoke(NULL, ";")) && *p)
+  {
+    if(*p == 'a')  use_accel = FB_ACCEL_MACH64;
+  
+  }
+  /*endif*/
+
+  mach64_xres __MN__    = xres;
+  mach64_yres __MN__    = yres;
+  mach64_depth __MN__   = depth;
+  mach64_pmode __MN__   = pmode;
+  mach64_use_accel __MN__   = use_accel;
+  phys_vmembase __MN__   = sm_addr;
+  phys_size __MN__    = sm_size;
+
+  return(0);
+
+  /*--------------------------------------------------------------------------*/
+  mach64_invalid:
+
+  phys_vmembase __MN__   = 0;
+
+  return(-1);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/* a strtok which returns empty strings, too */
+
+/*--------------------------------------------------------------------------*/
+
+static char * 
+strtoke(char * s, const char * ct)
+
+/*--------------------------------------------------------------------------*/
+{
+  static char    *ssave = NULL;
+  char          *sbegin, *send;
+  
+  /*--------------------------------------------------------------------------*/
+  sbegin  = s ? s : ssave;
+  if (!sbegin) {
+    return NULL;
+  }
+  if (*sbegin == '\0') {
+    ssave = NULL;
+    return NULL;
+  }
+  send = strpbrk(sbegin, ct);
+  if (send && *send != '\0')
+    *send++ = '\0';
+  ssave = send;
+  return sbegin;
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Initialization
+    */
+/*--------------------------------------------------------------------------*/
+
+__initfunc(
+unsigned long
+mach64fb_init(unsigned long mem_start)
+)
+/*--------------------------------------------------------------------------*/
+{
+  static unsigned long          virt_dummy;
+  static u_char                 fb_init_count;
+  DECLARE_STATIC_UINT08___MN_
+
+  struct mach64fb_par          par;
+  int                           err;
+  DECLARE_UINT08___MN_
+
+  /*--------------------------------------------------------------------------*/
+  FuncId("mach64fb_init($%08lX) \n", mem_start);
+
+  /*
+  _MN_ = fb_init_count;
+  */
+  if(phys_vmembase __MN__   == 0)  return mem_start;
+
+  fb_init_count++;
+
+  fbhws_ptr = &mach64_switch;
+
+  /* Map the video memory (physical address given) to somewhere
+   * in the kernel address space.
+   */
+  mem_start = (mem_start + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+  virt_vmembase __MN__   = kernel_map(
+    phys_vmembase __MN__  ,
+    phys_size __MN__  ,
+#ifdef  _OHNE_HW_ACCEL_
+    KERNELMAP_NO_COPYBACK,    /* must be changed if hardware blit */
+#else
+    KERNELMAP_NOCACHE_SER,
+#endif
+    &mem_start);
+
+#ifdef  _MAP_GUIREGS_0BFC00_
+    
+  if(phys_guiregbase __MN__  )
+  {
+    virt_guiregbase __MN__   = kernel_map(
+      phys_guiregbase __MN__  ,
+      0x10000,                           /* 64 K */
+      KERNELMAP_NOCACHE_SER,
+      &mem_start);
+  }
+  /*endif*/
+
+#endif
+
+  if(phys_vgaiobase __MN__  )
+  {
+/*
+    phys_guiregbase __MN__   = phys_vgaiobase __MN__  - 0x00100000 + 0x000B0000;
+*/
+
+#ifdef _MAP_768K_IO_
+
+    virt_vgaiobase __MN__   = kernel_map(
+      phys_vgaiobase __MN__  - 0x00080000,
+      0x0C0000,                          /* 768 K */
+      KERNELMAP_NOCACHE_SER,
+      &mem_start);
+
+#else
+
+    if(phys_guiregbase __MN__  )
+    {
+      virt_vgaiobase __MN__   = kernel_map(
+        phys_vgaiobase __MN__  ,
+        0x10000,                           /* 64 K */
+        KERNELMAP_NOCACHE_SER,
+        &mem_start);
+    }
+    else
+    {
+      virt_vgaiobase __MN__   = 0x00080000 + kernel_map(
+        phys_vgaiobase __MN__  - 0x00080000,
+        0x0C0000,                          /* 768 K */
+        KERNELMAP_NOCACHE_SER,
+        &mem_start);
+
+      Dprint(" faking virt_guiregbase to virt_vgaiobase - 0x00050000 \n");
+      virt_guiregbase __MN__   = virt_vgaiobase __MN__  - 0x00050000;
+    }
+    /*endif*/
+
+#endif  /* _MAP_768K_IO_ */
+  }
+  /*endif*/
+
+  Dprint(" phys_guiregbase=$%08lX virt_dummy=$%08lX\n",
+    phys_guiregbase __MN__  ,
+    virt_dummy);
+
+    
+#ifdef  _DUMP_KMAP_RANGE_
+  dump_kmap_range();
+#endif
+
+
+  virt_size __MN__   = phys_size __MN__   & PAGE_MASK;  /* abrunden */
+  virt_size __MN__   = (phys_size __MN__  - 0x00200000) & PAGE_MASK;  /* abrunden */
+
+  Dprint(" PAGE_MASK=$%08lX phys_size=$%08lX \n", PAGE_MASK, phys_size __MN__ );
+  /*
+  memset((char *) virt_vmembase __MN__  , 0, virt_size __MN__  );
+  */
+
+  strcpy(fb_info __MN__  .modename, mach64fb_name);
+  fb_info __MN__  .changevar = NULL;
+  fb_info __MN__  .node = -1;
+  fb_info __MN__  .fbops = &mach64fb_ops;
+  fb_info __MN__  .disp = &m_disp __MN__  ;
+  fb_info __MN__  .switch_con = &Mach64fb_switch;
+  fb_info __MN__  .updatevar = &Mach64fb_updatevar;
+  fb_info __MN__  .blank = &Mach64fb_blank;
+  strcat(fb_info __MN__  .modename, fb_var_names[mach64_mode __MN__  ]);
+  fb_info __MN__  .modename[39] =  _MN_ ;
+
+  err = register_framebuffer(&fb_info __MN__  );
+  if(err < 0)
+  {
+    Eprint(" Cannot register frame buffer() \n" );
+    return mem_start;
+  }
+  /*endif*/
+
+  fbhws_ptr->init( _ARG_MN_ );
+  fbhws_ptr->decode_var(&mach64fb_predefined[mach64_mode __MN__  ], &par);
+  fbhws_ptr->encode_var(&mach64fb_predefined[0], &par); /* store resolution */
+
+  do_fb_set_var(&mach64fb_predefined[0], 1);
+
+  M64_op_get_var(&m_disp __MN__  .var, -1, &fb_info);
+					    /* fill in m_disp.var */
+  mach64fb_set_disp(-1, &fb_info);          /* 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, &fb_info);
+
+  Iprint(
+    " %s FB device %d, using %ldK of video MEM @ $%08lX IO @ $%08lX $%08lX\n",
+    fb_info __MN__  .modename,
+     _MN_ ,
+    virt_size __MN__   >> 10,
+    virt_vmembase __MN__  ,
+    virt_vgaiobase __MN__  ,
+    virt_guiregbase __MN__  );
+
+  _INC_MN_ ;
+
+  return mem_start;
+}
+/*endproc mach64fb_init() */
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+
+static int 
+Mach64fb_switch(int con, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  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,
+      info);
+  }
+  /*endif*/
+  do_fb_set_var(&fb_display[con].var, 1);
+  currcon = con;
+  /* Install new colormap */
+  do_install_cmap(con, info);
+  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, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_updatevar() \n");
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Blank the display.
+    */
+/*--------------------------------------------------------------------------*/
+
+static void 
+Mach64fb_blank(int blank, struct fb_info *info)
+
+/*--------------------------------------------------------------------------*/
+{
+  /*--------------------------------------------------------------------------*/
+  CFuncId("Mach64fb_blank() \n");
+  fbhws_ptr->blank(blank);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*--------------------------------------------------------------------------*/
+   /*
+    *    Get a Video Mode
+    */
+/*--------------------------------------------------------------------------*/
+
+static int 
+get_video_mode(const char * name)
+
+/*--------------------------------------------------------------------------*/
+{
+  int i;
+
+  /*--------------------------------------------------------------------------*/
+  CFuncId("get_video_mode(%s) \n", name);
+
+  for (i = 1; i < NUM_PREDEF_MODES; i++)
+  {
+    if (!strcmp(name, fb_var_names[i]))  return(i);
+  }
+  /*next i*/
+  return(0);
+}
+/*endproc*/
+
+/*============================================================================*/
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+  static char
+  rcs_id_h[] = MACH64FB_H_ID;
+
+  static char
+  rcs_id_regs_h[] = MACH64REGS_H_ID;
+
+  static char
+  rcs_id_c[] =
+    "@(#) Linux-m68k: 1997 11 21 17:13:00 BHA: mach64fb.c ";
+
+/*                                        ^^^                         */
+/* Please update this & put your initials here on every modification. */
+/* It can be checked with '  strings vmlinux | grep "@(#) "  '        */
+/*============================================================================*/
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/mach64fb.h m68k-2.1.77/drivers/video/mach64fb.h
--- /usr/src/m68k-2.1.77/drivers/video/mach64fb.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/mach64fb.h	Fri Jan  9 01:25:09 1998
@@ -0,0 +1,49 @@
+
+
+#ifndef _MACH64FB_H_LOADED_
+#define _MACH64FB_H_LOADED_
+
+
+   /*
+    *    Accelerated Functions used by the low level console driver
+    */
+
+void Mach64_WaitQueue(u_short fifo);
+
+void Mach64_WaitBlit(void);
+
+void 
+Mach64_BitBLT(
+  int srcx,
+  int srcy,
+  int destx,
+  int desty,
+  u_int width,
+  u_int height,
+  u_short mode);
+
+
+void 
+Mach64_RectFill(
+  int     xpos,
+  int     ypos,
+  u_int   width,
+  u_int   height,
+  u_int   mode,
+  u_int   fcolor);
+
+void Mach64_MoveCursor(u_short xpos, u_short ypos);
+
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define MACH64FB_H_ID \
+  "@(#) Linux-m68k: 1997 11 21 17:12:18 BHA: mach64fb.h "
+
+/*                                      ^^^                           */
+/* Please update this & put your initials here on every modification. */
+/* It can be checked with '  strings vmlinux | grep "@(#) "  '        */
+/*============================================================================*/
+
+#endif /* _MACH64FB_H_LOADED_ */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/mach64regs.h m68k-2.1.77/drivers/video/mach64regs.h
--- /usr/src/m68k-2.1.77/drivers/video/mach64regs.h	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/mach64regs.h	Fri Jan  9 01:25:14 1998
@@ -0,0 +1,703 @@
+/* $Id: mach64regs.h,v 1.2 1998/01/02 14:38:13 geert Exp $
+ * mach64regs.h: ISA/Ultra/PCI mach64 driver constants etc.
+ *
+ * Copyright 1997 David S. Miller (davem@caip.rutgers.edu)
+ *              & Bernd Harries   (harries@atlas.de)
+ *
+ *  This is the file to be included by mach64 drivers.
+ *  Files using the interfaces of the mach64fb driver 
+ *  (functions & IOCTL options) include mach64fb.h.
+ */
+
+
+#ifndef MACH64REGS_H
+#define MACH64REGS_H
+
+struct mach64_info {
+	unsigned int color_mode;
+	unsigned int flags;
+	unsigned int total_vram;
+};
+
+/* The mach64_info flag bits. */
+#define MACH64_MASK_VT	0x00000001
+
+
+/* NON-GUI IO MAPPED Registers */
+
+extern unsigned ioCONFIG_CHIP_ID;
+extern unsigned ioCONFIG_CNTL;
+extern unsigned ioSCRATCH_REG0;
+extern unsigned ioSCRATCH_REG1;
+extern unsigned ioCONFIG_STAT0;
+extern unsigned ioMEM_CNTL;
+extern unsigned ioDAC_REGS;
+extern unsigned ioDAC_CNTL;
+extern unsigned ioGEN_TEST_CNTL;
+extern unsigned ioCLOCK_CNTL;
+extern unsigned ioCRTC_GEN_CNTL;
+
+/* NON-GUI sparse IO register offsets */
+
+#define sioCONFIG_CHIP_ID       0x1B
+#define sioCONFIG_CNTL          0x1A
+#define sioSCRATCH_REG0         0x10
+#define sioSCRATCH_REG1         0x11
+#define sioCONFIG_STAT0         0x1C
+#define sioMEM_CNTL             0x14
+#define sioDAC_REGS             0x17
+#define sioDAC_CNTL             0x18
+#define sioGEN_TEST_CNTL        0x19
+#define sioCLOCK_CNTL           0x12
+#define sioCRTC_GEN_CNTL        0x07
+
+/* NON-GUI MEMORY MAPPED Registers - expressed in BYTE offsets */
+
+#define CRTC_H_TOTAL_DISP       0x0000  /* Dword offset 00 */
+#define CRTC_H_SYNC_STRT_WID    0x0004  /* Dword offset 01 */
+#define CRTC_H_SYNC_STRT        0x0004
+#define CRTC_H_SYNC_DLY         0x0005
+#define CRTC_H_SYNC_WID         0x0006
+
+#define CRTC_V_TOTAL_DISP       0x0008  /* Dword offset 02 */
+#define CRTC_V_TOTAL            0x0008
+#define CRTC_V_DISP             0x000A
+#define CRTC_V_SYNC_STRT_WID    0x000C  /* Dword offset 03 */
+#define CRTC_V_SYNC_STRT        0x000C
+#define CRTC_V_SYNC_WID         0x000E
+
+#define CRTC_VLINE_CRNT_VLINE   0x0010  /* Dword offset 04 */
+#define CRTC_OFF_PITCH          0x0014  /* Dword offset 05 */
+#define CRTC_INT_CNTL           0x0018  /* Dword offset 06 */
+#define CRTC_GEN_CNTL           0x001C  /* Dword offset 07 */
+
+#define OVR_CLR                 0x0040  /* Dword offset 10 */
+#define OVR_WID_LEFT_RIGHT      0x0044  /* Dword offset 11 */
+#define OVR_WID_TOP_BOTTOM      0x0048  /* Dword offset 12 */
+
+#define CUR_CLR0                0x0060  /* Dword offset 18 */
+#define CUR_CLR1                0x0064  /* Dword offset 19 */
+#define CUR_OFFSET              0x0068  /* Dword offset 1A */
+#define CUR_HORZ_VERT_POSN      0x006C  /* Dword offset 1B */
+#define CRTC_PIX_WIDTH          0x001D
+#define CRTC_FIFO               0x001E
+#define CRTC_EXT_DISP           0x001F
+
+#define CUR_HORZ_VERT_OFF       0x0070  /* Dword offset 1C */
+
+#define SCRATCH_REG0            0x0080  /* Dword offset 20 */
+#define SCRATCH_REG1            0x0084  /* Dword offset 21 */
+
+#define CLOCK_CNTL              0x0090  /* Dword offset 24 */
+
+#define BUS_CNTL                0x00A0  /* Dword offset 28 */
+
+#define MEM_CNTL                0x00B0  /* Dword offset 2C */
+
+#define MEM_VGA_WP_SEL          0x00B4  /* Dword offset 2D */
+#define MEM_VGA_RP_SEL          0x00B8  /* Dword offset 2E */
+
+#define DAC_REGS                0x00C0  /* Dword offset 30 */
+#define DAC_W_INDEX             0x00C0  /* Dword offset 30 */
+#define DAC_DATA                0x00C1  /* Dword offset 30 */
+#define DAC_MASK                0x00C2  /* Dword offset 30 */
+#define DAC_R_INDEX             0x00C3  /* Dword offset 30 */
+#define DAC_CNTL                0x00C4  /* Dword offset 31 */
+
+#define GEN_TEST_CNTL           0x00D0  /* Dword offset 34 */
+
+#define CONFIG_CNTL             0x00DC  /* Dword offset 37 (CT, ET, VT) */
+#define CONFIG_CHIP_ID          0x00E0  /* Dword offset 38 */
+#define CONFIG_STAT0            0x00E4  /* Dword offset 39 */
+#define CONFIG_STAT1            0x00E8  /* Dword offset 3A */
+
+
+/* GUI MEMORY MAPPED Registers */
+
+#define DST_OFF_PITCH           0x0100  /* Dword offset 40 */
+#define DST_X                   0x0104  /* Dword offset 41 */
+#define DST_Y                   0x0108  /* Dword offset 42 */
+#define DST_Y_X                 0x010C  /* Dword offset 43 */
+#define DST_WIDTH               0x0110  /* Dword offset 44 */
+#define DST_HEIGHT              0x0114  /* Dword offset 45 */
+#define DST_HEIGHT_WIDTH        0x0118  /* Dword offset 46 */
+#define DST_X_WIDTH             0x011C  /* Dword offset 47 */
+#define DST_BRES_LNTH           0x0120  /* Dword offset 48 */
+#define DST_BRES_ERR            0x0124  /* Dword offset 49 */
+#define DST_BRES_INC            0x0128  /* Dword offset 4A */
+#define DST_BRES_DEC            0x012C  /* Dword offset 4B */
+#define DST_CNTL                0x0130  /* Dword offset 4C */
+
+#define SRC_OFF_PITCH           0x0180  /* Dword offset 60 */
+#define SRC_X                   0x0184  /* Dword offset 61 */
+#define SRC_Y                   0x0188  /* Dword offset 62 */
+#define SRC_Y_X                 0x018C  /* Dword offset 63 */
+#define SRC_WIDTH1              0x0190  /* Dword offset 64 */
+#define SRC_HEIGHT1             0x0194  /* Dword offset 65 */
+#define SRC_HEIGHT1_WIDTH1      0x0198  /* Dword offset 66 */
+#define SRC_X_START             0x019C  /* Dword offset 67 */
+#define SRC_Y_START             0x01A0  /* Dword offset 68 */
+#define SRC_Y_X_START           0x01A4  /* Dword offset 69 */
+#define SRC_WIDTH2              0x01A8  /* Dword offset 6A */
+#define SRC_HEIGHT2             0x01AC  /* Dword offset 6B */
+#define SRC_HEIGHT2_WIDTH2      0x01B0  /* Dword offset 6C */
+#define SRC_CNTL                0x01B4  /* Dword offset 6D */
+
+#define HOST_DATA0              0x0200  /* Dword offset 80 */
+#define HOST_DATA1              0x0204  /* Dword offset 81 */
+#define HOST_DATA2              0x0208  /* Dword offset 82 */
+#define HOST_DATA3              0x020C  /* Dword offset 83 */
+#define HOST_DATA4              0x0210  /* Dword offset 84 */
+#define HOST_DATA5              0x0214  /* Dword offset 85 */
+#define HOST_DATA6              0x0218  /* Dword offset 86 */
+#define HOST_DATA7              0x021C  /* Dword offset 87 */
+#define HOST_DATA8              0x0220  /* Dword offset 88 */
+#define HOST_DATA9              0x0224  /* Dword offset 89 */
+#define HOST_DATAA              0x0228  /* Dword offset 8A */
+#define HOST_DATAB              0x022C  /* Dword offset 8B */
+#define HOST_DATAC              0x0230  /* Dword offset 8C */
+#define HOST_DATAD              0x0234  /* Dword offset 8D */
+#define HOST_DATAE              0x0238  /* Dword offset 8E */
+#define HOST_DATAF              0x023C  /* Dword offset 8F */
+#define HOST_CNTL               0x0240  /* Dword offset 90 */
+
+#define PAT_REG0                0x0280  /* Dword offset A0 */
+#define PAT_REG1                0x0284  /* Dword offset A1 */
+#define PAT_CNTL                0x0288  /* Dword offset A2 */
+
+#define SC_LEFT                 0x02A0  /* Dword offset A8 */
+#define SC_RIGHT                0x02A4  /* Dword offset A9 */
+#define SC_LEFT_RIGHT           0x02A8  /* Dword offset AA */
+#define SC_TOP                  0x02AC  /* Dword offset AB */
+#define SC_BOTTOM               0x02B0  /* Dword offset AC */
+#define SC_TOP_BOTTOM           0x02B4  /* Dword offset AD */
+
+#define DP_BKGD_CLR             0x02C0  /* Dword offset B0 */
+#define DP_FRGD_CLR             0x02C4  /* Dword offset B1 */
+#define DP_WRITE_MASK           0x02C8  /* Dword offset B2 */
+#define DP_CHAIN_MASK           0x02CC  /* Dword offset B3 */
+#define DP_PIX_WIDTH            0x02D0  /* Dword offset B4 */
+#define DP_MIX                  0x02D4  /* Dword offset B5 */
+#define DP_SRC                  0x02D8  /* Dword offset B6 */
+
+#define CLR_CMP_CLR             0x0300  /* Dword offset C0 */
+#define CLR_CMP_MASK            0x0304  /* Dword offset C1 */
+#define CLR_CMP_CNTL            0x0308  /* Dword offset C2 */
+
+#define FIFO_STAT               0x0310  /* Dword offset C4 */
+
+#define CONTEXT_MASK            0x0320  /* Dword offset C8 */
+#define CONTEXT_LOAD_CNTL       0x032C  /* Dword offset CB */
+
+#define GUI_TRAJ_CNTL           0x0330  /* Dword offset CC */
+#define GUI_STAT                0x0338  /* Dword offset CE */
+
+
+/* CRTC control values */
+
+#define CRTC_H_SYNC_NEG         0x00200000
+#define CRTC_V_SYNC_NEG         0x00200000
+
+#define CRTC_DBL_SCAN_EN        0x00000001
+#define CRTC_INTERLACE_EN       0x00000002
+#define CRTC_HSYNC_DIS          0x00000004
+#define CRTC_VSYNC_DIS          0x00000008
+#define CRTC_CSYNC_EN           0x00000010
+#define CRTC_PIX_BY_2_EN        0x00000020
+
+#define CRTC_PIX_WIDTH          0x00000700
+#define CRTC_PIX_WIDTH_4BPP     0x00000100
+#define CRTC_PIX_WIDTH_8BPP     0x00000200
+#define CRTC_PIX_WIDTH_15BPP    0x00000300
+#define CRTC_PIX_WIDTH_16BPP    0x00000400
+#define CRTC_PIX_WIDTH_24BPP    0x00000500
+#define CRTC_PIX_WIDTH_32BPP    0x00000600
+
+#define CRTC_BYTE_PIX_ORDER     0x00000800
+#define CRTC_PIX_ORDER_MSN_LSN  0x00000000
+#define CRTC_PIX_ORDER_LSN_MSN  0x00000800
+
+#define CRTC_FIFO_LWM           0x000f0000
+#define CRTC_EXT_DISP_EN        0x01000000
+#define CRTC_EXT_EN             0x02000000
+
+#define CRTC_CRNT_VLINE         0x07f00000
+#define CRTC_VBLANK             0x00000001
+
+/* DAC control values */
+
+#define DAC_EXT_SEL_RS2         0x01
+#define DAC_EXT_SEL_RS3         0x02
+#define DAC_8BIT_EN             0x00000100
+#define DAC_PIX_DLY_MASK        0x00000600
+#define DAC_PIX_DLY_0NS         0x00000000
+#define DAC_PIX_DLY_2NS         0x00000200
+#define DAC_PIX_DLY_4NS         0x00000400
+#define DAC_BLANK_ADJ_MASK      0x00001800
+#define DAC_BLANK_ADJ_0         0x00000000
+#define DAC_BLANK_ADJ_1         0x00000800
+#define DAC_BLANK_ADJ_2         0x00001000
+
+
+/* Mix control values */
+
+#define MIX_NOT_DST             0x0000
+#define MIX_0                   0x0001
+#define MIX_1                   0x0002
+#define MIX_DST                 0x0003
+#define MIX_NOT_SRC             0x0004
+#define MIX_XOR                 0x0005
+#define MIX_XNOR                0x0006
+#define MIX_SRC                 0x0007
+#define MIX_NAND                0x0008
+#define MIX_NOT_SRC_OR_DST      0x0009
+#define MIX_SRC_OR_NOT_DST      0x000a
+#define MIX_OR                  0x000b
+#define MIX_AND                 0x000c
+#define MIX_SRC_AND_NOT_DST     0x000d
+#define MIX_NOT_SRC_AND_DST     0x000e
+#define MIX_NOR                 0x000f
+
+/* Maximum engine dimensions */
+#define ENGINE_MIN_X            0
+#define ENGINE_MIN_Y            0
+#define ENGINE_MAX_X            4095
+#define ENGINE_MAX_Y            16383
+
+/* Mach64 engine bit constants - these are typically ORed together */
+
+/* BUS_CNTL register constants */
+#define BUS_FIFO_ERR_ACK        0x00200000
+#define BUS_HOST_ERR_ACK        0x00800000
+
+/* GEN_TEST_CNTL register constants */
+#define GEN_OVR_OUTPUT_EN       0x20
+#define HWCURSOR_ENABLE         0x80
+#define GUI_ENGINE_ENABLE       0x100
+#define BLOCK_WRITE_ENABLE      0x200
+
+/* CLOCK_CNTL register constants */
+#define CLOCK_SEL               0x0f
+#define CLOCK_DIV               0x30
+#define CLOCK_DIV1              0x00
+#define CLOCK_DIV2              0x10
+#define CLOCK_DIV4              0x20
+#define CLOCK_STROBE            0x40
+#define PLL_WR_EN               0x02
+
+/* PLL registers */
+#define PLL_MACRO_CNTL          0x01
+#define PLL_REF_DIV             0x02
+#define PLL_GEN_CNTL            0x03
+#define MCLK_FB_DIV             0x04
+#define PLL_VCLK_CNTL           0x05
+#define VCLK_POST_DIV           0x06
+#define VCLK0_FB_DIV            0x07
+#define VCLK1_FB_DIV            0x08
+#define VCLK2_FB_DIV            0x09
+#define VCLK3_FB_DIV            0x0A
+#define PLL_XCLK_CNTL           0x0B
+#define PLL_TEST_CTRL           0x0E
+#define PLL_TEST_COUNT          0x0F
+
+/* Fields in PLL registers */
+#define PLL_PC_GAIN             0x07
+#define PLL_VC_GAIN             0x18
+#define PLL_DUTY_CYC            0xE0
+#define PLL_OVERRIDE            0x01
+#define PLL_MCLK_RST            0x02
+#define OSC_EN                  0x04
+#define EXT_CLK_EN              0x08
+#define MCLK_SRC_SEL            0x70
+#define EXT_CLK_CNTL            0x80
+#define VCLK_SRC_SEL            0x03
+#define PLL_VCLK_RST            0x04
+#define VCLK_INVERT             0x08
+#define VCLK0_POST              0x03
+#define VCLK1_POST              0x0C
+#define VCLK2_POST              0x30
+#define VCLK3_POST              0xC0
+
+/* CONFIG_CNTL register constants */
+#define APERTURE_4M_ENABLE      1
+#define APERTURE_8M_ENABLE      2
+#define VGA_APERTURE_ENABLE     4
+
+/* CONFIG_STAT0 register constants (GX, CX) */
+#define CFG_BUS_TYPE            0x00000007
+#define CFG_MEM_TYPE            0x00000038
+#define CFG_INIT_DAC_TYPE       0x00000e00
+
+/* CONFIG_STAT0 register constants (CT, ET, VT) */
+#define CFG_MEM_TYPE_xT         0x00000007
+
+#define ISA                     0
+#define EISA                    1
+#define LOCAL_BUS               6
+#define PCI                     7
+
+/* Memory types for GX, CX */
+#define DRAMx4                  0
+#define VRAMx16                 1
+#define VRAMx16ssr              2
+#define DRAMx16                 3
+#define GraphicsDRAMx16         4
+#define EnhancedVRAMx16         5
+#define EnhancedVRAMx16ssr      6
+
+/* Memory types for CT, ET, VT, GT */
+#define DRAM                    0
+#define EDO_DRAM                1
+#define PSEUDO_EDO              2
+#define SDRAM                   3
+
+#define DAC_INTERNAL            0x00
+#define DAC_IBMRGB514           0x01
+#define DAC_ATI68875            0x02
+#define DAC_TVP3026_A           0x72
+#define DAC_BT476               0x03
+#define DAC_BT481               0x04
+#define DAC_ATT20C491           0x14
+#define DAC_SC15026             0x24
+#define DAC_MU9C1880            0x34
+#define DAC_IMSG174             0x44
+#define DAC_ATI68860_B          0x05
+#define DAC_ATI68860_C          0x15
+#define DAC_TVP3026_B           0x75
+#define DAC_STG1700             0x06
+#define DAC_ATT498              0x16
+#define DAC_STG1702             0x07
+#define DAC_SC15021             0x17
+#define DAC_ATT21C498           0x27
+#define DAC_STG1703             0x37
+#define DAC_CH8398              0x47
+#define DAC_ATT20C408           0x57
+
+#define CLK_ATI18818_0          0
+#define CLK_ATI18818_1          1
+#define CLK_STG1703             2
+#define CLK_CH8398              3
+#define CLK_INTERNAL            4
+#define CLK_ATT20C408           5
+#define CLK_IBMRGB514           6
+
+/* MEM_CNTL register constants */
+#define MEM_SIZE_ALIAS          0x00000007
+#define MEM_SIZE_512K           0x00000000
+#define MEM_SIZE_1M             0x00000001
+#define MEM_SIZE_2M             0x00000002
+#define MEM_SIZE_4M             0x00000003
+#define MEM_SIZE_6M             0x00000004
+#define MEM_SIZE_8M             0x00000005
+#define MEM_SIZE_ALIAS_GTB      0x0000000F
+#define MEM_SIZE_2M_GTB         0x00000003
+#define MEM_SIZE_4M_GTB         0x00000007
+#define MEM_SIZE_6M_GTB         0x00000009
+#define MEM_SIZE_8M_GTB         0x0000000B
+#define MEM_BNDRY               0x00030000
+#define MEM_BNDRY_0K            0x00000000
+#define MEM_BNDRY_256K          0x00010000
+#define MEM_BNDRY_512K          0x00020000
+#define MEM_BNDRY_1M            0x00030000
+#define MEM_BNDRY_EN            0x00040000
+
+/* ATI PCI constants */
+#define PCI_ATI_VENDOR_ID       0x1002
+#define PCI_MACH64_GX           0x4758
+#define PCI_MACH64_CX           0x4358
+#define PCI_MACH64_CT           0x4354
+#define PCI_MACH64_ET           0x4554
+#define PCI_MACH64_VT           0x5654
+#define PCI_MACH64_GT           0x4754
+
+/* CONFIG_CHIP_ID register constants */
+#define CFG_CHIP_TYPE           0x0000FFFF
+#define CFG_CHIP_CLASS          0x00FF0000
+#define CFG_CHIP_REV            0xFF000000
+#define CFG_CHIP_VERSION        0x07000000
+#define CFG_CHIP_FOUNDRY        0x38000000
+#define CFG_CHIP_REVISION       0xC0000000
+
+/* Chip IDs read from CONFIG_CHIP_ID */
+#define MACH64_GX_ID            0xD7
+#define MACH64_CX_ID            0x57
+#define MACH64_CT_ID            0x4354
+#define MACH64_ET_ID            0x4554
+#define MACH64_VT_ID            0x5654
+#define MACH64_GT_ID            0x4754
+
+/* Mach64 chip types */
+#define MACH64_UNKNOWN	0
+#define MACH64_GX	1
+#define MACH64_CX	2
+#define MACH64_CT	3
+#define MACH64_ET	4
+#define MACH64_VT	5
+#define MACH64_GT	6
+
+/* DST_CNTL register constants */
+#define DST_X_RIGHT_TO_LEFT     0
+#define DST_X_LEFT_TO_RIGHT     1
+#define DST_Y_BOTTOM_TO_TOP     0
+#define DST_Y_TOP_TO_BOTTOM     2
+#define DST_X_MAJOR             0
+#define DST_Y_MAJOR             4
+#define DST_X_TILE              8
+#define DST_Y_TILE              0x10
+#define DST_LAST_PEL            0x20
+#define DST_POLYGON_ENABLE      0x40
+#define DST_24_ROTATION_ENABLE  0x80
+
+/* SRC_CNTL register constants */
+#define SRC_PATTERN_ENABLE      1
+#define SRC_ROTATION_ENABLE     2
+#define SRC_LINEAR_ENABLE       4
+#define SRC_BYTE_ALIGN          8
+#define SRC_LINE_X_RIGHT_TO_LEFT 0
+#define SRC_LINE_X_LEFT_TO_RIGHT 0x10
+
+/* HOST_CNTL register constants */
+#define HOST_BYTE_ALIGN         1
+
+/* GUI_TRAJ_CNTL register constants */
+#define PAT_MONO_8x8_ENABLE     0x01000000
+#define PAT_CLR_4x2_ENABLE      0x02000000
+#define PAT_CLR_8x1_ENABLE      0x04000000
+
+/* DP_CHAIN_MASK register constants */
+#define DP_CHAIN_4BPP	0x8888
+#define DP_CHAIN_7BPP	0xD2D2
+#define DP_CHAIN_8BPP	0x8080
+#define DP_CHAIN_8BPP_RGB	0x9292
+#define DP_CHAIN_15BPP	0x4210
+#define DP_CHAIN_16BPP	0x8410
+#define DP_CHAIN_24BPP	0x8080
+#define DP_CHAIN_32BPP	0x8080
+
+/* DP_PIX_WIDTH register constants */
+#define DST_1BPP                0
+#define DST_4BPP                1
+#define DST_8BPP                2
+#define DST_15BPP               3
+#define DST_16BPP               4
+#define DST_32BPP               6
+#define SRC_1BPP                0
+#define SRC_4BPP                0x100
+#define SRC_8BPP                0x200
+#define SRC_15BPP               0x300
+#define SRC_16BPP               0x400
+#define SRC_32BPP               0x600
+#define HOST_1BPP               0
+#define HOST_4BPP               0x10000
+#define HOST_8BPP               0x20000
+#define HOST_15BPP              0x30000
+#define HOST_16BPP              0x40000
+#define HOST_32BPP              0x60000
+#define BYTE_ORDER_MSB_TO_LSB   0
+#define BYTE_ORDER_LSB_TO_MSB   0x1000000
+
+/* DP_MIX register constants */
+#define BKGD_MIX_NOT_D              0
+#define BKGD_MIX_ZERO               1
+#define BKGD_MIX_ONE                2
+#define BKGD_MIX_D                  3
+#define BKGD_MIX_NOT_S              4
+#define BKGD_MIX_D_XOR_S            5
+#define BKGD_MIX_NOT_D_XOR_S        6
+#define BKGD_MIX_S                  7
+#define BKGD_MIX_NOT_D_OR_NOT_S     8
+#define BKGD_MIX_D_OR_NOT_S         9
+#define BKGD_MIX_NOT_D_OR_S         10
+#define BKGD_MIX_D_OR_S             11
+#define BKGD_MIX_D_AND_S            12
+#define BKGD_MIX_NOT_D_AND_S        13
+#define BKGD_MIX_D_AND_NOT_S        14
+#define BKGD_MIX_NOT_D_AND_NOT_S    15
+#define BKGD_MIX_D_PLUS_S_DIV2      0x17
+#define FRGD_MIX_NOT_D              0
+#define FRGD_MIX_ZERO               0x10000
+#define FRGD_MIX_ONE                0x20000
+#define FRGD_MIX_D                  0x30000
+#define FRGD_MIX_NOT_S              0x40000
+#define FRGD_MIX_D_XOR_S            0x50000
+#define FRGD_MIX_NOT_D_XOR_S        0x60000
+#define FRGD_MIX_S                  0x70000
+#define FRGD_MIX_NOT_D_OR_NOT_S     0x80000
+#define FRGD_MIX_D_OR_NOT_S         0x90000
+#define FRGD_MIX_NOT_D_OR_S         0xa0000
+#define FRGD_MIX_D_OR_S             0xb0000
+#define FRGD_MIX_D_AND_S            0xc0000
+#define FRGD_MIX_NOT_D_AND_S        0xd0000
+#define FRGD_MIX_D_AND_NOT_S        0xe0000
+#define FRGD_MIX_NOT_D_AND_NOT_S    0xf0000
+#define FRGD_MIX_D_PLUS_S_DIV2      0x170000
+
+/* DP_SRC register constants */
+#define BKGD_SRC_BKGD_CLR           0
+#define BKGD_SRC_FRGD_CLR           1
+#define BKGD_SRC_HOST               2
+#define BKGD_SRC_BLIT               3
+#define BKGD_SRC_PATTERN            4
+#define FRGD_SRC_BKGD_CLR           0
+#define FRGD_SRC_FRGD_CLR           0x100
+#define FRGD_SRC_HOST               0x200
+#define FRGD_SRC_BLIT               0x300
+#define FRGD_SRC_PATTERN            0x400
+#define MONO_SRC_ONE                0
+#define MONO_SRC_PATTERN            0x10000
+#define MONO_SRC_HOST               0x20000
+#define MONO_SRC_BLIT               0x30000
+
+/* CLR_CMP_CNTL register constants */
+#define COMPARE_FALSE               0
+#define COMPARE_TRUE                1
+#define COMPARE_NOT_EQUAL           4
+#define COMPARE_EQUAL               5
+#define COMPARE_DESTINATION         0
+#define COMPARE_SOURCE              0x1000000
+
+/* FIFO_STAT register constants */
+#define FIFO_ERR                    0x80000000
+
+/* CONTEXT_LOAD_CNTL constants */
+#define CONTEXT_NO_LOAD             0
+#define CONTEXT_LOAD                0x10000
+#define CONTEXT_LOAD_AND_DO_FILL    0x20000
+#define CONTEXT_LOAD_AND_DO_LINE    0x30000
+#define CONTEXT_EXECUTE             0
+#define CONTEXT_CMD_DISABLE         0x80000000
+
+/* GUI_STAT register constants */
+#define ENGINE_IDLE                 0
+#define ENGINE_BUSY                 1
+#define SCISSOR_LEFT_FLAG           0x10
+#define SCISSOR_RIGHT_FLAG          0x20
+#define SCISSOR_TOP_FLAG            0x40
+#define SCISSOR_BOTTOM_FLAG         0x80
+
+/* ATI VGA Extended Regsiters */
+#define sioATIEXT	0x1ce
+#define bioATIEXT	0x3ce
+extern unsigned ATIExtReg;
+#define ATI2E		0xae
+#define ATI32		0xb2
+#define ATI36		0xb6
+
+/* VGA Graphics Controller Registers */
+#define VGAGRA		0x3ce
+#define GRA06		0x06
+
+/* VGA Seququencer Registers */
+#define VGASEQ		0x3c4
+#define SEQ02		0x02
+#define SEQ04		0x04
+
+#define MACH64_MAX_X	ENGINE_MAX_X
+#define MACH64_MAX_Y	ENGINE_MAX_Y
+
+#define INC_X                   0x0020
+#define INC_Y                   0x0080
+
+#define RGB16_555               0x0000
+#define RGB16_565               0x0040
+#define RGB16_655               0x0080
+#define RGB16_664               0x00c0
+
+#define POLY_TEXT_TYPE          0x0001
+#define IMAGE_TEXT_TYPE         0x0002
+#define TEXT_TYPE_8_BIT         0x0004
+#define TEXT_TYPE_16_BIT        0x0008
+#define POLY_TEXT_TYPE_8        (POLY_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define IMAGE_TEXT_TYPE_8       (IMAGE_TEXT_TYPE | TEXT_TYPE_8_BIT)
+#define POLY_TEXT_TYPE_16       (POLY_TEXT_TYPE | TEXT_TYPE_16_BIT)
+#define IMAGE_TEXT_TYPE_16      (IMAGE_TEXT_TYPE | TEXT_TYPE_16_BIT)
+
+#define MACH64_NUM_CLOCKS	16
+#define MACH64_NUM_FREQS	50
+
+/*============================================================================*/
+
+typedef struct
+{
+    unsigned char h_disp;
+    unsigned char dacmask;
+    unsigned char ram_req;
+    unsigned char max_dot_clock;
+    unsigned char color_depth;
+}
+mach64FreqRec;
+
+typedef struct
+{
+    unsigned char r, g, b;
+}
+LUTENTRY;
+
+typedef struct
+{
+    unsigned long h_total_disp, h_sync_strt_wid;
+    unsigned long v_total_disp, v_sync_strt_wid;
+    unsigned long crtc_gen_cntl;
+    unsigned long color_depth;
+    unsigned long clock_cntl;
+    unsigned long dot_clock;
+    unsigned long fifo_v1;
+}
+mach64CRTCRegRec, * mach64CRTCRegPtr;
+
+
+/* Wait until "v" queue entries are free */
+#define WaitQueue(v)  \
+{ \
+  int   __cntr = 0;      \
+  while((regr(FIFO_STAT) & 0xFFFF) > ((unsigned short)(0x8000 >> (v))))  \
+  { \
+    if(__cntr++ > 500000)    \
+    { \
+      Eprint(" Timeout Waiting for FIFO. \n"); \
+    } \
+  } \
+}
+
+/* Wait until GP is idle and queue is empty */
+#define WaitIdleEmpty() \
+{  \
+  int   __cntr = 0;      \
+  WaitQueue(16); \
+  while ((regr(GUI_STAT) & 1) != 0) \
+  { \
+    if(__cntr++ > 500000)    \
+    { \
+      Eprint(" Timeout Waiting for BLT engine. \n"); \
+    } \
+  } \
+}
+
+#define SKIP_2(_v) ((((_v)<<1)&0xFFF8)|((_v)&0x3)|(((_v)&0x80)>>5))
+
+#define MACH64_BIT_BLT(_srcx, _srcy, _dstx, _dsty, _w, _h, _dir) \
+{ \
+  WaitQueue(5); \
+  regw(SRC_Y_X, (((_srcx) << 16) | ((_srcy) & 0x0000FFFF))); \
+  regw(SRC_WIDTH1, (_w)); \
+  regw(DST_CNTL, (_dir)); \
+  regw(DST_Y_X, (((_dstx) << 16) | ((_dsty) & 0x0000FFFF))); \
+  regw(DST_HEIGHT_WIDTH, (((_w) << 16) | ((_h) & 0x0000FFFF))); \
+}
+
+#ifndef NULL
+#define NULL    0
+#endif
+
+/*============================================================================*/
+/* RCS-ID */
+
+#define MACH64REGS_H_ID \
+  "@(#) Linux-m68k: 1997 11 21 17:00:18 BHA: mach64regs.h "
+
+/*                                      ^^^                           */
+/* Please update this & put your initials here on every modification. */
+/* It can be checked with '  strings vmlinux | grep "@(#) "  '        */
+/*============================================================================*/
+
+#endif /* MACH64REGS_H */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/offb.c m68k-2.1.77/drivers/video/offb.c
--- /usr/src/m68k-2.1.77/drivers/video/offb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/offb.c	Fri Jan  9 01:22:43 1998
@@ -12,6 +12,7 @@
  *  more details.
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -25,20 +26,26 @@
 #include <linux/fb.h>
 #include <linux/selection.h>
 #include <linux/init.h>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <linux/vc_ioctl.h>
+#endif
 #include <asm/io.h>
 #include <asm/prom.h>
 
 
 static int currcon = 0;
-static struct display disp;
-static struct fb_info fb_info;
-static struct { u_char red, green, blue, pad; } palette[256];
 
-static volatile unsigned char *unknown_cmap_adr = NULL;
-static volatile unsigned char *unknown_cmap_data = NULL;
+struct fb_info_offb {
+    struct fb_info info;
+    struct fb_fix_screeninfo fix;
+    struct fb_var_screeninfo var;
+    struct display disp;
+    struct { u_char red, green, blue, pad; } palette[256];
+    volatile unsigned char *cmap_adr;
+    volatile unsigned char *cmap_data;
+};
 
-static struct fb_fix_screeninfo fb_fix = { { "OFfb ", } };
-static struct fb_var_screeninfo fb_var = { 0, };
+static struct fb_info_offb fb_info[FB_MAX];
 
 #ifdef __powerpc__
 #define mach_eieio()	eieio()
@@ -46,31 +53,49 @@
 #define mach_eieio()	do {} while (0)
 #endif
 
+static int ofonly = 0;
+
 
     /*
      *  Interface used by the world
      */
 
-static int offb_open(int fbidx);
-static int offb_release(int fbidx);
-static int offb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
-static int offb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int offb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int offb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx);
-static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
-static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
+unsigned long offb_init(unsigned long mem_start);
+void offb_setup(char *options, int *ints);
+
+static int offb_open(struct fb_info *info);
+static int offb_release(struct fb_info *info);
+static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			struct fb_info *info);
+static int offb_get_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info);
+static int offb_set_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info);
+static int offb_pan_display(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info);
+static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
 static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			    u_long arg, int con, int fbidx);
+			    u_long arg, int con, struct fb_info *info);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+int console_getmode(struct vc_mode *);
+int console_setmode(struct vc_mode *, int);
+int console_powermode(int);
+int (*console_setmode_ptr)(struct vc_mode *, int) = NULL;
+struct vc_mode display_info;
+#endif /* CONFIG_FB_COMPAT_XPMAC */
 
 
     /*
      *  Interface to the low level console driver
      */
 
-unsigned long offb_init(unsigned long mem_start);
-static int offbcon_switch(int con);
-static int offbcon_updatevar(int con);
-static void offbcon_blank(int blank);
+static int offbcon_switch(int con, struct fb_info *info);
+static int offbcon_updatevar(int con, struct fb_info *info);
+static void offbcon_blank(int blank, struct fb_info *info);
 
 
     /*
@@ -78,10 +103,10 @@
      */
 
 static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp);
+			 u_int *transp, struct fb_info *info);
 static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp);
-static void do_install_cmap(int con);
+			 u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
 
 
 static struct fb_ops offb_ops = {
@@ -94,20 +119,20 @@
      *  Open/Release the frame buffer device
      */
 
-static int offb_open(int fbidx)                                       
+static int offb_open(struct fb_info *info)
 {
-    /*                                                                     
-     *  Nothing, only a usage count for the moment                          
-     */                                                                    
+    /*
+     *  Nothing, only a usage count for the moment
+     */
 
     MOD_INC_USE_COUNT;
-    return(0);                              
+    return(0);
 }
-        
-static int offb_release(int fbidx)
+
+static int offb_release(struct fb_info *info)
 {
     MOD_DEC_USE_COUNT;
-    return(0);                                                    
+    return(0);
 }
 
 
@@ -115,9 +140,12 @@
      *  Get the Fixed Part of the Display
      */
 
-static int offb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			struct fb_info *info)
 {
-    memcpy(fix, &fb_fix, sizeof(fb_fix));
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
+
+    memcpy(fix, &info2->fix, sizeof(struct fb_fix_screeninfo));
     return 0;
 }
 
@@ -126,9 +154,12 @@
      *  Get the User Defined Part of the Display
      */
 
-static int offb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int offb_get_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info)
 {
-    memcpy(var, &fb_var, sizeof(fb_var));
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
+
+    memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
     return 0;
 }
 
@@ -137,33 +168,36 @@
      *  Set the User Defined Part of the Display
      */
 
-static int offb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int offb_set_var(struct fb_var_screeninfo *var, int con,
+			struct fb_info *info)
 {
     struct display *display;
     int oldbpp = -1, err;
+    int activate = var->activate;
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
 
     if (con >= 0)
 	display = &fb_display[con];
     else
-	display = &disp;	/* used during initialization */
+	display = &info2->disp;	/* used during initialization */
 
-    if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
-	var->xres_virtual > fb_var.xres_virtual ||
-	var->yres_virtual > fb_var.yres_virtual ||
-	var->bits_per_pixel > fb_var.bits_per_pixel ||
+    if (var->xres > info2->var.xres || var->yres > info2->var.yres ||
+	var->xres_virtual > info2->var.xres_virtual ||
+	var->yres_virtual > info2->var.yres_virtual ||
+	var->bits_per_pixel > info2->var.bits_per_pixel ||
 	var->nonstd ||
 	(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
 	return -EINVAL;
-    memcpy(var, &fb_var, sizeof(fb_var));
+    memcpy(var, &info2->var, sizeof(struct fb_var_screeninfo));
 
-    if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+    if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
 	oldbpp = display->var.bits_per_pixel;
 	display->var = *var;
     }
     if (oldbpp != var->bits_per_pixel) {
 	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 	    return err;
-	do_install_cmap(con);
+	do_install_cmap(con, info);
     }
     return 0;
 }
@@ -175,7 +209,8 @@
      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
      */
 
-static int offb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+static int offb_pan_display(struct fb_var_screeninfo *var, int con,
+			    struct fb_info *info)
 {
     if (var->xoffset || var->yoffset)
 	return -EINVAL;
@@ -187,14 +222,16 @@
      *  Get the Colormap
      */
 
-static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+static int offb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			 struct fb_info *info)
 {
     if (con == currcon) /* current console? */
-	return fb_get_cmap(cmap, &fb_display[con].var, kspc, offb_getcolreg);
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, offb_getcolreg,
+			   info);
     else if (fb_display[con].cmap.len) /* non default colormap? */
 	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
     else
-	fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 		     cmap, kspc ? 0 : 2);
     return 0;
 }
@@ -203,11 +240,13 @@
      *  Set the Colormap
      */
 
-static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+static int offb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			 struct fb_info *info)
 {
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
     int err;
 
-    if (!unknown_cmap_adr)
+    if (!info2->cmap_adr)
 	return -ENOSYS;
 
     if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
@@ -216,7 +255,8 @@
 	    return err;
     }
     if (con == currcon)			/* current console? */
-	return fb_set_cmap(cmap, &fb_display[con].var, kspc, offb_setcolreg);
+	return fb_set_cmap(cmap, &fb_display[con].var, kspc, offb_setcolreg,
+			   info);
     else
 	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
     return 0;
@@ -224,12 +264,23 @@
 
 
 static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		      u_long arg, int con, int fbidx)
+		      u_long arg, int con, struct fb_info *info)
 {
     return -EINVAL;
 }
 
 
+#ifdef CONFIG_FB_ATY
+extern unsigned long atyfb_of_init(unsigned long mem_start,
+				   struct device_node *dp);
+
+static const char *aty_names[] = {
+    "ATY,mach64", "ATY,XCLAIM", "ATY,264VT", "ATY,mach64ii", "ATY,264GT-B", 
+    "ATY,mach64_3D_pcc", "ATY,XCLAIM3D", "ATY,XCLAIMVR", "ATY,RAGEII_M"
+};
+#endif /* CONFIG_FB_ATY */
+
+
     /*
      *  Initialisation
      */
@@ -237,130 +288,188 @@
 __initfunc(unsigned long offb_init(unsigned long mem_start))
 {
     struct device_node *dp;
-    int i, err, *pp, len;
+    int dpy, i, err, *pp, len;
     unsigned *up, address;
+    struct fb_fix_screeninfo *fix;
+    struct fb_var_screeninfo *var;
+    struct display *disp;
+    struct fb_info_offb *info;
+
+    for (dpy = 0; dpy < prom_num_displays; dpy++) {
+	if (!(dp = find_path_device(prom_display_paths[dpy])))
+	    continue;
+
+	info = &fb_info[dpy];
+	fix = &info->fix;
+	var = &info->var;
+	disp = &info->disp;
+
+	if (!ofonly) {
+#ifdef CONFIG_FB_ATY
+	    for (i = 0; i < sizeof(aty_names)/sizeof(*aty_names); i++)
+		if (!strcmp(dp->name, aty_names[i]))
+		    break;
+	    if (i < sizeof(aty_names)/sizeof(*aty_names)) {
+		mem_start = atyfb_of_init(mem_start, dp);
+		continue;
+	    }
+#endif /* CONFIG_FB_ATY */
+	}
 
-    if (!prom_display_path[0])
-	return mem_start;
-    if (!(dp = find_path_device(prom_display_path)))
-	return mem_start;
-
-    strncat(fb_fix.id, dp->name, sizeof(fb_fix.id));
-    fb_fix.id[sizeof(fb_fix.id)-1] = '\0';
-
-    if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
-	&& len == sizeof(int) && *pp != 8) {
-	printk("%s: can't use depth = %d\n", dp->full_name, *pp);
-	return mem_start;
-    }
-    if ((pp = (int *)get_property(dp, "width", &len)) != NULL
-	&& len == sizeof(int))
-	fb_var.xres = fb_var.xres_virtual = *pp;
-    if ((pp = (int *)get_property(dp, "height", &len)) != NULL
-	&& len == sizeof(int))
-	fb_var.yres = fb_var.yres_virtual = *pp;
-    if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
-	&& len == sizeof(int))
-	fb_fix.line_length = *pp;
-    else
-	fb_fix.line_length = fb_var.xres_virtual;
-    fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
-    if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
-	&& len == sizeof(unsigned))
-	address = (u_long)*up;
-    else {
-	for (i = 0; i < dp->n_addrs; ++i)
-	    if (dp->addrs[i].size >= len)
-		break;
-	if (i >= dp->n_addrs) {
-	    printk("no framebuffer address found for %s\n", dp->full_name);
-	    return mem_start;
+	strcpy(fix->id, "OFfb ");
+	strncat(fix->id, dp->name, sizeof(fix->id));
+	fix->id[sizeof(fix->id)-1] = '\0';
+
+	if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
+	    && len == sizeof(int) && *pp != 8) {
+	    printk("%s: can't use depth = %d\n", dp->full_name, *pp);
+	    continue;
+	}
+	if ((pp = (int *)get_property(dp, "width", &len)) != NULL
+	    && len == sizeof(int))
+	    var->xres = var->xres_virtual = *pp;
+	if ((pp = (int *)get_property(dp, "height", &len)) != NULL
+	    && len == sizeof(int))
+	    var->yres = var->yres_virtual = *pp;
+	if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
+	    && len == sizeof(int))
+	    fix->line_length = *pp;
+	else
+	    fix->line_length = var->xres_virtual;
+	fix->smem_len = fix->line_length*var->yres;
+	if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
+	    && len == sizeof(unsigned))
+	    address = (u_long)*up;
+	else {
+	    for (i = 0; i < dp->n_addrs; ++i)
+		if (dp->addrs[i].size >= len)
+		    break;
+	    if (i >= dp->n_addrs) {
+		printk("no framebuffer address found for %s\n", dp->full_name);
+		continue;
+	    }
+	    address = (u_long)dp->addrs[i].address;
+	}
+	fix->smem_start = ioremap(address, fix->smem_len);
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+
+	/* XXX kludge for ati */
+	if (strncmp(dp->name, "ATY,", 4) == 0) {
+	    info->cmap_adr = ioremap(address + 0x7ff000, 0x1000) + 0xcc0;
+	    info->cmap_data = info->cmap_adr + 1;
 	}
-	address = (u_long)dp->addrs[i].address;
-    }
-    fb_fix.smem_start = ioremap(address, fb_fix.smem_len);
-    fb_fix.type = FB_TYPE_PACKED_PIXELS;
-    fb_fix.type_aux = 0;
-
-    /* XXX kludge for ati */
-    if (strncmp(dp->name, "ATY,", 4) == 0) {
-	unknown_cmap_adr = ioremap(address + 0x7ff000, 0x1000) + 0xcc0;
-	unknown_cmap_data = unknown_cmap_adr + 1;
-    }
 
-    fb_fix.visual = unknown_cmap_adr ? FB_VISUAL_PSEUDOCOLOR :
+#ifdef CONFIG_FB_COMPAT_XPMAC
+	if (display_info.height == 0) {	/* Only the first display */
+	    display_info.height = var->yres;
+	    display_info.width = var->xres;
+	    display_info.depth = 8;
+	    display_info.pitch = fix->line_length;
+	    display_info.mode = 0;
+	    strncpy(display_info.name, dp->name, sizeof(display_info.name));
+	    display_info.fb_address = (unsigned long)fix->smem_start;
+	    display_info.cmap_adr_address = 0;
+	    display_info.cmap_data_address = 0;
+	    display_info.disp_reg_address = 0;
+	    /* XXX kludge for ati */
+	    if (strncmp(dp->name, "ATY,", 4) == 0) {
+		    display_info.disp_reg_address = address + 0x7ffc00;
+		    display_info.cmap_adr_address = address + 0x7ffcc0;
+		    display_info.cmap_data_address = address + 0x7ffcc1;
+	    }
+	}
+#endif /* CONFIG_FB_COMPAT_XPMAC) */
+
+	fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR :
 				       FB_VISUAL_STATIC_PSEUDOCOLOR;
 
-    fb_var.xoffset = fb_var.yoffset = 0;
-    fb_var.bits_per_pixel = 8;
-    fb_var.grayscale = 0;
-    fb_var.red.offset = fb_var.green.offset = fb_var.blue.offset = 0;
-    fb_var.red.length = fb_var.green.length = fb_var.blue.length = 8;
-    fb_var.red.msb_right = fb_var.green.msb_right = fb_var.blue.msb_right = 0;
-    fb_var.transp.offset = fb_var.transp.length = fb_var.transp.msb_right = 0;
-    fb_var.nonstd = 0;
-    fb_var.activate = 0;
-    fb_var.height = fb_var.width = -1;
-    fb_var.accel = FB_ACCEL_NONE;
-    fb_var.pixclock = 10000;
-    fb_var.left_margin = fb_var.right_margin = 16;
-    fb_var.upper_margin = fb_var.lower_margin = 16;
-    fb_var.hsync_len = fb_var.vsync_len = 8;
-    fb_var.sync = 0;
-    fb_var.vmode = FB_VMODE_NONINTERLACED;
-
-    disp.var = fb_var;
-    disp.cmap.start = 0;
-    disp.cmap.len = 0;
-    disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
-    disp.screen_base = fb_fix.smem_start;
-    disp.visual = fb_fix.visual;
-    disp.type = fb_fix.type;
-    disp.type_aux = fb_fix.type_aux;
-    disp.ypanstep = 0;
-    disp.ywrapstep = 0;
-    disp.line_length = fb_fix.line_length;
-    disp.can_soft_blank = unknown_cmap_adr ? 1 : 0;
-    disp.inverse = 0;
-
-    strcpy(fb_info.modename, "OFfb ");
-    strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
-    fb_info.node = -1;
-    fb_info.fbops = &offb_ops;
-    fb_info.disp = &disp;
-    fb_info.fontname[0] = '\0';
-    fb_info.changevar = NULL;
-    fb_info.switch_con = &offbcon_switch;
-    fb_info.updatevar = &offbcon_updatevar;
-    fb_info.blank = &offbcon_blank;
-
-    err = register_framebuffer(&fb_info);
-    if (err < 0)
-	return mem_start;
-
-    for (i = 0; i < 16; i++) {
-	int j = color_table[i];
-	palette[i].red = default_red[j];
-	palette[i].green = default_grn[j];
-	palette[i].blue = default_blu[j];
-    }
-    offb_set_var(&fb_var, -1, GET_FB_IDX(fb_info.node));
+	var->xoffset = var->yoffset = 0;
+	var->bits_per_pixel = 8;
+	var->grayscale = 0;
+	var->red.offset = var->green.offset = var->blue.offset = 0;
+	var->red.length = var->green.length = var->blue.length = 8;
+	var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;
+	var->transp.offset = var->transp.length = var->transp.msb_right = 0;
+	var->nonstd = 0;
+	var->activate = 0;
+	var->height = var->width = -1;
+	var->accel = FB_ACCEL_NONE;
+	var->pixclock = 10000;
+	var->left_margin = var->right_margin = 16;
+	var->upper_margin = var->lower_margin = 16;
+	var->hsync_len = var->vsync_len = 8;
+	var->sync = 0;
+	var->vmode = FB_VMODE_NONINTERLACED;
+
+	disp->var = *var;
+	disp->cmap.start = 0;
+	disp->cmap.len = 0;
+	disp->cmap.red = disp->cmap.green = disp->cmap.blue = disp->cmap.transp = NULL;
+	disp->screen_base = fix->smem_start;
+	disp->visual = fix->visual;
+	disp->type = fix->type;
+	disp->type_aux = fix->type_aux;
+	disp->ypanstep = 0;
+	disp->ywrapstep = 0;
+	disp->line_length = fix->line_length;
+	disp->can_soft_blank = info->cmap_adr ? 1 : 0;
+	disp->inverse = 0;
+
+	strcpy(info->info.modename, "OFfb ");
+	strncat(info->info.modename, dp->full_name,
+		sizeof(info->info.modename));
+	info->info.node = -1;
+	info->info.fbops = &offb_ops;
+	info->info.disp = disp;
+	info->info.fontname[0] = '\0';
+	info->info.changevar = NULL;
+	info->info.switch_con = &offbcon_switch;
+	info->info.updatevar = &offbcon_updatevar;
+	info->info.blank = &offbcon_blank;
+
+	err = register_framebuffer(&info->info);
+	if (err < 0)
+	    continue;
+
+	for (i = 0; i < 16; i++) {
+	    int j = color_table[i];
+	    info->palette[i].red = default_red[j];
+	    info->palette[i].green = default_grn[j];
+	    info->palette[i].blue = default_blu[j];
+	}
+	offb_set_var(var, -1, &info->info);
 
-    printk("Open Firmware frame buffer device on %s\n", dp->full_name);
+	printk("Open Firmware frame buffer device on %s\n", dp->full_name);
+    }
     return mem_start;
 }
 
 
-static int offbcon_switch(int con)
+    /*
+     *  Setup: parse used options
+     */
+
+void offb_setup(char *options, int *ints)
+{
+    if (!options || !*options)
+	return;
+
+    if (!strcmp(options, "ofonly"))
+	ofonly = 1;
+}
+
+
+static int offbcon_switch(int con, struct fb_info *info)
 {
     /* Do we have to save the colormap? */
     if (fb_display[currcon].cmap.len)
 	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
-		    offb_getcolreg);
+		    offb_getcolreg, info);
 
     currcon = con;
     /* Install new colormap */
-    do_install_cmap(con);
+    do_install_cmap(con, info);
     return 0;
 }
 
@@ -368,7 +477,7 @@
      *  Update the `var' structure (called by fbcon.c)
      */
 
-static int offbcon_updatevar(int con)
+static int offbcon_updatevar(int con, struct fb_info *info)
 {
     /* Nothing */
     return 0;
@@ -378,24 +487,25 @@
      *  Blank the display.
      */
 
-static void offbcon_blank(int blank)
+static void offbcon_blank(int blank, struct fb_info *info)
 {
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
     int i, j;
 
-    if (!unknown_cmap_adr)
+    if (!info2->cmap_adr)
 	return;
 
     if (blank)
 	for (i = 0; i < 256; i++) {
-	    *unknown_cmap_adr = i;
+	    *info2->cmap_adr = i;
 	    mach_eieio();
 	    for (j = 0; j < 3; j++) {
-		*unknown_cmap_data = 0;
+		*info2->cmap_data = 0;
 		mach_eieio();
 	    }
 	}
     else
-	do_install_cmap(currcon);
+	do_install_cmap(currcon, info);
 }
 
     /*
@@ -404,13 +514,15 @@
      */
 
 static int offb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp)
+			  u_int *transp, struct fb_info *info)
 {
-    if (!unknown_cmap_adr || regno > 255)
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
+
+    if (!info2->cmap_adr || regno > 255)
 	return 1;
-    *red = palette[regno].red;
-    *green = palette[regno].green;
-    *blue = palette[regno].blue;
+    *red = info2->palette[regno].red;
+    *green = info2->palette[regno].green;
+    *blue = info2->palette[regno].blue;
     return 0;
 }
 
@@ -422,33 +534,71 @@
      */
 
 static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp)
+			 u_int transp, struct fb_info *info)
 {
-    if (!unknown_cmap_adr || regno > 255)
+    struct fb_info_offb *info2 = (struct fb_info_offb *)info;
+
+    if (!info2->cmap_adr || regno > 255)
 	return 1;
-    palette[regno].red = red;
-    palette[regno].green = green;
-    palette[regno].blue = blue;
-    *unknown_cmap_adr = regno;
+    info2->palette[regno].red = red;
+    info2->palette[regno].green = green;
+    info2->palette[regno].blue = blue;
+    *info2->cmap_adr = regno;
     mach_eieio();
-    *unknown_cmap_data = red;
+    *info2->cmap_data = red;
     mach_eieio();
-    *unknown_cmap_data = green;
+    *info2->cmap_data = green;
     mach_eieio();
-    *unknown_cmap_data = blue;
+    *info2->cmap_data = blue;
     mach_eieio();
     return 0;
 }
 
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
     if (con != currcon)
 	return;
     if (fb_display[con].cmap.len)
 	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-		    offb_setcolreg);
+		    offb_setcolreg, info);
     else
-	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
-				    &fb_display[con].var, 1, offb_setcolreg);
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+				    &fb_display[con].var, 1, offb_setcolreg,
+				    info);
 }
+
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+
+    /*
+     *  Backward compatibility mode for Xpmac
+     */
+
+int console_getmode(struct vc_mode *mode)
+{
+    *mode = display_info;
+    return 0;
+}
+
+int console_setmode(struct vc_mode *mode, int doit)
+{
+    int err;
+
+    if (console_setmode_ptr == NULL)
+	return -EINVAL;
+    err = (*console_setmode_ptr)(mode, doit);
+    return err;
+}
+
+int console_powermode(int mode)
+{
+    if (mode == VC_POWERMODE_INQUIRY)
+	return 0;
+    if (mode < VESA_NO_BLANKING || mode > VESA_POWERDOWN)
+	return -EINVAL;
+    /* Not supported */
+    return -ENXIO;
+}
+
+#endif /* CONFIG_FB_COMPAT_XPMAC */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/retz3fb.c m68k-2.1.77/drivers/video/retz3fb.c
--- /usr/src/m68k-2.1.77/drivers/video/retz3fb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/retz3fb.c	Fri Jan  9 01:22:43 1998
@@ -118,9 +118,11 @@
    int (*decode_var)(struct fb_var_screeninfo *var, struct retz3fb_par *par);
    int (*encode_var)(struct fb_var_screeninfo *var, struct retz3fb_par *par);
    int (*getcolreg)(unsigned int regno, unsigned int *red, unsigned
-		    int *green, unsigned int *blue, unsigned int *transp);
+		    int *green, unsigned int *blue, unsigned int *transp,
+			struct fb_info *info);
    int (*setcolreg)(unsigned int regno, unsigned int red, unsigned int
-		    green, unsigned int blue, unsigned int transp);
+		    green, unsigned int blue, unsigned int transp,
+			struct fb_info *info);
    void (*blank)(int blank);
 } *fbhw;
 
@@ -248,20 +250,23 @@
 
 void retz3fb_setup(char *options, int *ints);
 
-static int retz3fb_open(int fbidx);
-static int retz3fb_release(int fbidx);
-static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
-static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int retz3fb_open(struct fb_info *info);
+static int retz3fb_release(struct fb_info *info);
+static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			   struct fb_info *info);
+static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info);
+static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info);
 static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx);
+			    struct fb_info *info);
 static int retz3fb_pan_display(struct fb_var_screeninfo *var, int con,
-				int fbidx);
+			       struct fb_info *info);
 static int retz3fb_ioctl(struct inode *inode, struct file *file,
-			  unsigned int cmd, unsigned long arg, int con,
-			  int fbidx);
+			 unsigned int cmd, unsigned long arg, int con,
+			 struct fb_info *info);
 
 
 /*
@@ -269,9 +274,9 @@
  */
 
 unsigned long retz3fb_init(unsigned long mem_start);
-static int z3fb_switch(int con);
-static int z3fb_updatevar(int con);
-static void z3fb_blank(int blank);
+static int z3fb_switch(int con, struct fb_info *info);
+static int z3fb_updatevar(int con, struct fb_info *info);
+static void z3fb_blank(int blank, struct fb_info *info);
 
 
 /*
@@ -300,10 +305,10 @@
                           struct retz3fb_par *par);
 static int retz3_getcolreg(unsigned int regno, unsigned int *red,
 			   unsigned int *green, unsigned int *blue,
-			   unsigned int *transp);
+			   unsigned int *transp, struct fb_info *info);
 static int retz3_setcolreg(unsigned int regno, unsigned int red,
 			   unsigned int green, unsigned int blue,
-			   unsigned int transp);
+			   unsigned int transp, struct fb_info *info);
 static void retz3_blank(int blank);
 
 
@@ -314,9 +319,9 @@
 static void retz3fb_get_par(struct retz3fb_par *par);
 static void retz3fb_set_par(struct retz3fb_par *par);
 static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static void do_install_cmap(int con);
+static void do_install_cmap(int con, struct fb_info *info);
 /*
-static void retz3fb_set_disp(int con);
+static void retz3fb_set_disp(int con, struct fb_info *info);
 */
 static int get_video_mode(const char *name);
 
@@ -798,8 +803,8 @@
 	}
 #endif
 
-	retz3_setcolreg (255, 56, 100, 160, 0);
-	retz3_setcolreg (254, 0, 0, 0, 0);
+	retz3_setcolreg (255, 56, 100, 160, 0, NULL /* unused */);
+	retz3_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);
 
 	return 0;
 }
@@ -931,7 +936,7 @@
 
 static int retz3_setcolreg(unsigned int regno, unsigned int red,
 			   unsigned int green, unsigned int blue,
-			   unsigned int transp)
+			   unsigned int transp, struct fb_info *info)
 {
 	/* We'll get to this */
 
@@ -959,7 +964,7 @@
 
 static int retz3_getcolreg(unsigned int regno, unsigned int *red,
 			   unsigned int *green, unsigned int *blue,
-			   unsigned int *transp)
+			   unsigned int *transp, struct fb_info *info)
 {
 	if (regno > 255)
 		return 1;
@@ -1171,17 +1176,17 @@
 }
 
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
 	if (con != currcon)
 		return;
 	if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-			    fbhw->setcolreg);
+			    fbhw->setcolreg, info);
 	else
-		fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 					    &fb_display[con].var, 1,
-					    fbhw->setcolreg);
+					    fbhw->setcolreg, info);
 }
 
 
@@ -1189,7 +1194,7 @@
  *    Open/Release the frame buffer device
  */
 
-static int retz3fb_open(int fbidx)
+static int retz3fb_open(struct fb_info *info)
 {
 	/*
 	 * Nothing, only a usage count for the moment
@@ -1199,7 +1204,7 @@
 	return 0;
 }
 
-static int retz3fb_release(int fbidx)
+static int retz3fb_release(struct fb_info *info)
 {
 	MOD_DEC_USE_COUNT;
 	return 0;
@@ -1210,7 +1215,8 @@
  *    Get the Fixed Part of the Display
  */
 
-static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			   struct fb_info *info)
 {
 	struct retz3fb_par par;
 	int error = 0;
@@ -1227,7 +1233,8 @@
  *    Get the User Defined Part of the Display
  */
 
-static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
 {
 	struct retz3fb_par par;
 	int error = 0;
@@ -1242,7 +1249,7 @@
 
 
 #if 1
-static void retz3fb_set_disp(int con)
+static void retz3fb_set_disp(int con, struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
 	struct display *display;
@@ -1252,8 +1259,7 @@
 	else
 		display = &disp;	/* used during initialization */
 
-	/* ### FN: Needs fixes later */
-	retz3fb_get_fix(&fix, con, 0);
+	retz3fb_get_fix(&fix, con, info);
 
 	if (con == -1)
 		con = 0;
@@ -1273,7 +1279,8 @@
  *    Set the User Defined Part of the Display
  */
 
-static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *info)
 {
 	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
 	struct display *display;
@@ -1304,7 +1311,7 @@
 		    oldbpp != var->bits_per_pixel) {
 
 			struct fb_fix_screeninfo fix;
-			retz3fb_get_fix(&fix, con, fbidx);
+			retz3fb_get_fix(&fix, con, info);
 
 			display->screen_base = fix.smem_start;
 			display->visual = fix.visual;
@@ -1316,7 +1323,7 @@
 			display->can_soft_blank = 1;
 			display->inverse = z3fb_inverse;
 /*
-	retz3fb_set_disp(con);
+	retz3fb_set_disp(con, info);
 */
 			if (fb_info.changevar)
 				(*fb_info.changevar)(con);
@@ -1325,7 +1332,7 @@
 		if (oldbpp != var->bits_per_pixel) {
 			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 				return err;
-			do_install_cmap(con);
+			do_install_cmap(con, info);
 		}
 	}
 	return 0;
@@ -1337,15 +1344,15 @@
  */
 
 static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			    struct fb_info *info)
 {
 	if (con == currcon) /* current console? */
 		return(fb_get_cmap(cmap, &fb_display[con].var, kspc,
-				   fbhw->getcolreg));
+				   fbhw->getcolreg, info));
 	else if (fb_display[con].cmap.len) /* non default colormap? */
 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
 	else
-		fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 			     cmap, kspc ? 0 : 2);
 	return 0;
 }
@@ -1356,7 +1363,7 @@
  */
 
 static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			     int fbidx)
+			    struct fb_info *info)
 {
 	int err;
 
@@ -1368,7 +1375,7 @@
 	}
 	if (con == currcon)              /* current console? */
 		return(fb_set_cmap(cmap, &fb_display[con].var, kspc,
-				   fbhw->setcolreg));
+				   fbhw->setcolreg, info));
 	else
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
 	return 0;
@@ -1382,7 +1389,7 @@
  */
 
 static int retz3fb_pan_display(struct fb_var_screeninfo *var, int con,
-				int fbidx)
+				struct fb_info *info)
 {
 	return -EINVAL;
 }
@@ -1393,8 +1400,8 @@
  */
 
 static int retz3fb_ioctl(struct inode *inode, struct file *file,
-                          unsigned int cmd, unsigned long arg, int con,
-                          int fbidx)
+                         unsigned int cmd, unsigned long arg, int con,
+                         struct fb_info *info)
 {
 	return -EINVAL;
 }
@@ -1486,11 +1493,11 @@
 	fbhw->encode_var(&retz3fb_default, &par);
 
 	do_fb_set_var(&retz3fb_default, 0);
-	retz3fb_get_var(&disp.var, -1, GET_FB_IDX(fb_info.node));
+	retz3fb_get_var(&disp.var, -1, &fb_info);
 
-	retz3fb_set_disp(-1);
+	retz3fb_set_disp(-1, &fb_info);
 
-	do_install_cmap(0);
+	do_install_cmap(0, &fb_info);
 
 	printk("%s frame buffer device, using %ldK of video memory\n",
 	       fb_info.modename, z3_size>>10);
@@ -1502,17 +1509,18 @@
 }
 
 
-static int z3fb_switch(int con)
+static int z3fb_switch(int con, struct fb_info *info)
 {
 	/* Do we have to save the colormap? */
 	if (fb_display[currcon].cmap.len)
 		fb_get_cmap(&fb_display[currcon].cmap,
-			    &fb_display[currcon].var, 1, fbhw->getcolreg);
+			    &fb_display[currcon].var, 1, fbhw->getcolreg,
+			    info);
 
 	do_fb_set_var(&fb_display[con].var, 1);
 	currcon = con;
 	/* Install new colormap */
-	do_install_cmap(con);
+	do_install_cmap(con, info);
 	return 0;
 }
 
@@ -1524,7 +1532,7 @@
  *    Since it's called by a kernel driver, no range checking is done.
  */
 
-static int z3fb_updatevar(int con)
+static int z3fb_updatevar(int con, struct fb_info *info)
 {
 	return 0;
 }
@@ -1534,7 +1542,7 @@
  *    Blank the display.
  */
 
-static void z3fb_blank(int blank)
+static void z3fb_blank(int blank, struct fb_info *info)
 {
 	fbhw->blank(blank);
 }
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/skeletonfb.c m68k-2.1.77/drivers/video/skeletonfb.c
--- /usr/src/m68k-2.1.77/drivers/video/skeletonfb.c	Thu Jan  1 01:00:00 1970
+++ m68k-2.1.77/drivers/video/skeletonfb.c	Fri Jan  9 01:25:17 1998
@@ -0,0 +1,263 @@
+/*
+ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
+ *
+ *  Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+
+
+    /*
+     *  This is just simple example code.
+     *
+     *  No warranty that it actually compiles.
+     *  Even less warranty that it actually works.
+     */
+
+
+static int default_par = 0;	/* default resolution (0=none) */
+
+static struct xxxfb_info {
+    struct fb_info_gen gen;
+    /* Here starts the frame buffer device dependent part */
+    /* You can use this to store e.g. the board number if you support */
+    /* multiple boards */
+} fb_info;
+
+static int currcon = 0;
+
+static struct display disp;
+
+static struct xxxfb_par {
+    ...
+} current_par;
+
+static int current_par_valid = 0;
+
+
+int inverse = 0;
+
+
+/* ------------------- chipset specific functions ---------------------- */
+
+
+static int xxx_detect(void)
+{
+    ...
+    xxx_get_par(&par);
+    xxx_encode_var(&xxxfb_predefined[0], &par);
+    return 1;
+}
+
+static int xxx_encode_fix(struct fb_fix_screeninfo *fix, struct xxxfb_par *par,
+			  const struct fb_info *fb_info)
+{
+    ...
+    return 0;
+}
+
+static int xxx_decode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
+			  const struct fb_info *fb_info)
+{
+    ...
+    return 0;
+}
+
+static int xxx_encode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
+			  const struct fb_info *fb_info)
+{
+    ...
+    return 0;
+}
+
+static void xxx_get_par(struct xxxfb_par *par, const struct fb_info *fb_info)
+{
+    if (current_par_valid)
+	*par = current_par;
+    else {
+	...
+    }
+}
+
+static void xxx_set_par(struct xxxfb_par *par, const struct fb_info *fb_info)
+{
+    current_par = *par;
+    current_par_valid = 1;
+    ...
+}
+
+static int xxx_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 const struct fb_info *fb_info)
+{
+    ...
+    return 0;
+}
+
+/* make colors available to fbcon */
+unsigned u16 packed16_cmap[16];
+unsigned u32 packed24_cmap[16];
+unsigned u32 packed32_cmap[16];
+
+static int xxx_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 const struct fb_info *fb_info)
+{
+    ...
+    if (regno < 16) {
+	if (is_cfb15)		/* RGB 555 */
+	    packed16_cmap[regno] = be16_to_cpu((red << 10) | (green << 5) |
+					       blue);
+	if (is_cfb16)		/* RGB 565 */
+	    packed16_cmap[regno] = be16_to_cpu((red << 11) | (green << 5) |
+					       blue);
+	if (is_cfb24)		/* RGB 888 */
+	    packed24_cmap[regno] = be32_to_cpu((red << 16) | (green << 8) |
+					       blue);
+	if (is_cfb32)		/* RGBA 8888 */
+	    packed32_cmap[regno] = be32_to_cpu((red << 24) | (green << 16) |
+					       (blue << 8) | transp);
+    }
+    return 0;
+}
+
+static int xxx_pan_display(struct fb_var_screeninfo *var,
+			   struct xxxfb_par *par,
+			   const struct fb_info *fb_info)
+{
+    ...
+    return 0;
+}
+
+static int xxx_blank(int blank_mode, const struct fb_info *fb_info)
+{
+    ...
+    return 0;
+}
+
+
+/* ------------ Interfaces to hardware functions ------------ */
+
+
+struct fbgen_hwswitch xxx_switch = {
+    xxx_detect, xxx_encode_fix, xxx_decode_var, xxx_encode_var, xxx_get_par,
+    xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_blank
+};
+
+
+
+/* =========================================================== */
+/* ============== Hardware Independant Functions ============= */
+/* =========================================================== */
+
+
+/* ----------------------------------------------------------------------------
+
+    /*
+     *  Initialization
+     */
+
+__initfunc(unsigned long xxxfb_init(unsigned long mem_start))
+{
+    int err;
+    struct fb_var_screeninfo var;
+
+    fb_info.fbhw = &xxx_switch;
+    detected_mode = fbhw->detect();
+    strcpy(fb_info.modename, "XXX");
+    fb_info.changevar = NULL;
+    fb_info.node = -1;
+    fb_info.fbops = &xxxfb_ops;
+    fb_info.disp = disp;
+    fb_info.switch_con = &xxxfb_switch;
+    fb_info.updatevar = &xxxfb_update_var;
+    fb_info.blank = &xxxfb_blank;
+    /* This should give a reasonable default video mode */
+    xxxfb_get_var(&disp.var, -1, &fb_info);
+    fb_do_set_var(var, 1);
+    err = register_framebuffer(&fb_info);
+    if (err < 0)
+	return err;
+    xxxfb_set_disp(-1, &fb_info);
+    fb_install_cmap(0);
+    printk("%s frame buffer device\n", fb_info.modename);
+
+    /* uncomment this if your driver cannot be unloaded */
+    /* MOD_INC_USE_COUNT; */
+
+    return mem_start;
+}
+
+
+    /*
+     *  Setup
+     */
+
+__initfunc(void xxxfb_setup(char *options, int *ints))
+{
+    /* Parse user speficied options (`video=xxxfb:')
+}
+
+
+/* ----------------------------------------------------------------------------
+
+
+    /*
+     *  Frame buffer operations
+     */
+
+static int xxxfb_open(const struct fb_info *info)
+{
+    /* Nothing, only a usage count for the moment */
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static int xxxfb_release(const struct fb_info *info)
+{
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+
+    /*
+     *  In most cases the `generic' routines should be satisfactory
+     */
+
+static struct fb_ops xxxfb_ops = {
+    xxxfb_open, xxxfb_release, fbgen_get_fix, fbgen_get_var, fbgen_set_var,
+    fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display, fbgen_ioctl
+};
+
+
+/* ----------------------------------------------------------------------------
+
+
+    /*
+     *  Modularization
+     */
+
+#ifdef MODULE
+int init_module(void)
+{
+    return xxxfb_init(NULL);
+}
+
+void cleanup_module(void)
+{
+    /* Not reached because the usecount will never be decremented to zero */
+    unregister_framebuffer(&fb_info);
+    /* TODO: further clean up ... */
+}
+#endif /* MODULE */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/tgafb.c m68k-2.1.77/drivers/video/tgafb.c
--- /usr/src/m68k-2.1.77/drivers/video/tgafb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/tgafb.c	Fri Jan  9 01:22:51 1998
@@ -17,13 +17,12 @@
  *
  *	- How to set a single color register?
  *
- *	- We don't have support for CFB32 yet (fbcon-cfb32.c)
- *
  *	- Hardware cursor (useful for other graphics boards too)
  *
  * KNOWN PROBLEMS/TO DO ==================================================== */
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -243,6 +242,9 @@
 static struct fb_info fb_info;
 static struct { u_char red, green, blue, pad; } palette[256];
 
+/* hack to tell fbcon-cfb32 the colormap */
+extern u32 cfb32_cmap[16];
+
 static struct fb_fix_screeninfo fb_fix = { { "DEC TGA ", } };
 static struct fb_var_screeninfo fb_var = { 0, };
 
@@ -251,17 +253,22 @@
      *  Interface used by the world
      */
 
-static int tgafb_open(int fbidx);
-static int tgafb_release(int fbidx);
-static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx);
-static int tgafb_get_var(struct fb_var_screeninfo *var, int con, int fbidx);
-static int tgafb_set_var(struct fb_var_screeninfo *var, int con, int fbidx);
+static int tgafb_open(struct fb_info *info);
+static int tgafb_release(struct fb_info *info);
+static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info);
+static int tgafb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
+static int tgafb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info);
 static int tgafb_pan_display(struct fb_var_screeninfo *var, int con,
-			     int fbidx);
-static int tgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
-static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx);
+			     struct fb_info *info);
+static int tgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info);
+static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info);
 static int tgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg, int con, int fbidx);
+		       u_long arg, int con, struct fb_info *info);
 
 
     /*
@@ -269,9 +276,9 @@
      */
 
 unsigned long tgafb_init(unsigned long mem_start);
-static int tgafbcon_switch(int con);
-static int tgafbcon_updatevar(int con);
-static void tgafbcon_blank(int blank);
+static int tgafbcon_switch(int con, struct fb_info *info);
+static int tgafbcon_updatevar(int con, struct fb_info *info);
+static void tgafbcon_blank(int blank, struct fb_info *info);
 
 
     /*
@@ -279,13 +286,13 @@
      */
 
 static int tgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			   u_int *transp);
+			   u_int *transp, struct fb_info *info);
 static int tgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			   u_int transp);
+			   u_int transp, struct fb_info *info);
 #if 1
 static void tga_update_palette(void);
 #endif
-static void do_install_cmap(int con);
+static void do_install_cmap(int con, struct fb_info *info);
 
 
 static struct fb_ops tgafb_ops = {
@@ -298,7 +305,7 @@
      *  Open/Release the frame buffer device
      */
 
-static int tgafb_open(int fbidx)                                       
+static int tgafb_open(struct fb_info *info)                                       
 {
     /*                                                                     
      *  Nothing, only a usage count for the moment                          
@@ -308,7 +315,7 @@
     return(0);                              
 }
         
-static int tgafb_release(int fbidx)
+static int tgafb_release(struct fb_info *info)
 {
     MOD_DEC_USE_COUNT;
     return(0);                                                    
@@ -319,7 +326,8 @@
      *  Get the Fixed Part of the Display
      */
 
-static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con, int fbidx)
+static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
 {
     memcpy(fix, &fb_fix, sizeof(fb_fix));
     return 0;
@@ -330,7 +338,8 @@
      *  Get the User Defined Part of the Display
      */
 
-static int tgafb_get_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int tgafb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
     memcpy(var, &fb_var, sizeof(fb_var));
     return 0;
@@ -341,7 +350,8 @@
      *  Set the User Defined Part of the Display
      */
 
-static int tgafb_set_var(struct fb_var_screeninfo *var, int con, int fbidx)
+static int tgafb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
 {
     struct display *display;
     int oldbpp = -1, err;
@@ -367,7 +377,7 @@
     if (oldbpp != var->bits_per_pixel) {
 	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 	    return err;
-	do_install_cmap(con);
+	do_install_cmap(con, info);
     }
     return 0;
 }
@@ -379,7 +389,8 @@
      *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
      */
 
-static int tgafb_pan_display(struct fb_var_screeninfo *var, int con, int fbidx)
+static int tgafb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info *info)
 {
     if (var->xoffset || var->yoffset)
 	return -EINVAL;
@@ -391,14 +402,16 @@
      *  Get the Colormap
      */
 
-static int tgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+static int tgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
 {
     if (con == currcon) /* current console? */
-	return fb_get_cmap(cmap, &fb_display[con].var, kspc, tgafb_getcolreg);
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, tgafb_getcolreg,
+			   info);
     else if (fb_display[con].cmap.len) /* non default colormap? */
 	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
     else
-	fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 		     cmap, kspc ? 0 : 2);
     return 0;
 }
@@ -407,7 +420,8 @@
      *  Set the Colormap
      */
 
-static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, int fbidx)
+static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
 {
     int err;
 
@@ -417,7 +431,8 @@
 	    return err;
     }
     if (con == currcon) {		/* current console? */
-	err = fb_set_cmap(cmap, &fb_display[con].var, kspc, tgafb_setcolreg);
+	err = fb_set_cmap(cmap, &fb_display[con].var, kspc, tgafb_setcolreg,
+			  info);
 #if 1
 	tga_update_palette();
 #endif
@@ -429,7 +444,7 @@
 
 
 static int tgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg, int con, int fbidx)
+		       u_long arg, int con, struct fb_info *info)
 {
     return -EINVAL;
 }
@@ -692,7 +707,16 @@
 
     fb_var.xoffset = fb_var.yoffset = 0;
     fb_var.grayscale = 0;
-    fb_var.red.offset = fb_var.green.offset = fb_var.blue.offset = 0;
+    if (tga_type == 0) { /* 8-plane */
+	fb_var.red.offset = 0;
+	fb_var.green.offset = 0;
+	fb_var.blue.offset = 0;
+    } else { /* 24-plane or 24plusZ */
+	/* XXX: is this correct?? */
+	fb_var.red.offset = 16;
+	fb_var.green.offset = 8;
+	fb_var.blue.offset = 0;
+    }
     fb_var.red.length = fb_var.green.length = fb_var.blue.length = 8;
     fb_var.red.msb_right = fb_var.green.msb_right = fb_var.blue.msb_right = 0;
     fb_var.transp.offset = fb_var.transp.length = fb_var.transp.msb_right = 0;
@@ -738,23 +762,23 @@
     if (err < 0)
 	return mem_start;
 
-    tgafb_set_var(&fb_var, -1, GET_FB_IDX(fb_info.node));
+    tgafb_set_var(&fb_var, -1, &fb_info);
 
     printk("%s frame buffer device\n", fb_fix.id);
     return mem_start;
 }
 
 
-static int tgafbcon_switch(int con)
+static int tgafbcon_switch(int con, struct fb_info *info)
 {
     /* Do we have to save the colormap? */
     if (fb_display[currcon].cmap.len)
 	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
-		    tgafb_getcolreg);
+		    tgafb_getcolreg, info);
 
     currcon = con;
     /* Install new colormap */
-    do_install_cmap(con);
+    do_install_cmap(con, info);
     return 0;
 }
 
@@ -762,7 +786,7 @@
      *  Update the `var' structure (called by fbcon.c)
      */
 
-static int tgafbcon_updatevar(int con)
+static int tgafbcon_updatevar(int con, struct fb_info *info)
 {
     /* Nothing */
     return 0;
@@ -772,7 +796,7 @@
      *  Blank the display.
      */
 
-static void tgafbcon_blank(int blank)
+static void tgafbcon_blank(int blank, struct fb_info *info)
 {
     /* Nothing */
 }
@@ -783,7 +807,7 @@
      */
 
 static int tgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp)
+                         u_int *transp, struct fb_info *info)
 {
     if (regno > 255)
 	return 1;
@@ -801,7 +825,7 @@
      */
 
 static int tgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp)
+                         u_int transp, struct fb_info *info)
 {
     if (regno > 255)
 	return 1;
@@ -809,6 +833,11 @@
     palette[regno].green = green;
     palette[regno].blue = blue;
 
+#ifdef CONFIG_FBCON_CFB32
+    if (regno < 16 && tga_type != 0)
+	cfb32_cmap[regno] = (red << 16) | (green << 8) | blue;
+#endif /* CONFIG_FBCON_CFB32 */
+
     /* How to set a single color register?? */
 
     return 0;
@@ -846,16 +875,17 @@
 }
 #endif
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
     if (con != currcon)
 	return;
     if (fb_display[con].cmap.len)
 	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-		    tgafb_setcolreg);
+		    tgafb_setcolreg, info);
     else
-	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
-				    &fb_display[con].var, 1, tgafb_setcolreg);
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+				    &fb_display[con].var, 1, tgafb_setcolreg,
+				    info);
 #if 1
     tga_update_palette();
 #endif
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/vfb.c m68k-2.1.77/drivers/video/vfb.c
--- /usr/src/m68k-2.1.77/drivers/video/vfb.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/vfb.c	Fri Jan  9 01:22:51 1998
@@ -58,22 +58,22 @@
 
 void vfb_setup(char *options, int *ints);
 
-static int vfb_open(int fbidx);
-static int vfb_release(int fbidx);
+static int vfb_open(struct fb_info *info);
+static int vfb_release(struct fb_info *info);
 static int vfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			      int fbidx);
+		       struct fb_info *info);
 static int vfb_get_var(struct fb_var_screeninfo *var, int con,
-			      int fbidx);
+		       struct fb_info *info);
 static int vfb_set_var(struct fb_var_screeninfo *var, int con,
-			      int fbidx);
+		       struct fb_info *info);
 static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
-				  int fbidx);
+			   struct fb_info *info);
 static int vfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			       int fbidx);
+			struct fb_info *info);
 static int vfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			       int fbidx);
+			struct fb_info *info);
 static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			    u_long arg, int con, int fbidx);
+		     u_long arg, int con, struct fb_info *info);
 
 
     /*
@@ -81,9 +81,9 @@
      */
 
 unsigned long vfb_init(unsigned long mem_start);
-static int vfbcon_switch(int con);
-static int vfbcon_updatevar(int con);
-static void vfbcon_blank(int blank);
+static int vfbcon_switch(int con, struct fb_info *info);
+static int vfbcon_updatevar(int con, struct fb_info *info);
+static void vfbcon_blank(int blank, struct fb_info *info);
 
 
     /*
@@ -95,10 +95,10 @@
 			   struct fb_var_screeninfo *var);
 static void set_color_bitfields(struct fb_var_screeninfo *var);
 static int vfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp);
+                         u_int *transp, struct fb_info *info);
 static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp);
-static void do_install_cmap(int con);
+                         u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
 
 
 static struct fb_ops vfb_ops = {
@@ -112,7 +112,7 @@
      *  Open/Release the frame buffer device
      */
 
-static int vfb_open(int fbidx)                                       
+static int vfb_open(struct fb_info *info)                                       
 {
     /*                                                                     
      *  Nothing, only a usage count for the moment                          
@@ -122,7 +122,7 @@
     return(0);                              
 }
         
-static int vfb_release(int fbidx)
+static int vfb_release(struct fb_info *info)
 {
     MOD_DEC_USE_COUNT;
     return(0);                                                    
@@ -134,7 +134,7 @@
      */
 
 static int vfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			      int fbidx)
+		       struct fb_info *info)
 {
     struct fb_var_screeninfo *var;
 
@@ -152,7 +152,7 @@
      */
 
 static int vfb_get_var(struct fb_var_screeninfo *var, int con,
-			      int fbidx)
+		       struct fb_info *info)
 {
     if (con == -1)
 	*var = vfb_default;
@@ -168,7 +168,7 @@
      */
 
 static int vfb_set_var(struct fb_var_screeninfo *var, int con,
-			      int fbidx)
+		       struct fb_info *info)
 {
     int err, activate = var->activate;
     int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
@@ -255,7 +255,7 @@
 	if (oldbpp != var->bits_per_pixel) {
 	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
 		return err;
-	    do_install_cmap(con);
+	    do_install_cmap(con, info);
 	}
     }
     return 0;
@@ -269,7 +269,7 @@
      */
 
 static int vfb_pan_display(struct fb_var_screeninfo *var, int con,
-				  int fbidx)
+			   struct fb_info *info)
 {
     if (var->vmode & FB_VMODE_YWRAP) {
 	if (var->yoffset < 0 ||
@@ -297,14 +297,15 @@
      */
 
 static int vfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			       int fbidx)
+			struct fb_info *info)
 {
     if (con == currcon) /* current console? */
-	return fb_get_cmap(cmap, &fb_display[con].var, kspc, vfb_getcolreg);
+	return fb_get_cmap(cmap, &fb_display[con].var, kspc, vfb_getcolreg,
+			   info);
     else if (fb_display[con].cmap.len) /* non default colormap? */
 	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
     else
-	fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+	fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
 		     cmap, kspc ? 0 : 2);
     return 0;
 }
@@ -314,7 +315,7 @@
      */
 
 static int vfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			       int fbidx)
+			struct fb_info *info)
 {
     int err;
 
@@ -324,7 +325,8 @@
 	    return err;
     }
     if (con == currcon)			/* current console? */
-	return fb_set_cmap(cmap, &fb_display[con].var, kspc, vfb_setcolreg);
+	return fb_set_cmap(cmap, &fb_display[con].var, kspc, vfb_setcolreg,
+			   info);
     else
 	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
     return 0;
@@ -336,7 +338,7 @@
      */
 
 static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			    u_long arg, int con, int fbidx)
+		     u_long arg, int con, struct fb_info *info)
 {
     return -EINVAL;
 }
@@ -389,7 +391,7 @@
     if (err < 0)
 	return mem_start;
 
-    vfb_set_var(&vfb_default, -1, GET_FB_IDX(fb_info.node));
+    vfb_set_var(&vfb_default, -1, &fb_info);
 
     printk("Virtual frame buffer device, using %ldK of video memory\n",
 	   videomemorysize>>10);
@@ -397,16 +399,16 @@
 }
 
 
-static int vfbcon_switch(int con)
+static int vfbcon_switch(int con, struct fb_info *info)
 {
     /* Do we have to save the colormap? */
     if (fb_display[currcon].cmap.len)
 	fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
-		    vfb_getcolreg);
+		    vfb_getcolreg, info);
 
     currcon = con;
     /* Install new colormap */
-    do_install_cmap(con);
+    do_install_cmap(con, info);
     return 0;
 }
 
@@ -414,7 +416,7 @@
      *  Update the `var' structure (called by fbcon.c)
      */
 
-static int vfbcon_updatevar(int con)
+static int vfbcon_updatevar(int con, struct fb_info *info)
 {
     /* Nothing */
     return 0;
@@ -424,7 +426,7 @@
      *  Blank the display.
      */
 
-static void vfbcon_blank(int blank)
+static void vfbcon_blank(int blank, struct fb_info *info)
 {
     /* Nothing */
 }
@@ -525,7 +527,7 @@
      */
 
 static int vfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp)
+                         u_int *transp, struct fb_info *info)
 {
     if (regno > 255)
 	return 1;
@@ -543,7 +545,7 @@
      */
 
 static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp)
+                         u_int transp, struct fb_info *info)
 {
     if (regno > 255)
 	return 1;
@@ -554,16 +556,16 @@
 }
 
 
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
 {
     if (con != currcon)
 	return;
     if (fb_display[con].cmap.len)
 	fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
-		    vfb_setcolreg);
+		    vfb_setcolreg, info);
     else
-	fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
-				    &fb_display[con].var, 1, vfb_setcolreg);
+	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+		    &fb_display[con].var, 1, vfb_setcolreg, info);
 }
 
 
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/drivers/video/vgacon.c m68k-2.1.77/drivers/video/vgacon.c
--- /usr/src/m68k-2.1.77/drivers/video/vgacon.c	Thu Jan  8 22:04:59 1998
+++ m68k-2.1.77/drivers/video/vgacon.c	Fri Jan  9 01:22:51 1998
@@ -312,7 +312,7 @@
 	 *	Find out if there is a graphics card present.
 	 *	Are there smarter methods around?
 	 */
-	p = (unsigned short *)video_mem_base;
+	p = (unsigned short *)vga_video_mem_base;
 	saved = vga_readw(p);
 	vga_writew(0xAA55, p);
 	if (vga_readw(p) != 0xAA55) {
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/include/asm-m68k/amifd.h m68k-2.1.77/include/asm-m68k/amifd.h
--- /usr/src/m68k-2.1.77/include/asm-m68k/amifd.h	Thu Sep 11 22:30:56 1997
+++ m68k-2.1.77/include/asm-m68k/amifd.h	Fri Jan  9 01:22:51 1998
@@ -5,21 +5,23 @@
 
 #include <linux/fd.h>
 
-#define FD_MAX_UNITS    4
+#define FD_MAX_UNITS    4	/* Max. Number of drives */
+#define MAX_SECTORS	22	/* Max. Number of sectors per track */
+
+#ifndef ASSEMBLER
 
 struct fd_data_type {
     char *name;			/* description of data type */
     int sects;			/* sectors per track */
 #ifdef __STDC__
-    int (*read_fkt)(int, unsigned char *, unsigned long, int);
-    void (*write_fkt)(int, unsigned long, unsigned char *, int);
+    int (*read_fkt)(int);
+    void (*write_fkt)(int);
 #else
     int (*read_fkt)();		/* read whole track */
     void (*write_fkt)();		/* write whole track */
 #endif
 };
 
-#ifndef ASSEMBLER
 /*
 ** Floppy type descriptions
 */
@@ -43,13 +45,15 @@
     struct fd_drive_type *type;	/* type of floppy for this unit */
     struct fd_data_type *dtype;	/* type of floppy for this unit */
     int track;			/* current track (-1 == unknown) */
+    unsigned char *trackbuf;    /* current track (kmaloc()'d */
 
     int blocks;			/* total # blocks on disk */
-    int sects;			/* number of sectors per track */
 
+    int changed;		/* true when not known */
     int disk;			/* disk in drive (-1 == unknown) */
     int motor;			/* true when motor is at speed */
     int busy;			/* true when drive is active */
+    int dirty;			/* true when trackbuf is not on disk */
     int status;			/* current error code for unit */
 };
 #endif
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/include/asm-m68k/setup.h m68k-2.1.77/include/asm-m68k/setup.h
--- /usr/src/m68k-2.1.77/include/asm-m68k/setup.h	Thu Jan  8 22:05:02 1998
+++ m68k-2.1.77/include/asm-m68k/setup.h	Fri Jan  9 01:30:36 1998
@@ -69,10 +69,14 @@
 
 #if defined(CONFIG_MAC)
 #  error Currently no Mac support!
+#else
+#define MACH_IS_MAC (0)
 #endif
 
 #if defined(CONFIG_SUN3)
 #  error Currently no Sun-3 support!
+#else
+#define MACH_IS_SUN3 (0)
 #endif
 
 #if !defined (CONFIG_APOLLO)
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/include/linux/console.h m68k-2.1.77/include/linux/console.h
--- /usr/src/m68k-2.1.77/include/linux/console.h	Thu Jan  8 22:05:02 1998
+++ m68k-2.1.77/include/linux/console.h	Fri Jan  9 01:22:51 1998
@@ -46,6 +46,9 @@
 
 extern struct consw *conswitchp;
 
+extern struct consw fb_con;	/* frame buffer based console */
+extern struct consw vga_con;	/* VGA text console */
+
 /* flag bits */
 #define CON_INITED  (1)
 
@@ -91,8 +94,8 @@
 	int	(*read)(struct console *, const char *, unsigned);
 	kdev_t	(*device)(struct console *);
 	int	(*wait_key)(struct console *);
-        void	(*unblank)(void);
-	void	(*setup)(struct console *, char *);
+	void	(*unblank)(void);
+	int	(*setup)(struct console *, char *);
 	short	flags;
 	short	index;
 	int	cflag;
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/include/linux/console_struct.h m68k-2.1.77/include/linux/console_struct.h
--- /usr/src/m68k-2.1.77/include/linux/console_struct.h	Wed Dec 17 22:56:46 1997
+++ m68k-2.1.77/include/linux/console_struct.h	Fri Jan  9 01:33:19 1998
@@ -4,16 +4,24 @@
  * Data structure and defines shared between console.c, vga.c and tga.c
  */
 
+/*
+ * You can set here how should the cursor look by default.
+ * In case you set CONFIG_SOFTCURSOR, this might be really interesting.
+ */
+#define CUR_DEFAULT CUR_UNDERLINE
+
 #include <linux/config.h>
 
 #define NPAR 16
 
 struct vc_data {
-        unsigned short  vc_num;                 /* Console number */
-	unsigned long   vc_cols;
-	unsigned long   vc_rows;
-	unsigned long   vc_size_row;
-	struct consw    *vc_sw;
+#ifdef CONFIG_ABSTRACT_CONSOLE
+	unsigned short	vc_num;			/* Console number */
+	unsigned long	vc_cols;
+	unsigned long	vc_rows;
+	unsigned long	vc_size_row;
+	struct consw	*vc_sw;
+#endif /* CONFIG_ABSTRACT_CONSOLE */
 	unsigned long	vc_screenbuf_size;
 	unsigned short	vc_video_erase_char;	/* Background erase character */
 	unsigned char	vc_attr;		/* Current attributes */
@@ -28,13 +36,8 @@
 	unsigned long	vc_top,vc_bottom;
 	unsigned long	vc_state;
 	unsigned long	vc_npar,vc_par[NPAR];
-#ifdef CONFIG_FB_CONSOLE
-	unsigned short	*vc_video_mem_start;	/* Start of video RAM		*/
-	unsigned short	*vc_pos;
-#else
 	unsigned long	vc_pos;
 	unsigned long	vc_video_mem_start;	/* Start of video RAM		*/
-#endif
 	unsigned long	vc_video_mem_end;	/* End of video RAM (sort of)	*/
 	unsigned long	vc_saved_x;
 	unsigned long	vc_saved_y;
@@ -61,7 +64,9 @@
 	/* misc */
 	unsigned long	vc_ques		: 1;
 	unsigned long	vc_need_wrap	: 1;
-	unsigned long	vc_can_do_color : 1;
+#ifdef CONFIG_ABSTRACT_CONSOLE
+	unsigned long	vc_can_do_color	: 1;
+#endif /* CONFIG_ABSTRACT_CONSOLE */
 	unsigned long	vc_has_scrolled : 1;	/* Info for unblank_screen */
 	unsigned long	vc_kmalloced	: 1;	/* kfree_s() needed */
 	unsigned long	vc_report_mouse : 2;
@@ -77,6 +82,7 @@
 	unsigned char 	vc_saved_G1;
 	unsigned int	vc_bell_pitch;		/* Console bell pitch */
 	unsigned int	vc_bell_duration;	/* Console bell duration */
+	unsigned int	vc_cursor_type;
 	/* additional information is in vt_kern.h */
 };
 
@@ -90,6 +96,8 @@
 
 extern struct vc vc_cons [MAX_NR_CONSOLES];
 
+#define cons_num	(vc_cons[currcons].d->vc_num)
+#define sw		(vc_cons[currcons].d->vc_sw)
 #define screenbuf_size	(vc_cons[currcons].d->vc_screenbuf_size)
 #define origin		(vc_cons[currcons].d->vc_origin)
 #define scr_end	(vc_cons[currcons].d->vc_scr_end)
@@ -149,6 +157,17 @@
 #define palette		(vc_cons[currcons].d->vc_palette)
 #define bell_pitch	(vc_cons[currcons].d->vc_bell_pitch)
 #define bell_duration	(vc_cons[currcons].d->vc_bell_duration)
+
+#define cursor_type	(vc_cons[currcons].d->vc_cursor_type)
+#define CUR_DEF		0
+#define CUR_NONE	1
+#define CUR_UNDERLINE	2
+#define CUR_LOWER_THIRD	3
+#define CUR_LOWER_HALF	4
+#define CUR_TWO_THIRDS	5
+#define CUR_BLOCK	6
+#define CUR_HWMASK	0x0f
+#define CUR_SWMASK	0xfff0
 
 #define vcmode		(vt_cons[currcons]->vc_mode)
 #define structsize	(sizeof(struct vc_data) + sizeof(struct vt_struct))
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/include/linux/fb.h m68k-2.1.77/include/linux/fb.h
--- /usr/src/m68k-2.1.77/include/linux/fb.h	Thu Jan  8 22:05:02 1998
+++ m68k-2.1.77/include/linux/fb.h	Fri Jan  9 01:33:23 1998
@@ -80,6 +80,7 @@
 #define FB_ACCEL_CYBERVISION3D	5	/* Cybervision64/3D (S3 ViRGE)	*/
 #define FB_ACCEL_MACH64		6	/* ATI Mach 64			*/
 #define FB_ACCEL_TGA		7	/* DEC 21030 TGA		*/
+#define FB_ACCEL_ATY		8	/* atyfb (ATI Mach64)		*/
 
 #define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active	*/
 #define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
@@ -154,25 +155,40 @@
 
 #include <linux/fs.h>
 
+
+struct fb_info;
+struct fb_info_gen;
+
+
+    /*
+     *  Frame buffer operations
+     */
+
 struct fb_ops {
-	/* open/release and usage marking */
-	int (*fb_open) (int);
-	int (*fb_release) (int);
-	/* get non settable parameters	*/
-	int (*fb_get_fix) (struct fb_fix_screeninfo *, int, int); 
-	/* get settable parameters	*/
-	int (*fb_get_var) (struct fb_var_screeninfo *, int, int);		
-	/* set settable parameters	*/
-	int (*fb_set_var) (struct fb_var_screeninfo *, int, int);		
-	/* get colormap			*/
-	int (*fb_get_cmap) (struct fb_cmap *, int, int, int);
-	/* set colormap			*/
-	int (*fb_set_cmap) (struct fb_cmap *, int, int, int);
-	/* pan display                   */
-	int (*fb_pan_display) (struct fb_var_screeninfo *, int, int);
-	/* perform fb specific ioctl	*/
-	int (*fb_ioctl)(struct inode *, struct file *, unsigned int,
-			unsigned long, int, int);
+    /* open/release and usage marking */
+    int (*fb_open)(struct fb_info *info);
+    int (*fb_release)(struct fb_info *info);
+    /* get non settable parameters */
+    int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
+		      struct fb_info *info); 
+    /* get settable parameters */
+    int (*fb_get_var)(struct fb_var_screeninfo *var, int con,
+		      struct fb_info *info);		
+    /* set settable parameters */
+    int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
+		      struct fb_info *info);		
+    /* get colormap */
+    int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
+		       struct fb_info *info);
+    /* set colormap */
+    int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
+		       struct fb_info *info);
+    /* pan display */
+    int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
+			  struct fb_info *info);
+    /* perform fb specific ioctl */
+    int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
+		    unsigned long arg, int con, struct fb_info *info);
 };
 
 
@@ -228,12 +244,86 @@
    char modename[40];               /* default video mode */
    int node;
    struct fb_ops *fbops;
-   struct display *disp;            /* initial display variable */
-   char fontname[40];               /* default font name */
-   int (*changevar)(int);           /* tell console var has changed */
-   int (*switch_con)(int);          /* tell fb to switch consoles */
-   int (*updatevar)(int);           /* tell fb to update the vars */
-   void (*blank)(int);              /* tell fb to (un)blank the screen */
+   struct display *disp;		/* initial display variable */
+   char fontname[40];			/* default font name */
+   int (*changevar)(int);		/* tell console var has changed */
+   int (*switch_con)(int, struct fb_info*);
+					/* tell fb to switch consoles */
+   int (*updatevar)(int, struct fb_info*);
+					/* tell fb to update the vars */
+   void (*blank)(int, struct fb_info*);	/* tell fb to (un)blank the screen */
+
+   /* From here on everything is device dependent */
+};
+
+
+    /*
+     *  This structure abstracts from the underlying hardware. It is not
+     *  mandatory but used by the `generic' frame buffer operations.
+     */
+
+struct fbgen_hwswitch {
+    int (*detect)(void);
+    /* This function should detect the current video mode settings and	*/
+    /* store them in xxxfb_predefined[0] for later reference by the	*/
+    /* user. Return the index+1 of an equivalent predefined mode or 0	*/
+    /* if there is no such.						*/
+
+    int (*encode_fix)(struct fb_fix_screeninfo *fix, const void *par,
+		      struct fb_info_gen *info);
+    /* This function should fill in the 'fix' structure based on the	*/
+    /* values in the 'par' structure.					*/
+
+    int (*decode_var)(const struct fb_var_screeninfo *var, void *par,
+		      struct fb_info_gen *info);
+    /* Get the video params out of 'var'. If a value doesn't fit, round	*/
+    /* it up, if it's too big, return EINVAL.				*/
+    /* Round up in the following order: bits_per_pixel, xres, yres,	*/
+    /* xres_virtual, yres_virtual, xoffset, yoffset, grayscale,		*/
+    /* bitfields, horizontal timing, vertical timing.			*/
+
+    int (*encode_var)(struct fb_var_screeninfo *var, const void *par,
+		      struct fb_info_gen *info);
+    /* Fill the 'var' structure based on the values in 'par' and maybe	*/
+    /* other values read out of the hardware.				*/
+
+    void (*get_par)(void *par, struct fb_info_gen *info);
+    /* Fill the hardware's 'par' structure.				*/
+
+    void (*set_par)(const void *par, struct fb_info_gen *info);
+    /* Set the hardware according to 'par'.				*/
+
+    int (*getcolreg)(unsigned regno, unsigned *red, unsigned *green,
+		     unsigned *blue, unsigned *transp, struct fb_info *info);
+    /* Read a single color register and split it into			*/
+    /* colors/transparent. Return != 0 for invalid regno.		*/
+
+    int (*setcolreg)(unsigned regno, unsigned red, unsigned green,
+		     unsigned blue, unsigned transp, struct fb_info *info);
+    /* 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.	*/
+
+    int (*pan_display)(const struct fb_var_screeninfo *var,
+		       struct fb_info_gen *info);
+    /* Pan the display (using the current `par' structure).		*/
+
+    int (*blank)(int blank_mode, struct fb_info_gen *info);
+    /* Blank the screen if blank_mode != 0, else unblank. If NULL then	*/
+    /* blanking is done by setting the CLUT to black. Return != 0 if	*/
+    /* un-/blanking failed due to e.g. video mode which doesn't support	*/
+    /* it. */
+};
+
+struct fb_info_gen {
+    struct fb_info info;
+
+    /* Entries for a generic frame buffer device */
+    /* Yes, this starts looking like C++ */
+    u_int parsize;
+    struct fbgen_hwswitch *fbhw;
+
+   /* From here on everything is device dependent */
 };
 
 
@@ -264,11 +354,14 @@
 			 int fsfromto);
 extern int fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
 		       int kspc, int (*getcolreg)(u_int, u_int *, u_int *,
-						  u_int *, u_int *));
+						  u_int *, u_int *,
+						  struct fb_info *),
+		       struct fb_info *fb_info);
 extern int fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
 		       int kspc, int (*setcolreg)(u_int, u_int, u_int, u_int,
-						  u_int));
-extern struct fb_cmap *fb_default_cmap(int bpp);
+						  u_int, struct fb_info *),
+		       struct fb_info *fb_info);
+extern struct fb_cmap *fb_default_cmap(int len);
 extern void fb_invert_cmaps(void);
 
 #endif /* __KERNEL__ */
diff -u --recursive --exclude-from=/home/geert/diff-excludes-linux --new-file /usr/src/m68k-2.1.77/include/linux/selection.h m68k-2.1.77/include/linux/selection.h
--- /usr/src/m68k-2.1.77/include/linux/selection.h	Wed Dec 17 22:56:46 1997
+++ m68k-2.1.77/include/linux/selection.h	Fri Jan  9 01:31:21 1998
@@ -15,16 +15,13 @@
 extern int mouse_reporting(void);
 extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
 
-#ifdef CONFIG_FB_CONSOLE
-extern unsigned long get_video_num_columns(unsigned int console);
-extern unsigned long get_video_num_lines(unsigned int console);
-extern unsigned long get_video_size_row(unsigned int console);
-#else
-#define get_video_num_columns(dummy) video_num_columns
-#define get_video_num_lines(dummy) video_num_lines
-#define get_video_size_row(dummy) video_size_row
-#endif
-
+#ifdef CONFIG_ABSTRACT_CONSOLE
+#define video_num_columns	(vc_cons[currcons].d->vc_cols)
+#define video_num_lines		(vc_cons[currcons].d->vc_rows)
+#define video_size_row		(vc_cons[currcons].d->vc_size_row)
+#define video_screen_size	(vc_cons[currcons].d->vc_screenbuf_size)
+#define can_do_color		(vc_cons[currcons].d->vc_can_do_color)
+#else /* !CONFIG_ABSTRACT_CONSOLE */
 extern unsigned long video_num_columns;
 extern unsigned long video_num_lines;
 extern unsigned long video_size_row;
@@ -34,9 +31,10 @@
 extern unsigned long video_screen_size;
 extern unsigned short video_port_reg;
 extern unsigned short video_port_val;
+extern int can_do_color;
+#endif /* !CONFIG_ABSTRACT_CONSOLE */
 
 extern int console_blanked;
-extern int can_do_color;
 
 extern unsigned long video_font_height;
 extern unsigned long video_scan_lines;
@@ -66,6 +64,14 @@
 	(((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4))
 /* this latter line used to have masks 0xf000 and 0x0f00, but selection
    requires a self-inverse operation; moreover, the old version looks wrong */
+#ifdef CONFIG_ABSTRACT_CONSOLE
+#define reverse_video_short_mono(a)	((a) ^ 0x800)
+#define complement_video_short(a)	((a) ^ (can_do_color ? 0x7700 : 0x800))
+#else /* !CONFIG_ABSTRACT_CONSOLE */
+#define reverse_video_short_mono(a)	((a) ^ ((((a) & 0x0700) == 0x0100) ? \
+						0x7000 : 0x7700))
+#define complement_video_short(a)	((a) ^ 0x7700)
+#endif /* !CONFIG_ABSTRACT_CONSOLE */
 
 extern void getconsxy(int currcons, char *p);
 extern void putconsxy(int currcons, char *p);
@@ -140,7 +146,19 @@
 	return *addr;
 }
 
-#else /* CONFIG_TGA_CONSOLE  || CONFIG_SUN_CONSOLE */
+#elif defined(CONFIG_ABSTRACT_CONSOLE)
+static inline void scr_writew(unsigned short val, unsigned short *addr)
+{
+	/* simply store the value in the "shadow screen" memory */
+	*addr = val;
+}
+
+static inline unsigned short scr_readw(unsigned short * addr)
+{
+	return *addr;
+}
+
+#elif defined(CONFIG_VGA_CONSOLE)
 
 /*
  * normal VGA console access

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

