]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.110pre2 2.1.110pre2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:56 +0000 (15:15 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:56 +0000 (15:15 -0500)
231 files changed:
CREDITS
Documentation/parport.txt
Documentation/sound/OPL3-SA [new file with mode: 0644]
Documentation/sound/Opti
Documentation/sound/Tropez+ [new file with mode: 0644]
Documentation/sound/Wavefront [new file with mode: 0644]
MAINTAINERS
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/bios32.c
arch/alpha/kernel/lca.c
arch/alpha/kernel/smc37c669.c
arch/alpha/kernel/smp.c
arch/arm/Makefile
arch/arm/boot/compressed/Makefile.debug
arch/arm/boot/compressed/head-nexuspci.S
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c
arch/arm/defconfig
arch/arm/kernel/armksyms.c
arch/arm/kernel/calls.S
arch/arm/kernel/dec21285.c
arch/arm/kernel/dma-a5k.c
arch/arm/kernel/dma-rpc.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
arch/arm/kernel/head-armv.S
arch/arm/kernel/iic.c
arch/arm/kernel/irq.c
arch/arm/kernel/process.c
arch/arm/kernel/setup-ebsa110.c
arch/arm/kernel/setup.c
arch/arm/kernel/signal.c
arch/arm/kernel/sys_arm.c
arch/arm/kernel/time.c
arch/arm/kernel/traps.c
arch/arm/lib/Makefile
arch/arm/lib/extractconstants.pl
arch/arm/lib/getconstants.c [deleted file]
arch/arm/lib/getconstants.h [deleted file]
arch/arm/lib/io-ebsa285.S
arch/arm/lib/io.c [new file with mode: 0644]
arch/arm/mm/fault-armo.c
arch/arm/mm/mm-a5k.c [deleted file]
arch/arm/mm/mm-arc.c
arch/arm/mm/mm-armv.c [new file with mode: 0644]
arch/arm/mm/mm-ebsa110.c
arch/arm/mm/mm-ebsa285.c
arch/arm/mm/mm-nexuspci.c
arch/arm/mm/mm-rpc.c
arch/arm/mm/mm-tbox.c [new file with mode: 0644]
arch/arm/mm/mm-vnc.c [new file with mode: 0644]
arch/arm/mm/proc-arm6,7.S
arch/arm/vmlinux-armo.lds [new file with mode: 0644]
arch/arm/vmlinux-armv.lds [new file with mode: 0644]
arch/arm/vmlinux.lds [deleted file]
arch/i386/defconfig
arch/i386/kernel/bios32.c
arch/i386/kernel/setup.c
arch/m68k/kernel/bios32.c
arch/mips/kernel/pci.c
arch/ppc/kernel/pci.c
arch/sparc64/kernel/psycho.c
drivers/acorn/block/mfmhd.c
drivers/acorn/char/serial-card.c
drivers/acorn/char/serial-dualsp.c
drivers/acorn/net/ether3.c
drivers/acorn/net/etherh.c
drivers/acorn/scsi/acornscsi.c
drivers/acorn/scsi/cumana_1.c
drivers/acorn/scsi/cumana_1.h
drivers/acorn/scsi/cumana_2.c
drivers/acorn/scsi/ecoscsi.c
drivers/acorn/scsi/ecoscsi.h
drivers/acorn/scsi/eesox.c
drivers/acorn/scsi/fas216.c
drivers/acorn/scsi/fas216.h
drivers/acorn/scsi/msgqueue.c
drivers/acorn/scsi/oak.c
drivers/acorn/scsi/oak.h
drivers/acorn/scsi/powertec.c
drivers/acorn/scsi/queue.c
drivers/char/Config.in
drivers/char/bttv.c
drivers/char/bttv.h
drivers/char/console.c
drivers/char/console_macros.h
drivers/char/fbmem.c
drivers/char/hfmodem/refclock.c
drivers/char/i2c.c
drivers/char/mem.c
drivers/char/radio-aimslab.c
drivers/char/radio-sf16fmi.c
drivers/char/radio-zoltrix.c [new file with mode: 0644]
drivers/char/radio.c [deleted file]
drivers/char/rsf16fmi.h
drivers/char/rtrack.c [deleted file]
drivers/char/rtrack.h [deleted file]
drivers/char/saa5249.c
drivers/char/tuner.c
drivers/char/videodev.c
drivers/misc/parport_arc.c
drivers/misc/parport_ax.c
drivers/misc/parport_pc.c
drivers/misc/parport_procfs.c
drivers/net/3c501.c
drivers/net/3c509.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/bpqether.c
drivers/pci/pci.c
drivers/scsi/ppa.c
drivers/sound/Config.in
drivers/sound/Makefile
drivers/sound/README.wavefront [new file with mode: 0644]
drivers/sound/Readme.modules
drivers/sound/ad1848.c
drivers/sound/cs4232.c
drivers/sound/dev_table.h
drivers/sound/mad16.c
drivers/sound/msnd.c
drivers/sound/msnd.h
drivers/sound/msnd_classic.c
drivers/sound/msnd_classic.h
drivers/sound/msnd_pinnacle.c
drivers/sound/msnd_pinnacle.h
drivers/sound/sound_calls.h
drivers/sound/wavfront.c [new file with mode: 0644]
drivers/sound/wf_midi.c [new file with mode: 0644]
drivers/sound/yss225.c [new file with mode: 0644]
drivers/sound/yss225.h [new file with mode: 0644]
drivers/video/Config.in
drivers/video/Makefile
drivers/video/S3triofb.c
drivers/video/atafb.c
drivers/video/atyfb.c
drivers/video/cgsixfb.c
drivers/video/chipsfb.c [new file with mode: 0644]
drivers/video/compatcon.c [deleted file]
drivers/video/creatorfb.c
drivers/video/cyberfb.c
drivers/video/fbcon-afb.c
drivers/video/fbcon-cfb16.c
drivers/video/fbcon-cfb2.c
drivers/video/fbcon-cfb24.c
drivers/video/fbcon-cfb32.c
drivers/video/fbcon-cfb4.c
drivers/video/fbcon-cfb8.c
drivers/video/fbcon-ilbm.c
drivers/video/fbcon-iplan2p2.c
drivers/video/fbcon-iplan2p4.c
drivers/video/fbcon-iplan2p8.c
drivers/video/fbcon-mac.c
drivers/video/fbcon-mfb.c
drivers/video/fbcon-vga.c
drivers/video/fbcon.c
drivers/video/fbcon.h
drivers/video/font.h
drivers/video/font_sun12x22.c [new file with mode: 0644]
drivers/video/fonts.c
drivers/video/macfb.c
drivers/video/macmodes.c [new file with mode: 0644]
drivers/video/mdafb.c
drivers/video/offb.c
drivers/video/promcon.c [new file with mode: 0644]
drivers/video/promfb.c [deleted file]
drivers/video/promfb.h [deleted file]
drivers/video/retz3fb.c
drivers/video/sbusfb.c
drivers/video/sbusfb.h
drivers/video/tgafb.c
drivers/video/vesafb.c
drivers/video/vgacon.c
drivers/video/vgafb.c
drivers/video/virgefb.c
include/asm-alpha/serial.h
include/asm-arm/arch-arc/io.h
include/asm-arm/arch-arc/processor.h
include/asm-arm/arch-ebsa110/processor.h
include/asm-arm/arch-ebsa285/hardware.h
include/asm-arm/arch-ebsa285/mmu.h
include/asm-arm/arch-ebsa285/serial.h [new file with mode: 0644]
include/asm-arm/arch-nexuspci/irq.h
include/asm-arm/arch-nexuspci/irqs.h
include/asm-arm/arch-nexuspci/mmu.h
include/asm-arm/arch-nexuspci/processor.h
include/asm-arm/arch-nexuspci/time.h
include/asm-arm/arch-rpc/hardware.h
include/asm-arm/arch-rpc/keyboard.h
include/asm-arm/arch-rpc/processor.h
include/asm-arm/arch-vnc/a.out.h [new file with mode: 0644]
include/asm-arm/arch-vnc/dma.h [new file with mode: 0644]
include/asm-arm/arch-vnc/hardware.h [new file with mode: 0644]
include/asm-arm/arch-vnc/ide.h [new file with mode: 0644]
include/asm-arm/arch-vnc/io.h [new file with mode: 0644]
include/asm-arm/arch-vnc/irq.h [new file with mode: 0644]
include/asm-arm/arch-vnc/irqs.h [new file with mode: 0644]
include/asm-arm/arch-vnc/keyboard.h [new file with mode: 0644]
include/asm-arm/arch-vnc/mm-init.h [new file with mode: 0644]
include/asm-arm/arch-vnc/mmu.h [new file with mode: 0644]
include/asm-arm/arch-vnc/oldlatches.h [new file with mode: 0644]
include/asm-arm/arch-vnc/processor.h [new file with mode: 0644]
include/asm-arm/arch-vnc/serial.h [new file with mode: 0644]
include/asm-arm/arch-vnc/shmparam.h [new file with mode: 0644]
include/asm-arm/arch-vnc/system.h [new file with mode: 0644]
include/asm-arm/arch-vnc/time.h [new file with mode: 0644]
include/asm-arm/arch-vnc/timex.h [new file with mode: 0644]
include/asm-arm/arch-vnc/uncompress.h [new file with mode: 0644]
include/asm-arm/elf.h
include/asm-arm/fiq.h
include/asm-arm/init.h
include/asm-arm/io.h
include/asm-arm/proc-armo/pgtable.h
include/asm-arm/proc-armv/mm-init.h
include/asm-arm/proc-armv/pgtable.h
include/asm-arm/procinfo.h
include/asm-arm/signal.h
include/asm-arm/spinlock.h
include/asm-arm/system.h
include/linux/console.h
include/linux/console_compat.h [deleted file]
include/linux/console_struct.h
include/linux/fb.h
include/linux/netdevice.h
include/linux/parport.h
include/linux/pci.h
include/linux/proc_fs.h
include/linux/videodev.h
include/linux/videotext.h
include/linux/vt_kern.h
include/linux/wavefront.h [new file with mode: 0644]
include/net/sock.h
net/sched/sch_api.c

diff --git a/CREDITS b/CREDITS
index a1de16becb371dbcb8a0e6480bb93ab4cfdd694b..431153ec4ed610833f515c71d715b0dce1562f7e 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -62,10 +62,12 @@ S: USA
 
 N: Andrea Arcangeli
 E: arcangeli@mbox.queen.it
-W: http://www.cs.unibo.it/~arcangel/
+W: http://e-mind.com/~andrea/
 P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC  C0 4B 81 1D 8C 15 C8 E5
-D: Parport sharing hacker.
-D: Various other kernel hacks.
+D: Parport hacker
+D: Implemented a workaround for some interrupt buggy printers
+D: Author of pscan that helps to fix lp/parport bug
+D: Various other kernel hacks
 S: Via Ciaclini 26
 S: Imola 40026
 S: Italy
index f9ee710921450aa24b1fade4b692dbe0a691b016..8695ba7db378893fdc1db7d8891992ba4c59cf29 100644 (file)
@@ -125,7 +125,7 @@ with no lp device associated with the second port (parport1).  Note
 that this is different to the way older kernels worked; there used to
 be a static association between the I/O port address and the device
 name, so /dev/lp0 was always the port at 0x3bc.  This is no longer the
-case - if you only have one port, it will always be /dev/lp0,
+case - if you only have one port, it will default to being /dev/lp0,
 regardless of base address.
 
 Also:
diff --git a/Documentation/sound/OPL3-SA b/Documentation/sound/OPL3-SA
new file mode 100644 (file)
index 0000000..62f7989
--- /dev/null
@@ -0,0 +1,76 @@
+OPL3-SA sound driver (opl3sa.o)
+
+The Yamaha OPL3-SAx sound chip is usually found built into motherboards, and
+it's a decent little chip offering a WSS mode, a SB Pro emulation mode, MPU401
+and OPL3 FM Synth capabilities.
+
+You can enable inclusion of the driver via CONFIG_SOUND_OPL3SA1=m, or
+CONFIG_SOUND_OPL3SA1=y through 'make config/xconfig/menuconfig'.
+
+You'll need to know all of the relevant info (irq, dma, and io port) for the
+chip's WSS mode, since that is the mode the kernel sound driver uses, and of
+course you'll also need to know about where the MPU401 and OPL3 ports and
+irq's are if you want to use those.
+
+Here's the skinny on how to load it as a module:
+
+       modprobe opl3sa io=0x530 irq=11 dma=0 dma2=1 mpu_io=0x330 mpu_irq=5
+
+Module options in detail:
+
+       io:     This is the WSS's port base.
+       irq:    This is the WSS's irq.
+       dma:    This is the WSS's dma line. In my BIOS setup screen this was
+               listed as "WSS Play DMA"
+       dma2:   This is the WSS's secondary dma line. My BIOS calls it the
+               "WSS capture DMA"
+       
+       mpu_io: This is the MPU401's port base.
+       mpu_irq: This is the MPU401's irq.
+
+If you'd like to use the OPL3 FM Synthesizer, make sure you enable
+CONFIG_YM3812 (in 'make config'). That'll build the opl3.o module.
+
+Then a simple 'insmod opl3 io=0x388', and you now have FM Synth.
+
+You can also use the SoftOSS software synthesizer instead of the builtin OPL3.
+Here's how:
+
+Say 'y' or 'm' to "SoftOSS software wave table engine" in make config.
+
+If you said yes, the software synth is availible once you boot your new
+kernel.
+
+If you chose to build it as a module, just insmod the resulting softoss2.o
+
+A 'cat /dev/sndstat' with all the above options should look similar to this:
+
+  OSS/Free:3.8s2++-971130
+  Load type: Driver loaded as a module
+  Kernel: Linux iniquity 2.1.105 #145 Mon Jun 8 11:40:47 MST 1998 i586
+  Config options: 0
+
+  Installed drivers: 
+
+  Card config: 
+
+  Audio devices:
+  0: MSS audio codec (CS4231) (DUPLEX)
+
+  Synth devices:
+  0: Yamaha OPL-3
+  1: SoftOSS
+
+  Midi devices:
+  0: OPL3-SA (MPU401)
+
+  Timers:
+  0: System clock
+  1: MSS audio codec (CS4231)
+
+  Mixers:
+  0: MSS audio codec (CS4231)
+
+Questions? Comments?
+<stiker@northlink.com>
+
index 55ef432e718b4ce5c5a0c41e706f31b3c021433d..34b0f433127d76c37cf84fcbf6603e29c6ba3ee9 100644 (file)
@@ -82,6 +82,14 @@ options mad16 irq=10 dma=0 dma16=1 io=0x530 joystick=1 cdtype=0
 options opl3 io=0x388
 post-install mad16 /sbin/ad1848_mixer_reroute 14 8 15 3 16 6
 
+If you have an MPU daughtercard or onboard MPU you will want to add to the
+"options mad16" line - eg 
+
+options mad16 irq=5 dma=0 dma16=3 io=0x530 mpu_io=0x330 mpu_irq=9
+
+To set the I/O and IRQ of the MPU.
+
+
 Explain:
 
 alias mixer0 mad16
diff --git a/Documentation/sound/Tropez+ b/Documentation/sound/Tropez+
new file mode 100644 (file)
index 0000000..b93a6b7
--- /dev/null
@@ -0,0 +1,26 @@
+From: Paul Barton-Davis <pbd@op.net>
+
+Here is the configuration I use with a Tropez+ and my modular
+driver:
+
+  alias char-major-14 wavefront
+  alias synth0 wavefront
+  alias mixer0 cs4232
+  alias audio0 cs4232
+  pre-install wavefront modprobe "-k" "cs4232"
+  post-install wavefront modprobe "-k" "opl3"
+  options wavefront io=0x200 irq=9
+  options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
+  options opl3 io=0x388
+
+Things to note: 
+
+       the wavefront options "io" and "irq" ***MUST*** match the "synthio"
+       and "synthirq" cs4232 options.
+
+       you can do without the opl3 module if you don't
+       want to use the OPL/[34] synth on the soundcard
+
+       the opl3 io parameter is conventionally not adjustable.
+
+Please see drivers/sound/README.wavefront for more details.
diff --git a/Documentation/sound/Wavefront b/Documentation/sound/Wavefront
new file mode 100644 (file)
index 0000000..4a2ad4b
--- /dev/null
@@ -0,0 +1,377 @@
+             An OSS/Free Driver for WaveFront soundcards
+               (Turtle Beach Maui, Tropez, Tropez Plus)
+
+                     Paul Barton-Davis, July 1998
+
+Driver Status
+-------------
+
+Requires: Kernel 2.1.106 or later
+        
+As of 7/3/1998, this driver is currently in *BETA* state. This means
+that it compiles and runs, and that I use it on my system (Linux
+2.1.106) with some reasonably demanding applications and uses.  I
+believe the code is approaching an initial "finished" state that
+provides bug-free support for the Tropez Plus.
+
+Please note that to date, the driver has ONLY been tested on a Tropez
+Plus. I would very much like to hear (and help out) people with Tropez
+and Maui cards, since I think the driver can support those cards as
+well.
+
+Finally, the driver has not been tested as a static (non-modular) part
+of the kernel. Alan Cox's good work in modularizing OSS/Free for Linux
+makes this rather unnecessary.
+
+Some Questions
+--------------
+
+**********************************************************************
+0) What does this driver do that the maui driver did not ?
+**********************************************************************
+
+* can fully initialize a WaveFront card from cold boot - no DOS
+          utilities needed
+* working patch/sample/program loading and unloading (the maui
+      driver didn't document how to make this work, and assumed
+      user-level preparation of the patch data for writing
+      to the board. ick.)
+* full user-level access to all WaveFront commands
+* for the Tropez Plus, (primitive) control of the YSS225 FX processor
+* Virtual MIDI mode supported - 2 MIDI devices accessible via the
+          WaveFront's MPU401/UART emulation. One
+          accesses the WaveFront synth, the other accesses the
+          external MIDI connector. Full MIDI read/write semantics
+          for both devices.
+* OSS-compliant /dev/sequencer interface for the WaveFront synth,
+          including native and GUS-format patch downloading.
+* semi-intelligent patch management (prototypical at this point)
+
+
+**********************************************************************
+1) What to do about MIDI interfaces ?
+**********************************************************************
+
+The Tropez Plus (and perhaps other WF cards) can in theory support up
+to 2 physical MIDI interfaces. One of these is connected to the
+ICS2115 chip (the WaveFront synth itself) and is controlled by
+MPU/UART-401 emulation code running as part of the WaveFront OS.  The
+other is controlled by the CS4232 chip present on the board. However,
+physical access to the CS4232 connector is difficult, and it is
+unlikely (though not impossible) that you will want to use it.
+
+An older version of this driver introduced an additional kernel config
+variable which controlled whether or not the CS4232 MIDI interface was
+configured. Because of Alan Cox's work on modularizing the sound
+drivers, and now backporting them to 2.0.34 kernels, there seems to be
+little reason to support "static" configuration variables, and so this
+has been abandoned in favor of *only* module parameters. Specifying
+"mpuio" and "mpuirq" for the cs4232 parameter will result in the
+CS4232 MIDI interface being configured; leaving them unspecified will
+leave it unconfigured (and thus unusable).
+
+BTW, I have heard from one Tropez+ user that the CS4232 interface is
+more reliable than the ICS2115 one. I have had no problems with the
+latter, and I don't have the right cable to test the former one
+out. Reports welcome.
+
+**********************************************************************
+2) Why does line XXX of the code look like this .... ?
+**********************************************************************
+
+Either because its not finished yet, or because you're a better coder
+than I am, or because you don't understand some aspect of how the card
+or the code works.
+
+I absolutely welcome comments, criticisms and suggestions about the
+design and implementation of the driver.
+
+**********************************************************************
+3) What files are included ?
+**********************************************************************
+
+   drivers/sound/README.wavefront       -- this file
+   drivers/sound/wavefront.patch        -- patches for the 2.1.106 sound driver
+s
+                                           needed to make the rest of this work
+   drivers/sound/wavfront.c             -- the driver
+   drivers/sound/ys225.h                -- data declarations for FX config
+   drivers/sound/ys225.c                -- data definitions for FX config
+   drivers/sound/wf_midi.c              -- the "uart401" driver
+                                              to support virtual MIDI mode.
+   include/wavefront.h                  -- the header file
+   Documentation/sound/Tropez+          -- short docs on configuration
+
+**********************************************************************
+4) How do I compile/install/use it ?
+**********************************************************************
+
+PART ONE: install the source code into your sound driver directory
+
+  cd <top-of-your-2.1.106-code-base-e.g.-/usr/src/linux>
+  tar -zxvf <where-you-put/wavefront.tar.gz>
+
+PART TWO: apply the patches
+
+  cd drivers/sound
+  patch < wavefront.patch
+
+PART THREE: configure your kernel
+
+  cd <top of your kernel tree>
+  make xconfig (or whichever config option you use)
+
+         - choose YES for Sound Support
+         - choose MODULE (M) for OSS Sound Modules
+         - choose MODULE(M) to Generic OPL2/OPL3 support
+         - choose MODULE(M) to YM3812/OPL3 support
+         - choose MODULE(M) for WaveFront support
+         - choose MODULE(M) for CS4232 support
+
+         - choose "N" for everything else (unless you have other
+              soundcards you want support for)
+
+
+   make dep
+   make boot
+   .
+   .
+   .
+   <whatever you normally do for a kernel install>
+   make modules
+   .
+   .
+   .
+   make modules_isntall
+
+Here's my autoconf.h SOUND section:
+
+/*
+ * Sound
+ */
+#define CONFIG_SOUND 1
+#undef  CONFIG_SOUND_OSS
+#define CONFIG_SOUND_OSS_MODULE 1
+#undef  CONFIG_SOUND_PAS
+#undef  CONFIG_SOUND_SB
+#undef  CONFIG_SOUND_ADLIB
+#define CONFIG_SOUND_ADLIB_MODULE 1
+#undef  CONFIG_SOUND_GUS
+#undef  CONFIG_SOUND_MPU401
+#undef  CONFIG_SOUND_PSS
+#undef  CONFIG_SOUND_MSS
+#undef  CONFIG_SOUND_SSCAPE
+#undef  CONFIG_SOUND_TRIX
+#undef  CONFIG_SOUND_MAD16
+#undef  CONFIG_SOUND_WAVEFRONT
+#define CONFIG_SOUND_WAVEFRONT_MODULE 1
+#undef  CONFIG_SOUND_CS4232
+#define CONFIG_SOUND_CS4232_MODULE 1
+#undef  CONFIG_SOUND_MAUI
+#undef  CONFIG_SOUND_SGALAXY
+#undef  CONFIG_SOUND_OPL3SA1
+#undef  CONFIG_SOUND_SOFTOSS
+#undef  CONFIG_SOUND_YM3812
+#define CONFIG_SOUND_YM3812_MODULE 1
+#undef  CONFIG_SOUND_VMIDI
+#undef  CONFIG_SOUND_UART6850
+/*
+ * Additional low level sound drivers
+ */
+#undef  CONFIG_LOWLEVEL_SOUND
+
+************************************************************
+6) How do I configure my card ?
+************************************************************
+
+You need to edit /etc/conf.modules. Here's mine (edited to show the
+relevant details):
+
+  # Sound system
+  alias char-major-14 wavefront
+  alias synth0 wavefront
+  alias mixer0 cs4232
+  pre-install wavefront modprobe "-k" "cs4232"
+  post-install wavefront modprobe "-k" "adlib_card"
+  options wavefront io=0x200 irq=9
+  options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
+  options adlib_card io=0x388
+
+Things to note:
+
+       the wavefront options "io" and "irq" ***MUST*** match the "synthio"
+       and "synthirq" cs4232 options.
+
+       you can do without the adlib_card module if you don't
+       want to use the OPL/[34] synth on the soundcard
+
+       the adlib_card io parameter is conventionally not adjustable.
+       In theory, any not-in-use IO port address would work, but
+       just use 0x388 and stick with the crowd.
+
+**********************************************************************
+7) What about firmware ?
+**********************************************************************
+
+Turtle Beach have not given me permission to distribute their firmware
+for the ICS2115. However, if you have a WaveFront card, then you
+almost certainly have the firmware, and if not, its freely available
+on their website, at:
+
+   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus
+
+The file is called WFOS2001.MOT (for the Tropez+).
+
+This driver, however, doesn't use the pure firmware as distributed,
+but instead relies on a somewhat processed form of it. You can
+generate this very easily. Following an idea from Andrew Veliath's
+Pinnacle driver, the following flex program will generate the
+processed version:
+
+---- cut here -------------------------
+%option main
+%%
+^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext);
+<<EOF>> { fputc ('\0', stdout); return; }
+\n {}
+.  {}
+---- cut here -------------------------
+
+To use it, put the above in file (say, ws.l) compile it like this:
+
+      shell> flex -ows.c ws.l
+      shell> cc -o ws ws.c
+
+and then use it like this:
+
+    ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os
+
+If you put it somewhere else, you'll always have to use the wf_ospath
+module parameter (see below) or alter the source code.
+
+**********************************************************************
+7) How do I get it working ?
+**********************************************************************
+
+Optionally, you can reboot with the "new" kernel (even though the only
+changes have really been made to a module).
+
+Then, as root do:
+
+     modprobe wavefront
+
+You should get something like this, directly if you're on a console, and in
+/var/log/messages:
+
+    WaveFront: firmware 1.20 already loaded.
+
+or
+
+    WaveFront: no response to firmware probe, assume raw.
+
+then:
+
+    WaveFront: waiting for memory configuration ...
+    WaveFront: hardware version 1.64
+    WaveFront: available DRAM 8191k
+    WaveFront: 332 samples used (266 real, 13 aliases, 53 multi), 180 empty
+    WaveFront: 128 programs slots in use
+    WaveFront: 256 patch slots filled, 142 in use
+
+The whole process takes about 16 seconds, the longest waits being
+after reporting the hardware version (during the firmware download),
+and after reporting program status (during patch status inquiry).  Its
+shorter (about 10 secs) if the firmware is already loaded (i.e. only
+warm reboots since the last firmware load).
+
+The "available DRAM" line will vary depending on how much added RAM
+your card has. Mine has 8MB.
+
+Next, check /dev/sndstat, which on my machine says:
+---------------------------------------------------------------------
+OSS/Free:3.8s2++-971130
+Load type: Driver loaded as a module
+Kernel: Linux bd 2.1.106 #12 SMP Fri Jul 3 00:37:34 EDT 1998 i486
+Config options: 0
+
+Installed drivers:
+
+Card config:
+
+Audio devices:
+0: Crystal audio controller (CS4232) (DUPLEX)
+
+Synth devices:
+0: Turtle Beach WaveFront
+1: Yamaha OPL-3
+
+Midi devices:
+0: WaveFront Internal MIDI
+1: WaveFront External MIDI
+
+Timers:
+0: System clock
+1: Crystal audio controller (CS4232)
+
+Mixers:
+0: Crystal audio controller (CS4232)
+-----------------------------------------------------------
+
+To check basically functionality, use play(1) or splay(1) to send a
+.WAV or other audio file through the audio portion. Then use playmidi
+to play a General MIDI file. Try the "-D 0" to hear the
+difference between sending MIDI to the WaveFront and using the OPL/3,
+which is the default (I think ...). If you have an external synth(s)
+hooked to the soundcard, you can use "-e" to route to the
+external synth(s) (in theory, -D 1 should work as well, but I think
+there is a bug in playmidi which prevents this from doing what it
+should).
+
+**********************************************************************
+8) What are the module parameters ?
+**********************************************************************
+
+Its best to read wavefront.c for this, but here is a summary:
+
+integers:
+          wf_raw  - if set, ignore apparent presence of firmware
+                    loaded onto the ICS2115, reset the whole
+                    board, and initialize it from scratch. (default = 0)
+
+          fx_raw  - if set, always initialize the YSS225 processor
+                    on the Tropez plus. (default = 1)
+
+          < The next 4 are basically for kernel hackers to allow
+            tweaking the driver for testing purposes. >
+
+          wf_short_wait_count - loop counter used when waiting for
+                                status conditions on the board. This
+                                is CPU-specific. After this many
+                                loops, the driver will sleep.
+                                The default is 5000. I have a 66Mhz 486.
+
+          wf_sleep_interval  - the driver sleeps for
+                               HZ/wf_sleep_interval seconds per sleep.
+                               The default is 50.
+
+          wf_sleep_tries  - the number of times the driver will sleep
+                            when waiting for a status condition on the
+                            board. The default is 100 (2 secs, if
+                            wf_sleep_interval is 50).
+
+          wf_debug_default - debugging flags. See sound/wavefront.h
+                             for WF_DEBUG_* values. Default is zero.
+                             Setting this allows you to debug the
+                             driver during module installation.
+strings:
+          wf_ospath - path to get to the pre-processed OS firmware.
+                    (default: /etc/sound/wavefront.os)
+
+**********************************************************************
+9) Who should I contact if I have problems?
+**********************************************************************
+
+Just me: Paul Barton-Davis <pbd@op.net>
+
+
+
index 15238d0d25492d35fb26f9c9ef16901def354bad..702819dcd61aae8350f782c7cfab1ebc2873bc34 100644 (file)
@@ -439,13 +439,15 @@ M:        emoenke@gwdg.de
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
-PARALLEL PORT SHARING SUPPORT
+PARALLEL PORT SUPPORT
 P:     Phil Blundell
 M:     Philip.Blundell@pobox.com
 P:     Tim Waugh
 M:     tim@cyberelk.demon.co.uk
 P:     David Campbell
-M:     campbell@tirian.che.curtin.edu.au
+M:     campbell@torque.net
+P:     Andrea Arcangeli
+M:     arcangeli@mbox.queen.it
 L:     linux-parport@torque.net
 L:     pnp-list@redhat.com
 W:     http://www.cyberelk.demon.co.uk/parport.html
index f66ace9a0be55d60cc8e47d4339dee8b849a69bc..3881287cd924cd525c869bdcc209e3616581d61b 100644 (file)
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(_writew);
 EXPORT_SYMBOL(_writel);
 EXPORT_SYMBOL(_memcpy_fromio);
 EXPORT_SYMBOL(_memcpy_toio);
-EXPORT_SYMBOL(_memset_c_io);
+EXPORT_SYMBOL(_memset_io);
 EXPORT_SYMBOL(insb);
 EXPORT_SYMBOL(insw);
 EXPORT_SYMBOL(insl);
@@ -87,7 +87,6 @@ EXPORT_SYMBOL(memcmp);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(__memsetw);
 EXPORT_SYMBOL(__constant_c_memset);
 
 EXPORT_SYMBOL(dump_thread);
index 344b6793b3b21ca97960d43ca74cd380dfeb4d9b..47f53a2f6cf2b2c47e449396426c77c9edaa5aa0 100644 (file)
@@ -1946,8 +1946,8 @@ static inline void sio_fixup(void)
 }
 
 
-void __init
-pcibios_fixup(void)
+__initfunc(void
+pcibios_fixup(void))
 {
          struct pci_bus *cur;
 
@@ -2022,6 +2022,12 @@ pcibios_fixup(void)
 }
 
 
+__initfunc(void
+pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
+
 asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn,
                                  unsigned long off, unsigned long len,
                                  unsigned char *buf)
index 29461afc05d44b67badfe8356bfc1254e0466080..e3cadff701244ab5dda0349a4dc91b1c16a2e177 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/io.h>
+##include <asm/smp.h>
 
 /*
  * BIOS32-style PCI interface:
index fa0d598d2f0e6beb8abb63b2d473888fcce26646..3d7cd05f807763bb76111225e58639f5b1364a11 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/malloc.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/hwrpb.h>
 #include <asm/io.h>
index ebf254c214d0958f583079d87c1e45fd2dcf6fe2..4e644a73292edc2c9a9614eeff07e33bb4a36132 100644 (file)
@@ -9,12 +9,12 @@
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/hwrpb.h>
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
 
-#include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
index 910c4fcf2b803eb1ef5a92aeba939677213c479b..201442d049422e6cd9e360f676a3d066b6fd7926 100644 (file)
@@ -21,6 +21,9 @@ ASFLAGS_PROC          :=
 
 ifeq ($(CONFIG_CPU_26),y)
   PROCESSOR             = armo
+  TEXTADDR              = 0x02080000
+  ZTEXTADDR             = 0x01800000
+  ZRELADDR              = 0x02080000
   ifeq ($(CONFIG_BINUTILS_NEW),y)
     CFLAGS_PROC                += -mapcs-26 -mshort-load-bytes
     ifeq ($(CONFIG_CPU_ARM2),y)
@@ -45,6 +48,7 @@ endif
 
 ifeq ($(CONFIG_CPU_32),y)
   PROCESSOR             = armv
+  TEXTADDR              = 0xC0008000
   ifeq ($(CONFIG_BINUTILS_NEW),y)
     CFLAGS_PROC                += -mapcs-32 -mshort-load-bytes
     ifeq ($(CONFIG_CPU_ARM6),y)
@@ -72,12 +76,6 @@ endif
 
 COMPRESSED_HEAD         = head.o
 
-ifeq ($(PROCESSOR),armo)
-TEXTADDR        = 0x02080000
-ZTEXTADDR       = 0x01800000
-ZRELADDR        = 0x02080000
-endif
-
 ifeq ($(CONFIG_ARCH_A5K),y)
 MACHINE                 = a5k
 ARCHDIR                 = arc
@@ -90,9 +88,6 @@ ARCHDIR                = arc
 COMPRESSED_EXTRA = $(TOPDIR)/arch/arm/lib/ll_char_wr.o
 endif
 
-ifeq ($(PROCESSOR),armv)
-TEXTADDR        = 0xC0008000
-
 ifeq ($(CONFIG_ARCH_RPC),y)
 MACHINE                 = rpc
 ARCHDIR                 = rpc
@@ -118,12 +113,22 @@ endif
 ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
 MACHINE                 = nexuspci
 ARCHDIR                 = nexuspci
-TEXTADDR        = 0xc0000000
 ZTEXTADDR       = 0x40200000
-ZRELADDR        = 0x40000000
+ZRELADDR        = 0x40008000
 COMPRESSED_EXTRA = $(TOPDIR)/arch/arm/lib/ll_char_wr_scc.o
 COMPRESSED_HEAD         = head-nexuspci.o
 endif
+
+ifeq ($(CONFIG_ARCH_VNC),y)
+MACHINE                 = vnc
+ARCHDIR                 = vnc
+endif
+
+ifeq ($(CONFIG_ARCH_TBOX),y)
+MACHINE                 = tbox
+ARCHDIR                 = tbox
+ZTEXTADDR       = 0x80008000
+ZRELDIR                 = 0x80008000
 endif
 
 PERL            = perl
@@ -144,23 +149,28 @@ CFLAGS            := $(CFLAGS:-fomit-frame-pointer=)
 endif
 CFLAGS         := $(CFLAGS_PROC) $(CFLAGS) -pipe
 ASFLAGS                := $(ASFLAGS_PROC) $(ASFLAGS)
-LINKFLAGS       = -T $(TOPDIR)/arch/arm/vmlinux.lds -e stext -Ttext $(TEXTADDR)
+LINKFLAGS       = -T $(TOPDIR)/arch/arm/vmlinux-$(PROCESSOR).lds -e stext -Ttext $(TEXTADDR)
 ZLINKFLAGS      = -Ttext $(ZTEXTADDR)
 
-SUBDIRS                := $(SUBDIRS:drivers=) arch/arm/lib arch/arm/kernel arch/arm/mm arch/arm/drivers
+SUBDIRS                := $(SUBDIRS:drivers=arch/arm/drivers) arch/arm/lib arch/arm/kernel arch/arm/mm
 HEAD           := arch/arm/kernel/head-$(PROCESSOR).o arch/arm/kernel/init_task.o
 CORE_FILES     := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
 LIBS           := arch/arm/lib/lib.a $(LIBS) $(GCCLIB)
 
 BLOCK_DRIVERS  := arch/arm/drivers/block/block.a
 CDROM_DRIVERS  := drivers/cdrom/cdrom.a
+ifeq ($(CONFIG_FB),y)
+CHAR_DRIVERS   := arch/arm/drivers/char1/char.a
+else
 CHAR_DRIVERS   := arch/arm/drivers/char/char.a
+endif
 MISC_DRIVERS   := drivers/misc/misc.a
 NET_DRIVERS    := drivers/net/net.a
 PARIDE_DRIVERS := drivers/block/paride/paride.a
 PCI_DRIVERS    := drivers/pci/pci.a
 SCSI_DRIVERS   := drivers/scsi/scsi.a
 SOUND_DRIVERS  := drivers/sound/sound.a
+VIDEO_DRIVERS  := drivers/video/video.a
 
 ifeq ($(CONFIG_ARCH_ACORN),y)
 BLOCK_DRIVERS  += drivers/acorn/block/acorn-block.a
@@ -171,6 +181,9 @@ endif
 
 DRIVERS                := $(BLOCK_DRIVERS) $(CHAR_DRIVERS) $(MISC_DRIVERS) $(NET_DRIVERS)
 
+ifeq ($(CONFIG_FB),y)
+DRIVERS                := $(DRIVERS) $(VIDEO_DRIVERS)
+endif
 ifeq ($(CONFIG_SCSI),y)
 DRIVERS                := $(DRIVERS) $(SCSI_DRIVERS)
 endif
@@ -192,7 +205,7 @@ symlinks::
        (cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc)
 
 # Once we've finished integrating the sources, the @$(MAKE) will disappear
-mrproper::
+archmrproper:
        rm -f include/asm-arm/arch include/asm-arm/proc
        @$(MAKE) -C arch/$(ARCH)/drivers mrproper
 
@@ -202,6 +215,9 @@ arch/arm/kernel: dummy
 arch/arm/mm: dummy
        $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm
 
+arch/arm/lib: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib
+
 MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
 
 zImage: vmlinux
@@ -226,8 +242,6 @@ archclean:
        @$(MAKEBOOT) clean
        $(RM) arch/arm/lib/constants.h
 
-archmrproper:
-
 archdep:
        @$(MAKEBOOT) dep
 sed -e /^MACHINE..*=/s,= .*,= rpc,;/^PROCESSOR..*=/s,= .*,= armv, linux/arch/arm/Makefile.normal
index 3c87b0569e975535e9f67d1e86c6328013220738..491a037b2973a44e0fad62920f6fa1bb2b0a7f04 100644 (file)
@@ -5,12 +5,19 @@
 #
 
 COMPRESSED_EXTRA=../../lib/ll_char_wr.o
-OBJECTS=misc-debug.o $(COMPRESSED_EXTRA)
+OBJECTS=misc-debug.o ll_char_wr.aout.o
 
 CFLAGS=-D__KERNEL__ -O2 -DSTDC_HEADERS -DSTANDALONE_DEBUG -Wall -I../../../../include -c
 
-test-gzip: piggy.o $(OBJECTS)
-       $(CC) -o $@ $(OBJECTS) piggy.o
+test-gzip: piggy.aout.o $(OBJECTS)
+       $(CC) -o $@ $(OBJECTS) piggy.aout.o
 
 misc-debug.o: misc.c
        $(CC) $(CFLAGS) -o $@ misc.c
+
+piggy.aout.o: piggy.o
+       arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux piggy.o piggy.aout.o
+
+ll_char_wr.aout.o: $(COMPRESSED_EXTRA)
+       arm-linuxelf-objcopy --change-leading-char -I elf32-arm -O arm-aout32-linux $(COMPRESSED_EXTRA) ll_char_wr.aout.o
+
index 92840fbdab09495809965715f0ea89a862375e1c..1fd49a95c1b59acb1538fa47b733ce966fd44a4c 100644 (file)
@@ -1,35 +1,32 @@
 /*
  * linux/arch/arm/boot/compressed/head-nexuspci.S
  *
- * Copyright (C) 1996 Philip Blundell
+ * Copyright (C) 1996, 1997, 1998 Philip Blundell
+ *
+ * NexusPCI is unusual because we don't have a bootloader -- the kernel is
+ * run directly out of ROM at the moment.  Maybe this will change one day and
+ * then this file can go away.
+ *
  */
 
-#define ARM_CP                 p15
-#define ARM610_REG_CONTROL     cr1
-#define ARM_REG_ZERO           cr0
-
                .text
 
-start:         b       skip1
-               b       go_uncompress
-               b       go_uncompress
-               b       go_uncompress
-               b       go_uncompress
+.globl _start
+_start:                b       reset
+               b       undefined
+               b       undefined
+               b       undefined
+               b       undefined
+               b       undefined
+               b       undefined
+               b       undefined
                b       go_uncompress
-               b       go_uncompress
-               b       go_uncompress
-               b       go_uncompress
-               b       go_uncompress
-skip1:         mov     sp, #0x40000000
-               add     sp, sp, #0x200000
-               mov     r2, #0x20000000
+       
+reset:         mov     r2, #0x20000000                 @ LED off
                mov     r1, #0x1a
                str     r1, [r2]
 
-               MOV     r0, #0x30
-               MCR     ARM_CP, 0, r0, ARM610_REG_CONTROL, ARM_REG_ZERO
-               
-               mov     r2, #0x10000000
+               mov     r2, #0x10000000                 @ SCC init
 
                mov     r1, #42
                strb    r1, [r2, #8]
@@ -57,37 +54,46 @@ skip1:              mov     sp, #0x40000000
                mov     r1, #5
                strb    r1, [r2, #0x8]
 
-               mov     r0, #0x50
+               ldr     r2, =_start
+               ldr     r3, =_edata
+               mov     r8, r2
+               mov     r0, #0
+1:
+               ldmia   r0!, {r4, r5, r6, r7}
+               stmia   r2!, {r4, r5, r6, r7}
+               cmp     r2, r3
+               ble     1b
+
+               ldr     r3, =_edata
+               ldr     r1, =_end
+               mov     r2, #0
+1:
+               strb    r2, [r3]
+               cmp     r3, r1
+               beq     2f
+               add     r3, r3, #1
+               b       1b
+2:     
+               add     pc, r8, #0x20
+
+undefined:     ldr     r4, =undef_msg
+1:             ldrb    r0, [r4], #1
+               movs    r0, r0
+2:             beq     2b
                bl      _ll_write_char
+               b       1b
 
-               mov     r4, #0x40000000
-               mov     r1, #0x00200000
-               add     r4, r4, r1
-copylp:
-               ldr     r3, [r1]
-               str     r3, [r4, r1]
-               subs    r1, r1, #4
-               bne     copylp
-
-               add     pc, r4, #0x28
-
+undef_msg:     .ascii  "Undefined instruction (or other problem)\000"
+               .align  4
 
 /*
  * Uncompress the kernel
  */
 go_uncompress:
-               mov     r0,   #0x40000000
-               add     r0, r0, #0x300000
-               bl      _decompress_kernel
-
-               mov     r0,   #0x40000000
-               add     r1, r0, #0x300000
-               mov     r2, #0x100000
-
-clp2:          ldr     r3, [r1, r2]
-               str     r3, [r0, r2]
-               subs    r2, r2, #4
-               bne     clp2
+               mov     r0, #0x40000000
+               ldr     sp, =user_stack
+               add     sp, sp, #4096
+               bl      decompress_kernel
 
                mov     r2, #0x40000000
                mov     r0, #0
index 98853511b64d578c082f64a6b2e8034d74df6a32..ab2541f3405c9f31937e7bba14fdca4215af2c3a 100644 (file)
@@ -20,7 +20,10 @@ start:               mov     r0, r0
                mov     r0, r0
                mov     r0, r0
                mov     r0, r0
-               teq     r0, #0
+               b       1f
+               .word   0x016f2818                      @ Magic numbers to help the loader
+               .word   _start  
+1:             teq     r0, #0
                beq     2f
                mov     r4, #0x02000000
                add     r4, r4, #0x7C000
@@ -59,11 +62,13 @@ start:              mov     r0, r0
  * Uncompress the kernel
  */
                mov     r1, #0x8000
-               add     r2, r2, r1, lsl #1      @ Add 64k for malloc
+               add     r3, r2, r1, lsl #1      @ Add 64k for malloc
                sub     r1, r1, #1
-               add     r2, r2, r1
-               bic     r5, r2, r1              @ decompress kernel to after end of the compressed
+               add     r3, r3, r1
+               bic     r5, r3, r1              @ decompress kernel to after end of the compressed
                mov     r0, r5
+               mov     r1, r2
+               mov     r2, r0
                bl      SYMBOL_NAME(decompress_kernel)
                add     r0, r0, #7
                bic     r2, r0, #7
index 181583b756963cdb6a3ede4f4ba6fd7a1d0835b8..ce2672911a22389e71c5fc965496933b8531a01e 100644 (file)
@@ -274,10 +274,10 @@ ulg user_stack [STACK_SIZE];
 
 #ifndef STANDALONE_DEBUG
 
-ulg decompress_kernel(ulg output_start)
+ulg decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p)
 {
-       free_mem_ptr = (ulg)&end;
-       free_mem_ptr_end = output_start;
+       free_mem_ptr = free_mem_ptr_p;
+       free_mem_ptr_end = free_mem_ptr_end_p;
 
        proc_decomp_setup ();
        arch_decomp_setup ();
index 5e587ffbf5ed5d828bf61926784eac6ce888e09d..fb4fd97e0d96808bfd000f89e56769f3cd6d8fa8 100644 (file)
@@ -172,7 +172,6 @@ CONFIG_PPP=m
 CONFIG_ETHER1=m
 CONFIG_ETHER3=m
 CONFIG_ETHERH=m
-CONFIG_CDROM=y
 
 #
 # Filesystems
index 1a4cc6a019ec3fd6edf88eff63928da3789d2018..5c2f1b502da4b0c56d8c9ddc9952aa2e4f2534c1 100644 (file)
@@ -5,10 +5,11 @@
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 
 #include <asm/ecard.h>
+#include <asm/elf.h>
 #include <asm/io.h>
-#include <asm/delay.h>
 #include <asm/dma.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -73,6 +74,9 @@ EXPORT_SYMBOL(ecard_readchunk);
 EXPORT_SYMBOL(ecard_address);
 #endif
 
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+
 /* processor dependencies */
 EXPORT_SYMBOL(processor);
 
@@ -100,26 +104,23 @@ EXPORT_SYMBOL(quicklists);
 EXPORT_SYMBOL(__bad_pmd);
 EXPORT_SYMBOL(__bad_pmd_kernel);
 
+#define EXPORT_VERS0(sym,orig) \
+ const char __kstrtab_##sym##[] __attribute__((section(".kstrtab"))) = \
+    __MODULE_STRING(##sym##_R00000000); \
+ const struct module_symbol __ksymtab_##sym __attribute__((section("__ksymtab"))) = \
+    { (unsigned long)&##orig, __kstrtab_##sym };
 /*
  * floating point math emulator support.
  * These symbols will never change their calling convention...
  */
-EXPORT_SYMBOL_NOVERS(fpreturn);
-EXPORT_SYMBOL_NOVERS(fpundefinstr);
-EXPORT_SYMBOL_NOVERS(fp_enter);
-EXPORT_SYMBOL_NOVERS(fp_save);
-EXPORT_SYMBOL_NOVERS(fp_restore);
-EXPORT_SYMBOL_NOVERS(fp_setup);
-
-const char __kstrtab_fp_printk[] __attribute__((section(".kstrtab"))) = __MODULE_STRING(fp_printk);
-const struct module_symbol __ksymtab_fp_printk __attribute__((section("__ksymtab"))) =
-{ (unsigned long)&printk, __kstrtab_fp_printk };
-
-const char __kstrtab_fp_send_sig[] __attribute__((section(".kstrtab"))) = __MODULE_STRING(fp_send_sig);
-const struct module_symbol __ksymtab_fp_send_sig __attribute__((section("__ksymtab"))) =
-{ (unsigned long)&send_sig, __kstrtab_fp_send_sig };
-
-//EXPORT_SYMBOL_NOVERS(fp_current);
+EXPORT_VERS0(fpreturn,fpreturn);
+EXPORT_VERS0(fpundefinstr,fpundefinstr);
+EXPORT_VERS0(fp_enter,fp_enter);
+EXPORT_VERS0(fp_save,fp_save);
+EXPORT_VERS0(fp_restore,fp_restore);
+EXPORT_VERS0(fp_setup,fp_setup);
+EXPORT_VERS0(fp_printk,printk);
+EXPORT_VERS0(fp_send_sig,send_sig);
 
        /*
         * string / mem functions
@@ -183,3 +184,8 @@ EXPORT_SYMBOL(change_bit);
 EXPORT_SYMBOL(test_and_change_bit);
 EXPORT_SYMBOL(find_first_zero_bit);
 EXPORT_SYMBOL(find_next_zero_bit);
+
+       /* elf */
+EXPORT_SYMBOL(armidlist);
+EXPORT_SYMBOL(armidindex);
+EXPORT_SYMBOL(elf_platform);
index fd3ed5a4fdc8655377e208d8a1be4a52c39f1645..751f9616a1441642198cd01b1ddec16d4dfbf844 100644 (file)
@@ -1,11 +1,12 @@
 /*
  * linux/arch/arm/lib/calls.h
  *
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This file is included twice in entry-common.S
  */
-#ifndef NR_SYSCALLS
+#ifndef NR_syscalls
 #define NR_syscalls 256
-#define NR_SYSCALLS 184
 #else
 
 /* 0 */                .long   SYMBOL_NAME(sys_setup)
@@ -24,7 +25,7 @@
                .long   SYMBOL_NAME(sys_time)
                .long   SYMBOL_NAME(sys_mknod)
 /* 15 */       .long   SYMBOL_NAME(sys_chmod)
-               .long   SYMBOL_NAME(sys_chown)
+               .long   SYMBOL_NAME(sys_lchown)
                .long   SYMBOL_NAME(sys_ni_syscall)             /* was sys_break */
                .long   SYMBOL_NAME(sys_stat)
                .long   SYMBOL_NAME(sys_lseek)
                .long   SYMBOL_NAME(sys_rt_sigsuspend_wrapper)
 /* 180 */      .long   SYMBOL_NAME(sys_pread)
                .long   SYMBOL_NAME(sys_pwrite)
-#if 0
-               .long   SYMBOL_NAME(sys_xstat)
-               .long   SYMBOL_NAME(sys_xmknod)
-#else
-               .space  8
-#endif
-               .space  (NR_syscalls - 184) * 4
+               .long   SYMBOL_NAME(sys_chown)
+               .long   SYMBOL_NAME(sys_getcwd)
+               .long   SYMBOL_NAME(sys_capget)
+/* 185 */      .long   SYMBOL_NAME(sys_capset)
+               .long   SYMBOL_NAME(sys_sigaltstack_wrapper)
+
+               .rept   NR_syscalls-186
+                       .long   SYMBOL_NAME(sys_ni_syscall)
+               .endr
 #endif
index 5a9f4e51b03fa2a22186a1c07700fa14fb4bf8c2..b041252f6ea8b4477c80e597e5cde4474b8c6bcc 100644 (file)
@@ -109,6 +109,7 @@ __initfunc(void pcibios_fixup(void))
 {
        struct pci_dev *dev;
        unsigned char pin;
+       unsigned int cmd;
 
        for (dev = pci_devices; dev; dev = dev->next) {
                pcibios_read_config_byte(dev->bus->number,
@@ -127,6 +128,10 @@ __initfunc(void pcibios_fixup(void))
                        dev->bus->number, dev->devfn,
                        dev->vendor, dev->device,
                        pin, dev->irq);
+
+               /* Turn on bus mastering - boot loader doesn't - perhaps it should! */
+               pcibios_read_config_byte(dev->bus->number, dev->devfn, PCI_COMMAND, &cmd);
+               pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);
        }
 }
 
@@ -138,6 +143,10 @@ __initfunc(void pcibios_init(void))
        printk("DEC21285 PCI revision %02X\n", rev);
 }
 
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
 __initfunc(char *pcibios_setup(char *str))
 {
        return str;
index cfb601240a6d765c297e86a75446daea459a2470..50ee4243566ca97e57f087d37e49733296a237fe 100644 (file)
@@ -9,12 +9,15 @@
 #include <linux/init.h>
 
 #include <asm/dma.h>
+#include <asm/fiq.h>
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/pgtable.h>
 
 #include "dma.h"
 
+static struct fiq_handler fh = { "floppydma", NULL };
+
 int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id)
 {
        if (channel == DMA_VIRTUAL_FLOPPY)
@@ -26,13 +29,13 @@ int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id)
 void arch_free_dma(dmach_t channel, dma_t *dma)
 {
        if (channel != DMA_VIRTUAL_FLOPPY)
-               printk ("arch_free_dma: invalid channel %d\n", channel);
+               printk("arch_free_dma: invalid channel %d\n", channel);
 }
 
 int arch_get_dma_residue(dmach_t channel, dma_t *dma)
 {
        if (channel != DMA_VIRTUAL_FLOPPY)
-               printk ("arch_dma_count: invalid channel %d\n", channel);
+               printk("arch_dma_count: invalid channel %d\n", channel);
        else {
                extern int floppy_fiqresidual(void);
                return floppy_fiqresidual();
@@ -43,11 +46,11 @@ int arch_get_dma_residue(dmach_t channel, dma_t *dma)
 void arch_enable_dma(dmach_t channel, dma_t *dma)
 {
        if (channel != DMA_VIRTUAL_FLOPPY)
-               printk ("arch_enable_dma: invalid channel %d\n", channel);
+               printk("arch_enable_dma: invalid channel %d\n", channel);
        else {
                void *fiqhandler_start;
                unsigned int fiqhandler_length;
-               extern void floppy_fiqsetup (unsigned long len, unsigned long addr,
+               extern void floppy_fiqsetup(unsigned long len, unsigned long addr,
                                             unsigned long port);
 
                if (dma->dma_mode == DMA_MODE_READ) {
@@ -59,19 +62,25 @@ void arch_enable_dma(dmach_t channel, dma_t *dma)
                        fiqhandler_start = &floppy_fiqout_start;
                        fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
                }
-               memcpy ((void *)0x1c, fiqhandler_start, fiqhandler_length);
+               if (claim_fiq(&fh)) {
+                       printk("floppydma: couldn't claim FIQ.\n");
+                       return;
+               }
+               memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
                flush_page_to_ram(0);
-               floppy_fiqsetup (dma->buf.length, __bus_to_virt(dma->buf.address), (int)PCIO_FLOPPYDMABASE);
-               enable_irq (dma->dma_irq);
+               floppy_fiqsetup(dma->buf.length, __bus_to_virt(dma->buf.address), (int)PCIO_FLOPPYDMABASE);
+               enable_irq(dma->dma_irq);
        }
 }
 
 void arch_disable_dma(dmach_t channel, dma_t *dma)
 {
        if (channel != DMA_VIRTUAL_FLOPPY)
-               printk ("arch_disable_dma: invalid channel %d\n", channel);
-       else
-               disable_irq (dma->dma_irq);
+               printk("arch_disable_dma: invalid channel %d\n", channel);
+       else {
+               disable_irq(dma->dma_irq);
+               release_fiq(&fh);
+       }
 }
 
 __initfunc(void arch_dma_init(dma_t *dma))
index eb5bc87d766798851e55060117c79dd6fe9368cd..301b3207163c888bbec10a0e23f20d522d8ed9b6 100644 (file)
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/dma.h>
+#include <asm/fiq.h>
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/uaccess.h>
 
 #include "dma.h"
 
+static struct fiq_handler fh = { "floppydma", NULL };
+
 #if 0
 typedef enum {
        dma_size_8      = 1,
@@ -270,6 +273,10 @@ void arch_enable_dma(dmach_t channel, dma_t *dma)
                        fiqhandler_start = &floppy_fiqout_start;
                        fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
                }
+               if (claim_fiq(&fh)) {
+                       printk("floppydma: couldn't claim FIQ.\n");
+                       return;
+               }
                /* Allow access to page 0 via domains */
                __asm__ __volatile__("mcr       p15, 0, %0, c3, c0" :
                                        : "r" (DOMAIN_USER_MANAGER |
index 3b568b5ecfd56ac30e95014a5b91419c91106aae..a7553d35041066d2edca963c9feeb2a696db88b5 100644 (file)
@@ -9,12 +9,13 @@
  * Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
  * it to save wrong values...  Be aware!
  */
-#include <linux/config.h> /* for CONFIG_ARCH_EBSA110 */
+#include <linux/config.h> /* for CONFIG_ARCH_xxxx */
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
 #include <asm/errno.h>
 #include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 
 #include "../lib/constants.h"
 
@@ -89,7 +90,7 @@
                adreq   \base, irq_prio_l
 
                teq     \irqstat, #0
-               ldrneb  \irqnr, [r5, \irqstat]          @ get IRQ number
+               ldrneb  \irqnr, [\base, \irqstat]       @ get IRQ number
                .endm
 
 /*
@@ -159,7 +160,7 @@ irq_prio_h: .byte    0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
                adr     \base, irq_prio_ebsa110
 
                teq     \irqstat, #0
-               ldrneb  \irqnr, [r5, \irqstat]          @ get IRQ number
+               ldrneb  \irqnr, [\base, \irqstat]       @ get IRQ number
                .endm
 
                .macro  irq_prio_table
@@ -225,6 +226,65 @@ irq_prio_ebsa110:
                .macro  irq_prio_table
                .endm
 
+#elif defined(CONFIG_ARCH_VNC)
+
+               .macro  disable_fiq
+               .endm
+
+               .macro  get_irqnr_and_base, irqnr, irqstat, base
+               mov     r4, #IO_BASE_ARM_CSR
+               ldr     \irqstat, [r4, #IRQ_STATUS]     @ just show us the unmasked ones
+
+               @ run through hard priorities
+               @ timer
+               tst     \irqstat, #IRQ_MASK_TIMER0
+               movne   \irqnr, #IRQ_TIMER0
+               bne     1f
+
+               @ ether10
+               tst     \irqstat, #IRQ_MASK_ETHER10
+               movne   \irqnr, #IRQ_ETHER10
+               bne     1f
+
+               @ ether100
+               tst     \irqstat, #IRQ_MASK_ETHER100
+               movne   \irqnr, #IRQ_ETHER100
+               bne     1f
+
+               @ video compressor
+               tst     \irqstat, #IRQ_VIDCOMP_MASK
+               movne   \irqnr, #IRQ_VIDCOMP
+               bne     1f
+
+               @ now try all the PIC sources
+               @ determine whether we have an irq
+               tst     \irqstat, #IRQ_MASK_EXTERN_IRQ
+               beq     3f
+               mov     r4, #(IO_BASE_PCI_IACK & 0xff000000)
+               orr     r4, r4, #(IO_BASE_PCI_IACK & 0x00ff0000)
+               ldrb    \irqnr, [r4]                    @ get the IACK byte
+               b       1f
+
+3:             @ PCI errors
+               tst     \irqstat, #IRQ_MASK_PCI_ERR
+               movne   \irqnr, #IRQ_PCI_ERR
+               bne     1f
+
+               @ softint
+               tst     \irqstat, #IRQ_MASK_SOFT_IRQ
+               movne   \irqnr, #IRQ_SOFT_IRQ
+               bne     1f
+
+               @ debug uart
+               tst     \irqstat, #IRQ_MASK_UART_DEBUG
+               movne   \irqnr, #IRQ_UART_DEBUG
+               bne     1f
+
+               @ watchdog
+               tst     \irqstat, #IRQ_WATCHDOG_MASK
+               movne   \irqnr, #IRQ_WATCHDOG
+
+1:             @ If Z is set, then we will not enter an interrupt
 #else
 #error Unknown architecture
 #endif
index c7d6a41f69d9475380cc37b4f97788686672f0a9..42232633872faeb778c38ace002507b3a83f634f 100644 (file)
@@ -73,7 +73,7 @@ vector_swi:   save_user_regs
                
                bic     r6, r6, #0xff000000     @ mask off SWI op-code
                eor     r6, r6, #OS_NUMBER<<20  @ check OS number
-               cmp     r6, #NR_SYSCALLS        @ check upper syscall limit
+               cmp     r6, #NR_syscalls        @ check upper syscall limit
                bcs     2f
 
                get_current_task r5
@@ -133,7 +133,7 @@ vector_swi: save_user_regs
 SYMBOL_NAME(sys_syscall):
                mov     r6, r0
                eor     r6, r6, #OS_NUMBER << 20
-               cmp     r6, #NR_SYSCALLS                @ check range
+               cmp     r6, #NR_syscalls                @ check range
                movgt   r0, #-ENOSYS
                movgt   pc, lr
                add     sp, sp, #4                      @ take of the save of our r4
@@ -193,6 +193,10 @@ sys_rt_sigreturn_wrapper:
                add     r0, sp, #4
                b       SYMBOL_NAME(sys_rt_sigreturn)
 
+sys_sigaltstack_wrapper:
+               ldr     r2, [sp, #4 + S_SP]
+               b       do_sigaltstack
+
 /*
  *=============================================================================
  *             Low-level interface code
index be1a69f248aae7244e2ed46152ec1ef8d7816c44..2219d37c3d29c95c09ff40450ef4bed92fb3e27d 100644 (file)
  * MMU off.  Note! These should be unique!!! Please read Documentation/ARM-README
  * for more information.
  *
- *  r1 = 0 -> ebsa110  (Ram @ 0x00000000)
- *  r1 = 1 -> RPC      (Ram @ 0x10000000)
- *  r1 = 2 -> ebsit    (???)
+ *  r1 = 0 -> ebsa110
+ *  r1 = 1 -> RPC
+ *  r1 = 2 -> ebsit
  *  r1 = 3 -> nexuspci
- *  r1 = 4 -> ebsa285  (Ram @ 0x00000000)
+ *  r1 = 4 -> ebsa285
+ *  r1 = 5 -> vnc
+ *  r1 = 6 -> CATS
  */
 ENTRY(stext)
 ENTRY(_stext)
 __entry:
                teq     r0, #0                                  @ check for illegal entry...
                bne     .Lerror                                 @ loop indefinitely
-               cmp     r1, #5                                  @ Unknown machine architecture
+               cmp     r1, #7                                  @ Unknown machine architecture
                bge     .Lerror
 @
 @ First thing to do is to get the page tables set up so that we can call the kernel
@@ -119,7 +121,8 @@ __entry:
                                                                @ we lose this page!
                mov     pc, lr
 
-.Lerror:       mov     r0, #0x02000000
+.Lerror:
+1:             mov     r0, #0x02000000
                mov     r1, #0x11
                orr     r1, r1, r1, lsl #8
                orr     r1, r1, r1, lsl #16
@@ -127,7 +130,7 @@ __entry:
                str     r1, [r0], #4
                str     r1, [r0], #4
                str     r1, [r0], #4
-               b       .Lerror
+               b       1b
 
 .Lbranch:      .long   .Lalready_done_mmap                     @ Real address of routine
 
@@ -156,12 +159,22 @@ __entry:
                .long   0
 
                @ EBSA285
-               .long   SYMBOL_NAME(swapper_pg_dir) - 0xc0000000        @ Address of page tables (physical)
+               .long   SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
                .long   0                                       @ Address of RAM
                .long   0x24000000                              @ I/O base address (0x42000000 -> 0xFE000000)
                .long   0
 
+               @ Corel VNC
+               .long   SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
+               .long   0                                       @ Address of RAM
+               .long   0x24000000                              @ I/O base address (0x42000000 -> 0xfe000000)
+               .long   0
 
+               @ CATS
+               .long   SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical)
+               .long   0                                       @ Address of RAM
+               .long   0x24000000                              @ I/O base address (0x42000000 -> 0xfe000000)
+               .long   0
 
 .LCProcTypes:  @ ARM6 / 610
                .long   0x41560600
@@ -170,13 +183,20 @@ __entry:
                b       .Larmv3_flush_early                     @ arm v3 flush & ctrl early setup
                mov     pc, lr
 
-               @ ARM7 / 710
+               @ ARM7
                .long   0x41007000
                .long   0xfffff000
                .long   0x00000c12
                b       .Larmv3_flush_late                      @ arm v3 flush & ctrl late setup
                mov     pc, lr
 
+               @ ARM710
+               .long   0x41007000
+               .long   0xfff8f000                              @ arm710 processors are weird
+               .long   0x00000c12
+               b       .Larmv3_flush_late                      @ arm v3 flush & ctrl late setup
+               mov     pc, lr
+
                @ StrongARM
                .long   0x4401a100
                .long   0xfffffff0
@@ -267,6 +287,7 @@ __entry:
                .macro  busyuart,rd,rx
 1002:          ldrb    \rd, [\rx, #0x14]
                and     \rd, \rd, #0x60
+               teq     \rd, #0x60
                bne     1002b
                .endm
 
@@ -289,6 +310,7 @@ __entry:
                .macro  busyuart,rd,rx
 1002:          ldrb    \rd, [\rx, #0x14]
                and     \rd, \rd, #0x60
+               teq     \rd, #0x60
                bne     1002b
                .endm
 
@@ -298,7 +320,7 @@ __entry:
                beq     1001b
                .endm
 
-#elif defined(CONFIG_ARCH_EBSA285)
+#elif defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_VNC)
                .macro  addruart,rx
                mov     \rx, #0xfe000000
                .endm
index 10a25e01b5050e9887a6cb1271691c9d0871e605..6eb0122e892e1d7dbabcd1819d29b28aaf5d2c8c 100644 (file)
@@ -6,8 +6,9 @@
  * IIC is used to get the current time from the CMOS rtc.
  */
 
+#include <linux/delay.h>
+
 #include <asm/system.h>
-#include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/hardware.h>
 
index 1dde0e0ba3481711692c9e89808afa6614e4aaff..89116048e2b3d74277ee4c551ed0d704aaaf8ed0 100644 (file)
@@ -2,7 +2,8 @@
  *  linux/arch/arm/kernel/irq.c
  *
  *  Copyright (C) 1992 Linus Torvalds
- *  Modifications for ARM processor Copyright (C) 1995, 1996 Russell King.
+ *  Modifications for ARM processor Copyright (C) 1995-1998 Russell King.
+ *  FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
  *
  * This file contains the code used by various IRQ handling routines:
  * asking for different IRQ's should be done through these routines
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 
+#include <asm/fiq.h>
+#include <asm/hardware.h>
 #include <asm/io.h>
+#include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/hardware.h>
 #include <asm/arch/irq.h>
 
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 spinlock_t irq_controller_lock;
+static struct fiq_handler *current_fiq;
+static unsigned long no_fiq_insn;
+
+#define FIQ_VECTOR ((unsigned long *)0x1c)
 
 #ifndef SMP
 #define irq_enter(cpu, irq)    (++local_irq_count[cpu])
@@ -46,6 +53,20 @@ spinlock_t irq_controller_lock;
 #error SMP not supported
 #endif
 
+#ifdef CONFIG_ARCH_ACORN
+/* Bitmask indicating valid interrupt numbers
+ * (to be moved to include/asm-arm/arch-*)
+ */
+unsigned long validirqs[NR_IRQS / 32] = {
+       0x003ffe7f,     0x000001ff,     0x000000ff,     0x00000000
+};
+
+#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31)))
+#else
+
+#define valid_irq(x) ((x) < NR_IRQS)
+#endif
+
 void disable_irq(unsigned int irq_nr)
 {
        unsigned long flags;
@@ -74,21 +95,6 @@ void enable_irq(unsigned int irq_nr)
 
 struct irqaction *irq_action[NR_IRQS];
 
-#ifdef CONFIG_ARCH_ACORN
-/* Bitmask indicating valid interrupt numbers
- * (to be moved to include/asm-arm/arch-*)
- */
-unsigned long validirqs[NR_IRQS / 32] = {
-       0x003ffe7f,     0x000001ff,     0x000000ff,     0x00000000
-};
-
-#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31)))
-#else
-
-#define valid_irq(x) ((x) < NR_IRQS)
-
-#endif
-
 int get_irq_list(char *buf)
 {
        int i;
@@ -106,6 +112,8 @@ int get_irq_list(char *buf)
                }
                *p++ = '\n';
        }
+       p += sprintf(p, "FIQ:              %s\n",
+                    current_fiq?current_fiq->name:"unused");
        return p - buf;
 }
 
@@ -186,7 +194,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
        }
 }
 
-#if defined(HAS_IOMD) || defined(HAS_IOC)
+#if defined(CONFIG_ARCH_ACORN)
 void do_ecard_IRQ(int irq, struct pt_regs *regs)
 {
        struct irqaction * action;
@@ -336,9 +344,41 @@ int probe_irq_off (unsigned long irqs)
        return i;
 }
 
+int claim_fiq(struct fiq_handler *f)
+{
+       if (current_fiq) {
+               if (current_fiq->callback == NULL || (*current_fiq->callback)())
+                       return -EBUSY;
+       }
+       current_fiq = f;
+       return 0;
+}
+
+void release_fiq(struct fiq_handler *f)
+{
+       if (current_fiq != f) {
+               printk(KERN_ERR "%s tried to release FIQ when not owner!\n",
+                      f->name);
+#ifdef CONFIG_DEBUG_ERRORS
+               __backtrace();
+#endif
+               return;
+       }
+       current_fiq = NULL;
+
+       *FIQ_VECTOR = no_fiq_insn;
+       __flush_entry_to_ram(FIQ_VECTOR);
+}
+
 __initfunc(void init_IRQ(void))
 {
        extern void init_dma(void);
+
        irq_init_irq();
+
+       current_fiq = NULL;
+       no_fiq_insn = *FIQ_VECTOR;
+
        init_dma();
 }
+
index 796556a8cf9d6c28e2f5d528f1047bbb03fffe9e..a6f1edf8bc7ea9b4357f705d5086e66ee05159f5 100644 (file)
@@ -38,6 +38,8 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
+struct task_struct *last_task_used_math;
+
 extern void fpe_save(struct fp_soft_struct *);
 extern char *processor_modes[];
 
@@ -171,18 +173,10 @@ void flush_thread(void)
        current->flags &= ~PF_USEDFPU;
 }
 
-void release_segments(struct mm_struct *mm)
-{
-}
-
 void release_thread(struct task_struct *dead_task)
 {
 }
 
-void copy_segments(int nr, struct task_struct *p, struct mm_struct *new_mm)
-{
-}
-
 int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        struct task_struct * p, struct pt_regs * regs)
 {
index 1381e516736d7c7034822a35cfc76e288227000d..2da4d632764ae02c58fd06d30027797849c35b35 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/major.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
+#include <linux/console.h>
 
 #include <asm/hardware.h>
 #include <asm/pgtable.h>
@@ -58,7 +59,7 @@ int armidindex;
 extern int root_mountflags;
 extern int _etext, _edata, _end;
 
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
+static char command_line[COMMAND_LINE_SIZE] __initdata = { 0, };
        char saved_command_line[COMMAND_LINE_SIZE];
 
 #ifdef CONFIG_BLK_DEV_RAM
@@ -164,6 +165,10 @@ __initfunc(void setup_arch(char **cmdline_p,
        *memory_start_p = memory_start;
        *memory_end_p = memory_end;
        strcpy (system_utsname.machine, "sa110");
+
+#ifdef CONFIG_FB
+       conswitchp = &fb_con;
+#endif
 }
 
 int get_cpuinfo(char * buffer)
index 605996cec76a6d0832a20cf4ec4714f0939f2f53..b69ce22cbb38cd470c9565f454b2d1d3505a9695 100644 (file)
@@ -27,7 +27,9 @@
 #include <linux/utsname.h>
 #include <linux/blk.h>
 #include <linux/init.h>
+#include <linux/console.h>
 
+#include <asm/elf.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -38,7 +40,9 @@
 #include <asm/arch/mmu.h>
 
 struct drive_info_struct { char dummy[32]; } drive_info;
-struct screen_info screen_info;
+struct screen_info screen_info = {
+  0, 0,  0,  0, 0, 0,  0,  0,  0,  0, 1, 8
+};
 struct processor processor;
 unsigned char aux_device_present;
 
@@ -49,27 +53,39 @@ extern const struct processor arm6_processor_functions;
 extern const struct processor arm7_processor_functions;
 extern const struct processor sa110_processor_functions;
 
-struct armversions armidlist[] = {
+char elf_platform[ELF_PLATFORM_SIZE];
+
+const struct armversions armidlist[] = {
+  /*-- Match -- --- Mask -- -- Manu --  Processor  uname -m   --- ELF STUFF ---
+       --- processor asm funcs --- */
 #if defined(CONFIG_CPU_26)
-       { 0x41560200, 0xfffffff0, F_MEMC        , "ARM/VLSI",   "arm2"          , &arm2_processor_functions   , "arm2"},
-       { 0x41560250, 0xfffffff0, F_MEMC        , "ARM/VLSI",   "arm250"        , &arm250_processor_functions , "arm3"},
-       { 0x41560300, 0xfffffff0, F_MEMC|F_CACHE, "ARM/VLSI",   "arm3"          , &arm3_processor_functions   , "arm3"},
+  { 0x41560200, 0xfffffff0, "ARM/VLSI",        "arm2"   , "armv1"  , "v1", 0,
+       &arm2_processor_functions   },
+  { 0x41560250, 0xfffffff0, "ARM/VLSI",        "arm250" , "armv2"  , "v2", HWCAP_SWP,
+       &arm250_processor_functions },
+  { 0x41560300, 0xfffffff0, "ARM/VLSI",        "arm3"   , "armv2"  , "v2", HWCAP_SWP,
+       &arm3_processor_functions   },
 #elif defined(CONFIG_CPU_32)
-       { 0x41560600, 0xfffffff0, F_MMU|F_32BIT , "ARM/VLSI",   "arm6"          , &arm6_processor_functions   , "arm6"},
-       { 0x41560610, 0xfffffff0, F_MMU|F_32BIT , "ARM/VLSI",   "arm610"        , &arm6_processor_functions   , "arm6"},
-       { 0x41007000, 0xffffff00, F_MMU|F_32BIT , "ARM/VLSI",   "arm7"          , &arm7_processor_functions   , "arm6"},
-       { 0x41007100, 0xffffff00, F_MMU|F_32BIT , "ARM/VLSI",   "arm710"        , &arm7_processor_functions   , "arm6"},
-       { 0x4401a100, 0xfffffff0, F_MMU|F_32BIT , "DEC",        "sa110"         , &sa110_processor_functions  , "sa1x"},
+  { 0x41560600, 0xfffffff0, "ARM/VLSI",        "arm6"   , "armv3"  , "v3", HWCAP_SWP,
+       &arm6_processor_functions   },
+  { 0x41560610, 0xfffffff0, "ARM/VLSI",        "arm610" , "armv3"  , "v3", HWCAP_SWP,
+       &arm6_processor_functions   },
+  { 0x41007000, 0xffffff00, "ARM/VLSI",        "arm7"   , "armv3"  , "v3", HWCAP_SWP,
+       &arm7_processor_functions   },
+  /* ARM710 IDs are non-standard */
+  { 0x41007100, 0xfff8ff00, "ARM/VLSI",        "arm710" , "armv3"  , "v3", HWCAP_SWP,
+       &arm7_processor_functions   },
+  { 0x4401a100, 0xfffffff0, "DEC",     "sa110"  , "armv4"  , "v3", HWCAP_SWP|HWCAP_HALF,
+       &sa110_processor_functions  },
 #endif
-       { 0x00000000, 0x00000000, 0             , "***",        "*unknown*"     , NULL                        , NULL  }
+  { 0x00000000, 0x00000000, "***", "unknown", "unknown", "**", 0, NULL }
 };
 
-static struct param_struct *params = (struct param_struct *)PARAMS_BASE;
+static const struct param_struct *params = (struct param_struct *)PARAMS_BASE;
 
 unsigned long arm_id;
 unsigned int vram_half_sam;
 int armidindex;
-int ioebpresent;
 int memc_ctrl_reg;
 int number_ide_drives;
 int number_mfm_drives;
@@ -91,9 +107,11 @@ extern unsigned long real_end_mem;
  */
 #ifdef CONFIG_ARCH_RPC
 
-extern void init_dram_banks(struct param_struct *params);
+extern void
+init_dram_banks(const struct param_struct *params);
 
-static void setup_rpc (struct param_struct *params)
+static void
+setup_rpc(const struct param_struct *params)
 {
        init_dram_banks(params);
 
@@ -123,11 +141,12 @@ extern int rd_doload;             /* 1 = load ramdisk, 0 = don't load */
 extern int rd_prompt;          /* 1 = prompt for ramdisk, 0 = don't prompt */
 extern int rd_image_start;     /* starting block # of image */
 
-static void setup_ramdisk (struct param_struct *params)
+static void
+setup_ramdisk(const struct param_struct *params)
 {
-    rd_image_start     = params->u1.s.rd_start;
-    rd_prompt          = (params->u1.s.flags & FLAG_RDPROMPT) == 0;
-    rd_doload          = (params->u1.s.flags & FLAG_RDLOAD) == 0;
+       rd_image_start  = params->u1.s.rd_start;
+       rd_prompt       = (params->u1.s.flags & FLAG_RDPROMPT) == 0;
+       rd_doload       = (params->u1.s.flags & FLAG_RDLOAD) == 0;
 }
 #else
 #define setup_ramdisk(p)
@@ -137,33 +156,30 @@ static void setup_ramdisk (struct param_struct *params)
  * initial ram disk
  */
 #ifdef CONFIG_BLK_DEV_INITRD
-static void setup_initrd (struct param_struct *params, unsigned long memory_end)
+static void
+setup_initrd(const struct param_struct *params, unsigned long memory_end)
 {
-    initrd_start = params->u1.s.initrd_start;
-    initrd_end   = params->u1.s.initrd_start + params->u1.s.initrd_size;
-
-    if (initrd_end > memory_end) {
-       printk ("initrd extends beyond end of memory "
-               "(0x%08lx > 0x%08lx) - disabling initrd\n",
-               initrd_end, memory_end);
-       initrd_start = 0;
-    }
-}
-#else
-#define setup_initrd(p,m)
-#endif
+       if (params->u1.s.initrd_start) {
+               initrd_start = params->u1.s.initrd_start;
+               initrd_end   = initrd_start + params->u1.s.initrd_size;
+       } else {
+               initrd_start = 0;
+               initrd_end   = 0;
+       }
 
-#ifdef IOEB_BASE
-static inline void check_ioeb_present(void)
-{
-       if (((*IOEB_BASE) & 15) == 5)
-               armidlist[armidindex].features |= F_IOEB;
+       if (initrd_end > memory_end) {
+               printk ("initrd extends beyond end of memory "
+                       "(0x%08lx > 0x%08lx) - disabling initrd\n",
+                       initrd_end, memory_end);
+               initrd_start = 0;
+       }
 }
 #else
-#define check_ioeb_present()
+#define setup_initrd(p,m)
 #endif
 
-static inline void get_processor_type (void)
+static inline void
+get_processor_type(void)
 {
        for (armidindex = 0; ; armidindex ++)
                if (!((armidlist[armidindex].id ^ arm_id) &
@@ -186,7 +202,7 @@ static inline void get_processor_type (void)
 /* Can this be initdata?  --pb
  *  command_line can be, saved_command_line can't though
  */
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
+static char command_line[COMMAND_LINE_SIZE] __initdata = { 0, };
        char saved_command_line[COMMAND_LINE_SIZE];
 
 __initfunc(void setup_arch(char **cmdline_p,
@@ -194,7 +210,8 @@ __initfunc(void setup_arch(char **cmdline_p,
 {
        static unsigned char smptrap;
        unsigned long memory_start, memory_end;
-       char c = ' ', *to = command_line, *from;
+       char endian = 'l', c = ' ', *to = command_line;
+       char *from;
        int len = 0;
 
        if (smptrap == 1)
@@ -202,12 +219,13 @@ __initfunc(void setup_arch(char **cmdline_p,
        smptrap = 1;
 
        get_processor_type ();
-       check_ioeb_present ();
        processor._proc_init ();
 
+#ifndef CONFIG_FB
        bytes_per_char_h  = params->u1.s.bytes_per_char_h;
        bytes_per_char_v  = params->u1.s.bytes_per_char_v;
-       from              = params->commandline;
+#endif
+       from              = (char *)params->commandline;
        ROOT_DEV          = to_kdev_t (params->u1.s.rootdev);
        ORIG_X            = params->u1.s.video_x;
        ORIG_Y            = params->u1.s.video_y;
@@ -217,8 +235,8 @@ __initfunc(void setup_arch(char **cmdline_p,
        number_ide_drives = (params->u1.s.adfsdrives >> 6) & 3;
        number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
 
-       setup_rpc (params);
-       setup_ramdisk (params);
+       setup_rpc(params);
+       setup_ramdisk(params);
 
        if (!(params->u1.s.flags & FLAG_READONLY))
                root_mountflags &= ~MS_RDONLY;
@@ -264,36 +282,73 @@ __initfunc(void setup_arch(char **cmdline_p,
        *memory_start_p = memory_start;
        *memory_end_p = memory_end;
 
-       setup_initrd (params, memory_end);
+       setup_initrd(params, memory_end);
+
+       sprintf(system_utsname.machine, "%s%c", armidlist[armidindex].arch_vsn, endian);
+       sprintf(elf_platform, "%s%c", armidlist[armidindex].elf_vsn, endian);
 
-       strcpy (system_utsname.machine, armidlist[armidindex].name);
+#ifdef CONFIG_FB
+       conswitchp = &fb_con;
+#endif
 }
 
-#define ISSET(bit) (armidlist[armidindex].features & bit)
+#if defined(CONFIG_ARCH_ARC)
+#define HARDWARE "Acorn-Archimedes"
+#define IO_BUS  "Acorn"
+#elif defined(CONFIG_ARCH_A5K)
+#define HARDWARE "Acorn-A5000"
+#define IO_BUS  "Acorn"
+#elif defined(CONFIG_ARCH_RPC)
+#define HARDWARE "Acorn-RiscPC"
+#define IO_BUS  "Acorn"
+#elif defined(CONFIG_ARCH_EBSA110)
+#define HARDWARE "DEC-EBSA110"
+#define IO_BUS  "DEC"
+#elif defined(CONFIG_ARCH_EBSA285)
+#define HARDWARE "DEC-EBSA285"
+#define IO_BUS   "PCI"
+#elif defined(CONFIG_ARCH_NEXUSPCI)
+#define HARDWARE "Nexus-NexusPCI"
+#define IO_BUS   "PCI"
+#elif defined(CONFIG_ARCH_VNC)
+#define HARDWARE "Corel-VNC"
+#define IO_BUS   "PCI"
+#else
+#define HARDWARE "unknown"
+#define IO_BUS   "unknown"
+#endif
+
+#if defined(CONFIG_CPU_ARM2)
+#define OPTIMISATION "ARM2"
+#elif defined(CONFIG_CPU_ARM3)
+#define OPTIMISATION "ARM3"
+#elif defined(CONFIG_CPU_ARM6)
+#define OPTIMISATION "ARM6"
+#elif defined(CONFIG_CPU_ARM7)
+#define OPTIMISATION "ARM7"
+#elif defined(CONFIG_CPU_SA110)
+#define OPTIMISATION "StrongARM"
+#else
+#define OPTIMISATION "unknown"
+#endif
 
 int get_cpuinfo(char * buffer)
 {
        int len;
 
-       len = sprintf (buffer,  "CPU:\n"
-                               "Type\t\t: %s\n"
-                               "Revision\t: %d\n"
-                               "Manufacturer\t: %s\n"
-                               "32bit modes\t: %s\n"
-                               "BogoMips\t: %lu.%02lu\n",
-                               armidlist[armidindex].name,
-                               (int)arm_id & 15,
-                               armidlist[armidindex].manu,
-                               ISSET (F_32BIT) ? "yes" : "no",
-                               (loops_per_sec+2500) / 500000,
-                               ((loops_per_sec+2500) / 5000) % 100);
-       len += sprintf (buffer + len,
-                               "\nHardware:\n"
-                               "Mem System\t: %s\n"
-                               "IOEB\t\t: %s\n",
-                               ISSET(F_MEMC)  ? "MEMC" : 
-                               ISSET(F_MMU)   ? "MMU"  : "*unknown*",
-                               ISSET(F_IOEB)  ? "present" : "absent"
-                               );
+       len = sprintf(buffer,
+               "Processor\t: %s %s rev %d\n"
+               "BogoMips\t: %lu.%02lu\n"
+               "Hardware\t: %s\n"
+               "Optimisation\t: %s\n"
+               "IO Bus\t: %s\n",
+               armidlist[armidindex].manu,
+               armidlist[armidindex].name,
+               (int)arm_id & 15,
+               (loops_per_sec+2500) / 500000,
+               ((loops_per_sec+2500) / 5000) % 100,
+               HARDWARE,
+               OPTIMISATION,
+               IO_BUS);
        return len;
 }
index eabd5f75edcbbdb211c07bc2221054fa309d760f..59e802a6ce63ff05948152477f4862195a02c9ee 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (C) 1995, 1996 Russell King
  */
 
-#include <linux/config.h> /* for CONFIG_CPU_ARM6 and CONFIG_CPU_SA110 */
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -37,7 +37,6 @@ extern int ptrace_set_bpt (struct task_struct *);
  */
 asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
 {
-
        sigset_t saveset;
 
        mask &= _BLOCKABLE;
index 6c13eaaf130c07c615822506ab649216317ccff0..ba0d4eda21cc0eabcfb9d1fa76fd7115078b2e38 100644 (file)
@@ -239,7 +239,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct
        lock_kernel();
        if (!newsp)
                newsp = regs->ARM_sp;
-
        ret = do_fork(clone_flags, newsp, regs);
        unlock_kernel();
        return ret;
index 1f598e14dd9ed063c6ebf66c2559109c956313ef..32aa6a083808e5278841ddb084fc00d83becd43d 100644 (file)
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/delay.h>
 
 #include <linux/timex.h>
 #include <asm/hardware.h>
index ad9dc7c471a23b90794fc6e09a2e83632845299b..2170dfd589569f3e4d00afd84eaac82324553cbc 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/atomic.h>
 #include <asm/pgtable.h>
 
+extern struct task_struct *last_task_used_math;
 extern void fpe_save(struct fp_soft_struct *);
 extern void fpe_restore(struct fp_soft_struct *);
 extern void die_if_kernel(char *str, struct pt_regs *regs, int err, int ret);
@@ -306,7 +307,7 @@ asmlinkage void arm_syscall (int no, struct pt_regs *regs)
 
 asmlinkage void deferred(int n, struct pt_regs *regs)
 {
-       dump_state("old system call", regs, 0);
+       dump_state("old system call", regs, n);
        force_sig (SIGILL, current);
 }
 
index b6bd196cf73ed5f90e09d62cf544d226881a4465..5d0974ab3f707d6d8a85083ca75e999de41f2f36 100644 (file)
@@ -6,7 +6,7 @@
 
 L_TARGET := lib.a
 L_OBJS   := backtrace.o bitops.o checksum.o delay.o fp_support.o \
-           loaders.o memcpy.o system.o string.o uaccess.o
+           loaders.o memcpy.o system.o string.o uaccess.o io.o
 
 ifeq ($(PROCESSOR),armo)
   L_OBJS += uaccess-armo.o
index 71484c2fdb3cc880cc6b41a0f858481499cfc50c..8c96b3f28993d6a2630f24f53380f9acb4cef519 100644 (file)
@@ -24,7 +24,7 @@ while (<DATA>) {
        /elf32/ && ( $elf = 1 );
        /a.out/ && ( $aout = 1 );
        next if ($aout && ! / 07 /);
-       next if ($elf && ! (/^00...... g/ && /.data/));
+       next if ($elf && ! (/^0*0...... g/ && /.data/));
        next if (!$aout && !$elf);
 
        if ($aout) {
@@ -33,7 +33,7 @@ while (<DATA>) {
        }
        if ($elf) {
                chomp;
-               $addr = substr ($_, 0, 8);
+               $addr = substr ($_, 0, index($_, " "));
                $name = substr ($_, rindex($_, " ") + 1);
                $nam[hex($addr)] = $name;
        }
diff --git a/arch/arm/lib/getconstants.c b/arch/arm/lib/getconstants.c
deleted file mode 100644 (file)
index edb67a5..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * linux/arch/arm/lib/getconstants.c
- *
- * Copyright (C) 1995, 1996 Russell King
- */
-
-#include <linux/mm.h>
-#include <asm/pgtable.h>
-#include <stdio.h>
-#include <linux/unistd.h>
-
-void printdef(char *def, int no)
-{
-       printf("#define %s\t%d\n", def, no);
-}
-
-#include "getconstants.h"
-
-int main()
-{
-       printf("/*\n *  contants.h generated by getconstants\n * DO NOT EDIT!\n */\n");
-
-       printf("#define _current\t_%s\n", "current_set");
-
-#ifdef _PAGE_PRESENT
-       printdef("PAGE_PRESENT",        _PAGE_PRESENT);
-#endif
-#ifdef _PAGE_RW
-       printdef("PAGE_RW",             _PAGE_RW);
-#endif
-#ifdef _PAGE_USER
-       printdef("PAGE_USER",           _PAGE_USER);
-#endif
-#ifdef _PAGE_ACCESSED
-       printdef("PAGE_ACCESSED",       _PAGE_ACCESSED);
-#endif
-#ifdef _PAGE_DIRTY
-       printdef("PAGE_DIRTY",          _PAGE_DIRTY);
-#endif
-#ifdef _PAGE_READONLY
-       printdef("PAGE_READONLY",       _PAGE_READONLY);
-#endif
-#ifdef _PAGE_NOT_USER
-       printdef("PAGE_NOT_USER",       _PAGE_NOT_USER);
-#endif
-#ifdef _PAGE_OLD
-       printdef("PAGE_OLD",            _PAGE_OLD);
-#endif
-#ifdef _PAGE_CLEAN
-       printdef("PAGE_CLEAN",          _PAGE_CLEAN);
-#endif
-       printdef("TSS_MEMMAP",          (int)tss_memmap);
-       printdef("TSS_SAVE",            (int)tss_save);
-#ifdef __HAS_tss_memcmap
-       printdef("TSS_MEMCMAP",         (int)tss_memcmap);
-#endif
-#ifdef __HAS_addr_limit
-       printdef("ADDR_LIMIT",          (int)addr_limit);
-#endif
-#ifdef __HAS_kernel_domain
-       printdef("KERNEL_DOMAIN",       kernel_domain);
-#endif
-#ifdef __HAS_user_domain
-       printdef("USER_DOMAIN",         user_domain);
-#endif
-       printdef("TSS_FPESAVE",         (int)tss_fpesave);
-       printdef("MM",                  (int)mm);
-       printdef("PGD",                 (int)pgd);
-
-       printf("#define KSWI_BASE       0x900000\n");
-       printf("#define KSWI_SYS_BASE   0x9F0000\n");
-       printf("#define SYS_ERROR0      0x9F0000\n");
-       return 0;
-}
diff --git a/arch/arm/lib/getconstants.h b/arch/arm/lib/getconstants.h
deleted file mode 100644 (file)
index ef96377..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * *** THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT! ***
- */
-unsigned long addr_limit = 56;
-#define __HAS_addr_limit
-unsigned long tss_memmap = 640;
-#define __HAS_tss_memmap
-unsigned long mm = 1676;
-#define __HAS_mm
-unsigned long pgd = 8;
-#define __HAS_pgd
-unsigned long tss_save = 636;
-#define __HAS_tss_save
-unsigned long tss_fpesave = 492;
-#define __HAS_tss_fpesave
-unsigned long tss_memcmap = 644;
-#define __HAS_tss_memcmap
index 6d4bf1b6717d965675ba5d595687b1b421221387..0ee1e37fc59c1d121c14279b7b66a63fbbda3d70 100644 (file)
@@ -97,12 +97,50 @@ ENTRY(outsl)
                bne     4b
                mov     pc, lr
 
+               /* Nobody could say these are optimal, but not to worry. */
 
-ENTRY(outsw)
 ENTRY(outswb)
+               mov     r2, r2, lsr #1
+ENTRY(outsw)
+               add     r0, r0, #0xff000000
+               add     r0, r0, #0x00e00000
+1:             teq     r2, #0
+               ldrneh  r3, [r1], #2
+               strneh  r3, [r0]
+               subne   r2, r2, #1
+               bne     1b
                mov     pc, lr
 
-ENTRY(insw)
 ENTRY(inswb)
+               mov     r2, r2, lsr #1
+ENTRY(insw)
+               add     r0, r0, #0xff000000
+               add     r0, r0, #0x00e00000
+1:             teq     r2, #0
+               ldrneh  r3, [r0]
+               strneh  r3, [r1], #2
+               subne   r2, r2, #1
+               bne     1b
                mov     pc, lr
 
+
+ENTRY(insb)
+               add     r0, r0, #0xff000000
+               add     r0, r0, #0x00e00000
+1:             teq     r2, #0
+               ldrneb  r3, [r0]
+               strneb  r3, [r1], #1
+               subne   r2, r2, #1
+               bne     1b
+               mov     pc, lr
+
+
+ENTRY(outsb)
+               add     r0, r0, #0xff000000
+               add     r0, r0, #0x00e00000
+1:             teq     r2, #0
+               ldrneb  r3, [r1], #1
+               strneb  r3, [r0]
+               subne   r2, r2, #1
+               bne     1b
+               mov     pc, lr
diff --git a/arch/arm/lib/io.c b/arch/arm/lib/io.c
new file mode 100644 (file)
index 0000000..ba2f9ef
--- /dev/null
@@ -0,0 +1,43 @@
+#include <asm/io.h>
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_fromio(void * to, unsigned long from, unsigned long count)
+{
+       while (count) {
+               count--;
+               *(char *) to = readb(from);
+               ((char *) to)++;
+               from++;
+       }
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_toio(unsigned long to, void * from, unsigned long count)
+{
+       while (count) {
+               count--;
+               writeb(*(char *) from, to);
+               ((char *) from)++;
+               to++;
+       }
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void _memset_io(unsigned long dst, int c, unsigned long count)
+{
+       while (count) {
+               count--;
+               writeb(c, dst);
+               dst++;
+       }
+}
+
index d4e2860c8bc3163ef56a384193f97260a6083df3..9959eacb6e2c8e086c62c4d80b626b3a1665e4ee 100644 (file)
@@ -28,8 +28,6 @@
 #define FAULT_CODE_WRITE       0x02
 #define FAULT_CODE_USER                0x01
 
-#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
-
 struct pgtable_cache_struct quicklists;
 
 void __bad_pmd(pmd_t *pmd)
diff --git a/arch/arm/mm/mm-a5k.c b/arch/arm/mm/mm-a5k.c
deleted file mode 100644 (file)
index 3906a29..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * arch/arm/mm/mm-a5k.c
- *
- * Extra MM routines for the Archimedes architecture
- *
- * Copyright (C) 1998 Russell King
- */
index ce93e2081f8c27d8b8cee72ea3b68d13276b3a11..6bb92f037f06adc13e1a58f039f49d4666ad1000 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1998 Russell King
  */
+#include <linux/init.h>
 #include <asm/hardware.h>
 #include <asm/pgtable.h>
 
@@ -13,7 +14,7 @@ unsigned long phys_screen_end;
 /*
  * This routine needs more work to make it dynamically release/allocate mem!
  */
-unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update)
+__initfunc(unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update))
 {
        static int updated = 0;
 
@@ -75,8 +76,7 @@ unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int up
 
                phys_screen_end = offset;
                flush_tlb_all ();
-               update_mm_cache_all ();
+               update_memc_all ();
        }
        return kmem;
 }
-
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
new file mode 100644 (file)
index 0000000..b229e89
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/mm/mm-armv.c
+ *
+ * Common routines for ARM v3 and v4 architectures.
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * Do not compile this file directly!
+ */
+
+#ifndef MAPPING
+#error MAPPING not defined - do not compile this file individually
+#endif
+
+static const struct mapping {
+       unsigned long virtual;
+       unsigned long physical;
+       unsigned long length;
+       int domain:4,
+           prot_read:1,
+           prot_write:1;
+} mapping[] __initdata = {
+       MAPPING
+};
+
+#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
+
+__initfunc(unsigned long setup_io_pagetables(unsigned long start_mem))
+{
+       const struct mapping *mp;
+       int i;
+
+       for (i = 0, mp = mapping; i < SIZEOFMAP; i++, mp++) {
+               unsigned long virtual, physical, length;
+               int prot;
+
+               virtual = mp->virtual;
+               physical = mp->physical;
+               length = mp->length;
+               prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0);
+
+               while ((virtual & 1048575 || physical & 1048575) && length >= PAGE_SIZE) {
+                       alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
+                       length -= PAGE_SIZE;
+                       virtual += PAGE_SIZE;
+                       physical += PAGE_SIZE;
+               }
+
+               prot = (mp->prot_read ? PMD_SECT_AP_READ : 0) |
+                      (mp->prot_write ? PMD_SECT_AP_WRITE : 0);
+
+               while (length >= 1048576) {
+                       alloc_init_section(&start_mem, virtual, physical, mp->domain, prot);
+                       length -= 1048576;
+                       virtual += 1048576;
+                       physical += 1048576;
+               }
+
+               prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0);
+
+               while (length >= PAGE_SIZE) {
+                       alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
+                       length -= PAGE_SIZE;
+                       virtual += PAGE_SIZE;
+                       physical += PAGE_SIZE;
+               }
+       }
+
+       return start_mem;
+}
+
index a937e098d8509abe118e879efff4d8c41654e4d8..90865e0b672d14ce45b658c47e2c71f3a2e6e642 100644 (file)
@@ -1,26 +1,15 @@
 /*
  * arch/arm/mm/mm-ebsa110.c
  *
- * Extra MM routines for the Archimedes architecture
+ * Extra MM routines for the EBSA-110 architecture
  *
  * Copyright (C) 1998 Russell King
  */
-
+#include <linux/init.h>
 #include <asm/io.h>
  
-/* map in IO */
-void setup_io_pagetables(void)
-{
-       unsigned long address = IO_START;
-       int spi = IO_BASE >> PGDIR_SHIFT;
-
-       pgd_val(swapper_pg_dir[spi-1]) = 0xc0000000 | PMD_TYPE_SECT |
-                                        PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_AP_WRITE;
+#define MAPPING \
+       { IO_BASE - PGDIR_SIZE  , 0xc0000000    , PGDIR_SIZE    , DOMAIN_IO, 0, 1 }, \
+       { IO_BASE               , IO_START      , IO_SIZE       , DOMAIN_IO, 0, 1 }
 
-       while (address < IO_START + IO_SIZE && address) {
-               pgd_val(swapper_pg_dir[spi++]) = address | PMD_TYPE_SECT |
-                                               PMD_DOMAIN(DOMAIN_IO) |
-                                               PMD_SECT_AP_WRITE;
-               address += PGDIR_SIZE;
-       }
-}
+#include "mm-armv.c"
index eb5d7152ae2b61e37e73e326eaed015a1ce110c3..ec635b1e73df1590319f0c23fc617ad2b6d8b9db 100644 (file)
@@ -3,16 +3,47 @@
  *
  * Extra MM routines for the EBSA285 architecture
  *
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Russell King, Dave Gilbert.
  */
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/init.h>
  
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/io.h>
 #include <asm/proc/mm-init.h>
+
+/*
+ * These two functions convert PCI bus addresses to virtual addresses
+ * and back again.
+ */ 
+unsigned long __virt_to_bus(unsigned long res)
+{
+       if (res < PAGE_OFFSET || res >= 0xD0000000) {
+               printk("__virt_to_bus: invalid address 0x%08lx\n", res);
+#ifdef CONFIG_DEBUG_ERRORS
+               __backtrace();
+#endif
+       } else
+               res = (res - PAGE_OFFSET) + 0x10000000;
+
+       return res;
+}
+
+unsigned long __bus_to_virt(unsigned long res)
+{
+       if (res < 0x10000000 || res >= 0x20000000) {
+               printk("__bus_to_virt: invalid address 0x%08lx\n", res);
+#ifdef CONFIG_DEBUG_ERRORS
+               __backtrace();
+#endif
+       } else
+               res = (res - 0x10000000) + PAGE_OFFSET;
+
+       return res;
+}
+
 /*    Logical    Physical
  * 0xfff00000  0x40000000      X-Bus
  * 0xffe00000  0x7c000000      PCI I/O space
  * 0xf8000000  0x7b000000      PCI Config type 0
  */
 
-static struct mapping {
-       unsigned long virtual;
-       unsigned long physical;
-       unsigned long length;
-} io_mapping[] = {
-       /*
-        * This is to allow us to fiddle with the EEPROM
-        *  This entry will go away in time
-        */
-       { 0xd8000000, 0x41000000, 0x00400000 },
-
-       /*
-        * These ones are so that we can fiddle
-        *  with the various cards (eg VGA)
-        *  until we're happy with them...
-        */
-       { 0xdc000000, 0x7c000000, 0x00100000 },
-       { 0xe0000000, 0x80000000, 0x10000000 },
-
-       { 0xf8000000, 0x7b000000, 0x01000000 }, /* Type 0 Config */
-
-       { 0xf9000000, 0x7a000000, 0x01000000 }, /* Type 1 Config */
-
-       { 0xfc000000, 0x79000000, 0x01000000 }, /* PCI IACK      */
-       { 0xfd000000, 0x78000000, 0x01000000 }, /* Outbound wflsh*/
-       { 0xfe000000, 0x42000000, 0x01000000 }, /* CSR           */
-       { 0xffe00000, 0x7c000000, 0x00100000 }, /* PCI I/O       */
-       { 0xfff00000, 0x40000000, 0x00100000 }, /* X-Bus         */
-};
-
-#define SIZEOFIO (sizeof(io_mapping) / sizeof(io_mapping[0]))
-
-/* map in IO */
-unsigned long setup_io_pagetables(unsigned long start_mem)
-{
-       struct mapping *mp;
-       int i;
-
-       for (i = 0, mp = io_mapping; i < SIZEOFIO; i++, mp++) {
-               while ((mp->virtual & 1048575 || mp->physical & 1048575) && mp->length >= PAGE_SIZE) {
-                       alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO,
-                                       PTE_AP_WRITE);
-
-                       mp->length -= PAGE_SIZE;
-                       mp->virtual += PAGE_SIZE;
-                       mp->physical += PAGE_SIZE;
-               }
-
-               while (mp->length >= 1048576) {
-if (mp->virtual > 0xf0000000)
-                       alloc_init_section(&start_mem, mp->virtual, mp->physical, DOMAIN_IO,
-                                          PMD_SECT_AP_WRITE);
-else
-alloc_init_section(&start_mem, mp->virtual, mp->physical, DOMAIN_USER, PMD_SECT_AP_WRITE | PMD_SECT_AP_READ);
-
-                       mp->length -= 1048576;
-                       mp->virtual += 1048576;
-                       mp->physical += 1048576;
-               }
-
-               while (mp->length >= PAGE_SIZE) {
-                       alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO,
-                                       PTE_AP_WRITE);
-
-                       mp->length -= PAGE_SIZE;
-                       mp->virtual += PAGE_SIZE;
-                       mp->physical += PAGE_SIZE;
-               }
-       }
-       return start_mem;
-}
+/*
+ * This is to allow us to fiddle with the EEPROM
+ *  This entry will go away in time, once the fmu
+ *  can mmap() the flash.
+ *
+ * These ones are so that we can fiddle
+ *  with the various cards (eg VGA)
+ *  until we're happy with them...
+ */
+#define MAPPING \
+       { 0xd8000000, 0x41000000, 0x00400000, DOMAIN_USER, 1, 1 },      /* EEPROM */        \
+       { 0xdc000000, 0x7c000000, 0x00100000, DOMAIN_USER, 1, 1 },      /* VGA */           \
+       { 0xe0000000, 0x80000000, 0x10000000, DOMAIN_USER, 1, 1 },      /* VGA */           \
+       { 0xf8000000, 0x7b000000, 0x01000000, DOMAIN_IO  , 0, 1 },      /* Type 0 Config */ \
+       { 0xf9000000, 0x7a000000, 0x01000000, DOMAIN_IO  , 0, 1 },      /* Type 1 Config */ \
+       { 0xfc000000, 0x79000000, 0x01000000, DOMAIN_IO  , 0, 1 },      /* PCI IACK      */ \
+       { 0xfd000000, 0x78000000, 0x01000000, DOMAIN_IO  , 0, 1 },      /* Outbound wflsh*/ \
+       { 0xfe000000, 0x42000000, 0x01000000, DOMAIN_IO  , 0, 1 },      /* CSR           */ \
+       { 0xffe00000, 0x7c000000, 0x00100000, DOMAIN_IO  , 0, 1 },      /* PCI I/O       */ \
+       { 0xfff00000, 0x40000000, 0x00100000, DOMAIN_IO  , 0, 1 },      /* X-Bus         */
 
+#include "mm-armv.c"
index 2bb2d0fabc81687d1f646150bbc49e2c266feec4..a7407c13082e28a7f5ed7d5265fe1ea1ec822115 100644 (file)
@@ -4,25 +4,24 @@
  *
  * Extra MM routines for the NexusPCI architecture
  *
+ * Copyright (C) 1998 Phil Blundell
  * Copyright (C) 1998 Russell King
  */
 
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
 #include <asm/io.h>
+#include <asm/proc/mm-init.h>
  
-/* map in IO */
-void setup_io_pagetables(void)
-{
-       unsigned long address = IO_START;
-       int spi = IO_BASE >> PGDIR_SHIFT;
-
-       pgd_val(swapper_pg_dir[spi-1]) = 0xc0000000 | PMD_TYPE_SECT |
-                                        PMD_DOMAIN(DOMAIN_KERNEL) | PMD_SECT_AP_WRITE;
-
-       while (address < IO_START + IO_SIZE && address) {
-               pgd_val(swapper_pg_dir[spi++]) = address | PMD_TYPE_SECT |
-                                               PMD_DOMAIN(DOMAIN_IO) |
-                                               PMD_SECT_AP_WRITE;
-               address += PGDIR_SIZE;
-       }
-}
+#define MAPPING                                                                \
+       { 0xfff00000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffe00000, 0x20000000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffc00000, 0x60000000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xfe000000, 0x80000000, 0x00100000, DOMAIN_IO, 0, 1 },        \
+       { 0xfd000000, 0x88000000, 0x00100000, DOMAIN_IO, 0, 1 }
 
+#include "mm-armv.c"
index f789b8f7970a29e28551d6e81fe730e9b92f4f8c..573a89b90814d00e61c520567ac3e5fa402f4aed 100644 (file)
@@ -5,9 +5,9 @@
  *
  * Copyright (C) 1998 Russell King
  */
-
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/init.h>
 
 #include <asm/pgtable.h>
 #include <asm/setup.h>
@@ -88,50 +88,10 @@ void init_dram_banks(struct param_struct *params)
        current->tss.memmap = __virt_to_phys((unsigned long)swapper_pg_dir);
 }
 
-static struct mapping {
-       unsigned long virtual;
-       unsigned long physical;
-       unsigned long length;
-} io_mapping[] = {
-       { SCREEN2_BASE, SCREEN_START,   2*1048576       },      /* VRAM         */
-       { IO_BASE,      IO_START,       IO_SIZE         }       /* IO space     */
-};
-
-#define SIZEOFIO (sizeof(io_mapping) / sizeof(io_mapping[0]))
-
-/* map in IO */
-unsigned long setup_io_pagetables(unsigned long start_mem)
-{
-       struct mapping *mp;
-       int i;
-
-       for (i = 0, mp = io_mapping; i < SIZEOFIO; i++, mp++) {
-               while ((mp->virtual & 1048575 || mp->physical & 1048575) && mp->length >= PAGE_SIZE) {
-                       alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO,
-                                       PTE_AP_WRITE);
-
-                       mp->length -= PAGE_SIZE;
-                       mp->virtual += PAGE_SIZE;
-                       mp->physical += PAGE_SIZE;
-               }
-
-               while (mp->length >= 1048576) {
-                       alloc_init_section(&start_mem, mp->virtual, mp->physical, DOMAIN_IO,
-                                          PMD_SECT_AP_WRITE);
-                       mp->length -= 1048576;
-                       mp->virtual += 1048576;
-                       mp->physical += 1048576;
-               }
-
-               while (mp->length >= PAGE_SIZE) {
-                       alloc_init_page(&start_mem, mp->virtual, mp->physical, DOMAIN_IO,
-                                       PTE_AP_WRITE);
-
-                       mp->length -= PAGE_SIZE;
-                       mp->virtual += PAGE_SIZE;
-                       mp->physical += PAGE_SIZE;
-               }
-       }
-
-       return start_mem;
-}
+#define MAPPING \
+       { SCREEN2_BASE, SCREEN_START,   2*1048576, DOMAIN_IO, 0, 1 },   /* VRAM         */ \
+       { IO_BASE,      IO_START,       IO_SIZE  , DOMAIN_IO, 0, 1 }    /* IO space     */
+/*
+ * Include common routine to set up page tables
+ */
+#include "mm-armv.c"
diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c
new file mode 100644 (file)
index 0000000..2cc5cc9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * arch/arm/mm/mm-tbox.c
+ *  from arch/arm/mm/mm-ebsa110.c
+ *
+ * Extra MM routines for the Tbox architecture
+ *
+ * Copyright (C) 1998 Phil Blundell
+ * Copyright (C) 1998 Russell King
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/proc/mm-init.h>
+/*    Logical    Physical
+ * 0xffff1000  0x00100000      DMA registers
+ * 0xffff2000  0x00200000      MPEG
+ * 0xffff3000  0x00300000      FPGA1 local control
+ * 0xffff4000  0x00400000      External serial
+ * 0xffff5000  0x00500000      Internal serial
+ * 0xffff6000  0x00600000      Parallel
+ * 0xffff7000  0x00700000      Interrupt control
+ * 0xffff8000  0x00800000      Computer video
+ * 0xffff9000  0x00900000      Control register 0
+ * 0xffffs000  0x00a00000      Control register 1
+ * 0xffffb000  0x00b00000      Control register 2
+ * 0xffffc000  0x00c00000      FPGA2 local control
+ * 0xffffd000  0x00d00000      Interrupt reset
+ * 0xffffe000  0x00e00000      MPEG DMA throttle
+ */
+#define MAPPING                                                                \
+       { 0xffff0000, 0x01000000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff1000, 0x00100000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff2000, 0x00200000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff3000, 0x00300000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff4000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xfe000000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff5000, 0x00500000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff6000, 0x00600000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff7000, 0x00700000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff8000, 0x00800000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffff9000, 0x00900000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffffa000, 0x00a00000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffffb000, 0x00b00000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffffc000, 0x00c00000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffffd000, 0x00d00000, 0x00001000, DOMAIN_IO, 0, 1 },        \
+       { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1 }
+
+#include "mm-armv.c"
diff --git a/arch/arm/mm/mm-vnc.c b/arch/arm/mm/mm-vnc.c
new file mode 100644 (file)
index 0000000..eed49eb
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mm/mm-vnc.c
+ *
+ * Extra MM routines for the Corel VNC architecture
+ *
+ * Copyright (C) 1998 Russell King
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/proc/mm-init.h>
+
+/* Table describing the MMU translation mapping
+ * mainly used to set up the I/O mappings.
+ */ 
+#define MAPPING \
+  { 0xe0000000, DC21285_PCI_IO,                      0x00100000, DOMAIN_IO, 0, 1 }, /* PCI I/O         */ \
+  { 0xe0100000, DC21285_PCI_TYPE_0_CONFIG,    0x00f00000, DOMAIN_IO, 0, 1 }, /* Type 0 Config  */ \
+  { 0xe1000000, DC21285_ARMCSR_BASE,         0x00100000, DOMAIN_IO, 0, 1 }, /* ARM CSR         */ \
+  { 0xe1100000, DC21285_PCI_IACK,            0x00100000, DOMAIN_IO, 0, 1 }, /* PCI IACK        */ \
+  { 0xe1300000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh     */ \
+  { 0xe1400000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh     */ \
+  { 0xe1500000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh     */ \
+  { 0xe1600000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh     */ \
+  { 0xe1700000, DC21285_OUTBOUND_WRITE_FLUSH, 0x00100000, DOMAIN_IO, 0, 1 }, /* Out wrflsh     */ \
+  { 0xe1800000, DC21285_FLASH,                0x00800000, DOMAIN_IO, 0, 1 }  /* Flash          */
+
+#include "mm-armv.c"
index a853671fc131e113eb1c73987ff4cbc1692329fa..f4f4dfee9f5de50f7d0e7085e30de001e9bd77b9 100644 (file)
@@ -347,12 +347,11 @@ _arm6_7_proc_fin:
  *
  * Purpose : Set a PMD and flush it out of any WB cache
  */
-_arm6_set_pmd: and     r2, r1, #3
-               teq     r2, #2
-               andeq   r2, r1, #8
-               orreq   r1, r1, r2, lsl #1              @ Updatable = Cachable
+_arm6_set_pmd: and     r2, r1, #11
                teq     r2, #1
-               orreq   r1, r1, #16                     @ Updatable = 1 if Page table
+               teqne   r2, #9
+               teqne   r2, #10
+               orreq   r1, r1, #16                     @ Updatable = 1 if Page table/Cacheable section
                str     r1, [r0]
                mov     pc, lr
 
@@ -364,7 +363,8 @@ _arm6_set_pmd:      and     r2, r1, #3
  *
  * Purpose : Set a PMD and flush it out of any WB cache
  */
-_arm7_set_pmd: orr     r1, r1, #16                     @ Updatable bit is always set on ARM7
+_arm7_set_pmd: tst     r1, #3
+               orrne   r1, r1, #16                     @ Updatable bit is always set on ARM7
                str     r1, [r0]
                mov     pc, lr
 
diff --git a/arch/arm/vmlinux-armo.lds b/arch/arm/vmlinux-armo.lds
new file mode 100644 (file)
index 0000000..db1f720
--- /dev/null
@@ -0,0 +1,63 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  _text = .;                   /* Text and read-only data */
+  .text : {
+       *(.text)
+       *(.fixup)
+       *(.gnu.warning)
+       } = 0x9090
+  .text.lock : { *(.text.lock) }       /* out-of-line lock text */
+  .rodata : { *(.rodata) }
+  .kstrtab : { *(.kstrtab) }
+
+  . = ALIGN(16);               /* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;       /* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  _etext = .;                  /* End of text section */
+
+  .data : {                    /* Data */
+       *(.data)
+       CONSTRUCTORS
+       }
+
+  _edata = .;                  /* End of data section */
+
+  /* This has to be aligned to a page boundary to do us any good.  This
+     alignment is overkill for ARM6 up but needed for ARM3.  Since all this
+     data will be thrown away I don't think the extra padding will hurt.
+       -- pb */
+  . = ALIGN(32768);            /* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(32768);
+  __init_end = .;
+
+  __bss_start = .;             /* BSS */
+  .bss : {
+       *(.bss)
+       }
+  _end = . ;
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/vmlinux-armv.lds b/arch/arm/vmlinux-armv.lds
new file mode 100644 (file)
index 0000000..a40664c
--- /dev/null
@@ -0,0 +1,63 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  _text = .;                   /* Text and read-only data */
+  .text : {
+       *(.text)
+       *(.fixup)
+       *(.gnu.warning)
+       } = 0x9090
+  .text.lock : { *(.text.lock) }       /* out-of-line lock text */
+  .rodata : { *(.rodata) }
+  .kstrtab : { *(.kstrtab) }
+
+  . = ALIGN(16);               /* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;       /* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  _etext = .;                  /* End of text section */
+
+  .data : {                    /* Data */
+       *(.data)
+       CONSTRUCTORS
+       }
+
+  _edata = .;                  /* End of data section */
+
+  /* This has to be aligned to a page boundary to do us any good.  This
+     alignment is overkill for ARM6 up but needed for ARM3.  Since all this
+     data will be thrown away I don't think the extra padding will hurt.
+       -- pb */
+  . = ALIGN(4096);             /* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;             /* BSS */
+  .bss : {
+       *(.bss)
+       }
+  _end = . ;
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/vmlinux.lds b/arch/arm/vmlinux.lds
deleted file mode 100644 (file)
index db1f720..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* ld script to make ARM Linux kernel
- * taken from the i386 version
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- */
-OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
-  _text = .;                   /* Text and read-only data */
-  .text : {
-       *(.text)
-       *(.fixup)
-       *(.gnu.warning)
-       } = 0x9090
-  .text.lock : { *(.text.lock) }       /* out-of-line lock text */
-  .rodata : { *(.rodata) }
-  .kstrtab : { *(.kstrtab) }
-
-  . = ALIGN(16);               /* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  __start___ksymtab = .;       /* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  _etext = .;                  /* End of text section */
-
-  .data : {                    /* Data */
-       *(.data)
-       CONSTRUCTORS
-       }
-
-  _edata = .;                  /* End of data section */
-
-  /* This has to be aligned to a page boundary to do us any good.  This
-     alignment is overkill for ARM6 up but needed for ARM3.  Since all this
-     data will be thrown away I don't think the extra padding will hurt.
-       -- pb */
-  . = ALIGN(32768);            /* Init code and data */
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(32768);
-  __init_end = .;
-
-  __bss_start = .;             /* BSS */
-  .bss : {
-       *(.bss)
-       }
-  _end = . ;
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-}
index c04f3dbc30533646d71de159b3d0b9f9652480a1..3e0794ec6171a0004a7c21e1281d7c1a631e9c6a 100644 (file)
@@ -269,7 +269,6 @@ CONFIG_82C710_MOUSE=y
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_NVRAM is not set
 # CONFIG_JOYSTICK is not set
-# CONFIG_MISC_RADIO is not set
 
 #
 # Ftape, the floppy tape device driver
index 64391ce13693bafcc9759a74cb5edd0699e0c4db..0c7e692a481cc807295d7466e22f6a75032cdceb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bios32.c - Low-Level PCI Access
  *
- * $Id: bios32.c,v 1.37 1998/06/19 17:11:37 mj Exp $
+ * $Id: bios32.c,v 1.40 1998/07/16 21:16:03 mj Exp $
  *
  * Copyright 1993, 1994 Drew Eckhardt
  *      Visionary Computing
@@ -80,7 +80,6 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/smp.h>
 #include <asm/spinlock.h>
 
@@ -795,7 +794,7 @@ __initfunc(void pcibios_sort(void))
                                break;
                        }
                }
-               if (!idx) {
+               if (e == dev) {
                        printk("PCI: Device %02x:%02x not found by BIOS\n",
                                dev->bus->number, dev->devfn);
                        d = dev;
@@ -869,6 +868,46 @@ __initfunc(void pcibios_fixup_io_addr(struct pci_dev *dev, int idx))
        pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
 }
 
+/*
+ * Several buggy motherboards address only 16 devices and mirror
+ * them to next 16 IDs. We try to detect this `feature' on all
+ * primary busses (those containing host bridges as they are
+ * expected to be unique) and remove the ghost devices.
+ */
+
+__initfunc(void pcibios_fixup_ghosts(struct pci_bus *b))
+{
+       struct pci_dev *d, *e, **z;
+       int mirror = PCI_DEVFN(16,0);
+       int seen_host_bridge = 0;
+
+       DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
+       for(d=b->devices; d && d->devfn < mirror; d=d->sibling) {
+               if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+                       seen_host_bridge++;
+               for(e=d->next; e; e=e->sibling)
+                       if (e->devfn == d->devfn + mirror &&
+                           e->vendor == d->vendor &&
+                           e->device == d->device &&
+                           e->class == d->class &&
+                           !memcmp(e->base_address, d->base_address, sizeof(e->base_address)))
+                               break;
+               if (!e)
+                       return;
+       }
+       if (!seen_host_bridge)
+               return;
+       printk("PCI: Ignoring ghost devices on bus %d\n", b->number);
+       for(e=b->devices; e->sibling != d; e=e->sibling);
+       e->sibling = NULL;
+       for(z=&pci_devices; (d=*z);)
+               if (d->bus == b && d->devfn >= mirror) {
+                       *z = d->next;
+                       kfree_s(d, sizeof(*d));
+               } else
+                       z = &d->next;
+}
+
 /*
  * In case there are peer host bridges, scan bus behind each of them.
  * Although several sources claim that the host bridges should have
@@ -962,7 +1001,7 @@ __initfunc(void pcibios_fixup_devices(void))
                }
 #endif
                /*
-                * Fix out-of-range IRQ numbers and report bogus IRQ.
+                * Fix out-of-range IRQ numbers
                 */
                if (dev->irq >= NR_IRQS)
                        dev->irq = 0;
@@ -984,6 +1023,11 @@ __initfunc(void pcibios_fixup(void))
 #endif
 }
 
+__initfunc(void pcibios_fixup_bus(struct pci_bus *b))
+{
+       pcibios_fixup_ghosts(b);
+}
+
 /*
  * Initialization. Try all known PCI access methods. Note that we support
  * using both PCI BIOS and direct access: in such cases, we use I/O ports
index 4e63c05468282b52cca306941d6f5c3864e75046..330a15982920233a596e3ef5d0cb6c4169338d0b 100644 (file)
@@ -147,8 +147,13 @@ __initfunc(void setup_arch(char **cmdline_p,
                        memory_end = memory_alt_end;
        }
 #endif
-       if (memory_end > (1024-64)*1024*1024)
-               memory_end = (1024-64)*1024*1024;
+
+#define VMALLOC_RESERVE        (64 << 20)      /* 64MB for vmalloc */
+#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
+
+       if (memory_end > MAXMEM)
+               memory_end = MAXMEM;
+
        memory_end &= PAGE_MASK;
 #ifdef CONFIG_BLK_DEV_RAM
        rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
index 219a89079c54bafa1c52ef182f7db886e5573830..b1322261a4e65f806ebef6dc777cfa92a8816a83 100644 (file)
@@ -587,6 +587,10 @@ __initfunc(void pcibios_fixup(void))
        hades_fixup();
 }
 
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
 __initfunc(char *pcibios_setup(char *str))
 {
        return str;
index 6f7374fd27d6f55487a84bf81b9559ce1fc138eb..f60fe11b7e1c0d3d702c91481ad160beb0797d9c 100644 (file)
@@ -129,4 +129,13 @@ int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
        return pci_ops->pcibios_write_config_dword(bus, dev_fn, where, val);
 }
 
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
+__initfunc(char *pcibios_setup(char *str))
+{
+       return str;
+}
+
 #endif /* defined(CONFIG_PCI) */
index 6e2b5e38ed99e297e5c3b0f284a148f241be7767..b330e0d45f5c710644b286b95fba4c5a422175ea 100644 (file)
@@ -245,6 +245,10 @@ __initfunc(void pcibios_fixup(void))
        }
 }
 
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
 __initfunc(char *pcibios_setup(char *str))
 {
        return str;
index 64a7bbe49f2e72d2f5ac50bf708e306857613b7a..7823d3c84af41f4df6ce04edfde9337ee9219dfc 100644 (file)
@@ -2381,6 +2381,10 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
        return err;
 }
 
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
 __initfunc(char *pcibios_setup(char *str))
 {
        return str;
index 45cdde90548b8b50dc2a65167ea868f14c05220b..614d8403c2c07872b43044600e9aa44367ce1183 100644 (file)
@@ -87,6 +87,8 @@
  * 17/1/97:RMK:        Upgraded to 2.1 kernels.
  *
  *  4/3/98:RMK:        Changed major number to 21.
+ *
+ * 27/6/98:RMK:        Changed asm/delay.h to linux/delay.h for mdelay().
  */
 
 /*
 #include <linux/genhd.h>
 #include <linux/major.h>
 #include <linux/ioport.h>
+#include <linux/delay.h>
 
 #define MAJOR_NR       MFM_ACORN_MAJOR
 #include <linux/blk.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/irq-no.h>
+#include <asm/irq.h>
 #include <asm/uaccess.h>
-#include <asm/delay.h>
 #include <asm/dma.h>
 #include <asm/hardware.h>
 #include <asm/ecard.h>
index 08341cc4957b9b443e14aa9763acb5a484cbcc99..10fe5db73da99d4c9a44cffaf2af79aa8a6f241f 100644 (file)
@@ -52,6 +52,7 @@ static inline int serial_register_onedev (unsigned long port, int irq)
     req.baud_base = MY_BAUD_BASE;
     req.irq = irq;
     req.port = port;
+    req.flags = 0;
 
     return register_serial(&req);
 }
index 89d9eb3144aced72d24e98ecdb7fb62aa517d772..6a9df75991b64a5c381b302142a519c0568f0de2 100644 (file)
@@ -15,4 +15,3 @@
 #define MY_PORT_ADDRESS(port,cardaddress) \
        ((cardaddress) + (port) * 8)
 #include "serial-card.c"
-
index 845633637b8936dd338d7896e07da37a7030e383..73abe64bee909b9d3887ad31259d019e3d1bd615 100644 (file)
  * 1.10        RMK     15/07/1997      Fixed autoprobing of NQ8004.
  * 1.11        RMK     16/11/1997      Fixed autoprobing of NQ8005A.
  * 1.12        RMK     31/12/1997      Removed reference to dev_tint for Linux 2.1.
- *
+ *      RMK    27/06/1998      Changed asm/delay.h to linux/delay.h.
+ * 1.13        RMK     29/06/1998      Fixed problem with transmission of packets.
+ *                             Chip seems to have a bug in, whereby if the
+ *                             packet starts two bytes from the end of the
+ *                             buffer, it corrupts the receiver chain, and
+ *                             never updates the transmit status correctly.
  * TODO:
  *  When we detect a fatal error on the interface, we should restart it.
  *  Reap transmit packets after some time even if the buffer never filled.
  */
 
-static char *version = "ether3 ethernet driver (c) 1995-1998 R.M.King v1.12\n";
+static char *version = "ether3 ethernet driver (c) 1995-1998 R.M.King v1.13\n";
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -51,20 +56,16 @@ static char *version = "ether3 ethernet driver (c) 1995-1998 R.M.King v1.12\n";
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/ecard.h>
-#include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
 #include "ether3.h"
 
-#ifndef MODULE
-#define CLAIM_IRQ_AT_OPEN
-#endif
-
 static unsigned int net_debug = NET_DEBUG;
 static const card_ids ether3_cids[] = {
        { MANU_ANT2, PROD_ANT_ETHER3 },
@@ -135,7 +136,7 @@ ether3_setbuffer(struct device *dev, buffer_rw_t read, int start)
 #define ether3_writelong(dev,data)     {                       \
        unsigned long reg_bufwin = REG_BUFWIN;                  \
        outw((data), reg_bufwin);                               \
-       outw((data) >> 16, reg_bufwin);                 \
+       outw((data) >> 16, reg_bufwin);                         \
 }
 
 /*
@@ -263,6 +264,7 @@ ether3_init_2(struct device *dev))
        priv->regs.config1 = CFG1_RECVCOMPSTAT0|CFG1_DMABURST8;
        priv->regs.config2 = CFG2_CTRLO|CFG2_RECVCRC|CFG2_ERRENCRC;
        priv->regs.command = 0;
+
        /*
         * Set up our hardware address
         */
@@ -311,6 +313,10 @@ ether3_init_for_open(struct device *dev)
 
        memset(&priv->stats, 0, sizeof(struct enet_statistics));
 
+       /* Reset the chip */
+       outw(CFG2_RESET, REG_CONFIG2);
+       udelay(4);
+
        priv->regs.command = 0;
        outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND);
        while (inw(REG_STATUS) & (STAT_RXON|STAT_TXON));
@@ -425,12 +431,8 @@ ether3_probe1(struct device *dev))
 
                /* Fill in the fields of the device structure with ethernet values. */
                ether_setup(dev);
-#ifndef CLAIM_IRQ_AT_OPEN
-               if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev))
-                       error = EAGAIN;
-               else
-#endif
-                       return 0;
+
+               return 0;
        }
 
 failed:
@@ -475,20 +477,19 @@ ether3_probe(struct device *dev))
 static int
 ether3_open(struct device *dev)
 {
-       ether3_init_for_open(dev);
-
        MOD_INC_USE_COUNT;
 
-#ifdef CLAIM_IRQ_AT_OPEN
        if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev)) {
                MOD_DEC_USE_COUNT;
                return -EAGAIN;
        }
-#endif
 
        dev->tbusy = 0;
        dev->interrupt = 0;
        dev->start = 1;
+
+       ether3_init_for_open(dev);
+
        return 0;
 }
 
@@ -511,10 +512,7 @@ ether3_close(struct device *dev)
        outb(0x80, REG_CONFIG2 + 1);
        outw(0, REG_COMMAND);
 
-       enable_irq(dev->irq);
-#ifdef CLAIM_IRQ_AT_OPEN
        free_irq(dev->irq, dev);
-#endif
 
        MOD_DEC_USE_COUNT;
        return 0;
@@ -545,8 +543,7 @@ static void ether3_setmulticastlist(struct device *dev)
        if (dev->flags & IFF_PROMISC) {
                /* promiscuous mode */
                priv->regs.config1 |= CFG1_RECVPROMISC;
-       } else
-       if (dev->flags & IFF_ALLMULTI) {
+       } else if (dev->flags & IFF_ALLMULTI) {
                priv->regs.config1 |= CFG1_RECVSPECBRMULTI;
        } else
                priv->regs.config1 |= CFG1_RECVSPECBROAD;
@@ -571,7 +568,7 @@ retry:
                        unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
                        unsigned int ptr, nextptr;
 
-                       length = (length + 1) & ~1;
+                       length = (length + 3) & ~3;
 
                        if (priv->broken) {
                                dev_kfree_skb(skb);
@@ -589,32 +586,42 @@ retry:
                        priv->tx_head = nextptr;
 
                        save_flags_cli(flags);
+
+#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS)
+
                        ether3_setbuffer(dev, buffer_write, nextptr);
                        ether3_writelong(dev, 0);
+
                        ether3_setbuffer(dev, buffer_write, ptr + 4);
                        ether3_writebuffer(dev, skb->data, length);
                        ether3_writeword(dev, htons(nextptr));
                        ether3_writeword(dev, (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE) >> 16);
+
                        ether3_setbuffer(dev, buffer_write, ptr);
-#define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS)
                        ether3_writeword(dev, htons(ptr + length + 4));
-                       ether3_writeword(dev, (TXHDR_FLAGS >> 16));
+                       ether3_writeword(dev, TXHDR_FLAGS >> 16);
                        ether3_ledon(dev, priv);
+
                        priv->tx_used ++;
-                       if (priv->tx_used < MAX_TX_BUFFERED)
-                               dev->tbusy = 0;
                        if (priv->tx_used >= (MAX_TX_BUFFERED * 3 / 4)) {
                                priv->regs.command |= CMD_ENINTTX;
                                outw(priv->regs.command, REG_COMMAND);
                        }
-                       restore_flags(flags);
 
-                       dev->trans_start = jiffies;
-                       dev_kfree_skb(skb);
                        if (!(inw(REG_STATUS) & STAT_TXON)) {
                                outw(ptr, REG_TRANSMITPTR);
                                outw(priv->regs.command | CMD_TXON, REG_COMMAND);
                        }
+
+                       if (priv->tx_used < MAX_TX_BUFFERED)
+                               dev->tbusy = 0;
+
+                       dev->trans_start = jiffies;
+
+                       restore_flags(flags);
+
+                       dev_kfree_skb(skb);
+
                        return 0;
                } else {
                        printk("%s: transmitter access conflict.\n", dev->name);
@@ -625,12 +632,27 @@ retry:
                 * There should really be a "kick me" function call instead.
                 */
                int tickssofar = jiffies - dev->trans_start;
+               unsigned long flags;
+
                if (tickssofar < 5)
                        return 1;
                del_timer(&priv->timer);
-               printk("%s: transmit timed out, network cable problem?\n", dev->name);
+
+               save_flags_cli(flags);
+               printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name);
+               printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name,
+                       inw(REG_STATUS), inw(REG_CONFIG1), inw(REG_CONFIG2));
+               printk(KERN_ERR "%s: { rpr=%04X rea=%04X tpr=%04X }\n", dev->name,
+                       inw(REG_RECVPTR), inw(REG_RECVEND), inw(REG_TRANSMITPTR));
+               printk(KERN_ERR "%s: tx head=%04X tx tail=%04X\n", dev->name,
+                       priv->tx_head, priv->tx_tail);
+               ether3_setbuffer(dev, buffer_read, priv->tx_tail);
+               printk(KERN_ERR "%s: packet status = %08X\n", dev->name, ether3_readlong(dev));
+               restore_flags(flags);
+
                dev->tbusy = 0;
                priv->regs.config2 |= CFG2_CTRLO;
+               priv->stats.tx_errors += 1;
                outw(priv->regs.config2 , REG_CONFIG2);
                dev->trans_start = jiffies;
                goto retry;
@@ -709,7 +731,8 @@ ether3_rx(struct device *dev, struct dev_priv *priv, unsigned int maxcnt)
                        ether3_setbuffer(dev, buffer_read, next_ptr);
                        temp_ptr = ether3_readword(dev);
                        status = ether3_readword(dev);
-                       if (!(status & RXSTAT_DONE) || !temp_ptr)
+                       if ((status & (RXSTAT_DONE | RXHDR_CHAINCONTINUE | RXHDR_RECEIVE)) !=
+                               (RXSTAT_DONE | RXHDR_CHAINCONTINUE) || !temp_ptr)
                                break;
 
                        this_ptr = next_ptr + 4;
@@ -754,7 +777,7 @@ ether3_rx(struct device *dev, struct dev_priv *priv, unsigned int maxcnt)
                } else {
                        struct enet_statistics *stats = &priv->stats;
                        outw(next_ptr >> 8, REG_RECVEND);
-                       if (status & RXSTAT_OVERSIZE)     stats->rx_length_errors ++;
+                       if (status & RXSTAT_OVERSIZE)     stats->rx_over_errors ++;
                        if (status & RXSTAT_CRCERROR)     stats->rx_crc_errors ++;
                        if (status & RXSTAT_DRIBBLEERROR) stats->rx_fifo_errors ++;
                        if (status & RXSTAT_SHORTPACKET)  stats->rx_length_errors ++;
@@ -804,6 +827,7 @@ ether3_tx(struct device *dev, struct dev_priv *priv)
 
        do {
                unsigned long status;
+
                /*
                 * Read the packet header
                 */
@@ -813,7 +837,8 @@ ether3_tx(struct device *dev, struct dev_priv *priv)
                /*
                 * Check to see if this packet has been transmitted
                 */
-               if (!(status & TXSTAT_DONE) || !(status & TXHDR_TRANSMIT))
+               if ((status & (TXSTAT_DONE | TXHDR_TRANSMIT)) !=
+                   (TXSTAT_DONE | TXHDR_TRANSMIT))
                        break;
 
                /*
index cc9a15eb6ddf02e17c2ce78eaba7800b8f8956b9..1add274980f46a2e813aa6f1907509e3ae937165 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/delay.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/ecard.h>
-#include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -525,8 +525,8 @@ static char ethernames[MAX_ETHERH_CARDS][9];
 static struct device *my_ethers[MAX_ETHERH_CARDS];
 static struct expansion_card *ec[MAX_ETHERH_CARDS];
 
-int
-init_module(void)
+static int
+init_all_cards(void)
 {
        struct device *dev = NULL;
        struct expansion_card *boguscards[MAX_ETHERH_CARDS];
@@ -550,6 +550,7 @@ init_module(void)
                if (!io[i]) {
                        if ((ec[i] = ecard_find (0, etherh_cids)) == NULL)
                                continue;
+
                        if (!dev)
                                return -ENOMEM;
 
@@ -567,7 +568,7 @@ init_module(void)
 
                my_ethers[i] = dev;
 
-               if (register_netdev (my_ethers[i]) != 0) {
+               if (register_netdev(dev) != 0) {
                        printk (KERN_WARNING "No etherh card found at %08lX\n", dev->base_addr);
                        if (ec[i]) {
                                boguscards[i] = ec[i];
@@ -578,16 +579,36 @@ init_module(void)
                found ++;
                dev = NULL;
        }
+
        if (dev)
                kfree (dev);
+
        for (i = 0; i < MAX_ETHERH_CARDS; i++)
                if (boguscards[i]) {
                        boguscards[i]->ops = NULL;
                        ecard_release (boguscards[i]);
                }
-       if (!found)
-               return -ENODEV;
-       return 0;
+
+       return found ? 0 : -ENODEV;
+}
+
+int
+init_module(void)
+{
+       int ret;
+
+       if (load_8390_module(__FILE__))
+               return -ENOSYS;
+
+       lock_8390_module();
+
+       ret = init_all_cards();
+
+       if (ret) {
+               unlock_8390_module();
+       }
+
+       return ret;
 }
 
 void
@@ -607,5 +628,6 @@ cleanup_module(void)
                        ec[i] = NULL;
                }
        }
+       unlock_8390_module();
 }
 #endif /* MODULE */
index 21fdb9fc35510bb377c13fc7f5fef645a559382e..a203bc5c292008d6fe24bf102f395be8f1df482c 100644 (file)
@@ -20,6 +20,7 @@
  *                     reconnect race condition causing a warning message.
  *  12-Oct-1997        RMK     Added catch for re-entering interrupt routine.
  *  15-Oct-1997        RMK     Improved handling of commands.
+ *  27-Jun-1998        RMK     Changed asm/delay.h to linux/delay.h.
  */
 #define DEBUG_NO_WRITE 1
 #define DEBUG_QUEUES   2
 #include <linux/stat.h>
 #include <linux/ioport.h>
 #include <linux/blk.h>
+#include <linux/delay.h>
+
 #include <asm/bitops.h>
-#include <asm/delay.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/ecard.h>
index 6ce607bd61aef042a86d62f5ceb8489e6b0f49ba..df00d6bff21af0c0a1b83326248df72f74d6ff07 100644 (file)
@@ -128,7 +128,7 @@ int cumanascsi_detect(Scsi_Host_Template * tpnt)
         outb(0x00, instance->io_port - 577);
 
        if (instance->irq != IRQ_NONE)
-           if (request_irq(instance->irq, cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", NULL)) {
+           if (request_irq(instance->irq, do_cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", NULL)) {
                printk("scsi%d: IRQ%d not free, interrupts disabled\n",
                    instance->host_no, instance->irq);
                instance->irq = IRQ_NONE;
index 447ce374488345b6448d532584c86847475faade..3767c40360bfcbc3026c3020df483da66d7aa3cd 100644 (file)
@@ -90,7 +90,7 @@ use_clustering:               DISABLE_CLUSTERING                              \
 #define NCR5380_read(reg) cumanascsi_read(_instance, reg)
 #define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value)
 
-#define NCR5380_intr cumanascsi_intr
+#define do_NCR5380_intr do_cumanascsi_intr
 #define NCR5380_queue_command cumanascsi_queue_command
 #define NCR5380_abort cumanascsi_abort
 #define NCR5380_reset cumanascsi_reset
index 8612bef1ba8d5360ea718d26d51c6bfa07e92c53..b0168468424746dbb90cf3342fd1535027986b78 100644 (file)
@@ -8,6 +8,7 @@
  *  22-01-1998 RMK     0.0.1   Updated to 2.1.80
  *  15-04-1998 RMK     0.0.1   Only do PIO if FAS216 will allow it.
  *  02-05-1998 RMK     0.0.2   Updated & added DMA support
+ *  27-06-1998 RMK             Changed asm/delay.h to linux/delay.h
  */
 
 #include <linux/module.h>
@@ -19,8 +20,8 @@
 #include <linux/proc_fs.h>
 #include <linux/unistd.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
 
-#include <asm/delay.h>
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/io.h>
 
 static struct expansion_card *ecs[MAX_ECARDS];
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Cumana SCSI II driver");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
  */
@@ -250,7 +256,7 @@ cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
                        if (!(status & STATUS_DRQ))
                                continue;
 
-                       word = *addr | (*addr + 1) << 8;
+                       word = *addr | *(addr + 1) << 8;
                        outw (info->dmaarea);
                        addr += 2;
                        length -= 2;
@@ -361,6 +367,7 @@ cumanascsi_2_detect(Scsi_Host_Template *tpnt)
                info->info.ifcfg.asyncperiod    = CUMANASCSI2_ASYNC_PERIOD;
                info->info.ifcfg.sync_max_depth = CUMANASCSI2_SYNC_DEPTH;
                info->info.ifcfg.cntl3          = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+               info->info.ifcfg.disconnect_ok  = 1;
                info->info.dma.setup            = cumanascsi_2_dma_setup;
                info->info.dma.pseudo           = cumanascsi_2_dma_pseudo;
                info->info.dma.stop             = cumanascsi_2_dma_stop;
index 9346ed4f86eead926ff4d449a51c1da9f602f0f8..1d1d0628cd4a06057ab2610c68927dde9add02c8 100644 (file)
@@ -131,7 +131,7 @@ int ecoscsi_detect(Scsi_Host_Template * tpnt)
     request_region (instance->io_port, instance->n_io_port, "ecoscsi");
 
     if (instance->irq != IRQ_NONE)
-       if (request_irq(instance->irq, ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) {
+       if (request_irq(instance->irq, do_ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) {
            printk("scsi%d: IRQ%d not free, interrupts disabled\n",
            instance->host_no, instance->irq);
            instance->irq = IRQ_NONE;
index 17a349173e67a66609da8c3ade19d83e90029ced..ede468f2ad04c2789773a3ac218c73f881671b91 100644 (file)
@@ -81,7 +81,7 @@ use_clustering:       DISABLE_CLUSTERING                              \
 #define NCR5380_read(reg) ecoscsi_read(_instance, reg)
 #define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value)
 
-#define NCR5380_intr ecoscsi_intr
+#define do_NCR5380_intr do_ecoscsi_intr
 #define NCR5380_queue_command ecoscsi_queue_command
 #define NCR5380_abort ecoscsi_abort
 #define NCR5380_reset ecoscsi_reset
index f061742ecfee83ba24426f5e86702b9f8135408c..b4884de118ab3de441b71a0c3bdeb0c43c5fc53f 100644 (file)
@@ -14,6 +14,7 @@
  *  14-03-1998 RMK     Updated DMA support
  *                     Added terminator control
  *  15-04-1998 RMK     Only do PIO if FAS216 will allow it.
+ *  27-06-1998 RMK     Changed asm/delay.h to linux/delay.h
  */
 
 #include <linux/module.h>
@@ -25,8 +26,8 @@
 #include <linux/proc_fs.h>
 #include <linux/unistd.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
 
-#include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/dma.h>
 
 static struct expansion_card *ecs[MAX_ECARDS];
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("EESOX SCSI driver");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+
 /*
  * Use term=0,1,0,0,0 to turn terminators on/off
  */
@@ -377,6 +383,7 @@ eesoxscsi_detect(Scsi_Host_Template *tpnt)
                info->info.ifcfg.asyncperiod    = EESOX_ASYNC_PERIOD;
                info->info.ifcfg.sync_max_depth = EESOX_SYNC_DEPTH;
                info->info.ifcfg.cntl3          = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+               info->info.ifcfg.disconnect_ok  = 1;
                info->info.dma.setup            = eesoxscsi_dma_setup;
                info->info.dma.pseudo           = eesoxscsi_dma_pseudo;
                info->info.dma.stop             = eesoxscsi_dma_stop;
index ba181f69ecdb0a773519edaf1af5ed9d10ff5161..b6ffe08d9ea01e0d7c47e833fbaae594e85b902c 100644 (file)
@@ -22,6 +22,8 @@
  *  06-04-1998 RMK     Tightened conditions for printing incomplete
  *                     transfers
  *  02-05-1998 RMK     Added extra checks in fas216_reset
+ *  24-05-1998 RMK     Fixed synchronous transfers with period >= 200ns
+ *  27-06-1998 RMK     Changed asm/delay.h to linux/delay.h
  *
  * Todo:
  *  - tighten up the MESSAGE_REJECT support.
@@ -37,8 +39,8 @@
 #include <linux/proc_fs.h>
 #include <linux/unistd.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
 
-#include <asm/delay.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include "../../scsi/hosts.h"
 #include "fas216.h"
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver");
+
 #define VER_MAJOR      0
 #define VER_MINOR      0
-#define VER_PATCH      3
+#define VER_PATCH      4
 
 #define SCSI2_TAG
 
@@ -81,7 +86,6 @@
  */
 #define SCSI2_SYNC
 
-#undef NO_DISCONNECTS
 #undef DEBUG_CONNECT
 #undef DEBUG_BUSSERVICE
 #undef DEBUG_FUNCTIONDONE
@@ -94,8 +98,7 @@ static int ptr;
 
 static void fas216_dumpstate(FAS216_Info *info)
 {
-       printk("FAS216 registers:\n");
-       printk("    CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
+       printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
               " INST=%02X IS=%02X CFIS=%02X",
                inb(REG_CTCL(info)), inb(REG_CTCM(info)),
                inb(REG_CMD(info)),  inb(REG_STAT(info)),
@@ -114,7 +117,7 @@ static void fas216_dumpinfo(FAS216_Info *info)
        if (used++)
                return;
 
-       printk("FAS216_Info = \n");
+       printk("FAS216_Info=\n");
        printk("  { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
                info->magic_start, info->host, info->SCpnt,
                info->origSCpnt);
@@ -122,17 +125,18 @@ static void fas216_dumpinfo(FAS216_Info *info)
                info->scsi.io_port, info->scsi.io_shift, info->scsi.irq,
                info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
                info->scsi.cfg[3]);
-       printk("           type=%p phase=%X reconnected = { target=%d lun=%d tag=%d }\n",
+       printk("           type=%p phase=%X reconnected={ target=%d lun=%d tag=%d }\n",
                info->scsi.type, info->scsi.phase,
                info->scsi.reconnected.target,
                info->scsi.reconnected.lun, info->scsi.reconnected.tag);
-       printk("           SCp = { ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
+       printk("           SCp={ ptr=%p this_residual=%X buffer=%p buffers_residual=%X }\n",
                info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
                info->scsi.SCp.buffer, info->scsi.SCp.buffers_residual);
        printk("      msgs async_stp=%X last_message=%X disconnectable=%d aborting=%d }\n",
                info->scsi.async_stp, info->scsi.last_message,
                info->scsi.disconnectable, info->scsi.aborting);
-       printk("    stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X disconnects=%X aborts=%X resets=%X }\n",
+       printk("    stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
+              "            disconnects=%X aborts=%X resets=%X }\n",
                info->stats.queues, info->stats.removes, info->stats.fins,
                info->stats.reads, info->stats.writes, info->stats.miscs,
                info->stats.disconnects, info->stats.aborts, info->stats.resets);
@@ -148,7 +152,7 @@ static void fas216_dumpinfo(FAS216_Info *info)
        printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
                info->dma.transfer_type, info->dma.setup,
                info->dma.pseudo, info->dma.stop);
-       printk("    internal_done=%X magic_end=%lX\n",
+       printk("    internal_done=%X magic_end=%lX }\n",
                info->internal_done, info->magic_end);
 }
 
@@ -228,9 +232,9 @@ static void print_debug_list(void)
 
        i = ptr;
 
-       printk(KERN_ERR "SCSI state trail: ");
+       printk(KERN_ERR "SCSI IRQ trail: ");
        do {
-               printk("%02X:%02X:%02X:%02X ",
+               printk("%02X:%02X:%02X:%1X ",
                        list[i].stat, list[i].ssr,
                        list[i].isr, list[i].ph);
                i = (i + 1) & 7;
@@ -265,7 +269,8 @@ static int fas216_clockrate(int clock)
  *         : ns   - period in ns (between subsequent bytes)
  * Returns : Value suitable for REG_STP
  */
-static int fas216_syncperiod(FAS216_Info *info, int ns)
+static int
+fas216_syncperiod(FAS216_Info *info, int ns)
 {
        int value = (info->ifcfg.clockrate * ns) / 1000;
 
@@ -279,6 +284,25 @@ static int fas216_syncperiod(FAS216_Info *info, int ns)
        return value & 31;
 }
 
+/* Function: void fas216_set_sync(FAS216_Info *info, int target)
+ * Purpose : Correctly setup FAS216 chip for specified transfer period.
+ * Params  : info   - state structure for interface
+ *         : target - target
+ * Notes   : we need to switch the chip out of FASTSCSI mode if we have
+ *           a transfer period >= 200ns - otherwise the chip will violate
+ *           the SCSI timings.
+ */
+static void
+fas216_set_sync(FAS216_Info *info, int target)
+{
+       outb(info->device[target].sof, REG_SOF(info));
+       outb(info->device[target].stp, REG_STP(info));
+       if (info->device[target].period >= (200 / 4))
+               outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info));
+       else
+               outb(info->scsi.cfg[2], REG_CNTL3(info));
+}
+
 /* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
  * Purpose : update data pointers after transfer suspended/paused
  * Params  : info              - interface's local pointer to update
@@ -504,6 +528,8 @@ fas216_stoptransfer(FAS216_Info *info)
                fas216_updateptrs(info, total - residual);
                info->dma.transfer_type = fasdma_none;
        }
+       if (info->scsi.phase == PHASE_DATAOUT)
+               outb(CMD_FLUSHFIFO, REG_CMD(info));
 }
 
 /* Function: void fas216_disconnected_intr(FAS216_Info *info)
@@ -857,13 +883,13 @@ static void fas216_message(FAS216_Info *info)
                                info->scsi.phase = PHASE_MSGOUT;
                        case syncneg_sent:
                                info->device[info->SCpnt->target].negstate = syncneg_complete;
+                               info->device[info->SCpnt->target].period = message[3];
                                info->device[info->SCpnt->target].sof = message[4];
                                info->device[info->SCpnt->target].stp =
                                        fas216_syncperiod(info, message[3] * 4);
                                printk(KERN_NOTICE "scsi%d.%c: using synchronous transfer, offset %d, %d ns\n",
                                        info->host->host_no, fas216_target(info), message[4], message[3] * 4);
-                               outb(info->device[info->SCpnt->target].sof, REG_SOF(info));
-                               outb(info->device[info->SCpnt->target].stp, REG_STP(info));
+                               fas216_set_sync(info, info->SCpnt->target);
                                break;
                        }
                        break;
@@ -1416,8 +1442,7 @@ static void fas216_kick(FAS216_Info *info)
        outb(info->ifcfg.select_timeout, REG_STIM(info));
 
        /* synchronous transfers */
-       outb(info->device[SCpnt->target].sof, REG_SOF(info));
-       outb(info->device[SCpnt->target].stp, REG_STP(info));
+       fas216_set_sync(info, SCpnt->target);
 
        msglen = msgqueue_msglength(&info->scsi.msgs);
 
@@ -1742,8 +1767,8 @@ int fas216_abort(Scsi_Cmnd *SCpnt)
        info->stats.aborts += 1;
 
        print_debug_list();
-       fas216_dumpinfo(info);
        fas216_dumpstate(info);
+       fas216_dumpinfo(info);
        printk(KERN_WARNING "scsi%d: fas216_abort: ", info->host->host_no);
 
        do {
@@ -1823,12 +1848,9 @@ static void fas216_reset_state(FAS216_Info *info)
 #endif
 
        for (i = 0; i < 8; i++) {
-#ifndef NO_DISCONNECTS
-               info->device[i].disconnect_ok = 1;
-#else
-               info->device[i].disconnect_ok = 0;
-#endif
+               info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
                info->device[i].negstate = negstate;
+               info->device[i].period = info->ifcfg.asyncperiod / 4;
                info->device[i].stp = info->scsi.async_stp;
                info->device[i].sof = 0;
        }
@@ -1980,6 +2002,8 @@ int fas216_init(struct Scsi_Host *instance)
                return 1;
        }
 
+       outb(CMD_RESETCHIP, REG_CMD(info));
+
        outb(0, REG_CNTL3(info));
        outb(CNTL2_S2FE, REG_CNTL2(info));
 
index bbf950668a430e3113bd2894ba41ef7ec0cf25ec..6518fbb422166d7d443294a31d505ea303d10e7c 100644 (file)
@@ -257,6 +257,7 @@ typedef struct {
                unsigned char   sync_max_depth;         /* Synchronous xfer max fifo depth      */
                unsigned char   cntl3;                  /* Control Reg 3                        */
                unsigned int    asyncperiod;            /* Async transfer period (ns)           */
+               unsigned int    disconnect_ok:1;        /* Disconnects allowed?                 */
        } ifcfg;
 
        /* queue handling */
@@ -268,6 +269,7 @@ typedef struct {
        /* per-device info */
        struct {
                unsigned char   disconnect_ok:1;        /* device can disconnect                */
+               unsigned int    period;                 /* sync xfer period (*4ns)              */
                unsigned char   stp;                    /* synchronous transfer period          */
                unsigned char   sof;                    /* synchronous offset register          */
                syncneg_t       negstate;               /* synchronous transfer mode            */
index 25912d34aeeca5b81a2172a10ce151b102267f23..7621b4d2bdcf2cd7edd3ffc4a92c78af48ea0fd1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * drivers/acorn/scsi/msgqueue.c: message queue handling
  *
- * Copyright (C) 1997,8 Russell King
+ * Copyright (C) 1997-1998 Russell King
  */
 
 #include <linux/module.h>
@@ -10,6 +10,9 @@
 
 #include "msgqueue.h"
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI message queue handling");
+
 /*
  * Function: struct msgqueue_entry *mqe_alloc(MsgQueue_t *msgq)
  * Purpose : Allocate a message queue entry
index ff56013d7c0e15329a337b58de91640098879fa4..44fc86eaf6109aca01893b77218f17ad3ad5ea2f 100644 (file)
@@ -116,7 +116,7 @@ int oakscsi_detect(Scsi_Host_Template * tpnt)
        request_region (instance->io_port, instance->n_io_port, "Oak SCSI");
 
        if (instance->irq != IRQ_NONE)
-           if (request_irq(instance->irq, oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) {
+           if (request_irq(instance->irq, do_oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) {
                printk("scsi%d: IRQ%d not free, interrupts disabled\n",
                    instance->host_no, instance->irq);
                instance->irq = IRQ_NONE;
index eeea25a72ce1008ac2f766f67a8240f6cd884644..f4ead3612daa6dd88f6a594f29917a6b6ccb0fd0 100644 (file)
@@ -85,7 +85,7 @@ use_clustering:       DISABLE_CLUSTERING                              \
 
 #define NCR5380_read(reg)              oakscsi_read(_instance, reg)
 #define NCR5380_write(reg, value)      oakscsi_write(_instance, reg, value)
-#define NCR5380_intr                   oakscsi_intr
+#define do_NCR5380_intr                        do_oakscsi_intr
 #define NCR5380_queue_command          oakscsi_queue_command
 #define NCR5380_abort                  oakscsi_abort
 #define NCR5380_reset                  oakscsi_reset
index a91f17c741b016ca863dee0fb4973a8c7c8f7d37..7a41d7d0c585732a648e11df4cf366926652c798 100644 (file)
@@ -12,6 +12,7 @@
  *  15-02-1998 RMK     Added DMA support and hardware definitions.
  *  15-04-1998 RMK     Only do PIO if FAS216 will allow it.
  *  02-05-1998 RMK     Moved DMA sg list into per-interface structure.
+ *  27-06-1998 RMK     Changed asm/delay.h to linux/delay.h
  */
 
 #include <linux/module.h>
@@ -23,8 +24,8 @@
 #include <linux/proc_fs.h>
 #include <linux/unistd.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
 
-#include <asm/delay.h>
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/io.h>
 #define VER_MINOR      0
 #define VER_PATCH      2
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("Powertec SCSI driver");
+MODULE_PARM(term, "1-8i");
+MODULE_PARM_DESC(term, "SCSI bus termination");
+
 static struct expansion_card *ecs[MAX_ECARDS];
 
 /*
@@ -271,6 +277,7 @@ powertecscsi_detect(Scsi_Host_Template *tpnt)
                info->info.ifcfg.asyncperiod    = POWERTEC_ASYNC_PERIOD;
                info->info.ifcfg.sync_max_depth = POWERTEC_SYNC_DEPTH;
                info->info.ifcfg.cntl3          = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK;
+               info->info.ifcfg.disconnect_ok  = 1;
                info->info.dma.setup            = powertecscsi_dma_setup;
                info->info.dma.pseudo           = NULL;
                info->info.dma.stop             = powertecscsi_dma_stop;
index 2be257bd361b6b998d74b20d1240007a047622ee..b8f5ba0ad00c8815d4eee80edb6e485214d10d09 100644 (file)
@@ -20,6 +20,9 @@
 
 #include "../../scsi/scsi.h"
 
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SCSI command queueing");
+
 typedef struct queue_entry {
        struct queue_entry *next;
        struct queue_entry *prev;
index eb63e36a7e289628ede7217e2bf2d30ede4e64fa..9eec9216d4992ed6019509ba798c07656741a3c1 100644 (file)
@@ -132,16 +132,13 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
   if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
     hex '  SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284
   fi
+  dep_tristate 'Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV
+  if [ "$CONFIG_RADIO_ZOLTRIX" != "n" ]; then
+    hex '  ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
+  fi
 fi
 tristate '/dev/nvram support' CONFIG_NVRAM
 tristate 'PC joystick support' CONFIG_JOYSTICK
-bool 'Radio Device Support' CONFIG_MISC_RADIO
-if [ "$CONFIG_MISC_RADIO" != "n" ]; then
-  bool '  AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK
-  if [ "$CONFIG_RADIO_RTRACK" != "n" ]; then
-    hex '    RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
-  fi
-fi
 
 mainmenu_option next_comment
 comment 'Ftape, the floppy tape device driver'
index 1177ed1adfa7ee0b38074759c750ba1afc79a541..bd6cc3c9605c3b9afe178e14d18f64d7f25cf7ac 100644 (file)
 */
 
 #include <linux/module.h>
-#include <linux/bios32.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/malloc.h>
+#include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/signal.h>
@@ -352,9 +352,9 @@ void attach_inform(struct i2c_bus *bus, int id)
                        break;
                case I2C_DRIVERID_TUNER:
                        btv->have_tuner = 1;
-                       if (btv->type == BTTV_MIRO
+                       if (btv->tuner_type != -1
                        {
-                               tunertype=((btread(BT848_GPIO_DATA)>>10)-1)&7;
+                               tunertype=btv->tuner_type;
                                i2c_control_device(&(btv->i2c), I2C_DRIVERID_TUNER,
                                        TUNER_SET_TYPE,&tunertype);
                        }
@@ -436,17 +436,6 @@ static struct tvcard tvcards[] =
  *     Tuner, Radio, internal, external and mute 
  */
  
-static unsigned char audiomuxs[][5] = 
-{
-       { 0x00, 0x00, 0x00, 0x00, 0x00}, /* unknown */
-       { 0x02, 0x00, 0x00, 0x00, 0x0a}, /* MIRO */
-       { 0x00, 0x01, 0x02, 0x03, 0x04}, /* Hauppauge */
-       { 0x04, 0x00, 0x02, 0x03, 0x01}, /* STB */
-       { 0x00, 0x01, 0x02, 0x03, 0x04}, /* Intel??? */
-       { 0x00, 0x01, 0x00, 0x01, 0x03}, /* Diamond DTV2000 */
-       { 0x0c, 0x00, 0x0b, 0x0b, 0x00}, /* AVerMedia TVPhone */
-};
-
 static void audio(struct bttv *btv, int mode)
 {
        btaor(tvcards[btv->type].gpiomask, ~tvcards[btv->type].gpiomask,
@@ -803,150 +792,6 @@ static inline void write_risc_segment(unsigned int **rp, unsigned long line_adr,
        *x+=dx;
 }
 
-static void make_clip_tab(struct bttv *btv, struct cliprec *cr, int count)
-{
-        int i,ncr;
-       int yy, y, x, dx;
-       struct cliprec first, *cur, *cur2, *nx, first2, *prev, *nx2;
-       int bpp, bpl, width, height, inter;
-       unsigned int **rp,*ro,*re;
-       unsigned long adr;
-       int cx,cx2,cy,cy2;
-
-       inter=(btv->win.interlace&1)^1;
-       bpp=btv->win.bpp;
-       bpl=btv->win.bpl;
-       ncr=btv->ncr;
-       ro=btv->risc_odd;
-       re=btv->risc_even;
-       width=btv->win.width;
-       height=btv->win.height;
-       adr=btv->win.vidadr+btv->win.x*bpp+btv->win.y*bpl;
-
-       /* clip clipping rects against viewing window AND screen 
-          so we do not have to rely on the user program
-        */
-       cx=(btv->win.x<0) ? (-btv->win.x) : 0;
-       cy=(btv->win.y<0) ? (-btv->win.y) : 0;
-       cx2=(btv->win.x+width>btv->win.swidth) ? 
-               (btv->win.swidth-btv->win.x) : width;
-       cy2=(btv->win.y+height>btv->win.sheight) ? 
-               (btv->win.sheight-btv->win.y) : height;
-       first.next=NULL;
-       for (i=0; i<ncr; i++)
-       {
-                if (cr[i].y<cy)
-               {
-                       if (cr[i].y2<cy)
-                               continue;
-                       cr[i].y=cy;
-               } 
-               if (cr[i].y2>=cy2) 
-               {
-                       if (cr[i].y>=cy2)
-                               continue;
-                       cr[i].y2=cy2-1;
-               }
-                if (cr[i].x<cx)
-               {
-                       if (cr[i].x2<cx)
-                               continue;
-                       cr[i].x=cx;
-               } 
-               if (cr[i].x2>=cx2) 
-               {
-                       if (cr[i].x>=cx2)
-                               continue;
-                       cr[i].x2=cx2-1;
-               }
-               cur=&first;
-               while ((nx=cur->next) && (cr[i].y > cur->next->y))
-                       cur=nx; 
-               cur->next=&(cr[i]);
-               cr[i].next=nx;
-       }
-       first2.next=NULL;
-       
-       *(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
-       *(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
-       
-       /* loop through all lines */
-       for (yy=0; yy<(height<<inter); yy++) 
-       {
-               y=yy>>inter;
-               rp= (yy&1) ? &re : &ro;
-         
-               /* remove rects with y2 > y */
-               if ((cur=first2.next))
-               {
-                       prev=&first2;
-                       do
-                       {
-                               if (cur->y2 < y) 
-                                       prev->next=cur->next;
-                               else
-                                       prev=cur;
-                       } 
-                       while ((cur=cur->next));
-               }
-
-               /* add rect to second (x-sorted) list if rect.y == y  */
-               if ((cur=first.next))
-               {
-                       while ((cur) && (cur->y == y))
-                       { 
-                               first.next=cur->next;
-                               cur2=&first2;
-                               while ((nx2=cur2->next) && (cur->x > cur2->next->x)) 
-                                       cur2=nx2; 
-                               cur2->next=cur;
-                               cur->next=nx2;
-                               cur=first.next;
-                       }
-               }
-               x=0;
-               if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
-                       write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
-                                       width, bpp, width);
-               else 
-               {
-                       dx=cx;
-                       for (cur2=first2.next; cur2; cur2=cur2->next)
-                       {
-                               if (x+dx < cur2->x)
-                               {
-                                       write_risc_segment(rp, adr, BT848_RISC_SKIP,
-                                               &x, dx, bpp, width);
-                                       dx=cur2->x-x;
-                                       write_risc_segment(rp, adr, BT848_RISC_WRITEC,
-                                               &x, dx, bpp, width);
-                                       dx=cur2->x2-x+1;
-                               }
-                               else if (x+dx < cur2->x2) 
-                                       dx=cur2->x2-x+1; 
-                       }
-                       if (cx2<width)
-                       {
-                               write_risc_segment(rp, adr, BT848_RISC_SKIP,
-                                       &x, dx, bpp, width);
-                               write_risc_segment(rp, adr, BT848_RISC_WRITEC,
-                                       &x, cx2-x, bpp, width);
-                               dx=width-x;
-                       }
-                       write_risc_segment(rp, adr, BT848_RISC_SKIP,
-                               &x, dx, bpp, width);
-                       write_risc_segment(rp, adr, BT848_RISC_WRITEC,
-                               &x, width-x, bpp, width);
-               }
-               if ((!inter)||(yy&1))
-                       adr+=bpl;
-       }
-       
-       *(ro++)=BT848_RISC_JUMP;
-       *(ro++)=btv->bus_vbi_even;
-       *(re++)=BT848_RISC_JUMP;
-       *(re++)=btv->bus_vbi_odd;
-}
 
 /*
  *     Set the registers for the size we have specified. Don't bother
@@ -1092,28 +937,15 @@ int bpp2fmt[4] = {
 static void bt848_set_winsize(struct bttv *btv)
 {
         unsigned short format;
-       int bpp;
 
         btv->win.color_fmt=format= (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
                bpp2fmt[(btv->win.bpp-1)&3];
-#if 0
-       bpp=fmtbppx2[btv->win.color_fmt&0x0f]/2;
-       if (btv->win.bpp == 0) 
-       {
-               btv->win.bpp=bpp;
-               format=btv->win.color_fmt;
-       }
-       else if (btv->win.bpp!=bpp)
-               btv->win.color_fmt=format=bpp2fmt[(btv->win.bpp-1)&3];
-       else
-                format=btv->win.color_fmt;
-#endif
                        
        /*      RGB8 seems to be a 9x5x5 GRB color cube starting at
         *      color 16. Why the h... can't they even mention this in the
-        *      datasheet???  [AC - because its a standard format so I guess
-        *      it never occured them]
-        *      Enable dithering in this mode
+        *      data sheet?  [AC - because it's a standard format so I guess
+        *      it never occurred to them]
+        *      Enable dithering in this mode.
         */
 #if 0   
        if (format==BT848_COLOR_FMT_RGB8)
@@ -1727,7 +1559,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        strcpy(v.name, "Television");
                        v.rangelow=0;
                        v.rangehigh=0xFFFFFFFF;
-                       v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC;
+                       v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
                        v.mode = btv->win.norm;
                        if(copy_to_user(arg,&v,sizeof(v)))
                                return -EFAULT;
@@ -1913,13 +1745,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        if(v.depth!=8 && v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
                                return -EINVAL;
-                       if (v.base) {
-                               /* also handle virtual base addresses */
-                               if ((unsigned int)v.base>=0xe0000000UL)
-                                       btv->win.vidadr=(uint)v.base;
-                               else 
-                                 btv->win.vidadr= __va(uvirt_to_bus((uint)v.base));
-                       }
+                       btv->win.vidadr=(unsigned long)v.base;
                        btv->win.sheight=v.height;
                        btv->win.swidth=v.width;
                        btv->win.bpp=((v.depth+1)&0x38)/8;
@@ -2315,6 +2141,8 @@ static struct vidbases vbs[] = {
                "Matrox Millennium", PCI_BASE_ADDRESS_1},
        { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2,
                "Matrox Millennium II", PCI_BASE_ADDRESS_0},
+       { PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP,
+               "Matrox Millennium II AGP", PCI_BASE_ADDRESS_0},
        { PCI_VENDOR_ID_MATROX, 0x051a, "Matrox Mystique", PCI_BASE_ADDRESS_1},
        { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128, 
                "Number Nine Imagine 128", PCI_BASE_ADDRESS_0},
@@ -2339,48 +2167,41 @@ static uint dec_offsets[4] = {
 
 static int find_vga(void)
 {
-       unsigned int devfn, class, vendev;
-       unsigned short vendor, device, badr;
-       int found=0, bus=0, i, tga_type;
+       unsigned short badr;
+       int found = 0, i, tga_type;
        unsigned int vidadr=0;
+       struct pci_dev *dev;
 
 
-       for (devfn = 0; devfn < 0xff; devfn++
+       for (dev = pci_devices; dev != NULL; dev = dev->next
        {
-               if (PCI_FUNC(devfn) != 0)
+               if (dev->class != PCI_CLASS_NOT_DEFINED_VGA &&
+                       (dev->class) >> 8 != PCI_BASE_CLASS_DISPLAY) 
+               {
                        continue;
-               pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendev);
-               if (vendev == 0xffffffff || vendev == 0x00000000) 
+               }
+               if (PCI_FUNC(dev->devfn) != 0)
                        continue;
-               pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor);
-               pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &device);
-               pcibios_read_config_dword(bus, devfn, PCI_CLASS_REVISION, &class);
-               class = class >> 16;
-/*             if (class == PCI_CLASS_DISPLAY_VGA) {*/
-               if ((class>>8) == PCI_BASE_CLASS_DISPLAY ||
-                       /* Number 9 GXE64Pro needs this */
-                       class == PCI_CLASS_NOT_DEFINED_VGA) 
+
+               badr=0;
+               printk(KERN_INFO "bttv: PCI display adapter: ");
+               for (i=0; i<NR_CARDS; i++) 
                {
-                       badr=0;
-                       printk(KERN_INFO "bttv: PCI display adapter: ");
-                       for (i=0; i<NR_CARDS; i++) 
+                       if (dev->vendor == vbs[i].vendor) 
                        {
-                               if (vendor==vbs[i].vendor) 
-                               {
-                                       if (vbs[i].device) 
-                                               if (vbs[i].device!=device)
-                                                       continue;
-                                       printk("%s.\n", vbs[i].name);
-                                       badr=vbs[i].badr;
-                                       break;
-                               }
+                               if (vbs[i].device) 
+                                       if (vbs[i].device!=dev->device)
+                                               continue;
+                               printk("%s.\n", vbs[i].name);
+                               badr=vbs[i].badr;
+                               break;
                        }
                        if (!badr) 
                        {
                                printk(KERN_ERR "bttv: Unknown video memory base address.\n");
                                continue;
                        }
-                       pcibios_read_config_dword(bus, devfn, badr, &vidadr);
+                       pci_read_config_dword(dev, badr, &vidadr);
                        if (vidadr & PCI_BASE_ADDRESS_SPACE_IO) 
                        {
                                printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
@@ -2394,8 +2215,8 @@ static int find_vga(void)
                                continue;
                        }
       
-                       if (vendor==PCI_VENDOR_ID_DEC)
-                               if (device==PCI_DEVICE_ID_DEC_TGA) 
+                       if (dev->vendor == PCI_VENDOR_ID_DEC &&
+                               dev->device == PCI_DEVICE_ID_DEC_TGA) 
                        {
                                tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
                                if (tga_type != 0 && tga_type != 1 && tga_type != 3) 
@@ -2405,9 +2226,8 @@ static int find_vga(void)
                                }
                                vidadr+=dec_offsets[tga_type];
                        }
-
                        DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
-                       DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", devfn));
+                       DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", dev->devfn));
                        found++;
                }
        }
@@ -2434,76 +2254,65 @@ static int find_vga(void)
   
 static void handle_chipset(void)
 {
-       int index;
+       struct pci_dev *dev = NULL;
   
        /*      Just in case some nut set this to something dangerous */
        if (triton1)
                triton1=BT848_INT_ETBF;
        
-       for (index = 0; index < 8; index++)
+       while ((dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, dev))) 
        {
-               unsigned char bus, devfn;
-               unsigned char b;
-    
                /* Beware the SiS 85C496 my friend - rev 49 don't work with a bttv */
-               
-               if (!pcibios_find_device(PCI_VENDOR_ID_SI, 
-                                        PCI_DEVICE_ID_SI_496, 
-                                        index, &bus, &devfn))
-               {
-                       printk(KERN_WARNING "BT848 and SIS 85C496 chipset don't always work together.\n");
-               }                       
+               printk(KERN_WARNING "BT848 and SIS 85C496 chipset don't always work together.\n");
+       }                       
 
-               if (!pcibios_find_device(PCI_VENDOR_ID_INTEL, 
-                                        PCI_DEVICE_ID_INTEL_82441,
-                                        index, &bus, &devfn)) 
-               {
-                       pcibios_read_config_byte(bus, devfn, 0x53, &b);
-                       DEBUG(printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "));
-                       DEBUG(printk("bufcon=0x%02x\n",b));
-               }
+       /* dev == NULL */
 
-               if (!pcibios_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437,
-                           index, &bus, &devfn)) 
-               {
-                       printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
-                       triton1=BT848_INT_ETBF;
-                       
-#if 0                  
-                       /* The ETBF bit SHOULD make all this unnecessary */
-                       /* 430FX (Triton I) freezes with bus concurrency on -> switch it off */
-                       {   
-                               unsigned char bo;
+       while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, dev))) 
+       {
+               unsigned char b;
+               pci_read_config_byte(dev, 0x53, &b);
+               DEBUG(printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "));
+               DEBUG(printk("bufcon=0x%02x\n",b));
+       }
 
-                               pcibios_read_config_byte(bus, devfn, TRITON_PCON, &b);
-                               bo=b;
-                               DEBUG(printk(KERN_DEBUG "bttv: 82437FX: PCON: 0x%x\n",b));
+       while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, dev))) 
+       {
+/*             unsigned char b;
+               unsigned char bo;*/
 
-                               if(!(b & TRITON_BUS_CONCURRENCY)) 
-                               {
-                                       printk(KERN_WARNING "bttv: 82437FX: disabling bus concurrency\n");
-                                       b |= TRITON_BUS_CONCURRENCY;
-                               }
+               printk(KERN_INFO "bttv: Host bridge 82437FX Triton PIIX\n");
+               triton1=BT848_INT_ETBF;
+                       
+#if 0                  
+               /* The ETBF bit SHOULD make all this unnecessary */
+               /* 430FX (Triton I) freezes with bus concurrency on -> switch it off */
 
-                               if(b & TRITON_PEER_CONCURRENCY) 
-                               {
-                                       printk(KERN_WARNING "bttv: 82437FX: disabling peer concurrency\n");
-                                       b &= ~TRITON_PEER_CONCURRENCY;
-                               }
-                               if(!(b & TRITON_STREAMING)) 
-                               {
-                                       printk(KERN_WARNING "bttv: 82437FX: disabling streaming\n");
-                                       b |=  TRITON_STREAMING;
-                               }
+               pci_read_config_byte(dev, TRITON_PCON, &b);
+               bo=b;
+               DEBUG(printk(KERN_DEBUG "bttv: 82437FX: PCON: 0x%x\n",b));
+               if(!(b & TRITON_BUS_CONCURRENCY)) 
+               {
+                       printk(KERN_WARNING "bttv: 82437FX: disabling bus concurrency\n");
+                       b |= TRITON_BUS_CONCURRENCY;
+               }
+               if(b & TRITON_PEER_CONCURRENCY) 
+               {
+                       printk(KERN_WARNING "bttv: 82437FX: disabling peer concurrency\n");
+                       b &= ~TRITON_PEER_CONCURRENCY;
+               }
+               if(!(b & TRITON_STREAMING)) 
+               {
+                       printk(KERN_WARNING "bttv: 82437FX: disabling streaming\n");
+                       b |=  TRITON_STREAMING;
+               }
 
-                               if (b!=bo) 
-                               {
-                                       pcibios_write_config_byte(bus, devfn, TRITON_PCON, b); 
-                                       printk(KERN_DEBUG "bttv: 82437FX: PCON changed to: 0x%x\n",b);
-                               }
-                       }
-#endif
+               if (b!=bo) 
+               {
+                       pci_write_config_byte(dev, TRITON_PCON, b); 
+                       printk(KERN_DEBUG "bttv: 82437FX: PCON changed to: 0x%x\n",b);
                }
+#endif
        }
 }
 
@@ -2534,13 +2343,13 @@ static void init_tda9850(struct i2c_bus *bus)
 
 static void idcard(struct bttv *btv)
 {
-       int tunertype;
        btwrite(0, BT848_GPIO_OUT_EN);
        DEBUG(printk(KERN_DEBUG "bttv: GPIO: 0x%08x\n", btread(BT848_GPIO_DATA)));
 
        /* Default the card to the user-selected one. */
        btv->type=card;
+        btv->tuner_type=-1; /* use default tuner type */
+
        /* If we were asked to auto-detect, then do so! 
           Right now this will only recognize Miro, Hauppauge or STB
           */
@@ -2553,6 +2362,11 @@ static void idcard(struct bttv *btv)
                else
                        if (I2CRead(&(btv->i2c), I2C_STBEE)>=0)
                                btv->type=BTTV_STB;
+
+                if (btv->type == BTTV_MIRO) {
+                        /* auto detect tuner for MIRO cards */
+                        btv->tuner_type=((btread(BT848_GPIO_DATA)>>10)-1)&7;
+                }
        }
 
         if (I2CRead(&(btv->i2c), I2C_TDA9850) >=0)
@@ -2583,13 +2397,6 @@ static void idcard(struct bttv *btv)
        {
                case BTTV_MIRO:
                        printk("MIRO\n");
-                       if (btv->have_tuner) 
-                       {
-                               tunertype=((btread(BT848_GPIO_DATA)>>10)-1)&7;
-                               i2c_control_device(&(btv->i2c),
-                                                  I2C_DRIVERID_TUNER,
-                                                  TUNER_SET_TYPE,&tunertype);
-                       }
                        strcpy(btv->video_dev.name,"BT848(Miro)");
                        break;
                case BTTV_HAUPPAUGE:
@@ -2666,7 +2473,7 @@ static void bt848_set_risc_jmps(struct bttv *btv)
        btv->risc_jmp[12]=BT848_RISC_JUMP;
        btv->risc_jmp[13]=virt_to_bus(btv->risc_jmp);
 
-       /* enable cpaturing and DMA */
+       /* enable capturing and DMA */
        btaor(flags, ~0x0f, BT848_CAP_CTL);
        if (flags&0x0f)
                bt848_dma(btv, 3);
@@ -2973,30 +2780,29 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
  
 static int find_bt848(void)
 {
-       short pci_index;    
        unsigned char command, latency;
        int result;
-       unsigned char bus, devfn;
        struct bttv *btv;
+       struct pci_dev *dev;
 
        bttv_num=0;
 
        if (!pcibios_present()) 
        {
-               DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessable!\n"));
+               DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessible!\n"));
                return 0;
        }
-
-       for (pci_index = 0;
-                !pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
-                                    pci_index, &bus, &devfn)
-             ||!pcibios_find_device(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
-                                   pci_index, &bus, &devfn);
-               ++pci_index) 
+       for (dev = pci_devices; dev != NULL; dev = dev->next) 
        {
+               if (dev->vendor != PCI_VENDOR_ID_BROOKTREE)
+                       continue;
+               if (dev->device != PCI_DEVICE_ID_BT849 &&
+                       dev->device != PCI_DEVICE_ID_BT848)
+                       continue;
+
+               /* Ok, Bt848 or Bt849 found! */
                btv=&bttvs[bttv_num];
-               btv->bus=bus;
-               btv->devfn=devfn;
+               btv->dev=dev;
                btv->bt848_mem=NULL;
                btv->vbibuf=NULL;
                btv->risc_jmp=NULL;
@@ -3009,12 +2815,10 @@ static int find_bt848(void)
 
                btv->vbip=VBIBUF_SIZE;
 
-               pcibios_read_config_word(btv->bus, btv->devfn, PCI_DEVICE_ID,
-                                        &btv->id);
-               pcibios_read_config_byte(btv->bus, btv->devfn,
-                       PCI_INTERRUPT_LINE, &btv->irq);
-               pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
-                       &btv->bt848_adr);
+               pci_read_config_word (btv->dev, PCI_DEVICE_ID,      &btv->id);
+
+               /* pci_read_config_dword(btv->dev, PCI_BASE_ADDRESS_0, &btv->bt848_adr); */
+               btv->bt848_adr = btv->dev->base_address[0];
     
                if (remap&&(!bttv_num))
                { 
@@ -3022,20 +2826,19 @@ static int find_bt848(void)
                        remap&=PCI_BASE_ADDRESS_MEM_MASK;
                        printk(KERN_INFO "Remapping to : 0x%08x.\n", remap);
                        remap|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
-                       pcibios_write_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
-                                remap);
-                       pcibios_read_config_dword(btv->bus, btv->devfn, PCI_BASE_ADDRESS_0,
-                               &btv->bt848_adr);
+                       pci_write_config_dword(btv->dev, PCI_BASE_ADDRESS_0, remap);
+                       pci_read_config_dword(btv->dev,  PCI_BASE_ADDRESS_0, &btv->bt848_adr);
+                       btv->dev->base_address[0] = btv->bt848_adr;
                }                                       
     
                btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_CLASS_REVISION,
+               pci_read_config_byte(btv->dev, PCI_CLASS_REVISION,
                             &btv->revision);
                printk(KERN_INFO "bttv: Brooktree Bt%d (rev %d) ",
                        btv->id, btv->revision);
                printk("bus: %d, devfn: %d, ",
-                       btv->bus, btv->devfn);
-               printk("irq: %d, ",btv->irq);
+                       btv->dev->bus->number, btv->dev->devfn);
+               printk("irq: %d, ",btv->dev->irq);
                printk("memory: 0x%08x.\n", btv->bt848_adr);
     
                btv->pll = 0;
@@ -3049,7 +2852,7 @@ static int find_bt848(void)
                 
                btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
 
-               result = request_irq(btv->irq, bttv_irq,
+               result = request_irq(btv->dev->irq, bttv_irq,
                        SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
                if (result==-EINVAL) 
                {
@@ -3058,29 +2861,27 @@ static int find_bt848(void)
                }
                if (result==-EBUSY)
                {
-                       printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->irq);
+                       printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->dev->irq);
                        return result;
                }
                if (result < 0) 
                        return result;
 
                /* Enable bus-mastering */
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
+               pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
                command|=PCI_COMMAND_MASTER;
-               pcibios_write_config_byte(btv->bus, btv->devfn, PCI_COMMAND, command);
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
+               pci_write_config_byte(btv->dev, PCI_COMMAND, command);
+               pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
                if (!(command&PCI_COMMAND_MASTER)) 
                {
                        printk(KERN_ERR "bttv: PCI bus-mastering could not be enabled\n");
                        return -1;
                }
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_LATENCY_TIMER,
-                       &latency);
+               pci_read_config_byte(btv->dev, PCI_LATENCY_TIMER, &latency);
                if (!latency) 
                {
                        latency=32;
-                       pcibios_write_config_byte(btv->bus, btv->devfn,
-                                                 PCI_LATENCY_TIMER, latency);
+                       pci_write_config_byte(btv->dev, PCI_LATENCY_TIMER, latency);
                }
                DEBUG(printk(KERN_DEBUG "bttv: latency: %02x\n", latency));
                bttv_num++;
@@ -3114,9 +2915,10 @@ static void release_bttv(void)
                i2c_unregister_bus((&btv->i2c));
 
                /* disable PCI bus-mastering */
-               pcibios_read_config_byte(btv->bus, btv->devfn, PCI_COMMAND, &command);
-               command|=PCI_COMMAND_MASTER;
-               pcibios_write_config_byte(btv->bus, btv->devfn, PCI_COMMAND, command);
+               pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
+               /* Should this be &=~ ?? */
+               command|=PCI_COMMAND_MASTER;
+               pci_write_config_byte(btv->dev, PCI_COMMAND, command);
     
                /* unmap and free memory */
                if (btv->grisc)
@@ -3137,7 +2939,7 @@ static void release_bttv(void)
                        vfree((void *) btv->vbibuf);
 
 
-               free_irq(btv->irq,btv);
+               free_irq(btv->dev->irq,btv);
                DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%08x.\n", btv->bt848_mem));
                if (btv->bt848_mem)
                        iounmap(btv->bt848_mem);
index c935e76f012781232d4435a35afaca5382e4caf4..737a6e4ec7e6f245d1aa6e0c0164a40235b1e48d 100644 (file)
@@ -54,7 +54,7 @@ struct bttv_window
        ushort swidth, sheight;
        short cropx, cropy;
        ushort cropwidth, cropheight;
-       unsigned int vidadr;
+       unsigned long vidadr;
        ushort freq;
        int norm;
        int interlace;
@@ -74,12 +74,11 @@ struct bttv
        struct i2c_bus i2c;
        int have_msp3400;
        int have_tuner;
+        int tuner_type;
 
        unsigned short id;
-       unsigned char bus;          /* PCI bus the Bt848 is on */
-       unsigned char devfn;
+       struct pci_dev *dev;
        unsigned char revision;
-       unsigned char irq;          /* IRQ used by Bt848 card */
        unsigned int bt848_adr;      /* bus address of IO mem returned by PCI BIOS */
        unsigned char *bt848_mem;   /* pointer to mapped IO memory */
        unsigned long busriscmem; 
index 56d67aa14104898383e65e74e727d20d94ccca34..c3944fd1b1b6d5f27488a0099042c84000198119 100644 (file)
@@ -164,16 +164,25 @@ int last_console = 0;
 int want_console = -1;
 int kmsg_redirect = 0;
 
+/*
+ * For each existing display, we have a pointer to console currently visible
+ * on that display, allowing consoles other than fg_console to be refreshed
+ * appropriately. Unless the low-level driver supplies its own display_fg
+ * variable, we use this one for the "master display".
+ */
+static struct vc_data *master_display_fg = NULL;
+
 /*
  *     Low-Level Functions
  */
 
 #define IS_FG (currcons == fg_console)
+#define IS_VISIBLE (*display_fg == vc_cons[currcons].d)
 
 #ifdef VT_BUF_VRAM_ONLY
 #define DO_UPDATE 0
 #else
-#define DO_UPDATE IS_FG
+#define DO_UPDATE IS_VISIBLE
 #endif
 
 static inline unsigned short *screenpos(int currcons, int offset, int viewed)
@@ -205,7 +214,7 @@ static void scrup(int currcons, unsigned int t, unsigned int b, int nr)
                nr = b - t - 1;
        if (b > video_num_lines || t >= b || nr < 1)
                return;
-       if (IS_FG && sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr))
+       if (IS_VISIBLE && sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr))
                return;
        d = (unsigned short *) (origin+video_size_row*t);
        s = (unsigned short *) (origin+video_size_row*(t+nr));
@@ -224,7 +233,7 @@ scrdown(int currcons, unsigned int t, unsigned int b, int nr)
                nr = b - t - 1;
        if (b > video_num_lines || t >= b || nr < 1)
                return;
-       if (IS_FG && sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr))
+       if (IS_VISIBLE && sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr))
                return;
        s = (unsigned short *) (origin+video_size_row*(b-nr-1));
        step = video_num_columns * nr;
@@ -401,7 +410,6 @@ static void delete_char(int currcons, unsigned int nr)
        }
 }
 
-/* FIXME: Does it make sense to hide cursor on non-fg consoles? */
 static inline void hide_cursor(int currcons)
 {
     sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
@@ -419,7 +427,7 @@ void set_cursor(int currcons)
 
 static void set_origin(int currcons)
 {
-       if (!IS_FG ||
+       if (!IS_VISIBLE ||
            !sw->con_set_origin ||
            !sw->con_set_origin(vc_cons[currcons].d))
                origin = (unsigned long) screenbuf;
@@ -442,9 +450,11 @@ static inline void save_screen(void)
 void update_screen(int new_console)
 {
        int currcons = fg_console;
-       int xx, yy, startx, attrib;
+       int redraw = 1;
+       int xx, yy, startx, attrib, old_console;
        unsigned short *p, *q;
        static int lock = 0;
+       struct vc_data **display;
 
        if (lock)
                return;
@@ -457,31 +467,42 @@ void update_screen(int new_console)
 
        clear_selection();
 
-       fg_console = new_console;
-       set_origin(currcons);
-       currcons = new_console;
-       sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
-       set_origin(currcons);
-       if (sw->con_switch (vc_cons[currcons].d)) {
-               /* Update the screen contents */
-               p = (unsigned short *)origin;
-               attrib = scr_readw(p) & 0xff00;
-               for (yy = 0; yy < video_num_lines; yy++) {
-                       q = p;
-                       for (startx = xx = 0; xx < video_num_columns; xx++) {
-                               if (attrib != (scr_readw(p) & 0xff00)) {
-                                       if (p > q)
-                                               sw->con_putcs (vc_cons[currcons].d, q,
-                                                              p - q, yy, startx);
-                                       startx = xx;
-                                       q = p;
-                                       attrib = (scr_readw(p) & 0xff00);
+       hide_cursor(currcons);
+       if (fg_console != new_console) {
+               display = vc_cons[new_console].d->vc_display_fg;
+               old_console = (*display) ? (*display)->vc_num : fg_console;
+               *display = vc_cons[new_console].d;
+               fg_console = new_console;
+               currcons = old_console;
+               if (!IS_VISIBLE)
+                       set_origin(currcons);
+               currcons = new_console;
+               if (old_console == new_console)
+                       redraw = 0;
+       }
+       if (redraw) {
+               set_origin(currcons);
+               if (sw->con_switch (vc_cons[currcons].d)) {
+                       /* Update the screen contents */
+                       p = (unsigned short *)origin;
+                       attrib = scr_readw(p) & 0xff00;
+                       for (yy = 0; yy < video_num_lines; yy++) {
+                               q = p;
+                               for (startx = xx = 0; xx < video_num_columns; xx++) {
+                                       if (attrib != (scr_readw(p) & 0xff00)) {
+                                               if (p > q)
+                                                       sw->con_putcs (vc_cons[currcons].d, q,
+                                                                      p - q, yy, startx);
+                                               startx = xx;
+                                               q = p;
+                                               attrib = (scr_readw(p) & 0xff00);
+                                       }
+                                       p++;
                                }
-                               p++;
+                               if (p > q)
+                                       sw->con_putcs (vc_cons[currcons].d, q,
+                                                      p - q, yy, startx);
                        }
-                       if (p > q)
-                               sw->con_putcs (vc_cons[currcons].d, q,
-                                              p - q, yy, startx);
                }
        }
        set_cursor (currcons);
@@ -504,6 +525,7 @@ void visual_init(int currcons)
     /* ++Geert: sw->con_init determines console size */
     sw = conswitchp;
     cons_num = currcons;
+    display_fg = &master_display_fg;
     sw->con_init(vc_cons[currcons].d, 1);
     video_size_row = video_num_columns<<1;
     video_screen_size = video_num_lines*video_size_row;
@@ -1155,6 +1177,7 @@ static void setterm_command(int currcons)
                                update_screen(par[1]-1);
                        break;
                case 13: /* unblank the screen */
+                       /* FIXME: call poke_blanked_console? */
                        unblank_screen();
                        break;
                case 14: /* set vesa powerdown interval */
@@ -1692,6 +1715,12 @@ static int do_con_write(struct tty_struct * tty, int from_user,
            return 0;
        }
 
+       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 ?? */
+       }
+
        /* undraw cursor first */
        if (DO_UPDATE)
                hide_cursor(currcons);
@@ -1700,12 +1729,6 @@ static int do_con_write(struct tty_struct * tty, int from_user,
        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);
@@ -1816,7 +1839,6 @@ static int do_con_write(struct tty_struct * tty, int from_user,
                        }
                        continue;
                }
-               /* FIXME: Handle tabs in a special way and use putcs for them as well */
                FLUSH
                do_con_trol(tty, currcons, c);
        }
@@ -1839,6 +1861,7 @@ static void console_bh(void)
 {
        if (want_console >= 0) {
                if (want_console != fg_console) {
+                       clear_selection();
                        save_screen();
                        change_console(want_console);
                        /* we only changed when the console had already
@@ -2095,12 +2118,9 @@ static void con_start(struct tty_struct *tty)
 
 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);
+       set_cursor(vt->vc_num);
 }
 
 /*
@@ -2155,8 +2175,6 @@ static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols,
  * This routine initializes console interrupts, and does nothing
  * else. If you want the screen to clear, call tty_write with
  * the appropriate escape-sequence.
- *
- * FIXME: return early if we don't _have_ a video card installed.
  */
 
 struct tty_driver console_driver;
@@ -2239,6 +2257,8 @@ __initfunc(unsigned long con_init(unsigned long kmem_start))
                }
        }
        currcons = fg_console = 0;
+       master_display_fg = vc_cons[currcons].d;
+       set_origin(currcons);
        save_screen();
        gotoxy(currcons,x,y);
        csi_J(currcons, 0);
@@ -2259,6 +2279,42 @@ __initfunc(unsigned long con_init(unsigned long kmem_start))
        return kmem_start;
 }
 
+/*
+ *     If we support more console drivers, this function is used
+ *     when a driver wants to take over some existing consoles
+ *     and become default driver for newly opened ones.
+ */
+
+#ifndef VT_BUF_VRAM_ONLY
+
+void take_over_console(struct consw *csw, int first, int last, int deflt)
+{
+       int i;
+       const char *desc;
+
+       if (deflt)
+               conswitchp = csw;
+       desc = csw->con_startup();
+       if (!desc) return;
+
+       for (i = first; i <= last; i++) {
+               if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)
+                       continue;
+               if (i == fg_console &&
+                   vc_cons[i].d->vc_sw->con_save_screen)
+                       vc_cons[i].d->vc_sw->con_save_screen(vc_cons[i].d);
+               vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);
+               vc_cons[i].d->vc_sw = csw;
+               vc_cons[i].d->vc_sw->con_init(vc_cons[i].d, 0);
+               }
+       printk("Console: switching to %s %s %dx%d\n",
+              vc_cons[fg_console].d->vc_can_do_color ? "colour" : "mono",
+              desc, vc_cons[fg_console].d->vc_cols, vc_cons[fg_console].d->vc_rows);
+       set_palette();
+}
+
+#endif
+
 /*
  *     Screen blanking
  */
@@ -2273,11 +2329,13 @@ void set_vesa_blanking(unsigned long arg)
 
 void vesa_blank(void)
 {
-    vc_cons[fg_console].d->vc_sw->con_blank(vesa_blank_mode + 1);
+    struct vc_data *c = vc_cons[fg_console].d;
+    c->vc_sw->con_blank(c, vesa_blank_mode + 1);
 }
 
 void vesa_powerdown(void)
 {
+    struct vc_data *c = vc_cons[fg_console].d;
     /*
      *  Power down if currently suspended (1 or 2),
      *  suspend if currently blanked (0),
@@ -2286,11 +2344,11 @@ void vesa_powerdown(void)
      */
     switch (vesa_blank_mode) {
        case VESA_NO_BLANKING:
-           vc_cons[fg_console].d->vc_sw->con_blank(VESA_VSYNC_SUSPEND+1);
+           c->vc_sw->con_blank(c, VESA_VSYNC_SUSPEND+1);
            break;
        case VESA_VSYNC_SUSPEND:
        case VESA_HSYNC_SUSPEND:
-           vc_cons[fg_console].d->vc_sw->con_blank(VESA_POWERDOWN+1);
+           c->vc_sw->con_blank(c, VESA_POWERDOWN+1);
            break;
     }
 }
@@ -2305,17 +2363,28 @@ void vesa_powerdown_screen(void)
 
 void do_blank_screen(int nopowersave)
 {
-       int currcons;
+       int currcons = fg_console;
 
        if (console_blanked)
                return;
 
+       /* entering graphics mode? */
+       if (nopowersave) {
+               save_screen();
+               hide_cursor(currcons);
+               sw->con_blank(vc_cons[currcons].d, -1);
+               console_blanked = fg_console + 1;
+               set_origin(currcons);
+               return;
+       }
+
        /* don't blank graphics */
        if (vt_cons[fg_console]->vc_mode != KD_TEXT) {
                console_blanked = fg_console + 1;
-               hide_cursor(fg_console);
                return;
        }
+
+       hide_cursor(fg_console);
        if(vesa_off_interval && !nopowersave) {
                timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
                timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
@@ -2325,9 +2394,8 @@ void do_blank_screen(int nopowersave)
                timer_table[BLANK_TIMER].fn = unblank_screen;
        }
 
-       currcons = fg_console;
        save_screen();
-       sw->con_blank(1);
+       sw->con_blank(vc_cons[currcons].d, 1);
        console_blanked = fg_console + 1;
 
        if(!nopowersave)
@@ -2358,16 +2426,12 @@ void do_unblank_screen(void)
 
        currcons = fg_console;
        console_blanked = 0;
-       if (sw->con_blank(0))
+       if (sw->con_blank(vc_cons[currcons].d, 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);
@@ -2400,7 +2464,7 @@ void poke_blanked_console(void)
 void set_palette(void)
 {
     if (vt_cons[fg_console]->vc_mode != KD_GRAPHICS)
-       conswitchp->con_set_palette(vc_cons[fg_console].d, color_table);
+       vc_cons[fg_console].d->vc_sw->con_set_palette(vc_cons[fg_console].d, color_table);
 }
 
 int set_get_cmap(unsigned char *arg, int set)
@@ -2579,3 +2643,7 @@ EXPORT_SYMBOL(default_grn);
 EXPORT_SYMBOL(default_blu);
 EXPORT_SYMBOL(video_font_height);
 EXPORT_SYMBOL(video_scan_lines);
+
+#ifndef VT_BUF_VRAM_ONLY
+EXPORT_SYMBOL(take_over_console);
+#endif
index 3fd85c5b100e79429513da2b9f58cd7cf08e13c7..4052f4db3a24a3c89a8c530bb5f369981407aa2d 100644 (file)
@@ -62,6 +62,8 @@
 #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 display_fg     (vc_cons[currcons].d->vc_display_fg)
+
 #define vcmode         (vt_cons[currcons]->vc_mode)
 
 #define structsize     (sizeof(struct vc_data) + sizeof(struct vt_struct))
index dd9851f9e833a319caf29368d7836e268a2cc079..7179022aae0821f86b3bb4214c4b531053169627 100644 (file)
@@ -83,8 +83,6 @@ extern void hpfb_init(void);
 extern void hpfb_setup(char *options, int *ints);
 extern void sbusfb_init(void);
 extern void sbusfb_setup(char *options, int *ints);
-extern void promfb_init(void);
-extern void promfb_setup(char *options, int *ints);
 
 static struct {
        const char *name;
@@ -145,9 +143,6 @@ static struct {
 #ifdef CONFIG_FB_SBUS
        { "sbus", sbusfb_init, sbusfb_setup },
 #endif
-#ifdef CONFIG_FB_PROM
-       { "prom", promfb_init, promfb_setup },
-#endif
 #ifdef CONFIG_GSP_RESOLVER
        /* Not a real frame buffer device... */
        { "resolver", NULL, resolver_video_setup },
@@ -474,27 +469,6 @@ static struct file_operations fb_fops = {
        NULL            /* fsync        */
 };
 
-static inline void take_over_console(struct consw *sw)
-{
-    int i;
-    extern void set_palette(void);
-
-    conswitchp = sw;
-    conswitchp->con_startup();
-
-    for (i = 0; i < MAX_NR_CONSOLES; i++) {
-       if (!vc_cons[i].d || !vc_cons[i].d->vc_sw)
-           continue;
-       if (i == fg_console &&
-           vc_cons[i].d->vc_sw->con_save_screen)
-               vc_cons[i].d->vc_sw->con_save_screen(vc_cons[i].d);
-       vc_cons[i].d->vc_sw->con_deinit(vc_cons[i].d);
-       vc_cons[i].d->vc_sw = conswitchp;
-       vc_cons[i].d->vc_sw->con_init(vc_cons[i].d, 0);
-    }
-    set_palette();
-}
-
 int
 register_framebuffer(struct fb_info *fb_info)
 {
@@ -523,7 +497,7 @@ register_framebuffer(struct fb_info *fb_info)
 
        if (first) {
                first = 0;
-               take_over_console(&fb_con);
+               take_over_console(&fb_con, 0, MAX_NR_CONSOLES-1, 1);
        }
 
        return 0;
index 9c7cdbcf5ea4222b1c23f842019b783df9231c76..2ca829fbf77921d39a753e91911a5971b1746a6f 100644 (file)
@@ -68,7 +68,7 @@ static int rdtsc_ok = 1;
 #ifdef __i386__
 __initfunc(static void i386_capability(void))
 {
-       if (boot_cpu_data.x86_capability & X86_FEATURE_TSC))
+       if (boot_cpu_data.x86_capability & X86_FEATURE_TSC)
                rdtsc_ok = 1;
        else
                printk(KERN_INFO "%s: cpu does not support the rdtsc instruction\n", hfmodem_drvname);
index 5507d94ba201a25cdee5234f07394139d34899bb..ad8f0fe950804b0a4a8d0b0838ad50cb7b96c014 100644 (file)
@@ -34,11 +34,18 @@ static struct i2c_bus    *busses[I2C_BUS_MAX];
 static struct i2c_driver *drivers[I2C_DRIVER_MAX];
 static int bus_count = 0, driver_count = 0;
 
+extern int i2c_tuner_init(void);
+extern int msp3400c_init(void);
+
 int i2c_init(void)
 {
        printk(KERN_INFO "i2c: initialized%s\n",
                scan ? " (i2c bus scan enabled)" : "");
        /* anything to do here ? */
+#ifdef CONFIG_VIDEO_BT848
+       i2c_tuner_init();
+       msp3400c_init();
+#endif 
        return 0;
 }
 
index ef6abbd4f87e86acdf757b9bcb2f28d00332c832..d2f51af82dbe5b37a10f50b61d92c72ca898105e 100644 (file)
@@ -566,6 +566,9 @@ __initfunc(int chr_dev_init(void))
 #ifdef CONFIG_FTAPE
        ftape_init();
 #endif
+#ifdef CONFIG_VIDEO_BT848
+       i2c_init();
+#endif
 #ifdef CONFIG_VIDEO_DEV
        videodev_init();
 #endif
index 7f97e0f899cf574dc249dcf5cefc3c1c8d685238..4f1e49cec02b3e56a30c5f267e15284a8d59c3bb 100644 (file)
@@ -43,6 +43,7 @@ struct rt_device
        int port;
        int curvol;
        unsigned long curfreq;
+       int muted;
 };
 
 
@@ -51,7 +52,7 @@ struct rt_device
 static void sleep_delay(long n)
 {
        /* Sleep nicely for 'n' uS */
-       int d=n/1000000/HZ;
+       int d=n/(1000000/HZ);
        if(!d)
                udelay(n);
        else
@@ -77,26 +78,33 @@ static void rt_incvol(void)
        outb(0xd8, io);         /* volume steady + sigstr + on  */
 }
 
-static void rt_mute(void)
+static void rt_mute(struct rt_device *dev)
 {
-       outb(0x48, io);                 /* volume down but still "on"   */
-       sleep_delay(2000000);           /* make sure it's totally down  */
-       outb(0xc0, io);                 /* volume steady, off           */
+       dev->muted = 1;
+       outb(0xd0, io);                 /* volume steady, off           */
 }
 
 static int rt_setvol(struct rt_device *dev, int vol)
 {
        int i;
 
-       if(vol == dev->curvol)          /* no change needed */
+       if(vol == dev->curvol) {        /* requested volume = current */
+               if (dev->muted) {       /* user is unmuting the card  */
+                       dev->muted = 0;
+                       outb (0xd8, io);        /* enable card */
+               }       
+       
                return 0;
+       }
 
        if(vol == 0) {                  /* volume = 0 means mute the card */
-               rt_mute();
-               dev->curvol = 0;
+               outb(0x48, io);         /* volume down but still "on"   */
+               sleep_delay(2000000);   /* make sure it's totally down  */
+               outb(0xd0, io);         /* volume steady, off           */
                return 0;
        }
 
+       dev->muted = 0;
        if(vol > dev->curvol)
                for(i = dev->curvol; i < vol; i++) 
                        rt_incvol();
@@ -116,7 +124,7 @@ static int rt_setvol(struct rt_device *dev, int vol)
 
 void send_0_byte(int port, struct rt_device *dev)
 {
-       if (dev->curvol == 0) {
+       if ((dev->curvol == 0) || (dev->muted)) {
                outb_p(128+64+16+  1, port);   /* wr-enable + data low */
                outb_p(128+64+16+2+1, port);   /* clock */
        }
@@ -129,7 +137,7 @@ void send_0_byte(int port, struct rt_device *dev)
 
 void send_1_byte(int port, struct rt_device *dev)
 {
-       if (dev->curvol == 0) {
+       if ((dev->curvol == 0) || (dev->muted)) {
                outb_p(128+64+16+4  +1, port);   /* wr-enable+data high */
                outb_p(128+64+16+4+2+1, port);   /* clock */
        } 
@@ -172,7 +180,7 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
        send_0_byte (io, dev);          /* 22: spacing (0 = 25 kHz)   */
        send_1_byte (io, dev);          /* 23: AM/FM (FM = 1, always) */
 
-       if (dev->curvol == 0)
+       if ((dev->curvol == 0) || (dev->muted))
                outb (0xd0, io);        /* volume steady + sigstr */
        else
                outb (0xd8, io);        /* volume steady + sigstr + on */
@@ -262,10 +270,8 @@ static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        if(v.audio) 
                                return -EINVAL;
 
-                       if(v.flags&VIDEO_AUDIO_MUTE) {
-                               rt_mute();
-                               rt->curvol=0;
-                       }
+                       if(v.flags&VIDEO_AUDIO_MUTE) 
+                               rt_mute(rt);
                        else
                                rt_setvol(rt,v.volume/6554);    
 
@@ -322,9 +328,15 @@ __initfunc(int rtrack_init(struct video_init *v))
                
        request_region(io, 2, "rtrack");
        printk(KERN_INFO "AIMSlab Radiotrack/radioreveal card driver.\n");
-       /* mute card - prevents noisy bootups */
-       rt_mute();
+
+       /* mute card - prevents noisy bootups */
+
+       /* this ensures that the volume is all the way down  */
+       outb(0x48, io);         /* volume down but still "on"   */
+       sleep_delay(2000000);   /* make sure it's totally down  */
+       outb(0xc0, io);         /* steady volume, mute card     */
        rtrack_unit.curvol = 0;
+
        return 0;
 }
 
index 49431ca9b909724beb1f9f2025f147a4cbb5f080..ae975288123d0dc07f8862e4d55664d98bcb5307 100644 (file)
@@ -39,7 +39,7 @@ static int io = CONFIG_RADIO_SF16FMI_PORT;
 static int users = 0;
 
 /* local things */
-#define RSF16_ENCODE(x)        ((x*(1000/RADIO_FM_RES)+10700)/50)
+#define RSF16_ENCODE(x)        ((x*(1000/4)+10700)/50)
 
 static void outbits(int bits, int data, int port)
 {
diff --git a/drivers/char/radio-zoltrix.c b/drivers/char/radio-zoltrix.c
new file mode 100644 (file)
index 0000000..b07f4ce
--- /dev/null
@@ -0,0 +1,337 @@
+/* zoltrix radio plus driver for Linux radio support
+ * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
+ *
+ * BUGS  
+ *  The signal strength query is unsurprisingly inaccurate.  And it seems
+ *  to indicate that (on my card, at least) the frequency setting isn't
+ *  too great.  It seems to work in a similar way to a car stereo which
+ *  flickers when it is near or on a station...
+ *
+ *  There seems to be a problem with the volume setting that I must still
+ *  figure out. This is a minor problem... It still works but you may
+ *  have to set the card lounder to get the same volume.
+ *
+ *  Some code derived from code by Frans Brinkman
+ */
+
+#include <linux/module.h>      /* Modules                        */
+#include <linux/init.h>                /* Initdata                       */
+#include <linux/ioport.h>      /* check_region, request_region   */
+#include <linux/delay.h>       /* udelay                 */
+#include <asm/io.h>            /* outb, outb_p                   */
+#include <asm/uaccess.h>       /* copy to/from user              */
+#include <linux/videodev.h>    /* kernel radio structs           */
+#include <linux/config.h>      /* CONFIG_RADIO_ZOLTRIX_PORT      */
+
+#ifndef CONFIG_RADIO_ZOLTRIX_PORT
+#define CONFIG_RADIO_ZOLTRIX_PORT -1
+#endif
+
+static int io = CONFIG_RADIO_ZOLTRIX_PORT;
+static int users = 0;
+
+struct zol_device {
+       int port;
+       int curvol;
+       unsigned long curfreq;
+       int muted;
+};
+
+
+/* local things */
+
+static void sleep_delay(long n)
+{
+       /* Sleep nicely for 'n' uS */
+       int d = n / (1000000 / HZ);
+       if (!d)
+               udelay(n);
+       else {
+               /* Yield CPU time */
+               unsigned long x = jiffies;
+               while ((jiffies - x) <= d)
+                       schedule();
+       }
+}
+
+static void zol_mute(struct zol_device *dev)
+{
+       dev->muted = 1;
+       outb(0, io);
+       outb(0, io);
+       inb(io + 3);            /* Zoltrix needs to be read to confirm */
+}
+
+static int zol_setvol(struct zol_device *dev, int vol)
+{
+       int l;
+
+       if (vol == dev->curvol) {       /* requested volume = current */
+               if (dev->muted) {       /* user is unmuting the card  */
+                       dev->muted = 0;
+                       outb(vol, io);
+                       sleep_delay(20000);
+                       l = inb(io + 2);
+               }
+               return 0;
+       }
+       if (vol == 0) {         /* volume = 0 means mute the card */
+               outb(0, io);
+               outb(0, io);
+               l = inb(io + 3);
+               return 0;
+       }
+       dev->muted = 0;
+       dev->curvol = vol;
+
+       outb(vol, io);
+       sleep_delay(20000);
+       l = inb(io + 2);
+
+       return 0;
+}
+
+static int zol_setfreq(struct zol_device *dev, unsigned long freq)
+{
+       /* tunes the radio to the desired frequency */
+       unsigned long long bitmask, f, m;
+       int i, l;
+
+       m = (freq * 25 / 4 - 8800) * 2;
+       f = (unsigned long long) m + 0x4d1c;
+
+       bitmask = 0xc480402c10080000ull;
+       i = 45;
+
+       outb(0x00, io);
+       outb(0x00, io);
+       sleep_delay(10000);
+       inb(io + 3);
+       outb(0x40, io);
+       outb(0xc0, io);
+
+       bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( /*stereo */ 0 << 31));
+       while (i--) {
+               if ((bitmask & 0x8000000000000000ull) != 0) {
+                       outb(0x80, io);
+                       sleep_delay(50);
+                       outb(0x00, io);
+                       sleep_delay(50);
+                       outb(0x80, io);
+                       sleep_delay(50);
+               } else {
+                       outb(0xc0, io);
+                       sleep_delay(50);
+                       outb(0x40, io);
+                       sleep_delay(50);
+                       outb(0xc0, io);
+                       sleep_delay(50);
+               }
+               bitmask *= 2;
+       }
+       /* termination sequence */
+       outb(0x80, io);
+       outb(0xc0, io);
+       outb(0x40, io);
+       outb(0x00, io);
+       sleep_delay(10000);
+       l = inb(io + 2);
+       sleep_delay(10000);
+       l = inb(io + 1);
+       outb(dev->curvol, io);
+       sleep_delay(10000);
+       l = inb(io + 2);
+       return 0;
+}
+
+/* Get signal strenght */
+int zol_getsigstr(struct zol_device *dev)
+{
+       int a, b;
+       outb(0x00, io);
+       sleep_delay(10000);
+       a = inb(io + 2);
+       sleep_delay(20000);
+       b = inb(io + 1);
+       outb(0x00, io);
+
+       if (((a | b) & 255) != 0x0ff)
+               return (1);
+       else
+               return (0);
+
+       if (inb(io) & 2)        /* bit set = no signal present    */
+               return 0;
+       return 1;               /* signal present               */
+}
+
+static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       struct zol_device *rt = dev->priv;
+
+       switch (cmd) {
+       case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+                       v.type = VID_TYPE_TUNER;
+                       v.channels = 1;
+                       v.audios = 1;
+                       /* No we don't do pictures */
+                       v.maxwidth = 0;
+                       v.maxheight = 0;
+                       v.minwidth = 0;
+                       v.minheight = 0;
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+       case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+                       if (copy_from_user(&v, arg, sizeof(v)) != 0)
+                               return -EFAULT;
+                       if (v.tuner)    /* Only 1 tuner */
+                               return -EINVAL;
+                       v.rangelow = (int) (88.0 * 16);
+                       v.rangehigh = (int) (108.0 * 16);
+                       v.flags = 0;
+                       v.mode = VIDEO_MODE_AUTO;
+                       v.signal = 0xFFFF * zol_getsigstr(rt);
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+       case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+                       if (copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if (v.tuner != 0)
+                               return -EINVAL;
+                       /* Only 1 tuner so no setting needed ! */
+                       return 0;
+               }
+       case VIDIOCGFREQ:
+               if (copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
+                       return -EFAULT;
+               return 0;
+       case VIDIOCSFREQ:
+               if (copy_from_user(&rt->curfreq, arg, sizeof(rt->curfreq)))
+                       return -EFAULT;
+               zol_setfreq(rt, rt->curfreq);
+               return 0;
+       case VIDIOCGAUDIO:
+               {
+                       struct video_audio v;
+                       memset(&v, 0, sizeof(v));
+                       v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
+                       v.volume = rt->curvol * 6554;
+                       strcpy(v.name, "Radio");
+                       if (copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+       case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+                       if (copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if (v.audio)
+                               return -EINVAL;
+
+                       if (v.flags & VIDEO_AUDIO_MUTE)
+                               zol_mute(rt);
+                       else
+                               zol_setvol(rt, v.volume / 6554);
+
+                       return 0;
+               }
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+static int zol_open(struct video_device *dev, int flags)
+{
+       if (users)
+               return -EBUSY;
+       users++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void zol_close(struct video_device *dev)
+{
+       users--;
+       MOD_DEC_USE_COUNT;
+}
+
+static struct zol_device zoltrix_unit;
+
+static struct video_device zoltrix_radio =
+{
+       "Zoltrix Radio Plus",
+       VID_TYPE_TUNER,
+       VID_HARDWARE_ZOLTRIX,
+       zol_open,
+       zol_close,
+       NULL,                   /* Can't read  (no capture ability) */
+       NULL,                   /* Can't write */
+       zol_ioctl,
+       NULL,
+       NULL
+};
+
+__initfunc(int zoltrix_init(struct video_init *v))
+{
+       if (check_region(io, 2)) {
+               printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
+               return -EBUSY;
+       }
+       zoltrix_radio.priv = &zoltrix_unit;
+
+       if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO) == -1)
+               return -EINVAL;
+
+       request_region(io, 2, "zoltrix");
+       printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
+
+       /* mute card - prevents noisy bootups */
+
+       /* this ensures that the volume is all the way down  */
+
+       outb(0, io);
+       outb(0, io);
+       sleep_delay(20000);
+       inb(io + 3);
+
+       zoltrix_unit.curvol = 0;
+
+       return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("C.van Schaik");
+MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
+
+EXPORT_NO_SYMBOLS;
+
+int init_module(void)
+{
+       if (io == -1) {
+               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+               return -EINVAL;
+       }
+       return zoltrix_init(NULL);
+}
+
+void cleanup_module(void)
+{
+       video_unregister_device(&zoltrix_radio);
+       release_region(io, 2);
+}
+
+#endif
diff --git a/drivers/char/radio.c b/drivers/char/radio.c
deleted file mode 100644 (file)
index 2b79e98..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Radio Card Device Driver for Linux
- *
- * (c) 1997 Matthew Kirkwood <weejock@ferret.lmh.ox.ac.uk>
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-
-#include <linux/miscdevice.h>
-
-#include <asm/uaccess.h>
-
-#include <linux/config.h>
-
-#include <linux/radio.h>
-#ifdef CONFIG_RADIO_RTRACK
-#include "rtrack.h"
-#endif
-#ifdef CONFIG_RADIO_WINRADIO
-#include "winradio.h"
-#endif
-
-int radio_open(struct inode *inode, struct file *file);
-int radio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-
-/* /dev/radio interface */
-static struct file_operations radio_fops = {
-       NULL,                   /* seek */
-       NULL,                   /* read */
-       NULL,                   /* write */
-       NULL,                   /* readdir */
-       NULL,                   /* select */
-       &radio_ioctl,           /* ioctl */
-       NULL,                   /* mmap */
-       &radio_open,            /* we're not allowed NULL, it seems... */
-       NULL                    /* release */
-};
-
-static struct miscdevice radio_miscdevice = {
-       RADIO_MINOR,            /* minor device number */
-       "radio",                /* title */
-       &radio_fops,            /* file operations */
-       NULL, NULL              /* previous and next (not our business) */
-};
-
-
-static struct radio_device *firstdevice, *lastdevice;
-static int numdevices;
-
-__initfunc(void radio_init(void))
-{
-       /* register the handler for the device number... */
-       if(misc_register(&radio_miscdevice)) {
-               printk("radio: couldn't register misc device\n");
-               return;
-       }
-
-       /* do some general initialisation stuff */
-       lastdevice = firstdevice = NULL;
-       numdevices = 0;
-
-#ifdef CONFIG_RADIO_RTRACK
-       radiotrack_init();
-#endif
-#ifdef CONFIG_RADIO_WINRADIO
-       printk("oooops.  no winradio support yet... :-(\n");
-#endif
-/* etc.... */
-
-       printk("radio: registered %d devices\n", numdevices);
-}
-
-
-/* according to drivers/char/misc.c, the "open" call must not be NULL.
- * I'm not sure if I approve, but I didn't write it, so...
- */
-int radio_open(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-
-/* append a device to the linked list... */
-int radio_add_device(struct radio_device *newdev)
-{
-       if(firstdevice == NULL) {
-               firstdevice = newdev;
-       } else {
-               lastdevice->next = newdev;
-       }
-       lastdevice = newdev; numdevices++;
-       newdev->cap->dev_num=numdevices;
-       newdev->next = NULL;                    /* don't need, but... */
-       return(numdevices);
-}
-
-struct radio_device *getdev(int index)
-{
-struct radio_device *retval;
-
-       if(index > numdevices)
-               return NULL;            /* let's have a bit less of that */
-
-       retval = firstdevice;
-       for(;index;index--)
-               retval = retval->next;
-
-       return retval;
-}
-
-
-/* interface routine */
-int radio_ioctl(struct inode *inode, struct file *file,
-               unsigned int cmd, unsigned long arg)
-{
-struct radio_device *dev;
-struct radio_ctl *ctl_arg = (struct radio_ctl*)arg;
-int nowrite;
-int val, ret;
-
-       if((void*)arg == NULL)
-               return -EFAULT;         /* XXX - check errnos are OK */
-
-
-       switch(cmd) {
-       case RADIO_NUMDEVS:
-               return (put_user(numdevices,(int*)arg) ? -EFAULT : 0);
-
-
-       case RADIO_GETCAPS:
-       /* p'raps I should verify for read then write ?? */
-               if(verify_area(VERIFY_WRITE, (void*)arg, sizeof(struct radio_cap)))
-                       return -EFAULT;
-               if((dev = getdev(((struct radio_cap*)arg)->dev_num)) == NULL)
-                       return -EINVAL;
-               copy_to_user((void*)arg, dev->cap, sizeof(struct radio_cap));
-               return 0;
-
-
-       case RADIO_GETBNDCAP:
-               if(verify_area(VERIFY_WRITE, (void*)arg, sizeof(struct radio_band)))
-                       return -EFAULT;
-
-               if((dev = getdev(((struct radio_band*)arg)->dev_num)) == NULL)
-                       return -EINVAL;
-
-               val = ((struct radio_band*)arg)->index;
-               if(val >= dev->cap->num_bwidths)
-                       return -EINVAL;                 /* XXX errno */
-
-               copy_to_user((void*)arg, (dev->bands)+(val*sizeof(struct radio_band)),
-                       sizeof(struct radio_band));
-               return 0;
-       }
-
-
-/* now, we know that arg points to a struct radio_ctl */
-       /* get the requested device */
-       if(verify_area(VERIFY_READ, ctl_arg, sizeof(struct radio_ctl)))
-               return -EFAULT;
-
-       if((dev = getdev(ctl_arg->dev_num)) == NULL)
-               return -EINVAL;
-
-       nowrite = verify_area(VERIFY_WRITE, ctl_arg, sizeof(struct radio_ctl));
-
-       val = ctl_arg->value;
-
-       switch(cmd) {
-       case RADIO_SETVOL:
-               if((val < dev->cap->volmin) || (val > dev->cap->volmax))
-                       return -EINVAL;
-               if((ret = (*(dev->setvol))(dev, val)))
-                       return ret;
-               dev->curvol = val;
-               return 0;
-
-       case RADIO_GETVOL:
-               if(nowrite)
-                       return -EFAULT;
-               ctl_arg->value = dev->curvol;
-               return 0;
-
-
-       case RADIO_SETBAND:
-               if(val >= dev->cap->num_bwidths)
-                       return -EINVAL;
-               if((ret = (*(dev->setband))(dev, val)))
-                       return ret;
-               dev->curband = val;
-               return 0;
-
-       case RADIO_GETBAND:
-               if(nowrite)
-                       return -EFAULT;
-               ctl_arg->value = dev->curband;
-               return 0;
-
-
-       case RADIO_SETFREQ: {
-       struct radio_band *bp;
-
-               bp = (dev->bands) + ((dev->curband) * sizeof(struct radio_band));
-               if((val < bp->freqmin) || (val > bp->freqmax))
-                       return -EINVAL;
-               if((ret = (*(dev->setfreq))(dev, val)))
-                       return ret;
-               dev->curfreq = val;
-               return 0;
-       }
-
-       case RADIO_GETFREQ:
-               if(nowrite)
-                       return -EFAULT;
-               ctl_arg->value = dev->curfreq;
-               return 0;
-
-
-       case RADIO_GETSIGSTR:
-               if(nowrite)
-                       return -EFAULT;
-               ctl_arg->value = (*(dev->getsigstr))(dev);
-               return 0;
-
-
-       default:
-               return -ENOSYS;
-       }
-}
index 20e730a2fac787e8aad92cff6ef329e80acb50b1..b71e35bdd73d2fa7f54540ed375cd422d0e9dde2 100644 (file)
@@ -8,8 +8,6 @@
 #ifndef __RSF16FMI_H
 #define __RSF16FMI_H
 
-#include <linux/radio.h>
-
 int radiosf16fmi_init(void);
 
 #endif /* __RSF16FMI_H */
diff --git a/drivers/char/rtrack.c b/drivers/char/rtrack.c
deleted file mode 100644 (file)
index 7a8163f..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* radiotrack (radioreveal) driver for Linux radio support
- * (c) 1997 M. Kirkwood
- */
-/* TODO: Allow for more than one of these foolish entities :-) */
-
-/* Notes on the hardware (reverse engineered from other peoples'
- * reverse engineering of AIMS' code :-)
- *
- *  Frequency control is done digitally -- ie out(port,encodefreq(95.8));
- *
- *  The signal strength query is unsurprisingly inaccurate.  And it seems
- *  to indicate that (on my card, at least) the frequency setting isn't
- *  too great.  (I have to tune up .025MHz from what the freq should be
- *  to get a report that the thing is tuned.)
- *
- *  Volume control is (ugh) analogue:
- *   out(port, start_increasing_volume);
- *   wait(a_wee_while);
- *   out(port, stop_changing_the_volume);
- *  
- */
-
-#include <linux/config.h>
-#include <linux/radio.h>
-#include <linux/ioport.h>
-
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include "rtrack.h"
-
-/* Let's just be a bit careful here, shall we? */
-#if (CONFIG_RADIO_RTRACK_PORT != 0x20f) && (CONFIG_RADIO_RTRACK_PORT != 0x30f)
-#error Invalid port specified for RadioTrack
-#endif
-
-/* local prototypes */
-void outbits(int bits, int data, int port);
-void decvol(int port);
-void incvol(int port);
-void mute(int port);
-void unmute(int port);
-
-/* public structurey-type things */
-int rt_port = CONFIG_RADIO_RTRACK_PORT;
-
-struct radio_cap rt_cap = {
-       0,                      /* device index (not dealt with here) */
-       RADIO_TYPE_RTRACK,      /* type */
-       1,                      /* number of bandwidths */
-       0, 10                   /* volmin, volmax */
-};
-
-/* we only get one band/protocol with radiotrack */
-struct radio_band rt_band = {
-       0,                      /* device index */
-       0,                      /* bandwidth "index" */
-       RADIO_PROTOCOL_FM,
-       RADIO_BAND_FM_STD,
-       RADIO_FM_FRTOINT(88.0), /* freq range */
-       RADIO_FM_FRTOINT(108.0),
-       0,1                     /* sig strength range */
-};
-
-/* p'raps these should become struct radio_ops and struct radio_status? */
-struct radio_device rt_dev = {
-       &rt_cap,
-       &rt_band,
-       &rt_setvol,
-       0,                              /* curvol */
-       &rt_setband,
-       0,                              /* curband */
-       &rt_setfreq,
-       0,                              /* curfreq */
-       &rt_getsigstr,
-       NULL,                           /* next (to be filled in later) */
-       &rt_port                        /* misc */
-};
-
-
-void radiotrack_init()
-{
-int dev_num, i;
-
-/* XXX - probe here?? - XXX */
-
-/* try to grab the i/o port */
-       if(check_region(rt_port,2)) {
-               printk("rtrack.c: port 0x%x already used\n", rt_port);
-               return;
-       }
-
-       request_region(rt_port,2,"rtrack");
-
-       dev_num = radio_add_device(&rt_dev);
-/* initialise the card */
-       /* set the volume very low */
-       for(i=rt_cap.volmax; i>rt_cap.volmin; i--)
-               decvol(rt_port);
-       rt_dev.curvol = rt_cap.volmin;
-}
-
-
-int rt_setvol(struct radio_device *dev, int vol)
-{
-int port, i;
-
-       if(vol == dev->curvol)
-               return 0;
-
-       port = *(int*)(dev->misc);
-       if(vol == 0)
-               mute(port);
-
-       if(vol > dev->curvol)
-               for(i = dev->curvol; i < vol; i++)
-                       incvol(port);
-       else
-               for(i = dev->curvol; i > vol; i--)
-                       decvol(port);
-
-       if(dev->curvol == 0)
-               unmute(port);
-
-       return 0;
-}
-
-
-int rt_setband(struct radio_device *dev, int band)
-{
-/* we know in advance that we only have one band, and
- * the wrapper checks the validity of all the inputs
- */
-       return 0;
-}
-
-int rt_setfreq(struct radio_device *dev, int freq)
-{
-int myport = *(int*)(dev->misc);
-
-       outbits(16, RTRACK_ENCODE(freq), myport);
-       outbits(8, 0xa0, myport);
-/* XXX - get rid of this once setvol is implemented properly - XXX */
-/* these insist on turning the thing on.  not sure I approve... */
-       mdelay(1);
-       outb(0, myport);
-       outb(0xc8, myport);
-
-       return 0;
-}
-
-int rt_getsigstr(struct radio_device *dev)
-{
-int res;
-int myport = *(int*)(dev->misc);
-
-       outb(0xf8, myport);
-       mdelay(200);
-       res = (int)inb(myport);
-       mdelay(10);
-       outb(0xe8, myport);
-       if(res == 0xfd)
-               return 1;
-       else
-               return 0;
-}
-
-
-/* local things */
-void outbits(int bits, int data, int port)
-{
-       while(bits--) {
-               if(data & 1) {
-                       outw(5, port);
-                       outw(5, port);
-                       outw(7, port);
-                       outw(7, port);
-               } else {
-                       outw(1, port);
-                       outw(1, port);
-                       outw(3, port);
-                       outw(3, port);
-               }
-               data>>=1;
-       }
-}
-
-void decvol(int port)
-{
-       outb(0x48, port);
-       mdelay(100);
-       outb(0xc8, port);
-}
-
-void incvol(int port)
-{
-       outb(0x88, port);
-       mdelay(100);
-       outb(0xc8, port);
-}
-
-void mute(int port)
-{
-       outb(0, port);
-       outb(0xc0, port);
-}
-
-void unmute(int port)
-{
-       outb(0, port);
-       outb(0xc8, port);
-}
diff --git a/drivers/char/rtrack.h b/drivers/char/rtrack.h
deleted file mode 100644 (file)
index b5a9bc1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* RadioTrack (RadioReveal) include file.
- * (c) 1997 M. Kirkwood
- *
- * Not in include/linux/ because there's no need for anyone
- * to know about these details, I reckon.
- */
-
-#ifndef __RTRACK_H
-#define __RTRACK_H
-
-#include <linux/radio.h>
-
-void radiotrack_init(void);
-int rt_setvol(struct radio_device *dev, int vol);
-int rt_setband(struct radio_device *dev, int vol);
-int rt_setfreq(struct radio_device *dev, int vol);
-int rt_getsigstr(struct radio_device *dev);
-
-/* frequency encoding stuff... */
-/* we have to careful not to introduce fp stuff here */
-#define        RTRACK_ENCODE(x)        (((((x)*2)/5)-(40*88))+0xf6c)
-#define        RTRACK_DECODE(x)        (((((x)-0xf6c)+(40*88))*5)/2)
-/* we shouldn't actually need the decode macro (or the excessive bracketing :-) */
-
-#endif /* __RTRACK_H */
index 45c335278ee4c2cfa73a333bcc5d82195e142c95..134c6141e4e423f846dee6d91b43fc687fa467b3 100644 (file)
@@ -48,8 +48,6 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
 #include <linux/malloc.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 1cbc958a384a4a997898c92af1e35bb5a1c0a86e..81bed0e257b3ba312c597b65b81675460f1508d2 100644 (file)
@@ -12,8 +12,8 @@
 
 #include "tuner.h"
 
-int debug = 0; /* insmod parameter */
-int type  = 0; /* tuner type */
+static int debug = 0; /* insmod parameter */
+static int type  = 0; /* tuner type */
 
 #define dprintk     if (debug) printk
 
@@ -248,7 +248,7 @@ EXPORT_NO_SYMBOLS;
 #ifdef MODULE
 int init_module(void)
 #else
-int msp3400c_init(void)
+int i2c_tuner_init(void)
 #endif
 {
        i2c_register_driver(&i2c_driver_tuner);
index deb24e1b568964cc849ba09ef37c3f959108cf86..174c3cc0dd38164d9432389ef6af5b1cd4938953 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
 
 #define VIDEO_NUM_DEVICES      256 
 
@@ -38,6 +42,7 @@ static struct video_device *video_device[VIDEO_NUM_DEVICES];
 
 #ifdef CONFIG_VIDEO_BT848
 extern int init_bttv_cards(struct video_init *);
+extern int i2c_tuner_init(struct video_init *);
 #endif
 #ifdef CONFIG_VIDEO_SAA5249
 extern int init_saa_5249(struct video_init *);
@@ -60,6 +65,7 @@ extern int fmi_init(struct video_init *);
 
 static struct video_init video_init_list[]={
 #ifdef CONFIG_VIDEO_BT848
+       {"i2c-tuner", i2c_tuner_init},
        {"bttv", init_bttv_cards},
 #endif 
 #ifdef CONFIG_VIDEO_SAA5249
@@ -132,8 +138,17 @@ static int video_open(struct inode *inode, struct file *file)
                return -ENODEV;
                
        vfl=video_device[minor];
-       if(vfl==NULL)
-               return -ENODEV;
+       if(vfl==NULL) {
+#ifdef CONFIG_KMOD
+               char modname[20];
+
+               sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor);
+               request_module(modname);
+               vfl=video_device[minor];
+               if (vfl==NULL)
+#endif
+                       return -ENODEV;
+       }
        if(vfl->busy)
                return -EBUSY;
        vfl->busy=1;            /* In case vfl->open sleeps */
index 0b2f1c660e3db5cbc4194c6604b75271de360d44..6825c22ac778cf8248de32b786878b0b24a318e4 100644 (file)
@@ -58,6 +58,16 @@ static void arc_dec_use_count(void)
 #endif
 }
 
+static void arc_fill_inode(struct inode *inode, int fill)
+{
+#ifdef MODULE
+       if (fill)
+               MOD_INC_USE_COUNT;
+       else
+               MOD_DEC_USE_COUNT;
+#endif
+}
+
 static struct parport_operations parport_arc_ops = 
 {
        arc_write_data,
@@ -103,7 +113,8 @@ static struct parport_operations parport_arc_ops =
        arc_examine_irq,
 
        arc_inc_use_count,
-       arc_dec_use_count
+       arc_dec_use_count,
+       arc_fill_inode
 };
 
 /* --- Initialisation code -------------------------------- */
index fa1b6fddeaba60b6125a4436cc3673a5dc413376..85ed64d0ecda41ebdb2921d00d99050f0d2a1f18 100644 (file)
@@ -300,6 +300,16 @@ parport_ax_dec_use_count(void)
 #endif
 }
 
+static void parport_ax_fill_inode(struct inode *inode, int fill)
+{
+#ifdef MODULE
+       if (fill)
+               MOD_INC_USE_COUNT;
+       else
+               MOD_DEC_USE_COUNT;
+#endif
+}
+
 static struct parport_operations parport_ax_ops = 
 {
        parport_ax_write_data,
@@ -345,7 +355,8 @@ static struct parport_operations parport_ax_ops =
        parport_ax_examine_irq,
 
        parport_ax_inc_use_count,
-       parport_ax_dec_use_count
+       parport_ax_dec_use_count,
+       parport_ax_fill_inode
 };
 
 
index 4a57e879ee74d4de87d5cc7211413d1a36d6fa31..334f9a1d2cb64ee23dbcb54713cf34f4dab01325 100644 (file)
@@ -261,6 +261,16 @@ void parport_pc_dec_use_count(void)
 #endif
 }
 
+static void parport_pc_fill_inode(struct inode *inode, int fill)
+{
+#ifdef MODULE
+       if (fill)
+               MOD_INC_USE_COUNT;
+       else
+               MOD_DEC_USE_COUNT;
+#endif
+}
+
 struct parport_operations parport_pc_ops = 
 {
        parport_pc_write_data,
@@ -306,7 +316,8 @@ struct parport_operations parport_pc_ops =
        parport_pc_examine_irq,
 
        parport_pc_inc_use_count,
-       parport_pc_dec_use_count
+       parport_pc_dec_use_count,
+       parport_pc_fill_inode
 };
 
 /* --- Mode detection ------------------------------------- */
index a3f40e9f465a225afb1bd9c8312f6af52cb93ba2..09d6ebdda13bc4774e95889b003471a8b7a16c18 100644 (file)
@@ -199,7 +199,8 @@ static void destroy_proc_tree(struct parport *pp) {
 
 static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode,
                                             struct proc_dir_entry *parent,
-                                            unsigned short ino)
+                                            unsigned short ino,
+                                            struct parport *p)
 {
        struct proc_dir_entry *ent;
 
@@ -219,9 +220,12 @@ static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode,
        ent->namelen = strlen(name);
        ent->mode = mode;
 
-       if (S_ISDIR(mode)) 
+       if (S_ISDIR(mode))
+       {
+               if (p && p->ops)
+                       ent->fill_inode = p->ops->fill_inode;
                ent->nlink = 2;
-       else
+       else
                ent->nlink = 1;
 
        proc_register(parent, ent);
@@ -229,10 +233,29 @@ static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode,
        return ent;
 }
 
+/*
+ * This is called as the fill_inode function when an inode
+ * is going into (fill = 1) or out of service (fill = 0).
+ * We use it here to manage the module use counts.
+ *
+ * Note: only the top-level directory needs to do this; if
+ * a lower level is referenced, the parent will be as well.
+ */
+static void parport_modcount(struct inode *inode, int fill)
+{
+#ifdef MODULE
+       if (fill)
+               inc_parport_count();
+       else
+               dec_parport_count();
+#endif
+}
 
 int parport_proc_init(void)
 {
-       base = new_proc_entry("parport", S_IFDIR, &proc_root,PROC_PARPORT);
+       base = new_proc_entry("parport", S_IFDIR, &proc_root,PROC_PARPORT,
+                             NULL);
+       base->fill_inode = &parport_modcount;
 
        if (base == NULL) {
                printk(KERN_ERR "Unable to initialise /proc/parport.\n");
@@ -244,8 +267,11 @@ int parport_proc_init(void)
 
 void parport_proc_cleanup(void)
 {
-       if (base) proc_unregister(&proc_root,base->low_ino);
-       base = NULL;
+       if (base) {
+               proc_unregister(&proc_root,base->low_ino);
+               kfree(base);
+               base = NULL;
+       }
 }
 
 int parport_proc_register(struct parport *pp)
@@ -260,12 +286,12 @@ int parport_proc_register(struct parport *pp)
        strncpy(pp->pdir.name, pp->name + strlen("parport"), 
                sizeof(pp->pdir.name));
 
-       pp->pdir.entry = new_proc_entry(pp->pdir.name, S_IFDIR, base, 0);
+       pp->pdir.entry = new_proc_entry(pp->pdir.name, S_IFDIR, base, 0, pp);
        if (pp->pdir.entry == NULL)
                goto out_fail;
 
        pp->pdir.irq = new_proc_entry("irq", S_IFREG | S_IRUGO | S_IWUSR, 
-                                     pp->pdir.entry, 0);
+                                     pp->pdir.entry, 0, pp);
        if (pp->pdir.irq == NULL)
                goto out_fail;
 
@@ -273,14 +299,15 @@ int parport_proc_register(struct parport *pp)
        pp->pdir.irq->write_proc = irq_write_proc;
        pp->pdir.irq->data = pp;
        
-       pp->pdir.devices = new_proc_entry("devices", 0, pp->pdir.entry, 0);
+       pp->pdir.devices = new_proc_entry("devices", 0, pp->pdir.entry, 0, pp);
        if (pp->pdir.devices == NULL)
                goto out_fail;
 
        pp->pdir.devices->read_proc = devices_read_proc;
        pp->pdir.devices->data = pp;
        
-       pp->pdir.hardware = new_proc_entry("hardware", 0, pp->pdir.entry, 0);
+       pp->pdir.hardware = new_proc_entry("hardware", 0, pp->pdir.entry, 0,
+                                          pp);
        if (pp->pdir.hardware == NULL)
                goto out_fail;
 
index dd1b4a6ae5e8a959b4ddc76b0224c3685399b582..188de03d020423e5ad97e6bbe0c61846b6656104 100644 (file)
@@ -1,4 +1,4 @@
-/* 3c501.c: A 3Com 3c501 ethernet driver for linux. */
+/* 3c501.c: A 3Com 3c501 Ethernet driver for Linux. */
 /*
     Written 1992,1993,1994  Donald Becker
 
 
        The driver is less efficient than it could be. It switches through
     receive mode even if more transmits are queued. If this worries you buy
-    a real ethernet card.
+    a real Ethernet card.
 
        The combination of slow receive restart and no real multicast
     filter makes the board unusable with a kernel compiled for IP
     multicasting in a real multicast environment. That's down to the board,
     but even with no multicast programs running a multicast IP kernel is
     in group 224.0.0.1 and you will therefore be listening to all multicasts.
-    One nv conference running over that ethernet and you can give up.
+    One nv conference running over that Ethernet and you can give up.
 
 */
 
@@ -564,7 +564,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                         *      Timed out
                         */
                        if (el_debug)
-                               printk("%s: Transmit failed 16 times, ethernet jammed?\n",dev->name);
+                               printk("%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name);
                        outb(AX_SYS, AX_CMD);
                        lp->stats.tx_aborted_errors++;
                }
@@ -749,7 +749,7 @@ static int el1_close(struct device *dev)
        int ioaddr = dev->base_addr;
 
        if (el_debug > 2)
-               printk("%s: Shutting down ethercard at %#x.\n", dev->name, ioaddr);
+               printk("%s: Shutting down Ethernet card at %#x.\n", dev->name, ioaddr);
 
        dev->tbusy = 1;
        dev->start = 0;
index ae344c99dcdb744446a507cac67c4af1090da15c..1bc7ed8afc11df596131544410855c587939419b 100644 (file)
@@ -47,11 +47,9 @@ static char *version = "3c509.c:1.12 6/4/97 becker@cesdis.gsfc.nasa.gov\n";
 #include <linux/module.h>
 
 #include <linux/config.h>      /* for CONFIG_MCA */
-#include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/interrupt.h>
-#include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/malloc.h>
@@ -136,7 +134,7 @@ static ushort read_eeprom(short ioaddr, int index);
 static int el3_open(struct device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
 static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void update_stats(int addr, struct device *dev);
+static void update_stats(struct device *dev);
 static struct enet_statistics *el3_get_stats(struct device *dev);
 static int el3_rx(struct device *dev);
 static int el3_close(struct device *dev);
@@ -533,10 +531,11 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        dev->interrupt = 1;
 
        ioaddr = dev->base_addr;
-       status = inw(ioaddr + EL3_STATUS);
 
-       if (el3_debug > 4)
+       if (el3_debug > 4) {
+               status = inw(ioaddr + EL3_STATUS);
                printk("%s: interrupt, status %4.4x.\n", dev->name, status);
+       }
 
        while ((status = inw(ioaddr + EL3_STATUS)) &
                   (IntLatch | RxComplete | StatsFull)) {
@@ -555,7 +554,7 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if (status & (AdapterFailure | RxEarly | StatsFull)) {
                        /* Handle all uncommon interrupts. */
                        if (status & StatsFull)                         /* Empty statistics. */
-                               update_stats(ioaddr, dev);
+                               update_stats(dev);
                        if (status & RxEarly) {                         /* Rx early is unused. */
                                el3_rx(dev);
                                outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
@@ -602,7 +601,7 @@ el3_get_stats(struct device *dev)
 
        save_flags(flags);
        cli();
-       update_stats(dev->base_addr, dev);
+       update_stats(dev);
        restore_flags(flags);
        return &lp->stats;
 }
@@ -612,9 +611,10 @@ el3_get_stats(struct device *dev)
        operation, and it's simpler for the rest of the driver to assume that
        window 1 is always valid rather than use a special window-state variable.
        */
-static void update_stats(int ioaddr, struct device *dev)
+static void update_stats(struct device *dev)
 {
        struct el3_private *lp = (struct el3_private *)dev->priv;
+       int ioaddr = dev->base_addr;
 
        if (el3_debug > 5)
                printk("   Updating the statistics.\n");
@@ -760,7 +760,7 @@ el3_close(struct device *dev)
        /* But we explicitly zero the IRQ line select anyway. */
        outw(0x0f00, ioaddr + WN0_IRQ);
 
-       update_stats(ioaddr, dev);
+       update_stats(dev);
        MOD_DEC_USE_COUNT;
        return 0;
 }
@@ -771,6 +771,10 @@ static int debug = -1;
 static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
+MODULE_PARM(debug,"i");
+MODULE_PARM(irq,"1-8i");
+MODULE_PARM(xcvr,"1-8i");
+
 int
 init_module(void)
 {
index c7adc638239b54861f017ca9f5c338136bc4d02a..2a2f4e909b1288009e9a2d92eff6a6c20369aa34 100644 (file)
@@ -453,7 +453,7 @@ static int exec_eppfpga(void *b)
                bc->cfg.intclk ? "int" : "ext",
                bc->cfg.extmodem ? "ext" : "int", bc->cfg.divider,
                bc->cfg.loopback ? ",loopback" : "");
-       sprintf(portarg, "%d", bc->pdev->port->base);
+       sprintf(portarg, "%ld", bc->pdev->port->base);
        printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
 
         for (i = 0; i < current->files->max_fds; i++ )
index fcc9ed7cca81ff08801afaff19896e3704fd6650..6116f3642b9a6a4177719550b97a82c0a1027098 100644 (file)
@@ -318,6 +318,7 @@ static int bpq_xmit(struct sk_buff *skb, struct device *dev)
        }
 
        skb->dev = dev;
+       skb->nh.raw = skb->data;
        dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
        bpq->stats.tx_packets++;
        bpq->stats.tx_bytes+=skb->len;
index 6adfe85198c3185e685da9d847b92c7486552b55..b70b879ab661634837095c88f0850675285f023e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: pci.c,v 1.85 1998/05/12 07:36:01 mj Exp $
+ *     $Id: pci.c,v 1.86 1998/07/15 20:34:47 mj Exp $
  *
  *     PCI Bus Services, see include/linux/pci.h for further explanation.
  *
@@ -161,7 +161,6 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
        unsigned char cmd, irq, tmp, hdr_type, is_multi = 0;
        struct pci_dev *dev, **bus_last;
        struct pci_bus *child;
-       int reg;
 
        DBG("pci_scan_bus for bus %d\n", bus->number);
        bus_last = &bus->devices;
@@ -232,10 +231,7 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
                case PCI_HEADER_TYPE_CARDBUS:               /* CardBus bridge header */
                        if (class != PCI_CLASS_BRIDGE_CARDBUS)
                                goto bad;
-                       for (reg = 0; reg < 2; reg++) {
-                               pcibios_read_config_dword(bus->number, devfn, PCI_CB_MEMORY_BASE_0 + (reg << 3), &l);
-                               dev->base_address[reg] = (l == 0xffffffff) ? 0 : l;
-                       }
+                       pci_read_bases(dev, 1);
                        break;
                default:                                    /* unknown header */
                bad:
@@ -274,12 +270,20 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
                if (tmp < 32)
                        pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER, 32);
 #endif
+       }
 
+       /*
+        * After performing arch-dependent fixup of the bus, look behind
+        * all PCI-to-PCI bridges on this bus.
+        */
+       pcibios_fixup_bus(bus);
+       for(dev=bus->devices; dev; dev=dev->sibling)
                /*
                 * If it's a bridge, scan the bus behind it.
                 */
-               if (class == PCI_CLASS_BRIDGE_PCI) {
+               if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
                        unsigned int buses;
+                       unsigned int devfn = dev->devfn;
                        unsigned short cr;
 
                        /*
@@ -350,7 +354,7 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
                          }
                        pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, cr);
                }
-       }
+
        /*
         * We've scanned the bus and so we know all about what's on
         * the other side of any bridges that may be on this bus plus
index 99db6db28e2923a91406b4cdfe156a0806720048..854f9e539e10fc4bc63569508e348af0af86450f 100644 (file)
@@ -122,9 +122,6 @@ int ppa_detect(Scsi_Host_Template * host)
     nhosts = 0;
     try_again = 0;
 
-    if (!pb)
-       pb = parport_enumerate();
-
     if (!pb) {
        printk("ppa: parport reports no devices.\n");
        return 0;
index 8930f9672abaa84a600abf93a047652800de843a..4f511f3abf36e5828d18cd32eadfd81125bb4031 100644 (file)
@@ -148,6 +148,12 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
       int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9
   fi
   
+  dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS
+  if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then
+      hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330
+      int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9
+  fi
+
   dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS
   if [ "$CONFIG_SOUND_CS4232" = "y" ]; then
       hex 'CS4232 audio I/O base 530, 604, E80 or F40' CONFIG_CS4232_BASE 530
@@ -157,8 +163,8 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
       hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330
       int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9
   fi
-  
-  dep_tristate 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS
+
+  dep_tristate 'Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS
   if [ "$CONFIG_SOUND_MAUI" = "y" ]; then
       hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_MAUI_BASE 330
       int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9
index d10ccc39655c5316c4ff8b21f2de23beac7560e7..c4708f617781a3933fbd3dd731c9810e51fde29a 100644 (file)
@@ -49,7 +49,14 @@ else
 obj-$(CONFIG_SOUND)            += soundcore.o
 obj-$(CONFIG_SOUND_OSS)                += sound.o
 obj-$(CONFIG_SOUND_ADLIB)      += adlib_card.o opl3.o
-obj-$(CONFIG_SOUND_CS4232)     += cs4232.o ad1848.o uart401.o
+obj-$(CONFIG_SOUND_CS4232)     += cs4232.o ad1848.o 
+
+# In theory, there's probably no reason to include the uart401 code
+# to support a WaveFront card's CS4232 module. However, it makes
+# reconfiguring things require a recompile, so just leave this
+# here and try not to worry about the extra uart401 module.
+
+obj-$(CONFIG_SOUND_CS4232)     += uart401.o
 obj-$(CONFIG_SOUND_GUS)                += gus.o ad1848.o
 obj-$(CONFIG_SOUND_MAD16)      += mad16.o ad1848.o sb.o uart401.o
 obj-$(CONFIG_SOUND_MAUI)       += maui.o mpu401.o
@@ -69,7 +76,7 @@ obj-$(CONFIG_SOUND_UART6850)  += uart6850.c
 obj-$(CONFIG_SOUND_VMIDI)      += v_midi.o
 obj-$(CONFIG_SOUND_YM3812)     += adlib_card.o opl3.o
 obj-$(CONFIG_VIDC_SOUND)       += vidc_mod.o
-
+obj-$(CONFIG_SOUND_WAVEFRONT)   += wavefront.o
 #jnx
 obj-$(CONFIG_SOUND_ES1370)     += es1370.o
 obj-$(CONFIG_SOUND_ES1371)     += es1371.o
@@ -81,7 +88,8 @@ endif
 
 # Declare multi-part drivers.
 
-list-multi     := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o soundcore.o
+list-multi     := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
+    soundcore.o wavefront.o
 
 sound-objs     :=                                                      \
     dev_table.o soundcard.o sound_syms.o               \
@@ -96,7 +104,7 @@ pas2-objs    := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
 sb-objs                := sb_audio.o sb_card.o sb_common.o sb_midi.o sb_mixer.o
 softoss2-objs  := softoss.o softoss_rs.o
 vidc_mod-objs  := vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o
-
+wavefront-objs  := wavfront.o wf_midi.o yss225.o
 
 
 # Extract lists of the multi-part drivers.
@@ -179,7 +187,8 @@ softoss2.o: $(softoss2-objs)
 vidc_mod.o: $(vidc_mod-objs)
        $(LD) -r -o $@ $(vidc_mod-objs)
 
-
+wavefront.o: $(wavefront-objs)
+       $(LD) -r -o $@ $(wavefront-objs)
 
 # Firmware files that need translation
 #
diff --git a/drivers/sound/README.wavefront b/drivers/sound/README.wavefront
new file mode 100644 (file)
index 0000000..afd6ae8
--- /dev/null
@@ -0,0 +1,375 @@
+            An OSS/Free Driver for WaveFront soundcards
+              (Turtle Beach Maui, Tropez, Tropez Plus)
+
+                    Paul Barton-Davis, July 1998
+
+                         VERSION 0.2.2
+
+Driver Status
+-------------
+
+Requires: Kernel 2.1.106 or later
+         
+As of 7/13/1998, this driver is currently in *BETA* state. This means
+that it compiles and runs, and that I use it on my system (Linux
+2.1.106) with some reasonably demanding applications and uses.  I
+believe the code is approaching an initial "finished" state that
+provides bug-free support for the Tropez Plus.
+
+Please note that to date, the driver has ONLY been tested on a Tropez
+Plus. I would very much like to hear (and help out) people with Tropez
+and Maui cards, since I think the driver can support those cards as
+well. 
+
+Finally, the driver has not been tested as a static (non-modular) part
+of the kernel. Alan Cox's good work in modularizing OSS/Free for Linux
+makes this rather unnecessary.
+
+Some Questions
+--------------
+
+**********************************************************************
+0) What does this driver do that the maui driver did not ?
+**********************************************************************
+
+* can fully initialize a WaveFront card from cold boot - no DOS 
+          utilities needed
+* working patch/sample/program loading and unloading (the maui
+      driver didn't document how to make this work, and assumed
+      user-level preparation of the patch data for writing
+      to the board. ick.)
+* full user-level access to all WaveFront commands
+* for the Tropez Plus, (primitive) control of the YSS225 FX processor
+* Virtual MIDI mode supported - 2 MIDI devices accessible via the
+          WaveFront's MPU401/UART emulation. One
+         accesses the WaveFront synth, the other accesses the
+         external MIDI connector. Full MIDI read/write semantics
+         for both devices.
+* OSS-compliant /dev/sequencer interface for the WaveFront synth,
+         including native and GUS-format patch downloading.
+* semi-intelligent patch management (prototypical at this point)
+
+
+**********************************************************************
+1) What to do about MIDI interfaces ?
+**********************************************************************
+
+The Tropez Plus (and perhaps other WF cards) can in theory support up
+to 2 physical MIDI interfaces. One of these is connected to the
+ICS2115 chip (the WaveFront synth itself) and is controlled by
+MPU/UART-401 emulation code running as part of the WaveFront OS.  The
+other is controlled by the CS4232 chip present on the board. However,
+physical access to the CS4232 connector is difficult, and it is
+unlikely (though not impossible) that you will want to use it.
+
+An older version of this driver introduced an additional kernel config
+variable which controlled whether or not the CS4232 MIDI interface was
+configured. Because of Alan Cox's work on modularizing the sound
+drivers, and now backporting them to 2.0.34 kernels, there seems to be
+little reason to support "static" configuration variables, and so this
+has been abandoned in favor of *only* module parameters. Specifying
+"mpuio" and "mpuirq" for the cs4232 parameter will result in the
+CS4232 MIDI interface being configured; leaving them unspecified will
+leave it unconfigured (and thus unusable).
+
+BTW, I have heard from one Tropez+ user that the CS4232 interface is
+more reliable than the ICS2115 one. I have had no problems with the
+latter, and I don't have the right cable to test the former one
+out. Reports welcome.
+
+**********************************************************************
+2) Why does line XXX of the code look like this .... ?
+**********************************************************************
+
+Either because its not finished yet, or because you're a better coder
+than I am, or because you don't understand some aspect of how the card
+or the code works. 
+
+I absolutely welcome comments, criticisms and suggestions about the
+design and implementation of the driver. 
+
+**********************************************************************
+3) What files are included ?
+**********************************************************************
+
+   drivers/sound/README.wavefront       -- this file
+   drivers/sound/wavefront.patch       -- patches for the 2.1.106 sound drivers
+                                          needed to make the rest of this work
+   drivers/sound/wavfront.c             -- the driver
+   drivers/sound/ys225.h                -- data declarations for FX config
+   drivers/sound/ys225.c                -- data definitions for FX config
+   drivers/sound/wf_midi.c              -- the "uart401" driver 
+                                             to support virtual MIDI mode.
+   include/wavefront.h                  -- the header file
+   Documentation/sound/Tropez+          -- short docs on configuration
+
+**********************************************************************
+4) How do I compile/install/use it ?
+**********************************************************************
+
+PART ONE: install the source code into your sound driver directory
+
+  cd <top-of-your-2.1.106-code-base-e.g.-/usr/src/linux>
+  tar -zxvf <where-you-put/wavefront.tar.gz>
+
+PART TWO: apply the patches
+
+  cd drivers/sound
+  patch < wavefront.patch
+
+PART THREE: configure your kernel
+
+  cd <top of your kernel tree>
+  make xconfig (or whichever config option you use)
+
+         - choose YES for Sound Support              
+         - choose MODULE (M) for OSS Sound Modules
+         - choose MODULE(M) to YM3812/OPL3 support
+        - choose MODULE(M) for WaveFront support
+        - choose MODULE(M) for CS4232 support
+
+        - choose "N" for everything else (unless you have other
+             soundcards you want support for)
+
+
+   make dep
+   make boot
+   .
+   .
+   .
+   <whatever you normally do for a kernel install>
+   make modules
+   .
+   .
+   .
+   make modules_isntall
+
+Here's my autoconf.h SOUND section:
+
+/*
+ * Sound
+ */
+#define CONFIG_SOUND 1
+#undef  CONFIG_SOUND_OSS
+#define CONFIG_SOUND_OSS_MODULE 1
+#undef  CONFIG_SOUND_PAS
+#undef  CONFIG_SOUND_SB
+#undef  CONFIG_SOUND_ADLIB
+#undef  CONFIG_SOUND_GUS
+#undef  CONFIG_SOUND_MPU401
+#undef  CONFIG_SOUND_PSS
+#undef  CONFIG_SOUND_MSS
+#undef  CONFIG_SOUND_SSCAPE
+#undef  CONFIG_SOUND_TRIX
+#undef  CONFIG_SOUND_MAD16
+#undef  CONFIG_SOUND_WAVEFRONT
+#define CONFIG_SOUND_WAVEFRONT_MODULE 1
+#undef  CONFIG_SOUND_CS4232
+#define CONFIG_SOUND_CS4232_MODULE 1
+#undef  CONFIG_SOUND_MAUI
+#undef  CONFIG_SOUND_SGALAXY
+#undef  CONFIG_SOUND_OPL3SA1
+#undef  CONFIG_SOUND_SOFTOSS
+#undef  CONFIG_SOUND_YM3812
+#define CONFIG_SOUND_YM3812_MODULE 1
+#undef  CONFIG_SOUND_VMIDI
+#undef  CONFIG_SOUND_UART6850
+/*
+ * Additional low level sound drivers
+ */
+#undef  CONFIG_LOWLEVEL_SOUND
+
+************************************************************
+6) How do I configure my card ?
+************************************************************
+
+You need to edit /etc/conf.modules. Here's mine (edited to show the
+relevant details):
+
+  # Sound system
+  alias char-major-14 wavefront
+  alias synth0 wavefront
+  alias mixer0 cs4232
+  alias audio0 cs4232
+  pre-install wavefront modprobe "-k" "cs4232"
+  post-install wavefront modprobe "-k" "opl3"
+  options wavefront io=0x200 irq=9
+  options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
+  options opl3 io=0x388
+
+Things to note: 
+
+       the wavefront options "io" and "irq" ***MUST*** match the "synthio"
+       and "synthirq" cs4232 options.
+
+       you can do without the adlib_card module if you don't
+       want to use the OPL/[34] synth on the soundcard
+
+       the adlib_card io parameter is conventionally not adjustable.
+       In theory, any not-in-use IO port address would work, but
+       just use 0x388 and stick with the crowd.
+
+**********************************************************************
+7) What about firmware ?
+**********************************************************************
+
+Turtle Beach have not given me permission to distribute their firmware
+for the ICS2115. However, if you have a WaveFront card, then you
+almost certainly have the firmware, and if not, its freely available
+on their website, at:
+
+   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus 
+
+The file is called WFOS2001.MOT (for the Tropez+).
+
+This driver, however, doesn't use the pure firmware as distributed,
+but instead relies on a somewhat processed form of it. You can
+generate this very easily. Following an idea from Andrew Veliath's
+Pinnacle driver, the following flex program will generate the
+processed version:
+
+---- cut here -------------------------
+%option main
+%%
+^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext);
+<<EOF>> { fputc ('\0', stdout); return; }
+\n {} 
+.  {}
+---- cut here -------------------------
+
+To use it, put the above in file (say, ws.l) compile it like this:
+
+      shell> flex -ows.c ws.l
+      shell> cc -o ws ws.c
+      
+and then use it like this:
+
+    ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os
+
+If you put it somewhere else, you'll always have to use the wf_ospath
+module parameter (see below) or alter the source code.
+
+**********************************************************************
+7) How do I get it working ?
+**********************************************************************
+
+Optionally, you can reboot with the "new" kernel (even though the only
+changes have really been made to a module).
+
+Then, as root do:
+
+     modprobe wavefront
+
+You should get something like this in /var/log/messages:
+
+    WaveFront: firmware 1.20 already loaded.
+
+or 
+
+    WaveFront: no response to firmware probe, assume raw.
+
+then:
+
+    WaveFront: waiting for memory configuration ...
+    WaveFront: hardware version 1.64
+    WaveFront: available DRAM 8191k
+    WaveFront: 332 samples used (266 real, 13 aliases, 53 multi), 180 empty
+    WaveFront: 128 programs slots in use
+    WaveFront: 256 patch slots filled, 142 in use
+
+The whole process takes about 16 seconds, the longest waits being
+after reporting the hardware version (during the firmware download),
+and after reporting program status (during patch status inquiry).  Its
+shorter (about 10 secs) if the firmware is already loaded (i.e. only
+warm reboots since the last firmware load).
+
+The "available DRAM" line will vary depending on how much added RAM
+your card has. Mine has 8MB.
+
+Next, check /dev/sndstat, which on my machine says:
+---------------------------------------------------------------------
+OSS/Free:3.8s2++-971130
+Load type: Driver loaded as a module
+Kernel: Linux bd 2.1.106 #12 SMP Fri Jul 3 00:37:34 EDT 1998 i486
+Config options: 0
+
+Installed drivers: 
+
+Card config: 
+
+Audio devices:
+0: Crystal audio controller (CS4232) (DUPLEX)
+
+Synth devices:
+0: Turtle Beach WaveFront
+1: Yamaha OPL-3
+
+Midi devices:
+0: WaveFront Internal MIDI
+1: WaveFront External MIDI
+
+Timers:
+0: System clock
+1: Crystal audio controller (CS4232)
+
+Mixers:
+0: Crystal audio controller (CS4232)
+-----------------------------------------------------------
+
+To check basically functionality, use play(1) or splay(1) to send a
+.WAV or other audio file through the audio portion. Then use playmidi
+to play a General MIDI file. Try the "-D 0" to hear the
+difference between sending MIDI to the WaveFront and using the OPL/3,
+which is the default (I think ...). If you have an external synth(s)
+hooked to the soundcard, you can use "-e" to route to the
+external synth(s) (in theory, -D 1 should work as well, but I think
+there is a bug in playmidi which prevents this from doing what it
+should). 
+
+**********************************************************************
+8) What are the module parameters ?
+**********************************************************************
+
+Its best to read wavefront.c for this, but here is a summary:
+
+integers: 
+         wf_raw  - if set, ignore apparent presence of firmware
+                   loaded onto the ICS2115, reset the whole
+                   board, and initialize it from scratch. (default = 0)
+
+          fx_raw  - if set, always initialize the YSS225 processor
+                   on the Tropez plus. (default = 1)
+
+          < The next 4 are basically for kernel hackers to allow
+           tweaking the driver for testing purposes. >             
+
+          wf_short_wait_count - loop counter used when waiting for
+                               status conditions on the board. This
+                               is CPU-specific. After this many
+                               loops, the driver will sleep.
+                               The default is 5000. I have a 66Mhz 486.
+
+          wf_sleep_interval  - the driver sleeps for
+                              HZ/wf_sleep_interval seconds per sleep.
+                              The default is 50.       
+
+          wf_sleep_tries  - the number of times the driver will sleep
+                           when waiting for a status condition on the
+                           board. The default is 100 (2 secs, if 
+                           wf_sleep_interval is 50).
+
+          wf_debug_default - debugging flags. See sound/wavefront.h
+                            for WF_DEBUG_* values. Default is zero.
+                            Setting this allows you to debug the
+                            driver during module installation.
+strings:
+         wf_ospath - path to get to the pre-processed OS firmware.
+                   (default: /etc/sound/wavefront.os)
+
+**********************************************************************
+9) Who should I contact if I have problems?
+**********************************************************************
+
+Just me: Paul Barton-Davis <pbd@op.net>
+
+
index 9740035b47cc4d23a839b20e49ca4fa13d7cea2d..4e75d04a6a5aa151e1fe3a997e6cfebbcdb9d466 100644 (file)
@@ -31,7 +31,7 @@ modules in the usual way.
 alias char-major-14 sb
 post-install sb /sbin/modprobe "-k" "adlib_card"
 options sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330
-options adlib_card io=0x388     # FM synthesizer
+options adlib_card io=0x388     # FM synthetiser
 
   The effect of this is that the sound driver and all necessary bits and
 pieces autoload on demand, assuming you use kerneld (a sound choice) and
index b97ee546fe9b88315c3a9e92a620314c2bc99f77..407b5da6fb7361c9b82bf55c58f7308557d03d0b 100644 (file)
@@ -1721,7 +1721,7 @@ int ad1848_init(char *name, int io_base, int irq, int dma_playback, int dma_capt
         */
 
 
-       int my_dev;
+       long my_dev;
        char dev_name[100];
        int e;
 
@@ -1951,12 +1951,12 @@ void adintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        unsigned char status;
        ad1848_info *devc;
-       int dev;
+       long dev;
        int alt_stat = 0xff;
        unsigned char c930_stat = 0;
        int cnt = 0;
 
-       dev = (int)dev_id;
+       dev = (long)dev_id;
        devc = (ad1848_info *) audio_devs[dev]->devc;
 
 interrupt_again:               /* Jump back here if int status doesn't reset */
index 33222626fbc1d11cbfba2da3f2d8d93ee41075e4..fcaaf804159035a0027755d907e85d7a0a6fb819 100644 (file)
@@ -8,6 +8,21 @@
  * gets implemented. Just the WSS codec, FM synth and the MIDI ports are
  * supported. Other interfaces are left uninitialized.
  *
+ * ifdef ...WAVEFRONT...
+ * 
+ *   Support is provided for initializing the WaveFront synth
+ *   interface as well, which is logical device #4. Note that if
+ *   you have a Tropez+ card, you probably don't need to setup
+ *   the CS4232-supported MIDI interface, since it corresponds to
+ *   the internal 26-pin header that's hard to access. Using this
+ *   requires an additional IRQ, a resource none too plentiful in
+ *   this environment. Just don't set module parameters mpuio and
+ *   mpuirq, and the MIDI port will be left uninitialized. You can
+ *   still use the ICS2115 hosted MIDI interface which corresponds
+ *   to the 9-pin D connector on the back of the card.
+ *
+ * endif  ...WAVEFRONT...
+ *
  * Supported chips are:
  *      CS4232
  *      CS4236
@@ -17,7 +32,9 @@
  * anyway.
  *
  * Changes
- *     Alan Cox        Modularisation, Basic cleanups.
+ *     Alan Cox                Modularisation, Basic cleanups.
+ *      Paul Barton-Davis      Separated MPU configuration, added
+ *                                       Tropez+ (WaveFront) support
  */
 
 /*
@@ -46,6 +63,9 @@ static void CS_OUT(unsigned char a)
 #define CS_OUT3(a, b, c)       {CS_OUT(a);CS_OUT(b);CS_OUT(c);}
 
 static int mpu_base = 0, mpu_irq = 0;
+#ifdef CONFIG_SOUND_WAVEFRONT_MODULE
+static int synth_base = 0, synth_irq = 0;
+#endif CONFIG_SOUND_WAVEFRONT_MODULE
 static int mpu_detected = 0;
 
 int probe_cs4232_mpu(struct address_info *hw_config)
@@ -170,6 +190,15 @@ int probe_cs4232(struct address_info *hw_config)
                }
 #endif
 
+#if defined(CONFIG_SOUND_WAVEFRONT) || defined(CONFIG_SOUND_WAVEFRONT_MODULE)
+               {
+                   CS_OUT2 (0x15, 0x04);               /* logical device 4 (WaveFront) */
+                   CS_OUT3 (0x47, (synth_base >> 8) & 0xff,
+                            synth_base & 0xff);        /* base */
+                   CS_OUT2 (0x22, synth_irq);          /* IRQ */
+                   CS_OUT2 (0x33, 0x01);               /* Activate logical dev 4 */
+               }
+#endif
                /*
                 * Finally activate the chip
                 */
@@ -248,6 +277,7 @@ void unload_cs4232(struct address_info *hw_config)
 {
        int base = hw_config->io_base, irq = hw_config->irq;
        int dma1 = hw_config->dma, dma2 = hw_config->dma2;
+       int mixer = audio_devs[hw_config->slots[0]]->mixer_dev;
 
        if (dma2 == -1)
                dma2 = dma1;
@@ -257,6 +287,10 @@ void unload_cs4232(struct address_info *hw_config)
                      dma1,     /* Playback DMA */
                      dma2,     /* Capture DMA */
                      0);
+
+       if (mixer >= 0) {
+           sound_unload_mixerdev (mixer);
+       }
        sound_unload_audiodev(hw_config->slots[0]);
 #if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
        if (mpu_base != 0 && mpu_irq != 0 && mpu_detected)
@@ -293,15 +327,27 @@ int             io = -1;
 int             irq = -1;
 int             dma = -1;
 int             dma2 = -1;
+int             mpuio = -1;
+int             mpuirq = -1;
 
 MODULE_PARM(io,"i");
 MODULE_PARM(irq,"i");
 MODULE_PARM(dma,"i");
 MODULE_PARM(dma2,"i");
+MODULE_PARM(mpuio,"i");
+MODULE_PARM(mpuirq,"i");
+
+#ifdef CONFIG_SOUND_WAVEFRONT_MODULE
+int             synthio = -1;
+int             synthirq = -1;
+MODULE_PARM(synthio,"i");
+MODULE_PARM(synthirq,"i");
+#endif CONFIG_SOUND_WAVEFRONT_MODULE
 
 EXPORT_NO_SYMBOLS;
 
 struct address_info cfg;
+struct address_info mpu_cfg;
 
 /*
  *     Install a CS4232 based card. Need to have ad1848 and mpu401
@@ -310,31 +356,60 @@ struct address_info cfg;
 
 int init_module(void)
 {
+
+#ifndef CONFIG_SOUND_WAVEFRONT_MODULE
+
        if (io == -1 || irq == -1 || dma == -1 || dma2 == -1)
        {
                printk(KERN_ERR "cs4232: dma, dma2, irq and io must be set.\n");
                return -EINVAL;
        }
+#else 
+       if (synthio == -1 || synthirq == -1 ||
+           io == -1 || irq == -1 || dma == -1 || dma2 == -1)
+       {
+               printk(KERN_ERR "cs4232: synthio, synthirq, dma, dma2, "
+                      "irq and io must be set.\n");
+               return -EINVAL;
+       }
+
+#endif CONFIG_SOUND_WAVEFRONT_MODULE
+
        cfg.io_base = io;
        cfg.irq = irq;
        cfg.dma = dma;
        cfg.dma2 = dma2;
 
+#ifdef CONFIG_SOUND_WAVEFRONT_MODULE
+       synth_base = synthio;
+       synth_irq =  synthirq;
+#endif CONFIG_SOUND_WAVEFRONT_MODULE   
+
        if (probe_cs4232(&cfg) == 0)
                return -ENODEV;
 
-       probe_cs4232_mpu(&cfg); /* Bug always returns 0 not OK -- AC */
+       mpu_cfg.io_base = -1;
+       mpu_cfg.irq = -1;
+
+       if (mpuio != -1 && mpuirq != -1) {
+           mpu_cfg.io_base = mpuio;
+           mpu_cfg.irq = mpuirq;
+           probe_cs4232_mpu(&mpu_cfg); /* Bug always returns 0 not OK -- AC */
+       }
 
        attach_cs4232(&cfg);
-       attach_cs4232_mpu(&cfg);
+
+       if (mpuio != -1 && mpuirq != -1) {
+           attach_cs4232_mpu(&mpu_cfg);
+       }
+
        SOUND_LOCK;
        return 0;
 }
 
 void cleanup_module(void)
 {
-       unload_cs4232_mpu(&cfg);
-       unload_cs4232(&cfg);
+        unload_cs4232(&cfg); /* unloads MPU as well, if needed */
        SOUND_LOCK_END;
 }
 
index 32b4b8e2901d71cbb13427fac498b2101d90281a..bf5d62bffd868a43d6c087ab7f0fa07d2f9b0766 100644 (file)
@@ -30,6 +30,7 @@
 #define SNDCARD_OPL3SA1_MPU            40
 #define SNDCARD_SOFTOSS                        36
 #define SNDCARD_VMIDI                  37
+#define SNDCARD_WAVEFRONT               41
 
 void attach_opl3sa_wss (struct address_info *hw_config);
 int probe_opl3sa_wss (struct address_info *hw_config);
@@ -408,6 +409,8 @@ struct driver_info sound_drivers[] =
 
 #ifdef CONFIG_SOUND_CS4232
        {"CS4232", 0, SNDCARD_CS4232,   "CS4232",               attach_cs4232, probe_cs4232, unload_cs4232},
+#endif
+#ifdef CONFIG_CS4232_MPU_BASE
        {"CS4232MPU", 0, SNDCARD_CS4232_MPU,    "CS4232 MIDI",          attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu},
 #endif
 
@@ -432,6 +435,10 @@ struct driver_info sound_drivers[] =
                attach_uart401, probe_uart401, unload_uart401},
 #endif
 
+#if defined(CONFIG_SOUND_WAVEFRONT)
+       {"WAVEFRONT", 0, SNDCARD_WAVEFRONT,"TB WaveFront", attach_wavefront, probe_wavefront, unload_wavefront},
+#endif
+
 #if defined(CONFIG_SOUND_MAUI)
        {"MAUI", 0, SNDCARD_MAUI,"TB Maui",     attach_maui, probe_maui, unload_maui},
 #endif
@@ -596,6 +603,10 @@ struct card_info snd_installed_cards[] =
 #endif
 #endif
 
+#if defined(CONFIG_WAVEFRONT) 
+       {SNDCARD_WAVEFRONT, {WAVEFRONT_BASE, WAVEFRONT_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+#endif
+
 #ifdef CONFIG_SOUND_MAUI
        {SNDCARD_MAUI, {CONFIG_MAUI_BASE, CONFIG_MAUI_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
 #endif
index 798a94acb661bbebc9374883b15c5f57a4576576..5924f10afa2bdf2d4e68b4b2d66c750d70c9332d 100644 (file)
@@ -1033,10 +1033,10 @@ int init_module(void)
 
        config_mpu.io_base = mpu_io;
        config_mpu.irq = mpu_irq;
-       found_mpu = probe_mad16_mpu(&config_mpu);
-
        attach_mad16(&config);
 
+       found_mpu = probe_mad16_mpu(&config_mpu);
+
        if (found_mpu)
                attach_mad16_mpu(&config_mpu);
 
@@ -1047,7 +1047,7 @@ int init_module(void)
 void cleanup_module(void)
 {
        if (found_mpu)
-               unload_mad16_mpu(&config);
+               unload_mad16_mpu(&config_mpu);
        unload_mad16(&config);
        SOUND_LOCK_END;
 }
index dcdb78dee01aa423558152a9ed3cb3641b80aac4..8052f204eab8e3a2ef5d4d35a8952b50005c238d 100644 (file)
@@ -212,7 +212,7 @@ int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user)
 int msnd_wait_TXDE(multisound_dev_t *dev)
 {
        register unsigned int io = dev->io;
-       register int timeout = 5000;
+       register int timeout = 100;
     
        while(timeout-- > 0)
                if (inb(io + HP_ISR) & HPISR_TXDE)
@@ -224,7 +224,7 @@ int msnd_wait_TXDE(multisound_dev_t *dev)
 int msnd_wait_HC0(multisound_dev_t *dev)
 {
        register unsigned int io = dev->io;
-       register int timeout = 25000;
+       register int timeout = 100;
 
        while(timeout-- > 0)
                if (!(inb(io + HP_CVR) & HPCVR_HC))
@@ -291,7 +291,7 @@ int msnd_upload_host(multisound_dev_t *dev, char *bin, int len)
 
 int msnd_enable_irq(multisound_dev_t *dev)
 {
-       printk(KERN_INFO LOGNAME ": enable_irq: count %d\n", dev->irq_ref);
+       printk(KERN_DEBUG LOGNAME ": enable_irq: count %d\n", dev->irq_ref);
 
        if (dev->irq_ref++ != 0)
                return 0;
@@ -333,6 +333,8 @@ int msnd_disable_irq(multisound_dev_t *dev)
                dev->irq_ref = 0;
 
        printk(KERN_DEBUG LOGNAME ": Disabling IRQ\n");
+       
+       udelay(50);
 
        spin_lock_irqsave(&dev->lock, flags);
        outb(inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR);
index 252b005a0ad5c79cb1f76e42990bd8237e8d930d..4c337e392f9f87085134fb0e24f68b1431c4dba0 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: msnd.h,v 1.3 1998/06/09 20:39:34 andrewtv Exp $
+ * $Id: msnd.h,v 1.4 1998/07/14 22:59:25 andrewtv Exp $
  *
  ********************************************************************/
 #ifndef __MSND_H
 #define __MSND_H
 
-#define VERSION                        "0.6"
+#define VERSION                        "0.6.2"
 
-#define DEFSAMPLERATE          44100
-#define DEFSAMPLESIZE          16
-#define DEFCHANNELS            2
+#define DEFSAMPLERATE          DSP_DEFAULT_SPEED
+#define DEFSAMPLESIZE          8
+#define DEFCHANNELS            1
 
 #define DEFFIFOSIZE            64
 
 #define        HIMT_MIDI_IN_UCHAR      0x0E
 #define        HIMT_DSP                0x0F
 
+#define        HDEX_BASE               0x92
+#define        HDEX_PLAY_START         (0 + HDEX_BASE)
+#define        HDEX_PLAY_STOP          (1 + HDEX_BASE)
+#define        HDEX_PLAY_PAUSE         (2 + HDEX_BASE)
+#define        HDEX_PLAY_RESUME        (3 + HDEX_BASE)
+#define        HDEX_RECORD_START       (4 + HDEX_BASE)
+#define        HDEX_RECORD_STOP        (5 + HDEX_BASE)
+#define        HDEX_MIDI_IN_START      (6 + HDEX_BASE)
+#define        HDEX_MIDI_IN_STOP       (7 + HDEX_BASE)
+#define        HDEX_MIDI_OUT_START     (8 + HDEX_BASE)
+#define        HDEX_MIDI_OUT_STOP      (9 + HDEX_BASE)
+#define        HDEX_AUX_REQ            (10 + HDEX_BASE)
+
 #define HIWORD(l)              ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF ))
 #define LOWORD(l)              ((WORD)(DWORD)(l))
 #define HIBYTE(w)              ((BYTE)(((WORD)(w) >> 8 ) & 0xFF ))
 #define PCTODSP_BASED(w)       (USHORT)(((w)/2) + DSP_BASE_ADDR)
 
 #ifdef SLOWIO
+#  undef outb
+#  undef inb
 #  define outb                 outb_p
 #  define inb                  inb_p
 #endif
@@ -195,8 +210,9 @@ typedef struct multisound_dev {
        struct SMA0_CommonData *SMA;    /* diff. structure for classic vs. pinnacle */
        struct DAQueueDataStruct *CurDAQD;
        struct DAQueueDataStruct *CurDARQD;
-       WORD *pwDSPQData , *pwMIDQData , *pwMODQData;
-       struct JobQueueStruct *DAPQ , *DARQ , *MODQ , *MIDQ , *DSPQ;
+       volatile WORD *pwDSPQData , *pwMIDQData , *pwMODQData;
+       volatile struct JobQueueStruct *DAPQ , *DARQ , *MODQ , *MIDQ , *DSPQ;
+       BYTE bCurrentMidiPatch;
 
        /* State variables */
        mode_t mode;
@@ -210,7 +226,10 @@ typedef struct multisound_dev {
 #define F_AUDIO_INUSE                  6
 #define F_EXT_MIDI_INUSE               7
 #define F_INT_MIDI_INUSE               8
+#define F_WRITEFLUSH                   9
+
        struct wait_queue *writeblock, *readblock;
+       struct wait_queue *writeflush;
        unsigned long recsrc;
        int left_levels[16];
        int right_levels[16];
index 52cc66f0bf0276d1a681bfdad157ce802707ab52..fe2bb6e86c87095b884b04bbc574fd251572b2f5 100644 (file)
@@ -453,8 +453,17 @@ static void dsp_halt(void)
        mdelay(1);
        if (test_and_clear_bit(F_WRITING, &dev.flags)) {
 
+               set_bit(F_WRITEFLUSH, &dev.flags);
+               interruptible_sleep_on(&dev.writeflush);
+               current->state = TASK_INTERRUPTIBLE;
+               current->timeout = 
+                       jiffies + DAP_BUFF_SIZE / 2 * HZ /
+                       dev.sample_rate / dev.channels;
+               schedule();
+               current->timeout = 0;
                msnd_send_dsp_cmd(&dev, HDEX_PLAY_STOP);
                msnd_disable_irq(&dev);
+               memset_io(dev.base, 0, DAP_BUFF_SIZE * 3);
 
        }
        mdelay(1);
@@ -674,8 +683,9 @@ static void eval_dsp_msg(WORD wMessage)
                        } 
                        else if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
 
-                               memset_io(dev.base, 0, DAP_BUFF_SIZE * 3);
                                clear_bit(F_WRITING, &dev.flags);
+                               if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
+                                       wake_up_interruptible(&dev.writeflush);
                                msnd_disable_irq(&dev);
 
                        }
@@ -728,7 +738,7 @@ static void eval_dsp_msg(WORD wMessage)
                        break;
 
                default:
-                       printk(KERN_INFO LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
+                       printk(KERN_DEBUG LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
                        break;
                }
                break;
@@ -738,15 +748,19 @@ static void eval_dsp_msg(WORD wMessage)
                        (*dev.midi_in_interrupt)(&dev);
                break;
 
+       case HIMT_MIDI_OUT:
+               printk(KERN_DEBUG LOGNAME ": MIDI out event\n");
+               break;
+
        default:
+               printk(KERN_DEBUG LOGNAME ": HIMT message %u\n", HIBYTE(wMessage));
                break;
        }
 }
 
 static void intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-       if (test_bit(F_INTERRUPT, &dev.flags) || 
-           ((multisound_dev_t *)dev_id != &dev))
+       if (test_bit(F_INTERRUPT, &dev.flags))
                return;
 
        set_bit(F_INTERRUPT, &dev.flags);
@@ -1261,6 +1275,7 @@ __initfunc(msnd_classic_init(void))
 
        init_waitqueue(&dev.writeblock);
        init_waitqueue(&dev.readblock);
+       init_waitqueue(&dev.writeflush);
        msnd_fifo_init(&dev.DAPF);
        msnd_fifo_init(&dev.DARF);
        spin_lock_init(&dev.lock);
index 49e58851990c21f580e7dcecc9034ce72a68ad99..62c167f1196825c5ab8e83574893f24411e7e9b1 100644 (file)
@@ -24,7 +24,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * 
- * $Id: msnd_classic.h,v 1.3 1998/06/09 20:39:34 andrewtv Exp $
+ * $Id: msnd_classic.h,v 1.4 1998/07/14 22:59:25 andrewtv Exp $
  *
  ********************************************************************/
 #ifndef __MSND_CLASSIC_H
 #define        HIDSP_MIDI_IN_OVER      0x10
 #define        HIDSP_MIDI_OVERRUN_ERR  0x13
 
-#define        HDEX_BASE               0x92
-#define        HDEX_PLAY_START         (0 + HDEX_BASE)
-#define        HDEX_PLAY_STOP          (1 + HDEX_BASE)
-#define        HDEX_PLAY_PAUSE         (2 + HDEX_BASE)
-#define        HDEX_PLAY_RESUME        (3 + HDEX_BASE)
-#define        HDEX_RECORD_START       (4 + HDEX_BASE)
-#define        HDEX_RECORD_STOP        (5 + HDEX_BASE)
-#define        HDEX_MIDI_IN_START      (6 + HDEX_BASE)
-#define        HDEX_MIDI_IN_STOP       (7 + HDEX_BASE)
-#define        HDEX_MIDI_OUT_START     (8 + HDEX_BASE)
-#define        HDEX_MIDI_OUT_STOP      (9 + HDEX_BASE)
-#define        HDEX_AUX_REQ            (10 + HDEX_BASE)
-
 #define        HDEXAR_CLEAR_PEAKS      1
 #define        HDEXAR_IN_SET_POTS      2
 #define        HDEXAR_AUX_SET_POTS     3
@@ -181,6 +168,14 @@ struct SMA0_CommonData {
 #  define PERMCODESIZE         sizeof(msndperm)
 #  define INITCODESIZE         sizeof(msndinit)
 #else
+#  ifndef CONFIG_MSNDCLAS_INIT_FILE
+#    define CONFIG_MSNDCLAS_INIT_FILE                          \
+                               "/etc/sound/msndinit.bin"
+#  endif
+#  ifndef CONFIG_MSNDCLAS_PERM_FILE
+#    define CONFIG_MSNDCLAS_PERM_FILE                          \
+                               "/etc/sound/msndperm.bin"
+#  endif
 #  define PERMCODEFILE         CONFIG_MSNDCLAS_PERM_FILE
 #  define INITCODEFILE         CONFIG_MSNDCLAS_INIT_FILE
 #  define PERMCODE             dspini
index 218ff1a81d54d7fe84a023d793715ce5abd040ad..bddedb92cf5073f9bd4719e229487d8c59ba5b95 100644 (file)
@@ -485,8 +485,17 @@ static void dsp_halt(void)
        mdelay(1);
        if (test_and_clear_bit(F_WRITING, &dev.flags)) {
 
+               set_bit(F_WRITEFLUSH, &dev.flags);
+               interruptible_sleep_on(&dev.writeflush);
+               current->state = TASK_INTERRUPTIBLE;
+               current->timeout = 
+                       jiffies + DAP_BUFF_SIZE / 2 * HZ /
+                       dev.sample_rate / dev.channels;
+               schedule();
+               current->timeout = 0;
                msnd_send_dsp_cmd(&dev, HDEX_PLAY_STOP);
                msnd_disable_irq(&dev);
+               memset_io(dev.base, 0, DAP_BUFF_SIZE * 3);
 
        }
        mdelay(1);
@@ -706,8 +715,9 @@ static void eval_dsp_msg(WORD wMessage)
                        } 
                        else if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
 
-                               memset_io(dev.base, 0, DAP_BUFF_SIZE * 3);
                                clear_bit(F_WRITING, &dev.flags);
+                               if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
+                                       wake_up_interruptible(&dev.writeflush);
                                msnd_disable_irq(&dev);
 
                        }
@@ -761,7 +771,7 @@ static void eval_dsp_msg(WORD wMessage)
                        break;
 
                default:
-                       printk(KERN_INFO LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
+                       printk(KERN_DEBUG LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
                        break;
                }
                break;
@@ -771,15 +781,19 @@ static void eval_dsp_msg(WORD wMessage)
                        (*dev.midi_in_interrupt)(&dev);
                break;
 
+       case HIMT_MIDI_OUT:
+               printk(KERN_DEBUG LOGNAME ": MIDI out event\n");
+               break;
+
        default:
+               printk(KERN_DEBUG LOGNAME ": HIMT message %u\n", HIBYTE(wMessage));
                break;
        }
 }
 
 static void intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-       if (test_bit(F_INTERRUPT, &dev.flags) || 
-           ((multisound_dev_t *)dev_id != &dev))
+       if (test_bit(F_INTERRUPT, &dev.flags))
                return;
 
        set_bit(F_INTERRUPT, &dev.flags);
@@ -1293,6 +1307,7 @@ __initfunc(int msnd_pinnacle_init(void))
 
        init_waitqueue(&dev.writeblock);
        init_waitqueue(&dev.readblock);
+       init_waitqueue(&dev.writeflush);
        msnd_fifo_init(&dev.DAPF);
        msnd_fifo_init(&dev.DARF);
        spin_lock_init(&dev.lock);
index 05dab5d877f5731198f79728f5bb6d8a10f8e064..de621184a51db4087eb887a1ac4673cc63fa7384 100644 (file)
@@ -24,7 +24,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: msnd_pinnacle.h,v 1.3 1998/06/09 20:39:34 andrewtv Exp $
+ * $Id: msnd_pinnacle.h,v 1.4 1998/07/14 22:59:25 andrewtv Exp $
  *
  ********************************************************************/
 #ifndef __MSND_PINNACLE_H
 #define        HIDSP_MIX_CLIPPING      0x30
 #define HIDSP_DAT_IN_OFF       0x21
 
-#define        HDEX_BASE               0x92
-#define        HDEX_PLAY_START         (0 + HDEX_BASE)
-#define        HDEX_PLAY_STOP          (1 + HDEX_BASE)
-#define        HDEX_PLAY_PAUSE         (2 + HDEX_BASE)
-#define        HDEX_PLAY_RESUME        (3 + HDEX_BASE)
-#define        HDEX_RECORD_START       (4 + HDEX_BASE)
-#define        HDEX_RECORD_STOP        (5 + HDEX_BASE)
-#define        HDEX_MIDI_IN_START      (6 + HDEX_BASE)
-#define        HDEX_MIDI_IN_STOP       (7 + HDEX_BASE)
-#define        HDEX_MIDI_OUT_START     (8 + HDEX_BASE)
-#define        HDEX_MIDI_OUT_STOP      (9 + HDEX_BASE)
-#define        HDEX_AUX_REQ            (10 + HDEX_BASE)
-
 #define        HDEXAR_SET_ANA_IN       0
 #define        HDEXAR_CLEAR_PEAKS      1
 #define        HDEXAR_IN_SET_POTS      2
@@ -237,6 +224,14 @@ struct SMA0_CommonData {
 #  define PERMCODESIZE         sizeof(pndsperm)
 #  define INITCODESIZE         sizeof(pndspini)
 #else
+#  ifndef CONFIG_MSNDPIN_INIT_FILE
+#    define CONFIG_MSNDPIN_INIT_FILE                           \
+                               "/etc/sound/pndspini.bin"
+#  endif
+#  ifndef CONFIG_MSNDPIN_PERM_FILE
+#    define CONFIG_MSNDPIN_PERM_FILE                           \
+                               "/etc/sound/pndsperm.bin"
+#  endif
 #  define PERMCODEFILE         CONFIG_MSNDPIN_PERM_FILE
 #  define INITCODEFILE         CONFIG_MSNDPIN_INIT_FILE
 #  define PERMCODE             dspini
index 2a95950e52199c5d3c68ddb43bd71308c3261d06..a5d2272b4658daf6c97af639f165e555629fbd4c 100644 (file)
@@ -272,3 +272,39 @@ void unload_v_midi (struct address_info *hw_config);
 void attach_vidc(struct address_info *hw_config);
 int probe_vidc(struct address_info *hw_config);
 void unload_vidc(struct address_info *hw_config);
+
+/*      From wavefront.c */
+void attach_wavefront (struct address_info *hw_config);
+int probe_wavefront (struct address_info *hw_config);
+void unload_wavefront (struct address_info *hw_config);
+
+/*      From wf_midi.c */
+void attach_wf_mpu(struct address_info * hw_config);
+int probe_wf_mpu(struct address_info *hw_config);
+void unload_wf_mpu(struct address_info *hw_config);
+int virtual_midi_enable (int mididev, struct address_info *);
+void virtual_midi_disable (int mididev);
+
+/*      From wavefront.c */
+void attach_wavefront (struct address_info *hw_config);
+int probe_wavefront (struct address_info *hw_config);
+void unload_wavefront (struct address_info *hw_config);
+
+/*      From wf_midi.c */
+void attach_wf_mpu(struct address_info * hw_config);
+int probe_wf_mpu(struct address_info *hw_config);
+void unload_wf_mpu(struct address_info *hw_config);
+int virtual_midi_enable (int mididev, struct address_info *);
+void virtual_midi_disable (int mididev);
+
+/*      From wavefront.c */
+void attach_wavefront (struct address_info *hw_config);
+int probe_wavefront (struct address_info *hw_config);
+void unload_wavefront (struct address_info *hw_config);
+
+/*      From wf_midi.c */
+void attach_wf_mpu(struct address_info * hw_config);
+int probe_wf_mpu(struct address_info *hw_config);
+void unload_wf_mpu(struct address_info *hw_config);
+int virtual_midi_enable (int mididev, struct address_info *);
+void virtual_midi_disable (int mididev);
diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c
new file mode 100644 (file)
index 0000000..c864be6
--- /dev/null
@@ -0,0 +1,3412 @@
+/*
+ * sound/wavefront.c
+ *
+ * A low level driver for Turtle Beach WaveFront Series
+ *    (Maui, Tropez, Tropez Plus, and perhaps the Monterey & Rio)
+ *
+ * This driver supports the onboard wavetable synthesizer (an ICS2115),
+ * including patch, sample and program loading and unloading, conversion
+ * of GUS patches during loading, and full user-level access to all
+ * WaveFront commands. It tries to provide semi-intelligent patch and
+ * sample management as well.
+ *
+ * It also provides support for the ICS emulation of an MPU-401.  Full
+ * support for the ICS emulation's "virtual MIDI mode" is provided in
+ * wf_midi.c.
+ *
+ * Support is also provided for the Tropez Plus' onboard FX processor,
+ * a Yamaha YSS225. Currently, code exists to configure the YSS225,
+ * and there is an interface allowing tweaking of any of its memory
+ * addresses. However, I have been unable to decipher the logical
+ * positioning of the configuration info for various effects, so for
+ * now, you just get the YSS225 in the same state as Turtle Beach's
+ * "SETUPSND.EXE" utility leaves it.
+ *
+ * The boards' CODEC (a Crystal CS4232) is supported by cs4232.[co],
+ * This chip also controls the configuration of the card: the wavefront
+ * synth is logical unit 4.
+ *
+ * NOTE: this driver has been written to support multiple WaveFront
+ * cards, but without using PnP to configure the CS4232, all of them
+ * would end up with the same configuration. Further, the current
+ * module loading interface doesn't permit this, since it only allows
+ * once instance of a module (which happens to be equivalent to a
+ * single hardware configuration) to be installed at one time.In
+ * addition, there is a hard limit on the available DMA channels that
+ * also makes installing more than 1 card limited to purely MIDI/synth
+ * activities on the second card. Still, the coding style gets rid of
+ * virtually all globals, which I believe is a better way to code
+ * device drivers (or anything else, for that matter).
+ *
+ **********************************************************************
+ *
+ * Copyright (C) by Paul Barton-Davis 1998
+ *
+ * Some portions of this file are taken from work that is
+ * copyright (C) by Hannu Savolainen 1993-1996
+ *
+ * Although the relevant code here is all new, the handling of
+ * sample/alias/multi- samples is entirely based on a driver by Matt
+ * Martin and Rutger Nijlunsing which demonstrated how to get things
+ * to most aspects of this to work correctly. The GUS patch loading
+ * code has been almost unaltered by me, except to fit formatting and
+ * function names in the rest of the file. Many thanks to them.
+ *
+ * Appreciation and thanks to Hannu Savolainen for his early work on the Maui
+ * driver, and answering a few questions while this one was developed.
+ *
+ * Absolutely NO thanks to Turtle Beach/Voyetra and Yamaha for their
+ * complete lack of help in developing this driver, and in particular
+ * for their utter silence in response to questions about undocumented
+ * aspects of configuring a WaveFront soundcard, particularly the
+ * effects processor.
+ *
+ * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.  */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/init.h>
+
+#include "sound_config.h"
+#include "soundmodule.h"
+
+#include <linux/wavefront.h>
+
+#define MIDI_SYNTH_NAME        "WaveFront MIDI"
+#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
+#include "midi_synth.h"
+
+#define COPY_FROM_USER(a,b,c) copy_from_user ((a),(b),(c))
+#define COPY_TO_USER(a,b,c)   copy_to_user ((a),(b),(c))
+
+#if defined(CONFIG_SOUND_WAVEFRONT) || defined(CONFIG_SOUND_WAVEFRONT_MODULE)
+
+/* This thing is meant to work as a module */
+
+#ifdef MODULE
+
+/* bitmasks for WaveFront status port value */
+
+#define STAT_INTR_WRITE                0x40
+#define STAT_CAN_WRITE         0x20
+#define STAT_RINTR_ENABLED     0x10
+#define STAT_INTR_READ         0x04
+#define STAT_CAN_READ          0x02
+#define STAT_WINTR_ENABLED     0x01
+
+/*** Module-accessible parameters ***************************************/
+
+int wf_raw = 0; /* we normally check for "raw state" to firmware
+                  loading. if set, then during driver loading, the
+                  state of the board is ignored, and we reset the
+                  board and load the firmware anyway.
+               */
+                  
+int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
+                  whatever state it is when the driver is loaded.
+                  The default is to download the microprogram and
+                  associated coefficients to set it up for "default"
+                  operation, whatever that means.
+               */
+
+int wf_debug_default = 0;  /* you can set this to control debugging
+                             during driver loading. it takes any combination
+                             of the WF_DEBUG_* flags defined in
+                             wavefront.h
+                          */
+
+/* XXX this needs to be made firmware and hardware version dependent */
+
+char *wf_ospath = "/etc/sound/wavefront.os"; /* where to find a processed
+                                               version of the WaveFront OS
+                                            */
+
+/* These three don't need to be messed with unless you're trying to
+   tweak the driver for optimal I/O performance. Read wavefront_wait()
+   and wavefront_sleep() to see what they do. You may need or want to
+   tweak them for CPU's different than the 486/66Mhz that I run on.
+*/
+
+int wf_short_wait_count = 5000; /* loops, CPU dependent */
+int wf_sleep_interval = 50;     /* HZ/wf_sleep_interval seconds per sleep */
+int wf_sleep_tries = 100;  /*2sec*/ /* number of times we'll try to sleep */
+
+MODULE_PARM(wf_raw,"i");
+MODULE_PARM(fx_raw,"i");
+MODULE_PARM(wf_debug_default,"i");
+MODULE_PARM(wf_ospath,"s");
+MODULE_PARM(wf_short_wait_count,"i");
+MODULE_PARM(wf_sleep_interval,"i");
+MODULE_PARM(wf_sleep_tries,"i");
+
+/***************************************************************************/
+
+static struct synth_info wavefront_info =
+{"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
+ 0, 32, 0, 0, SYNTH_CAP_INPUT};
+
+static int (*midi_load_patch) (int dev, int format, const char *addr,
+                              int offs, int count, int pmgr_flag) = NULL;
+
+
+typedef struct wf_config {
+       int installed;        /* well, is it ? note: doesn't mean "working" */
+       int devno;            /* device number from kernel */
+       int irq;              /* "you were one, one of the few ..." */
+       int base;             /* low i/o port address */
+
+#define mpu_data_port    base 
+#define mpu_command_port base + 1 /* write semantics */
+#define mpu_status_port  base + 1 /* read semantics */
+#define data_port        base + 2 
+#define status_port      base + 3 /* read semantics */
+#define control_port     base + 3 /* write semantics  */
+#define block_port       base + 4 /* 16 bit, writeonly */
+#define last_block_port  base + 6 /* 16 bit, writeonly */
+
+       /* FX ports. These are mapped through the ICS2115 to the YS225.
+          The ICS2115 takes care of flipping the relevant pins on the
+          YS225 so that access to each of these ports does the right
+          thing. Note: these are NOT documented by Turtle Beach.
+       */
+
+#define fx_status       base + 8 
+#define fx_op           base + 8 
+#define fx_lcr          base + 9 
+#define fx_dsp_addr     base + 0xa
+#define fx_dsp_page     base + 0xb 
+#define fx_dsp_lsb      base + 0xc 
+#define fx_dsp_msb      base + 0xd 
+#define fx_mod_addr     base + 0xe
+#define fx_mod_data     base + 0xf 
+
+       volatile int irq_ok;               /* set by interrupt handler */
+       int opened;                        /* flag, holds open(1) mode */
+       char debug;                        /* debugging flags */
+       unsigned int freemem;              /* installed RAM, in bytes */ 
+       int synthdev;                      /* OSS minor devnum for synth */
+       int mididev;                       /* OSS minor devno for internal MIDI */
+       int ext_mididev;                   /* OSS minor devno for external MIDI */ 
+       char fw_version[2];                /* major = [0], minor = [1] */
+       char hw_version[2];                /* major = [0], minor = [1] */
+       char israw;                        /* needs Motorola microcode */
+       char prog_status[WF_MAX_PROGRAM];  /* WF_SLOT_* */
+       char patch_status[WF_MAX_PATCH];   /* WF_SLOT_* */
+       char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
+       int samples_used;                  /* how many */
+       char interrupts_on;                /* h/w MPU interrupts enabled ? */
+       char rom_samples_rdonly;           /* can we write on ROM samples */
+} wf_config;
+
+static wf_config wfs[WAVEFRONT_MAX_DEVICES];
+
+#define wavefront_status(hw) (inb (hw->status_port))
+
+/* forward references */
+
+static int wffx_ioctl (struct wf_config *, wavefront_fx_info *);
+static int wffx_init (struct wf_config *hw);
+static int wavefront_delete_sample (struct wf_config *hw, int sampnum);
+
+static volatile int irq2hw[17] =
+{-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+static volatile int dev2hw[17] =
+{-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+typedef struct {
+       int cmd;
+       char *action;
+       unsigned int read_cnt;
+       unsigned int write_cnt;
+       int need_ack;
+} wavefront_command;
+
+static struct {
+       int errno;
+       const char *errstr;
+} wavefront_errors[] = {
+       { 0x01, "Bad sample number" },
+       { 0x02, "Out of sample memory" },
+       { 0x03, "Bad patch number" },
+       { 0x04, "Error in number of voices" },
+       { 0x06, "Sample load already in progress" },
+       { 0x0B, "No sample load request pending" },
+       { 0x0E, "Bad MIDI channel number" },
+       { 0x10, "Download Record Error" },
+       { 0x80, "Success" },
+       { 0x0, 0x0 }
+};
+
+#define NEEDS_ACK 1
+
+static wavefront_command wavefront_commands[] = {
+       { WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
+       { WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
+       { WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
+       { WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
+       { WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
+       { WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
+       { WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
+       { WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
+       { WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
+       { WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
+       { WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
+       { WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
+       { WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
+       { WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
+       { WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
+       { WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
+       { WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
+       { WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
+       { WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
+       { WFC_DOWNLOAD_SAMPLE, "download sample",
+         0, WF_SAMPLE_BYTES, NEEDS_ACK },
+       { WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
+       { WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
+         0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
+       { WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },
+
+       /* This command requires a variable number of bytes to be written.
+          There is a hack in wavefront_cmd() to support this. The actual
+          count is passed in as the read buffer ptr, cast appropriately.
+          Ugh.
+       */
+
+       { WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },
+
+       /* This one is a hack as well. We just read the first byte of the
+          response, don't fetch an ACK, and leave the rest to the 
+          calling function. Ugly, ugly, ugly.
+       */
+
+       { WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
+       { WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
+         0, WF_ALIAS_BYTES, NEEDS_ACK },
+       { WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
+       { WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
+       { WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
+       { WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
+       { WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
+       { WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
+       { WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
+       { WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
+       { WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
+       { WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
+         NEEDS_ACK},
+       { WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
+       { WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
+         0, 1, NEEDS_ACK },
+       { WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
+       { WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
+         32, 0, 0 },
+       { 0x00 }
+};
+
+wf_config *
+hw_from_dev (int dev)
+
+{
+       int i;
+
+       if ((i = dev2hw[dev]) == -1) {
+               printk (KERN_ERR
+                       "WaveFront: no hardware associated with device %d.\n",
+                       dev);
+               return 0;
+       }
+
+       return &wfs[i];
+}
+
+static const char *
+wavefront_errorstr (int errnum)
+
+{
+       int i;
+
+       for (i = 0; wavefront_errors[i].errstr; i++) {
+               if (wavefront_errors[i].errno == errnum) {
+                       return wavefront_errors[i].errstr;
+               }
+       }
+
+       return "Unknown WaveFront error";
+}
+
+static wavefront_command *
+wavefront_get_command (int cmd) 
+
+{
+       int i;
+
+       for (i = 0; wavefront_commands[i].cmd != 0; i++) {
+               if (cmd == wavefront_commands[i].cmd) {
+                       return &wavefront_commands[i];
+               }
+       }
+
+       return (wavefront_command *) 0;
+}
+
+static int
+wavefront_sleep (wf_config *hw, int limit)
+
+{
+       current->timeout = jiffies + limit;
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       current->timeout = 0;
+
+       return signal_pending(current);
+}
+    
+static int
+wavefront_wait (wf_config *hw, int mask)
+
+{
+       int             i;
+
+       for (i = 0; i < wf_short_wait_count; i++) {
+               if (wavefront_status(hw) & mask) {
+                       return 1;
+               }
+       }
+
+       for (i = 0; i < wf_sleep_tries; i++) {
+
+               if (wavefront_status(hw) & mask) {
+                       return 1;
+               }
+
+               if (wavefront_sleep (hw, HZ/wf_sleep_interval)) {
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static int
+wavefront_read (wf_config *hw)
+{
+       if (wavefront_wait (hw, STAT_CAN_READ))
+               return inb (hw->data_port);
+
+       if (hw->debug & WF_DEBUG_DATA) {
+               printk (KERN_DEBUG "WaveFront: read timeout.\n");
+       }
+       return -1;
+}
+
+static int
+wavefront_write (wf_config *hw, unsigned char data)
+{
+       if (wavefront_wait (hw, STAT_CAN_WRITE)) {
+               outb (data, hw->data_port);
+               return 1;
+       }
+
+       if (hw->debug & WF_DEBUG_DATA) {
+               printk (KERN_DEBUG "WaveFront: write timeout.\n");
+       }
+       return 0;
+}
+
+static int
+wavefront_cmd (wf_config *hw, int cmd,
+              unsigned char *rbuf,
+              unsigned char *wbuf)
+
+{
+       int ack;
+       int i;
+       int c;
+       wavefront_command *wfcmd;
+
+       if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
+               printk (KERN_WARNING "WaveFront: command 0x%x not supported.\n",
+                       cmd);
+               return 1;
+       }
+
+       /* Hack to handle the one variable-size write command. See
+          wavefront_send_multisample() for the other half of this
+          gross and ugly strategy.
+       */
+
+       if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
+               wfcmd->write_cnt = (unsigned int) rbuf;
+               rbuf = 0;
+       }
+
+       if (hw->debug & WF_DEBUG_CMD) {
+               printk (KERN_DEBUG "Wavefront: 0x%x [%s] (%d,%d,%d)\n",
+                       cmd, wfcmd->action, wfcmd->read_cnt, wfcmd->write_cnt,
+                       wfcmd->need_ack);
+       }
+    
+       if (!wavefront_write (hw, cmd)) { 
+               if (hw->debug & (WF_DEBUG_IO|WF_DEBUG_CMD)) {
+                       printk (KERN_DEBUG "WaveFront: cannot request "
+                               "0x%x [%s].\n",
+                               cmd, wfcmd->action);
+               }
+               return 1;
+       } 
+
+       if (wfcmd->write_cnt > 0) {
+               if (hw->debug & WF_DEBUG_DATA) {
+                       printk (KERN_DEBUG "WaveFront: writing %d bytes "
+                               "for 0x%x\n",
+                               wfcmd->write_cnt, cmd);
+               }
+
+               for (i = 0; i < wfcmd->write_cnt; i++) {
+                       if (!wavefront_write (hw, wbuf[i])) {
+                               if (hw->debug & WF_DEBUG_IO) {
+                                       printk (KERN_DEBUG
+                           "WaveFront: bad write for byte %d of 0x%x [%s].\n",
+                                               i, cmd, wfcmd->action);
+                               }
+                               return 1;
+                       }
+                       if (hw->debug & WF_DEBUG_DATA) {
+                               printk (KERN_DEBUG
+                                        "WaveFront: write[%d] = 0x%x\n",
+                                       i, wbuf[i]);
+                       }
+               }
+       }
+
+       if (wfcmd->read_cnt > 0) {
+               if (hw->debug & WF_DEBUG_DATA) {
+                       printk (KERN_DEBUG "WaveFront: reading %d ints "
+                               "for 0x%x\n",
+                               wfcmd->read_cnt, cmd);
+               }
+
+               for (i = 0; i < wfcmd->read_cnt; i++) {
+
+                       if ((c = wavefront_read(hw)) == -1) {
+                               if (hw->debug & WF_DEBUG_IO) {
+                                       printk (KERN_DEBUG
+                               "WaveFront: bad read for byte %d of 0x%x [%s].\n",
+                                               i, cmd, wfcmd->action);
+                               }
+                               return 1;
+                       }
+
+                       /* Now handle errors. Lots of special cases here */
+           
+                       if (c == 0xff) { 
+                               if ((c = wavefront_read (hw)) == -1) {
+                                       if (hw->debug & WF_DEBUG_IO) {
+                                               printk (KERN_DEBUG
+                                 "WaveFront: bad read for error byte at "
+                                  "read byte %d of 0x%x [%s].\n",
+                                                       i, cmd, wfcmd->action);
+                                       }
+                                       return 1;
+                               }
+
+                               /* Can you believe this madness ? */
+
+                               if (c == 1 &&
+                                   wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
+                                       rbuf[0] = WF_ST_EMPTY;
+                                       return 0;
+
+                               } else if (c == 3 &&
+                                          wfcmd->cmd == WFC_UPLOAD_PATCH) {
+
+                                       return 3;
+
+                               } else if (c == 1 &&
+                                          wfcmd->cmd == WFC_UPLOAD_PROGRAM) {
+
+                                       return 1;
+
+                               } else {
+
+                                       if (hw->debug & WF_DEBUG_IO) {
+                                               printk (KERN_DEBUG
+                                            "WaveFront: error %d (%s) during "
+                                                "read for byte "
+                                                 "%d of 0x%x [%s].\n",
+                                                       c,
+                                                       wavefront_errorstr (c),
+                                                       i, cmd, wfcmd->action);
+                                       }
+                                       return 1;
+
+                               }
+                       } else {
+                               rbuf[i] = c;
+                       }
+
+                       if (hw->debug & WF_DEBUG_DATA) {
+                               printk (KERN_DEBUG
+                                       "WaveFront: read[%d] = 0x%x\n",
+                                       i, rbuf[i]);
+                       }
+               }
+       }
+
+       if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {
+
+               if (hw->debug & WF_DEBUG_CMD) {
+                       printk (KERN_DEBUG "WaveFront: reading ACK for 0x%x\n",
+                               cmd);
+               }
+
+               /* Some commands need an ACK, but return zero instead
+                  of the standard value.
+               */
+           
+               if ((ack = wavefront_read(hw)) == 0) {
+                       ack = WF_ACK;
+               }
+       
+               if (ack != WF_ACK) {
+                       if (ack == -1) {
+                               if (hw->debug & WF_DEBUG_IO) {
+                                       printk (KERN_DEBUG
+                               "WaveFront: cannot read ack for 0x%x [%s].\n",
+                                               cmd, wfcmd->action);
+                               }
+                               return 1;
+               
+                       } else {
+                               int err = -1; /* something unknown */
+
+                               if (ack == 0xff) { /* explicit error */
+                   
+                                       if ((err = wavefront_read (hw)) == -1) {
+                                               if (hw->debug & WF_DEBUG_DATA) {
+                                                       printk (KERN_DEBUG
+                               "WaveFront: cannot read err for 0x%x [%s].\n",
+                                                            cmd, wfcmd->action);
+                                               }
+                                       }
+                               }
+
+                               if (hw->debug & WF_DEBUG_IO) {
+                                       printk (KERN_DEBUG
+                                               "WaveFront: 0x%x [%s] "
+                                               "failed (0x%x, 0x%x, %s)\n",
+                                               cmd, wfcmd->action, ack, err,
+                                               wavefront_errorstr (err));
+                               }
+                               return -err;
+                       } 
+               }
+
+               if (hw->debug & WF_DEBUG_DATA) {
+                       printk (KERN_DEBUG "WaveFront: ack received "
+                               "for 0x%x [%s]\n",
+                               cmd, wfcmd->action);
+               }
+       } else {
+               if (hw->debug & WF_DEBUG_CMD) {
+                       printk (KERN_DEBUG 
+                               "Wavefront: 0x%x [%s] does not need "
+                               "ACK (%d,%d,%d)\n",
+                               cmd, wfcmd->action, wfcmd->read_cnt,
+                               wfcmd->write_cnt, wfcmd->need_ack);
+               }
+       }
+
+       return 0;
+       
+}
+\f
+/***********************************************************************
+WaveFront: data munging   
+
+Things here are wierd. All data written to the board cannot 
+have its most significant bit set. Any data item with values 
+potentially > 0x7F (127) must be split across multiple bytes.
+
+Sometimes, we need to munge numeric values that are represented on
+the x86 side as 8-32 bit values. Sometimes, we need to munge data
+that is represented on the x86 side as an array of bytes. The most
+efficient approach to handling both cases seems to be to use 2
+different functions for munging and 2 for de-munging. This avoids
+wierd casting and worrying about bit-level offsets.
+
+**********************************************************************/
+
+static 
+unsigned char *
+munge_int32 (unsigned int src,
+            unsigned char *dst,
+            unsigned int dst_size)
+{
+       int i;
+
+       for (i = 0;i < dst_size; i++) {
+               *dst = src & 0x7F;  /* Mask high bit of LSB */
+               src = src >> 7;     /* Rotate Right 7 bits  */
+                                   /* Note: we leave the upper bits in place */ 
+
+               dst++;
+       };
+       return dst;
+};
+
+static int 
+demunge_int32 (unsigned char* src, int src_size)
+
+{
+       int i;
+       int outval = 0;
+       
+       for (i = src_size - 1; i >= 0; i--) {
+               outval=(outval<<7)+src[i];
+       }
+
+       return outval;
+};
+
+static 
+unsigned char *
+munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)
+
+{
+       int i;
+       unsigned int last = dst_size / 2;
+
+       for (i = 0; i < last; i++) {
+               *dst++ = src[i] & 0x7f;
+               *dst++ = src[i] >> 7;
+       }
+       return dst;
+}
+
+static 
+unsigned char *
+demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)
+
+{
+       int i;
+       unsigned char *end = src + src_bytes;
+    
+       end = src + src_bytes;
+
+       /* NOTE: src and dst *CAN* point to the same address */
+
+       for (i = 0; src != end; i++) {
+               dst[i] = *src++;
+               dst[i] |= (*src++)<<7;
+       }
+
+       return dst;
+}
+\f
+/***********************************************************************
+WaveFront: sample, patch and program management.
+***********************************************************************/
+
+static int
+wavefront_delete_sample (wf_config *hw, int sample_num)
+
+{
+       unsigned char wbuf[2];
+       int x;
+
+       wbuf[0] = sample_num & 0x7f;
+       wbuf[1] = sample_num >> 7;
+
+       if ((x = wavefront_cmd (hw, WFC_DELETE_SAMPLE, 0, wbuf)) == 0) {
+               hw->sample_status[sample_num] = WF_ST_EMPTY;
+       }
+
+       return x;
+}
+
+static int
+wavefront_get_sample_status (struct wf_config *hw, int assume_rom)
+
+{
+       int i;
+       unsigned char rbuf[32], wbuf[32];
+       unsigned int    sc_real, sc_alias, sc_multi;
+
+       /* check sample status */
+    
+       if (wavefront_cmd (hw, WFC_GET_NSAMPLES, rbuf, wbuf)) {
+               printk ("WaveFront: cannot request sample count.\n");
+       } 
+    
+       sc_real = sc_alias = sc_multi = hw->samples_used = 0;
+    
+       for (i = 0; i < WF_MAX_SAMPLE; i++) {
+       
+               wbuf[0] = i & 0x7f;
+               wbuf[1] = i >> 7;
+
+               if (wavefront_cmd (hw, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
+                       printk (KERN_WARNING
+                               "WaveFront: cannot identify sample "
+                               "type of slot %d\n", i);
+                       hw->sample_status[i] = WF_ST_EMPTY;
+                       continue;
+               }
+
+               hw->sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
+
+               if (assume_rom) {
+                       hw->sample_status[i] |= WF_SLOT_ROM;
+               }
+
+               switch (rbuf[0] & WF_ST_MASK) {
+               case WF_ST_SAMPLE:
+                       sc_real++;
+                       break;
+               case WF_ST_MULTISAMPLE:
+                       sc_multi++;
+                       break;
+               case WF_ST_ALIAS:
+                       sc_alias++;
+                       break;
+               case WF_ST_EMPTY:
+                       break;
+
+               default:
+                       printk (KERN_WARNING
+                               "WaveFront: unknown sample type for "
+                               "slot %d (0x%x)\n", 
+                               i, rbuf[0]);
+               }
+
+               if (rbuf[0] != WF_ST_EMPTY) {
+                       hw->samples_used++;
+               } 
+       }
+
+       printk (KERN_INFO
+               "WaveFront: %d samples used (%d real, %d aliases, %d multi), "
+               "%d empty\n", hw->samples_used, sc_real, sc_alias, sc_multi,
+               WF_MAX_SAMPLE - hw->samples_used);
+
+
+       return 0;
+
+}
+
+static int
+wavefront_get_patch_status (struct wf_config *hw)
+{
+       unsigned char patchbuf[WF_PATCH_BYTES];
+       unsigned char patchnum[2];
+       wavefront_patch *p;
+       int i, x, cnt, cnt2;
+
+       for (i = 0; i < WF_MAX_PATCH; i++) {
+               patchnum[0] = i & 0x7f;
+               patchnum[1] = i >> 7;
+
+               if ((x = wavefront_cmd (hw, WFC_UPLOAD_PATCH, patchbuf,
+                                       patchnum)) == 0) {
+
+                       hw->patch_status[i] |= WF_SLOT_FILLED;
+                       p = (wavefront_patch *) patchbuf;
+                       hw->sample_status
+                               [p->sample_number|(p->sample_msb<<7)] |=
+                               WF_SLOT_USED;
+           
+               } else if (x == 3) { /* Bad patch number */
+                       hw->patch_status[i] = 0;
+               } else {
+                       printk (KERN_ERR "WaveFront: upload patch "
+                               "error 0x%x\n", x);
+                       hw->patch_status[i] = 0;
+               }
+       }
+
+       /* program status has already filled in slot_used bits */
+
+       for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
+               if (hw->patch_status[i] & WF_SLOT_FILLED) {
+                       cnt++;
+               }
+               if (hw->patch_status[i] & WF_SLOT_USED) {
+                       cnt2++;
+               }
+       
+       }
+       printk (KERN_INFO
+               "WaveFront: %d patch slots filled, %d in use\n", cnt, cnt2);
+
+       return 0;
+}
+
+static int
+wavefront_get_program_status (struct wf_config *hw)
+{
+       unsigned char progbuf[WF_PROGRAM_BYTES];
+       wavefront_program prog;
+       unsigned char prognum;
+       int i, x, l, cnt;
+
+       for (i = 0; i < WF_MAX_PROGRAM; i++) {
+               prognum = i;
+
+               if ((x = wavefront_cmd (hw, WFC_UPLOAD_PROGRAM, progbuf,
+                                       &prognum)) == 0) {
+
+                       hw->prog_status[i] |= WF_SLOT_USED;
+
+                       demunge_buf (progbuf, (unsigned char *) &prog,
+                                    WF_PROGRAM_BYTES);
+
+                       for (l = 0; l < WF_NUM_LAYERS; l++) {
+                               if (prog.layer[l].mute) {
+                                       hw->patch_status
+                                               [prog.layer[l].patch_number] |=
+                                               WF_SLOT_USED;
+                               }
+                       }
+               } else if (x == 1) { /* Bad program number */
+                       hw->prog_status[i] = 0;
+               } else {
+                       printk (KERN_ERR "WaveFront: upload program "
+                               "error 0x%x\n", x);
+                       hw->prog_status[i] = 0;
+               }
+       }
+
+       for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
+               if (hw->prog_status[i]) {
+                       cnt++;
+               }
+       }
+
+       printk (KERN_INFO "WaveFront: %d programs slots in use\n", cnt);
+
+       return 0;
+}
+
+static int
+wavefront_send_patch (wf_config *hw, 
+                     wavefront_patch_info *header)
+
+{
+       unsigned char buf[WF_PATCH_BYTES+2];
+       unsigned char *bptr;
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG "WaveFront: downloading patch %d\n",
+                       header->number);
+       }
+
+       hw->patch_status[header->number] |= WF_SLOT_FILLED;
+
+       bptr = buf;
+       bptr = munge_int32 (header->number, buf, 2);
+       munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
+    
+       if (wavefront_cmd (hw, WFC_DOWNLOAD_PATCH, 0, buf)) {
+               printk (KERN_ERR "WaveFront: download patch failed\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int
+wavefront_send_program (wf_config *hw, 
+                       wavefront_patch_info *header)
+
+{
+       unsigned char buf[WF_PROGRAM_BYTES+1];
+       int i;
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG
+                       "WaveFront: downloading program %d\n", header->number);
+       }
+
+       hw->prog_status[header->number] = WF_SLOT_USED;
+
+       /* XXX need to zero existing SLOT_USED bit for program_status[i]
+          where `i' is the program that's being (potentially) overwritten.
+       */
+    
+       for (i = 0; i < WF_NUM_LAYERS; i++) {
+               if (header->hdr.pr.layer[i].mute) {
+                       hw->patch_status[header->hdr.pr.layer[i].patch_number] |=
+                               WF_SLOT_USED;
+
+                       /* XXX need to mark SLOT_USED for sample used by
+                          patch_number, but this means we have to load it. Ick.
+                       */
+               }
+       }
+
+       buf[0] = header->number;
+       munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
+    
+       if (wavefront_cmd (hw, WFC_DOWNLOAD_PROGRAM, 0, buf)) {
+               printk (KERN_WARNING "WaveFront: download patch failed\n");     
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int
+wavefront_freemem (wf_config *hw)
+
+{
+       char rbuf[8];
+
+       if (wavefront_cmd (hw, WFC_REPORT_FREE_MEMORY, rbuf, 0)) {
+               printk (KERN_WARNING "WaveFront: can't get memory stats.\n");
+               return -1;
+       } else {
+               return demunge_int32 (rbuf, 4);
+       }
+}
+
+static int
+wavefront_send_sample (wf_config      *hw,
+                      wavefront_patch_info *header,
+                      UINT16 *dataptr,
+                      int data_is_unsigned)
+
+{
+       /* samples are downloaded via a 16-bit wide i/o port
+          (you could think of it as 2 adjacent 8-bit wide ports
+          but its less efficient that way). therefore, all
+          the blocksizes and so forth listed in the documentation,
+          and used conventionally to refer to sample sizes,
+          which are given in 8-bit units (bytes), need to be
+          divided by 2.
+        */
+
+       UINT16 sample_short;
+       UINT32 length;
+       UINT16 *data_end = 0;
+       unsigned int i;
+       const int max_blksize = 4096/2;
+       unsigned int written;
+       unsigned int blocksize;
+       int dma_ack;
+       int blocknum;
+       unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
+       unsigned char *shptr;
+       int skip = 0;
+       int initial_skip = 0;
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG "WaveFront: sample %sdownload for slot %d, "
+                       "type %d, %d bytes from 0x%x\n",
+                       header->size ? "" : "header ", 
+                       header->number, header->subkey, header->size,
+                       (int) header->dataptr);
+       }
+
+       if (header->size) {
+
+               /* XXX its a debatable point whether or not RDONLY semantics
+                  on the ROM samples should cover just the sample data or
+                  the sample header. For now, it only covers the sample data,
+                  so anyone is free at all times to rewrite sample headers.
+
+                  My reason for this is that we have the sample headers
+                  available in the WFB file for General MIDI, and so these
+                  can always be reset if needed. The sample data, however,
+                  cannot be recovered without a complete reset and firmware
+                  reload of the ICS2115, which is a very expensive operation.
+
+                  So, doing things this way allows us to honor the notion of
+                  "RESETSAMPLES" reasonably cheaply. Note however, that this
+                  is done purely at user level: there is no WFB parser in
+                  this driver, and so a complete reset (back to General MIDI,
+                  or theoretically some other configuration) is the
+                  responsibility of the user level library. 
+
+                  To try to do this in the kernel would be a little crazy:
+                  we'd need 24 * 512 bytes (12K) of kernel space just to
+                  hold copies of the original sample headers; the whole
+                  patch/program/sample header data is about 158K!!!
+               */
+
+               if (hw->rom_samples_rdonly) {
+                       if (hw->sample_status[header->number] & WF_SLOT_ROM) {
+                               printk (KERN_ERR "WaveFront: sample slot %d "
+                                       "write protected\n",
+                                       header->number);
+                               return -EACCES;
+                       }
+               }
+
+               wavefront_delete_sample (hw, header->number);
+       }
+
+       if (header->size) {
+               hw->freemem = wavefront_freemem (hw);
+
+               if (hw->freemem < header->size) {
+                       printk (KERN_ERR
+                               "WaveFront: insufficient memory to "
+                               "load %d byte sample.\n",
+                               header->size);
+                       return -ENOMEM;
+               }
+       
+       }
+
+       skip = WF_GET_CHANNEL(&header->hdr.s);
+
+       if (skip > 0) {
+               switch (header->hdr.s.SampleResolution) {
+               case LINEAR_16BIT:
+                       break;
+               default:
+                       printk (KERN_ERR
+                               "WaveFront: channel selection only possible "
+                               "on 16-bit samples");
+                       return -EINVAL;
+               }
+       }
+
+       switch (skip) {
+       case 0:
+               initial_skip = 0;
+               skip = 1;
+               break;
+       case 1:
+               initial_skip = 0;
+               skip = 2;
+               break;
+       case 2:
+               initial_skip = 1;
+               skip = 2;
+               break;
+       case 3:
+               initial_skip = 2;
+               skip = 3;
+               break;
+       case 4:
+               initial_skip = 3;
+               skip = 4;
+               break;
+       case 5:
+               initial_skip = 4;
+               skip = 5;
+               break;
+       case 6:
+               initial_skip = 5;
+               skip = 6;
+               break;
+       }
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG "WaveFront: channel selection: %d => "
+                       "initial skip = %d, skip = %d\n",
+                       WF_GET_CHANNEL (&header->hdr.s), initial_skip, skip);
+       }
+    
+       /* Be safe, and zero the "Unused" bits ... */
+
+       WF_SET_CHANNEL(&header->hdr.s, 0);
+
+       /* adjust size for 16 bit samples by dividing by two.  We always
+          send 16 bits per write, even for 8 bit samples, so the length
+          is always half the size of the sample data in bytes.
+       */
+
+       length = header->size / 2;
+
+       /* the data we're sent has not been munged, and in fact, the
+          header we have to send isn't just a munged copy either.
+          so, build the sample header right here.
+       */
+
+       shptr = &sample_hdr[0];
+
+       shptr = munge_int32 (header->number, shptr, 2);
+
+       if (header->size) {
+               shptr = munge_int32 (length, shptr, 4);
+       }
+
+       /* Yes, a 4 byte result doesn't contain all of the offset bits,
+          but the offset only uses 24 bits.
+       */
+
+       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleStartOffset),
+                            shptr, 4);
+       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopStartOffset),
+                            shptr, 4);
+       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopEndOffset),
+                            shptr, 4);
+       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset),
+                            shptr, 4);
+       
+       /* This one is truly wierd. What kind of wierdo decided that in
+          a system dominated by 16 and 32 bit integers, they would use
+          a 12 bit transfer size ?
+       */
+       
+       shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
+       
+       /* Why is this nybblified, when the MSB is *always* zero ? 
+          Anyway, we can't take address of bitfield, so make a
+          good-faith guess at where it starts.
+       */
+       
+       shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
+                            shptr, 2);
+
+       if (wavefront_cmd (hw, header->size ?
+                          WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
+                          0, sample_hdr)) {
+               printk (KERN_WARNING "WaveFront: sample %sdownload refused.\n",
+                       header->size ? "" : "header ");
+               return -EIO;
+       }
+
+       if (header->size == 0) {
+               goto sent; /* Sorry. Just had to have one somewhere */
+       }
+    
+       data_end = dataptr + length;
+
+       /* Do any initial skip over an unused channel's data */
+
+       dataptr += initial_skip;
+    
+       for (written = 0, blocknum = 0;
+            written < length; written += max_blksize, blocknum++) {
+       
+               if ((length - written) > max_blksize) {
+                       blocksize = max_blksize;
+               } else {
+                       /* round to nearest 16-byte value */
+                       blocksize = ((length-written+7)&~0x7);
+               }
+
+               if (wavefront_cmd (hw, WFC_DOWNLOAD_BLOCK, 0, 0)) {
+                       printk (KERN_WARNING "WaveFront: download block "
+                               "request refused.\n");
+                       return -EIO;
+               }
+
+               for (i = 0; i < blocksize; i++) {
+
+                       if (dataptr < data_end) {
+               
+                               get_user (sample_short, dataptr);
+                               dataptr += skip;
+               
+                               if (data_is_unsigned) {
+
+                                       if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
+                       
+                                               /* 8 bit sample
+                                                resolution, sign
+                                                extend both bytes.
+                                               */
+                       
+                                               ((unsigned char*)
+                                                &sample_short)[0] += 0x7f;
+                                               ((unsigned char*)
+                                                &sample_short)[1] += 0x7f;
+                       
+                                       } else {
+                       
+                                               /* 16 bit sample
+                                                resolution, sign
+                                                extend the MSB.
+                                               */
+                       
+                                               sample_short += 0x7fff;
+                                       }
+                               }
+
+                       } else {
+
+                               /* In padding section of final block:
+
+                                  Don't fetch unsupplied data from
+                                  user space, just continue with
+                                  whatever the final value was.
+                               */
+                       }
+           
+                       if (i < blocksize - 1) {
+                               outw (sample_short, hw->block_port);
+                       } else {
+                               outw (sample_short, hw->last_block_port);
+                       }
+               }
+
+               /* Get "DMA page acknowledge" */
+       
+               if ((dma_ack = wavefront_read (hw)) != WF_DMA_ACK) {
+                       if (dma_ack == -1) {
+                               printk (KERN_ERR "WaveFront: upload sample "
+                                       "DMA ack timeout\n");
+                               return -EIO;
+                       } else {
+                               printk (KERN_ERR "WaveFront: upload sample "
+                                       "DMA ack error 0x%x\n",
+                                       dma_ack);
+                               return -EIO;
+                       }
+               }
+       }
+
+       hw->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
+
+       /* Note, label is here because sending the sample header shouldn't
+          alter the sample_status info at all.
+       */
+
+ sent:
+       return 0;
+}
+
+static int
+wavefront_send_alias (struct wf_config *hw, 
+                     wavefront_patch_info *header)
+
+{
+       unsigned char alias_hdr[WF_ALIAS_BYTES];
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG "WaveFront: download alias, %d is "
+                       "alias for %d\n",
+                       header->number,
+                       header->hdr.a.OriginalSample);
+       }
+    
+       munge_int32 (header->number, &alias_hdr[0], 2);
+       munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
+       munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
+                    &alias_hdr[4], 4);
+       munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
+                    &alias_hdr[8], 4);
+       munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
+                    &alias_hdr[12], 4);
+       munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
+                    &alias_hdr[16], 4);
+       munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
+       munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
+
+       if (wavefront_cmd (hw, WFC_DOWNLOAD_SAMPLE_ALIAS, 0, alias_hdr)) {
+               printk (KERN_ERR "WaveFront: download alias failed.\n");
+               return -EIO;
+       }
+
+       hw->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
+
+       return 0;
+}
+
+static int
+wavefront_send_multisample (struct wf_config *hw,
+                           wavefront_patch_info *header)
+{
+       int i;
+       int num_samples;
+       unsigned char msample_hdr[WF_MSAMPLE_BYTES];
+
+       munge_int32 (header->number, &msample_hdr[0], 2);
+
+       /* You'll recall at this point that the "number of samples" value
+          in a wavefront_multisample struct is actually the log2 of the
+          real number of samples.
+       */
+
+       num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
+       msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG "WaveFront: multi %d with %d=%d samples\n",
+                       header->number, header->hdr.ms.NumberOfSamples, num_samples);
+       }
+
+       for (i = 0; i < num_samples; i++) {
+               if ((hw->debug & (WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA)) ==
+                   (WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA)) {
+                       printk (KERN_DEBUG "WaveFront: sample[%d] = %d\n",
+                               i, header->hdr.ms.SampleNumber[i]);
+               }
+               munge_int32 (header->hdr.ms.SampleNumber[i],
+                            &msample_hdr[3+(i*2)], 2);
+       }
+    
+       /* Need a hack here to pass in the number of bytes
+          to be written to the synth. This is ugly, and perhaps
+          one day, I'll fix it.
+       */
+
+       if (wavefront_cmd (hw, WFC_DOWNLOAD_MULTISAMPLE, 
+                          (unsigned char *) ((num_samples*2)+3),
+                          msample_hdr)) {
+               printk (KERN_ERR "WaveFront: download of multisample failed.\n");
+               return -EIO;
+       }
+
+       hw->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
+
+       return 0;
+}
+
+static int
+wavefront_fetch_multisample (struct wf_config *hw,
+                            wavefront_patch_info *header)
+{
+       int i;
+       unsigned char log_ns[1];
+       unsigned char number[2];
+       int num_samples;
+
+       munge_int32 (header->number, number, 2);
+    
+       if (wavefront_cmd (hw, WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
+               printk (KERN_ERR "WaveFront: upload multisample failed.\n");
+               return -EIO;
+       }
+    
+       if (hw->debug & WF_DEBUG_DATA) {
+               printk (KERN_DEBUG "WaveFront: msample %d has %d samples\n",
+                       header->number, log_ns[0]);
+       }
+
+       header->hdr.ms.NumberOfSamples = log_ns[0];
+
+       /* get the number of samples ... */
+
+       num_samples = (1 << log_ns[0]);
+    
+       for (i = 0; i < num_samples; i++) {
+               char d[2];
+       
+               if ((d[0] = wavefront_read (hw)) == -1) {
+                       printk (KERN_ERR "WaveFront: upload multisample failed "
+                               "during sample loop.\n");
+                       return -EIO;
+               }
+
+               if ((d[1] = wavefront_read (hw)) == -1) {
+                       printk (KERN_ERR "WaveFront: upload multisample failed "
+                               "during sample loop.\n");
+                       return -EIO;
+               }
+       
+               header->hdr.ms.SampleNumber[i] =
+                       demunge_int32 ((unsigned char *) d, 2);
+       
+               if (hw->debug & WF_DEBUG_DATA) {
+                       printk (KERN_DEBUG "WaveFront: msample "
+                               "sample[%d] = %d\n",
+                               i, header->hdr.ms.SampleNumber[i]);
+               }
+       }
+
+       return 0;
+}
+
+
+static int
+wavefront_send_drum (struct wf_config *hw, wavefront_patch_info *header)
+
+{
+       unsigned char drumbuf[WF_DRUM_BYTES];
+       wavefront_drum *drum = &header->hdr.d;
+       int i;
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG
+                       "WaveFront: downloading edrum for MIDI "
+                       "note %d, patch = %d\n", 
+                       header->number, drum->PatchNumber);
+       }
+
+       drumbuf[0] = header->number & 0x7f;
+
+       for (i = 0; i < 4; i++) {
+               munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
+       }
+
+       if (wavefront_cmd (hw, WFC_DOWNLOAD_EDRUM_PROGRAM, 0, drumbuf)) {
+               printk (KERN_ERR "WaveFront: download drum failed.\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int 
+wavefront_find_free_sample (struct wf_config *hw)
+
+{
+       int i;
+
+       for (i = 0; i < WF_MAX_SAMPLE; i++) {
+               if (!(hw->sample_status[i] & WF_SLOT_FILLED)) {
+                       return i;
+               }
+       }
+       printk (KERN_WARNING "WaveFront: no free sample slots!\n");
+       return -1;
+}
+
+static int 
+wavefront_find_free_patch (struct wf_config *hw)
+
+{
+       int i;
+
+       for (i = 0; i < WF_MAX_SAMPLE; i++) {
+               if (!(hw->patch_status[i] & WF_SLOT_FILLED)) {
+                       return i;
+               }
+       }
+       printk (KERN_WARNING "WaveFront: no free patch slots!\n");
+       return -1;
+}
+
+static int 
+log2_2048(int n)
+
+{
+       int tbl[]={0, 0, 2048, 3246, 4096, 4755, 5294, 5749, 6143,
+                  6492, 6803, 7084, 7342, 7578, 7797, 8001, 8192,
+                  8371, 8540, 8699, 8851, 8995, 9132, 9264, 9390,
+                  9510, 9626, 9738, 9845, 9949, 10049, 10146};
+       int i;
+
+       /* Returns 2048*log2(n) */
+
+       /* FIXME: this is like doing integer math
+          on quantum particles (RuN) */
+
+       i=0;
+       while(n>=32*256) {
+               n>>=8;
+               i+=2048*8;
+       }
+       while(n>=32) {
+               n>>=1;
+               i+=2048;
+       }
+       i+=tbl[n];
+       return(i);
+}
+
+static int
+wavefront_load_gus_patch (struct wf_config *hw,
+                         int dev, int format, const char *addr,
+                         int offs, int count, int pmgr_flag)
+{
+       struct patch_info guspatch;
+       wavefront_patch_info samp, pat, prog;
+       wavefront_patch *patp;
+       wavefront_sample *sampp;
+       wavefront_program *progp;
+
+       int i,base_note;
+       long sizeof_patch;
+
+       /* Copy in the header of the GUS patch */
+
+       sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch; 
+       COPY_FROM_USER (&((char *) &guspatch)[offs],
+                       &(addr)[offs], sizeof_patch - offs);
+
+       if ((i = wavefront_find_free_patch (hw)) == -1) {
+               return -EBUSY;
+       }
+       pat.number = i;
+       pat.subkey = WF_ST_PATCH;
+       patp = &pat.hdr.p;
+
+       if ((i = wavefront_find_free_sample (hw)) == -1) {
+               return -EBUSY;
+       }
+       samp.number = i;
+       samp.subkey = WF_ST_SAMPLE;
+       samp.size = guspatch.len;
+       sampp = &samp.hdr.s;
+
+       prog.number = guspatch.instr_no;
+       progp = &prog.hdr.pr;
+
+       /* Setup the patch structure */
+
+       patp->amplitude_bias=guspatch.volume;
+       patp->portamento=0;
+       patp->sample_number= samp.number & 0xff;
+       patp->sample_msb= samp.number>>8;
+       patp->pitch_bend= /*12*/ 0;
+       patp->mono=1;
+       patp->retrigger=1;
+       patp->nohold=(guspatch.mode & WAVE_SUSTAIN_ON) ? 0:1;
+       patp->frequency_bias=0;
+       patp->restart=0;
+       patp->reuse=0;
+       patp->reset_lfo=1;
+       patp->fm_src2=0;
+       patp->fm_src1=WF_MOD_MOD_WHEEL;
+       patp->am_src=WF_MOD_PRESSURE;
+       patp->am_amount=127;
+       patp->fc1_mod_amount=0;
+       patp->fc2_mod_amount=0; 
+       patp->fm_amount1=0;
+       patp->fm_amount2=0;
+       patp->envelope1.attack_level=127;
+       patp->envelope1.decay1_level=127;
+       patp->envelope1.decay2_level=127;
+       patp->envelope1.sustain_level=127;
+       patp->envelope1.release_level=0;
+       patp->envelope2.attack_velocity=127;
+       patp->envelope2.attack_level=127;
+       patp->envelope2.decay1_level=127;
+       patp->envelope2.decay2_level=127;
+       patp->envelope2.sustain_level=127;
+       patp->envelope2.release_level=0;
+       patp->envelope2.attack_velocity=127;
+       patp->randomizer=0;
+
+       /* Program for this patch */
+
+       progp->layer[0].patch_number= pat.number; /* XXX is this right ? */
+       progp->layer[0].mute=1;
+       progp->layer[0].pan_or_mod=1;
+       progp->layer[0].pan=7;
+       progp->layer[0].mix_level=127  /* guspatch.volume */;
+       progp->layer[0].split_type=0;
+       progp->layer[0].split_point=0;
+       progp->layer[0].updown=0;
+
+       for (i = 1; i < 4; i++) {
+               progp->layer[i].mute=0;
+       }
+
+       /* Sample data */
+
+       sampp->SampleResolution=((~guspatch.mode & WAVE_16_BITS)<<1);
+
+       for (base_note=0;
+            note_to_freq (base_note) < guspatch.base_note;
+            base_note++);
+
+       if ((guspatch.base_note-note_to_freq(base_note))
+           >(note_to_freq(base_note)-guspatch.base_note))
+               base_note++;
+
+       printk(KERN_DEBUG "ref freq=%d,base note=%d\n",
+              guspatch.base_freq,
+              base_note);
+
+       sampp->FrequencyBias = (29550 - log2_2048(guspatch.base_freq)
+                               + base_note*171);
+       printk(KERN_DEBUG "Freq Bias is %d\n", sampp->FrequencyBias);
+       sampp->Loop=(guspatch.mode & WAVE_LOOPING) ? 1:0;
+       sampp->sampleStartOffset.Fraction=0;
+       sampp->sampleStartOffset.Integer=0;
+       sampp->loopStartOffset.Fraction=0;
+       sampp->loopStartOffset.Integer=guspatch.loop_start
+               >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
+       sampp->loopEndOffset.Fraction=0;
+       sampp->loopEndOffset.Integer=guspatch.loop_end
+               >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
+       sampp->sampleEndOffset.Fraction=0;
+       sampp->sampleEndOffset.Integer=guspatch.len >> (guspatch.mode&1);
+       sampp->Bidirectional=(guspatch.mode&WAVE_BIDIR_LOOP) ? 1:0;
+       sampp->Reverse=(guspatch.mode&WAVE_LOOP_BACK) ? 1:0;
+
+       /* Now ship it down */
+
+       wavefront_send_sample (hw, &samp, 
+                              (unsigned short *) &(addr)[sizeof_patch],
+                              (guspatch.mode & WAVE_UNSIGNED) ? 1:0);
+       wavefront_send_patch (hw, &pat);
+       wavefront_send_program (hw, &prog);
+
+       /* Now pan as best we can ... use the slave/internal MIDI device
+          number if it exists (since it talks to the WaveFront), or the
+          master otherwise.
+       */
+
+#ifdef CONFIG_MIDI
+       if (hw->mididev > 0) {
+               midi_synth_controller (hw->mididev, guspatch.instr_no, 10,
+                                      ((guspatch.panning << 4) > 127) ?
+                                      127 : (guspatch.panning << 4));
+       }
+#endif CONFIG_MIDI
+
+       return(0);
+}
+
+int
+wavefront_load_patch (int dev, int format, const char *addr,
+                     int offs, int count, int pmgr_flag)
+{
+
+       struct wf_config *hw;
+       wavefront_patch_info header;
+
+       if ((hw = hw_from_dev (dev)) == 0) {
+               return -EINVAL;
+       }
+
+       if (format == SYSEX_PATCH) {    /* Handled by midi_synth.c */
+               if (midi_load_patch == NULL) {
+                       printk (KERN_ERR
+                               "WaveFront: SYSEX not loadable: "
+                               "no midi patch loader!\n");
+                       return -EINVAL;
+               }
+               return midi_load_patch (dev, format, addr,
+                                       offs, count, pmgr_flag);
+
+       } else if (format == GUS_PATCH) {
+               return wavefront_load_gus_patch (hw, dev, format,
+                                                addr, offs, count, pmgr_flag);
+
+       } else if (format != WAVEFRONT_PATCH) {
+               printk (KERN_ERR "WaveFront: unknown patch format %d\n", format);
+               return -EINVAL;
+       }
+
+       if (count < sizeof (wavefront_patch_info)) {
+               printk (KERN_ERR "WaveFront: sample header too short\n");
+               return -EINVAL;
+       }
+
+       /* copied in so far: `offs' bytes from `addr'. We shouldn't copy
+          them in again, and they correspond to header->key and header->devno.
+          So now, copy the rest of the wavefront_patch_info struct, except
+          for the 'hdr' field, since this is handled via indirection
+          through the 'hdrptr' field.
+       */
+
+       COPY_FROM_USER (&((char *) &header)[offs], &(addr)[offs],
+                       sizeof(wavefront_patch_info) -
+                       sizeof(wavefront_any) - offs);
+
+       if (hw->debug & WF_DEBUG_LOAD_PATCH) {
+               printk (KERN_DEBUG "WaveFront: download "
+                       "Sample type: %d "
+                       "Sample number: %d "
+                       "Sample size: %d\n",
+                       header.subkey,
+                       header.number,
+                       header.size);
+       }
+
+       switch (header.subkey) {
+       case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */
+
+               COPY_FROM_USER ((unsigned char *) &header.hdr.s,
+                               (unsigned char *) header.hdrptr,
+                               sizeof (wavefront_sample));
+
+               return wavefront_send_sample (hw, &header, header.dataptr, 0);
+
+       case WF_ST_MULTISAMPLE:
+
+               COPY_FROM_USER ((unsigned char *) &header.hdr.s,
+                               (unsigned char *) header.hdrptr,
+                               sizeof (wavefront_multisample));
+
+               return wavefront_send_multisample (hw, &header);
+
+
+       case WF_ST_ALIAS:
+
+               COPY_FROM_USER ((unsigned char *) &header.hdr.a,
+                               (unsigned char *) header.hdrptr,
+                               sizeof (wavefront_alias));
+
+               return wavefront_send_alias (hw, &header);
+
+       case WF_ST_DRUM:
+               COPY_FROM_USER ((unsigned char *) &header.hdr.d, 
+                               (unsigned char *) header.hdrptr,
+                               sizeof (wavefront_drum));
+
+               return wavefront_send_drum (hw, &header);
+
+       case WF_ST_PATCH:
+               COPY_FROM_USER ((unsigned char *) &header.hdr.p, 
+                               (unsigned char *) header.hdrptr,
+                               sizeof (wavefront_patch));
+
+               return wavefront_send_patch (hw, &header);
+
+       case WF_ST_PROGRAM:
+               COPY_FROM_USER ((unsigned char *) &header.hdr.pr, 
+                               (unsigned char *) header.hdrptr,
+                               sizeof (wavefront_program));
+
+               return wavefront_send_program (hw, &header);
+
+       default:
+               printk (KERN_ERR "WaveFront: unknown patch type %d.\n",
+                       header.subkey);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+\f
+/***********************************************************************
+WaveFront: /dev/sequencer{,2} and other hardware-dependent interfaces
+***********************************************************************/
+
+static void
+process_sample_hdr (UCHAR8 *buf)
+
+{
+       wavefront_sample s;
+       UCHAR8 *ptr;
+
+       ptr = buf;
+
+       /* The board doesn't send us an exact copy of a "wavefront_sample"
+          in response to an Upload Sample Header command. Instead, we 
+          have to convert the data format back into our data structure,
+          just as in the Download Sample command, where we have to do
+          something very similar in the reverse direction.
+       */
+
+       *((UINT32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
+       *((UINT32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
+       *((UINT32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
+       *((UINT32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
+       *((UINT32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;
+
+       s.SampleResolution = *ptr & 0x3;
+       s.Loop = *ptr & 0x8;
+       s.Bidirectional = *ptr & 0x10;
+       s.Reverse = *ptr & 0x40;
+
+       /* Now copy it back to where it came from */
+
+       memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
+}
+
+static int
+wavefront_synth_control (int dev, int cmd, caddr_t arg)
+
+{
+       struct wf_config *hw;
+       wavefront_control wc;
+       unsigned char patchnumbuf[2];
+       int i;
+
+       if ((hw = hw_from_dev (dev)) == 0) {
+               printk (KERN_ERR
+                       "WaveFront: synth_control with unknown "
+                       "device number %d\n", dev);
+               return -EINVAL;
+       }
+
+       COPY_FROM_USER (&wc, arg, sizeof (wc));
+
+       if (hw->debug & WF_DEBUG_CMD) {
+               printk (KERN_DEBUG "WaveFront: synth control with "
+                       "cmd 0x%x\n", wc.cmd);
+       }
+
+       /* special case handling of or for various commands */
+
+       switch (wc.cmd) {
+       case WFC_DISABLE_INTERRUPTS:
+               printk (KERN_INFO "WaveFront: interrupts disabled.\n");
+               outb (0x80|0x20, hw->control_port);
+               hw->interrupts_on = 0;
+               return 0;
+
+       case WFC_ENABLE_INTERRUPTS:
+               printk (KERN_INFO "WaveFront: interrupts enabled.\n");
+               outb (0x80|0x20|0x40, hw->control_port);
+               hw->interrupts_on = 1;
+               return 0;
+
+       case WFC_INTERRUPT_STATUS:
+               wc.rbuf[0] = hw->interrupts_on;
+               return 0;
+
+       case WFC_ROMSAMPLES_RDONLY:
+               hw->rom_samples_rdonly = wc.wbuf[0];
+               wc.status = 0;
+               return 0;
+
+       case WFC_IDENTIFY_SLOT_TYPE:
+               i = wc.wbuf[0] | (wc.wbuf[1] << 7);
+               if (i <0 || i >= WF_MAX_SAMPLE) {
+                       printk (KERN_WARNING "WaveFront: invalid slot ID %d\n",
+                               i);
+                       wc.status = EINVAL;
+                       return 0;
+               }
+               wc.rbuf[0] = hw->sample_status[i];
+               wc.status = 0;
+               return 0;
+
+       case WFC_DEBUG_DRIVER:
+               hw->debug = wc.wbuf[0];
+               printk (KERN_INFO "WaveFront: debug = 0x%x\n", hw->debug);
+               return 0;
+
+       case WFC_FX_IOCTL:
+               wffx_ioctl (hw, (wavefront_fx_info *) &wc.wbuf[0]);
+               return 0;
+
+       case WFC_UPLOAD_PATCH:
+               munge_int32 (*((UINT32 *) wc.wbuf), patchnumbuf, 2);
+               memcpy (wc.wbuf, patchnumbuf, 2);
+               break;
+
+       case WFC_UPLOAD_MULTISAMPLE:
+       case WFC_UPLOAD_SAMPLE_ALIAS:
+               printk (KERN_INFO "WaveFront: support for various uploads "
+                       "being considered.\n");
+               wc.status = EINVAL;
+               return -EINVAL;
+       }
+
+       wc.status = wavefront_cmd (hw, wc.cmd, wc.rbuf, wc.wbuf);
+
+       /* Special case handling of certain commands.
+
+          In particular, if the command was an upload, demunge the data
+          so that the user-level doesn't have to think about it.
+       */
+
+       if (wc.status == 0) {
+               switch (wc.cmd) {
+                       /* intercept any freemem requests so that we know
+                          we are always current with the user-level view
+                          of things.
+                       */
+
+               case WFC_REPORT_FREE_MEMORY:
+                       hw->freemem = demunge_int32 (wc.rbuf, 4);
+                       break;
+
+               case WFC_UPLOAD_PATCH:
+                       demunge_buf (wc.rbuf, wc.rbuf, WF_PATCH_BYTES);
+                       break;
+
+               case WFC_UPLOAD_PROGRAM:
+                       demunge_buf (wc.rbuf, wc.rbuf, WF_PROGRAM_BYTES);
+                       break;
+
+               case WFC_UPLOAD_EDRUM_PROGRAM:
+                       demunge_buf (wc.rbuf, wc.rbuf, WF_DRUM_BYTES - 1);
+                       break;
+
+               case WFC_UPLOAD_SAMPLE_HEADER:
+                       process_sample_hdr (wc.rbuf);
+                       break;
+
+               case WFC_UPLOAD_MULTISAMPLE:
+               case WFC_UPLOAD_SAMPLE_ALIAS:
+                       printk (KERN_INFO "WaveFront: support for "
+                               "various uploads "
+                               "being considered.\n");
+                       break;
+
+               case WFC_VMIDI_OFF:
+                       virtual_midi_disable (hw->mididev);
+                       break;
+
+               case WFC_VMIDI_ON:
+                       virtual_midi_enable (hw->mididev, 0);
+                       break;
+
+                       break;
+               }
+       }
+
+       /* XXX It would be nice to avoid a complete copy of the whole
+          struct sometimes. But I think its fast enough that this
+          is a low priority fix.
+       */
+
+       COPY_TO_USER (arg, &wc, sizeof (wc));
+       return 0;
+}
+
+\f
+/***********************************************************************
+WaveFront: MIDI synth interface
+***********************************************************************/
+
+
+static int
+wavefront_ioctl (int dev, unsigned int cmd, caddr_t arg)
+{
+       wf_config *hw;
+       unsigned char rbuf[4];
+
+       if ((hw = hw_from_dev (dev)) == 0) {
+               return -EINVAL;
+       }
+
+       switch (cmd) {
+       case SNDCTL_SYNTH_INFO:
+               memcpy (&((char *) arg)[0], &wavefront_info,
+                       sizeof (wavefront_info));
+               return 0;
+               break;
+
+       case SNDCTL_SEQ_RESETSAMPLES:
+               printk (KERN_WARNING
+                       "WaveFront: cannot reset sample status in kernel.\n");
+               return 0; /* don't force an error */
+               break;
+
+       case SNDCTL_SEQ_PERCMODE:
+               /* XXX does this correspond to anything obvious ?*/
+               return 0; /* don't force an error */
+               break;
+
+       case SNDCTL_SYNTH_MEMAVL:
+               if (wavefront_cmd (hw, WFC_REPORT_FREE_MEMORY, rbuf, 0) != 0) {
+                       printk (KERN_ERR
+                               "WaveFront: cannot get free memory size\n");
+                       return 0;
+               } else {
+                       hw->freemem = demunge_int32 (rbuf, 4);
+                       return hw->freemem;
+               }
+
+       case SNDCTL_SYNTH_CONTROL:
+               return wavefront_synth_control (dev, cmd, arg);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static int
+wavefront_open (int dev, int mode)
+
+{
+       struct wf_config *hw;
+
+       if ((hw = hw_from_dev (dev)) == 0) {
+               return -EINVAL;
+       }
+
+       if (hw->opened) {
+               printk (KERN_ERR "WaveFront: warning: device in use\n");
+       }
+
+       hw->opened = mode;
+       return 0;
+}
+
+static void
+wavefront_close (int dev)
+
+{
+       struct wf_config *hw;
+
+       if ((hw = hw_from_dev (dev)) == 0) {
+               printk (KERN_ERR
+                       "WaveFront: close() called on non-existent dev %d", dev);
+               return;
+       }
+
+       hw->opened = 0;
+       hw->debug = 0;
+
+       return;
+}
+
+static void
+wavefront_aftertouch (int dev, int channel, int pressure)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return;
+       midi_synth_aftertouch (hw->mididev,channel,pressure);
+};
+
+static void
+wavefront_bender (int dev, int chn, int value)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return;
+       midi_synth_bender (hw->mididev, chn, value);
+};
+
+static void
+wavefront_controller (int dev, int channel, int ctrl_num, int value)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return;
+       if(ctrl_num==CTRL_PITCH_BENDER) wavefront_bender(0,channel,value);
+       midi_synth_controller (hw->mididev, channel,ctrl_num,value);
+};
+
+static void
+wavefront_panning(int dev, int channel, int pressure)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return;
+       midi_synth_controller(hw->mididev,channel,CTL_PAN,pressure);
+};
+
+static int
+wavefront_set_instr (int dev, int channel, int instr_no)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return 1;
+       return(midi_synth_set_instr(hw->mididev,channel,instr_no));
+};
+
+static int
+wavefront_kill_note (int dev, int channel, int note, int volume)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return 1;
+       if (note==255)
+               return(midi_synth_start_note(hw->mididev, channel, 0, 0));
+       return(midi_synth_kill_note(hw->mididev, channel, note, volume));
+};
+
+static int
+wavefront_start_note (int dev, int channel, int note, int volume)
+{
+       struct wf_config *hw = hw_from_dev (dev);
+       if (!hw) return 1;
+
+       if (note==255) {
+               /*midi_synth_controller(hw->mididev,channel,7,volume);*/
+               midi_synth_aftertouch(hw->mididev,channel,volume); 
+               return(0);
+       };
+       if (volume==0) {
+               volume=127;
+               midi_synth_aftertouch(hw->mididev,channel,0);
+       };
+       midi_synth_start_note (hw->mididev, channel, note, volume);
+       return(0);
+};
+
+static void
+wavefront_setup_voice (int dev, int voice, int chn)
+{
+};
+
+static void wavefront_reset (int dev)
+
+{
+       int i;
+       for(i=0;i<16;i++) {
+               midi_synth_kill_note (dev,i,0,0);
+       };
+};
+
+static struct synth_operations wavefront_operations =
+{
+       "WaveFront",
+       &wavefront_info,
+       0,
+       SYNTH_TYPE_SAMPLE,
+       SAMPLE_TYPE_WAVEFRONT,
+       wavefront_open,
+       wavefront_close,
+       wavefront_ioctl,
+       wavefront_kill_note,
+       wavefront_start_note,
+       wavefront_set_instr,
+       wavefront_reset,
+       NULL,
+       wavefront_load_patch,
+       wavefront_aftertouch,
+       wavefront_controller,
+       wavefront_panning,
+       NULL,
+       wavefront_bender,
+       NULL,
+       wavefront_setup_voice
+};
+
+\f
+/***********************************************************************
+WaveFront: OSS/Free and/or Linux kernel installation interface
+***********************************************************************/
+
+void
+wavefrontintr (int irq, void *dev_id, struct pt_regs *dummy)
+{
+       int i;
+
+       if (irq < 0 || irq > 16) {
+               printk (KERN_WARNING "WaveFront: bogus interrupt %d recv'd\n",
+                       irq);
+       } else if ((i = irq2hw[irq]) == -1) {
+               printk (KERN_ALERT
+                       "WaveFront: interrupt from unknown hw (irq=%d).\n", irq);
+       } else {
+               wfs[i].irq_ok = 1;
+       }
+}
+
+/* STATUS REGISTER 
+
+0 Host Rx Interrupt Enable (1=Enabled)
+1 Host Rx Register Full (1=Full)
+2 Host Rx Interrupt Pending (1=Interrupt)
+3 Unused
+4 Host Tx Interrupt (1=Enabled)
+5 Host Tx Register empty (1=Empty)
+6 Host Tx Interrupt Pending (1=Interrupt)
+7 Unused
+
+*/
+
+/* CONTROL REGISTER
+0 Host Rx Interrupt Enable (1=Enabled)      0x1
+1 Unused                                    0x2
+2 Unused                                    0x4
+3 Unused                                    0x8
+4 Host Tx Interrupt Enable                 0x10
+5 Mute (0=Mute; 1=Play)                    0x20
+6 Master Interrupt Enable (1=Enabled)      0x40
+7 Master Reset (0=Reset; 1=Run)            0x80
+*/
+
+int
+probe_wavefront (struct address_info *hw_config)
+
+{
+       int             i;
+       int             tmp1, tmp2;
+       unsigned char   bits;
+       unsigned char   rbuf[32], wbuf[32];
+       wf_config       *hw;
+
+       if (hw_config->irq < 0 || hw_config->irq > 16) {
+           printk (KERN_WARNING "WaveFront: impossible IRQ suggested(%d)\n", 
+                   hw_config->irq);
+           return 0;
+       }
+  
+       /* Yeah yeah, TB docs say 8, but the FX device on the Tropez Plus
+          takes up another 8 ...
+       */
+
+       if (check_region (hw_config->io_base, 16)) {
+               printk (KERN_ERR "WaveFront: IO address range 0x%x - 0x%x "
+                       "already in use - ignored\n", hw_config->io_base,
+                       hw_config->io_base+15);
+               return 0;
+       }
+  
+       for (i = 0; i < WAVEFRONT_MAX_DEVICES; i++) {
+               if (!wfs[i].installed) {
+                       wfs[i].installed = 1;
+                       break;
+               }
+       }
+
+       if (i == WAVEFRONT_MAX_DEVICES) {
+               printk (KERN_WARNING "WaveFront: no device slots available (max = %d).\n",
+                       WAVEFRONT_MAX_DEVICES);
+               return 0;
+       }
+  
+       hw = &wfs[i];
+
+       hw->irq = hw_config->irq;
+       hw->base = hw_config->io_base;
+
+       hw->israw = 0;
+       hw->debug = wf_debug_default;
+       hw->interrupts_on = 0;
+       hw->rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
+
+       hw_config->slots[WF_SYNTH_SLOT] = hw->synthdev = -1;
+       hw_config->slots[WF_INTERNAL_MIDI_SLOT] = hw->mididev = -1;
+       hw_config->slots[WF_EXTERNAL_MIDI_SLOT] = hw->ext_mididev = -1;
+
+       irq2hw[hw_config->irq] = i;
+  
+       if (wavefront_cmd (hw, WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
+               hw->fw_version[0] = rbuf[0];
+               hw->fw_version[1] = rbuf[1];
+               printk (KERN_INFO "WaveFront: firmware %d.%d already loaded.\n",
+                       rbuf[0], rbuf[1]);
+      
+               if (wavefront_cmd (hw, WFC_HARDWARE_VERSION, rbuf, wbuf) == 0) {
+                       hw->hw_version[0] = rbuf[0];
+                       hw->hw_version[1] = rbuf[1];
+               } else {
+                       printk (KERN_INFO "WaveFront: not raw, but no hardware version!\n");
+                       return 0;
+               }
+               if (!wf_raw) {
+                       return 1;
+               }
+       } else {
+               hw->israw = 1;
+               printk (KERN_INFO
+                       "WaveFront: no response to firmware probe, "
+                       "assume raw.\n");
+       }
+
+       if (request_irq (hw_config->irq, wavefrontintr,
+                        0, "WaveFront", NULL) < 0) {
+               printk (KERN_WARNING "WaveFront: IRQ %d not available!\n",
+                       hw_config->irq);
+               return 0;
+       }
+
+       switch (hw_config->irq) {
+       case 9:
+               bits = 0x00;
+               break;
+       case 5:
+               bits = 0x08;
+               break;
+       case 12:
+               bits = 0x10;
+               break;
+       case 15:
+               bits = 0x18;
+               break;
+       
+       default:
+               printk (KERN_WARNING "WaveFront: invalid IRQ %d\n",
+                       hw_config->irq);
+               return 0;
+       }
+  
+       /* try reset of port */
+      
+       outb (0x0, hw->control_port); 
+  
+       /* At this point, the board is in reset, and the H/W initialization
+          register is accessed at the same address as the data port.
+     
+          Bit 7 - Enable IRQ Driver    
+          0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
+          1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
+     
+          Bit 6 - MIDI Interface Select
+
+          XXX PBD: I think this documentation is backwards. I leave bit
+          6 unset, and get MIDI data from the 9 pin D connector.
+
+          0 - Use the MIDI Input from the 26-pin WaveBlaster
+          compatible header as the serial MIDI source
+          1 - Use the MIDI Input from the 9-pin D connector as the serial MIDI 
+          source.
+     
+          Bits 5:3 - IRQ Selection
+          0 0 0 - IRQ 2/9
+          0 0 1 - IRQ 5
+          0 1 0 - IRQ 12
+          0 1 1 - IRQ 15
+          1 0 0 - Reserved
+          1 0 1 - Reserved
+          1 1 0 - Reserved
+          1 1 1 - Reserved
+     
+          Bits 2:1 - Reserved
+          Bit 0 - Disable Boot ROM
+          0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
+          1 - memory accesses to 03FC30-03FFFFH are directed to external 
+          storage.
+     
+       */
+
+       /* configure hardware: IRQ, plus external MIDI interface selected */
+  
+       outb (bits | 0x80, hw->data_port);      
+  
+       /* take us out of reset, unmute, master + TX + RX interrupts on */
+  
+       outb (0x80|0x20|0x40|0x10|0x1, hw->control_port);
+  
+       for (i = 0; i < 1000000 && !hw->irq_ok; i++);
+  
+       /* Data port is now the data port, not the h/w initialization port 
+     
+          The boot ROM will check the OSRAM, and will then
+          wait for the either the "download OS" or
+          "report h/w version" commands.
+
+          Any other command will supposedly be ignored.
+       */
+  
+       if (!hw->irq_ok) {
+               printk (KERN_WARNING
+                       "WaveFront: intr not received after h/w un-reset.\n");
+               free_irq (hw_config->irq, NULL);
+               return 0;
+       } else {
+               hw->irq_ok = 0;
+       }
+
+       hw->interrupts_on = 1;
+
+       /* WaveFront SDK says:
+     
+          "When the Master Reset is set to zero (0), the audio board is held
+          in reset, which is the power-up condition. Setting Master Reset to one
+          (1) allows the on-board processor to run. It takes approximately two
+          to four seconds, depending on the memory configuration, for the
+          on-board processor to complete it's initialization routine before it
+          will respond to commands after a reset."
+
+          Actually, it seems that most of the time, even with 8MB of RAM,
+          its actually ready immediately.
+       */
+
+       if (!wavefront_wait (hw, STAT_CAN_WRITE)) {
+               if (!wavefront_wait (hw, STAT_CAN_WRITE)) {
+                       if (!wavefront_wait (hw, STAT_CAN_WRITE)) {
+                               printk (KERN_WARNING
+                                       "WaveFront: OS not ready after "
+                                       "memory check.\n");
+                               free_irq (hw_config->irq, NULL);
+                               return 0;
+                       }
+               }
+       }
+
+       /* get H/W version, and check we get an interrupt */
+  
+       outb (WFC_HARDWARE_VERSION, hw->data_port);
+  
+       for (i = 0; i < 1000000 && !hw->irq_ok; i++);
+  
+       /* We don't need the IRQ anymore for the WaveFront code,
+          and to allow an MPU-401 driver to attach to it later, lets
+          give it back ....
+
+          DO NOT alter irq2hw[], since we'll still use this to lookup
+          the config struct from an address_info struct.
+       */
+
+       free_irq (hw_config->irq, NULL);
+
+       if (!hw->irq_ok) {
+               printk (KERN_WARNING
+                       "WaveFront: interrupt not received after "
+                       "h/w version cmd.\n");
+               return 0;
+       } else {
+               hw->irq_ok = 0;
+       }
+  
+       if ((tmp1 = wavefront_read(hw)) == -1) {
+               printk (KERN_WARNING
+                       "WaveFront @ 0x%x not ready, ignoring\n", hw->base);
+               return 0;
+       }
+  
+       if ((tmp2 = wavefront_read(hw)) == -1) {
+               printk (KERN_WARNING
+                       "WaveFront @ 0x%x not responding correctly, ignoring\n",
+                       hw->base);
+               return 0;
+       }
+  
+       printk (KERN_INFO "WaveFront: hardware version %d.%d\n", tmp1, tmp2);
+  
+       return 1;
+}
+
+#include "os.h"
+#define __KERNEL_SYSCALLS__
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+
+static int errno; 
+
+static int
+wavefront_download_firmware (wf_config *hw, char *path)
+
+{
+       unsigned char section[WF_SECTION_MAX];
+       char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
+       int section_cnt_downloaded = 0;
+       int fd;
+       int c;
+       int i;
+       mm_segment_t fs;
+
+       /* This tries to be a bit cleverer than the stuff Alan Cox did for
+          the generic sound firmware, in that it actually knows
+          something about the structure of the Motorola firmware. In
+          particular, it uses a version that has been stripped of the
+          20K of useless header information, and had section lengths
+          added, making it possible to load the entire OS without any
+          [kv]malloc() activity, since the longest entity we ever read is
+          42 bytes (well, WF_SECTION_MAX) long.
+       */
+
+       fs = get_fs();
+       set_fs (get_ds());
+
+       if ((fd = open (path, 0, 0)) < 0) {
+               printk (KERN_WARNING "WaveFront: Unable to load \"%s\".\n", path);
+               return 1;
+       }
+
+       while (1) {
+               int x;
+
+               if ((x = read (fd, &section_length, sizeof (section_length))) !=
+                   sizeof (section_length)) {
+                       printk (KERN_ERR "WaveFront: firmware read error.\n");
+                       goto failure;
+               }
+
+               if (section_length == 0) {
+                       break;
+               }
+
+               if (read (fd, section, section_length) != section_length) {
+                       printk (KERN_ERR "WaveFront: firmware section "
+                               "read error.\n");
+                       goto failure;
+               }
+
+               /* Send command */
+       
+               if (!wavefront_write (hw, WFC_DOWNLOAD_OS)) {
+                       goto failure;
+               }
+       
+               for (i = 0; i < section_length; i++) {
+                       if (!wavefront_write (hw, section[i])) {
+                               goto failure;
+                       }
+               }
+       
+               /* get ACK */
+       
+               if (wavefront_wait (hw, STAT_CAN_READ)) {
+
+                       if ((c = inb (hw->data_port)) != WF_ACK) {
+
+                               printk (KERN_ERR "WaveFront: download "
+                                       "of section #%d not "
+                                       "acknowledged, ack = 0x%x\n",
+                                       section_cnt_downloaded + 1, c);
+                               goto failure;
+               
+                       } else if ((hw->debug & WF_DEBUG_IO) &&
+                                  !(++section_cnt_downloaded % 10)) {
+                               printk (KERN_DEBUG ".");
+                       }
+
+               } else {
+                       printk (KERN_ERR "WaveFront: timed out "
+                               "for download ACK.\n");
+               }
+
+       }
+
+       close (fd);
+       set_fs (fs);
+       if (hw->debug & WF_DEBUG_IO) {
+               printk (KERN_DEBUG "\n");
+       }
+       return 0;
+
+ failure:
+       close (fd);
+       set_fs (fs);
+       printk (KERN_ERR "\nWaveFront: firmware download failed!!!\n");
+       return 1;
+}
+
+static int
+wavefront_config_midi (wf_config *hw, struct address_info *hw_config)
+
+{
+       unsigned char rbuf[4], wbuf[4];
+    
+       if (!probe_wf_mpu (hw_config)) {
+               printk (KERN_WARNING "WaveFront: could not install "
+                       "MPU-401 device.\n");
+               return 1;
+       } 
+
+       /* Attach an modified MPU-401 driver to the master MIDI interface */
+
+       hw_config->name = "WaveFront Internal MIDI";
+       attach_wf_mpu (hw_config);
+
+       if (hw_config->slots[WF_INTERNAL_MIDI_SLOT] == -1) {
+               printk (KERN_WARNING "WaveFront: MPU-401 not configured.\n");
+               return 1;
+       }
+
+       hw->mididev = hw_config->slots[WF_INTERNAL_MIDI_SLOT];
+
+       /* Route external MIDI to WaveFront synth (by default) */
+    
+       if (wavefront_cmd (hw, WFC_MISYNTH_ON, rbuf, wbuf)) {
+               printk (KERN_WARNING
+                       "WaveFront: cannot enable MIDI-IN to synth routing.\n");
+               /* XXX error ? */
+       }
+
+       /* Get the regular MIDI patch loading function, so we can
+          use it if we ever get handed a SYSEX patch. This is
+          unlikely, because its so damn slow, but we may as well
+          leave this functionality from maui.c behind, since it
+          could be useful for sequencer applications that can
+          only use MIDI to do patch loading.
+       */
+
+       if (midi_devs[hw->mididev]->converter != NULL) {
+               midi_load_patch = midi_devs[hw->mididev]->converter->load_patch;
+               midi_devs[hw->mididev]->converter->load_patch =
+                   &wavefront_load_patch;
+       }
+
+       /* Turn on Virtual MIDI, but first *always* turn it off,
+          since otherwise consectutive reloads of the driver will
+          never cause the hardware to generate the initial "internal" or 
+          "external" source bytes in the MIDI data stream. This
+          is pretty important, since the internal hardware generally will
+          be used to generate none or very little MIDI output, and
+          thus the only source of MIDI data is actually external. Without
+          the switch bytes, the driver will think it all comes from
+          the internal interface. Duh.
+       */
+
+       if (wavefront_cmd (hw, WFC_VMIDI_OFF, rbuf, wbuf)) { 
+               printk (KERN_WARNING "WaveFront: cannot disable "
+                       "virtual MIDI mode\n");
+               /* XXX go ahead and try anyway ? */
+       }
+
+       hw_config->name = "WaveFront External MIDI";
+    
+       if (virtual_midi_enable (hw->mididev, hw_config)) {
+               printk (KERN_WARNING "WaveFront: no virtual MIDI access.\n");
+       } else {
+               hw->ext_mididev = hw_config->slots[WF_EXTERNAL_MIDI_SLOT];
+               if (wavefront_cmd (hw, WFC_VMIDI_ON, rbuf, wbuf)) {
+                       printk (KERN_WARNING
+                               "WaveFront: cannot enable virtual MIDI mode.\n");
+                       virtual_midi_disable (hw->mididev);
+               } 
+       }
+    
+       return 0;
+}
+
+static int
+wavefront_init (wf_config *hw, struct address_info *hw_config)
+
+{
+       int samples_are_from_rom = 0;
+
+       /* XXX what state does the board need to be in before
+          I can download the firmware ? I think any state
+          after it acknowledges a hardware version command
+          post-booting.
+       */
+
+       if (hw->israw || wf_raw) {
+               samples_are_from_rom = 1;
+
+               if (wavefront_download_firmware (hw, wf_ospath)) {
+                       return 1;
+               }
+    
+               /* enter normal operation:
+                  bit 7: (on) reset  0x80
+                  bit 6: interrupts enabled 0x40
+                  bit 5: (on) mute (i.e. in play mode) 0x20
+                  bits 4-0: zero
+          
+                  note: tx and rx interrupts turned off
+               */
+       
+               outb (0x80|0x40|0x20, hw->control_port);
+       
+               /* Set up MPU-401 emulation mode.  For some reason, this always
+                  fails the first time, and generates no ACK, so we'll
+                  treat it as a special case by sleeping for a while, and then
+                  trying again.
+               */
+       
+               wavefront_write (hw, 0xf0);
+               wavefront_write (hw, 1);
+               wavefront_sleep (hw, (HZ/wf_sleep_interval) * wf_sleep_tries);
+               wavefront_write (hw, 0xf0);
+               wavefront_write (hw, 1);
+               if (wavefront_read (hw) != 0x80) {
+                       printk (KERN_ERR
+                               "WaveFront: set MPU emulation mode "
+                               "command failed.\n");
+                       return (1);
+               }
+       }
+
+       hw->freemem = wavefront_freemem (hw);
+       printk (KERN_INFO "WaveFront: available DRAM %dk\n", hw->freemem / 1024);
+    
+       wavefront_get_sample_status (hw, samples_are_from_rom);
+       wavefront_get_program_status (hw);
+       wavefront_get_patch_status (hw);
+
+       if (fx_raw) {
+               wffx_init (hw);
+       }
+    
+       return 0;
+}
+
+void
+attach_wavefront (struct address_info *hw_config)
+{
+       int i;
+       struct wf_config *hw;
+
+       if ((i = irq2hw[hw_config->irq]) == -1) {
+               printk (KERN_ERR "WaveFront: cannot attach unknown irq 0x%x.\n",
+                       hw_config->irq);
+               return;
+       }
+
+       hw = &wfs[i];
+
+       if ((i = sound_alloc_synthdev()) == -1) {
+               printk (KERN_ERR "WaveFront: Too many synthesizers\n");
+               return;
+       } else {
+               hw_config->slots[WF_SYNTH_SLOT] = i;
+               hw->synthdev = i;
+               dev2hw[hw->synthdev] = i;
+               synth_devs[hw->synthdev] = &wavefront_operations;
+       }
+
+       if (wavefront_init (hw, hw_config)) {
+               printk (KERN_WARNING "WaveFront: board could not "
+                       "be initialized.\n");
+               sound_unload_synthdev (i);
+               hw->installed = 0;
+               return;
+       }
+    
+       request_region (hw_config->io_base+2, 6, "WaveFront synth");
+       request_region (hw_config->io_base+8, 8, "WaveFront FX");
+
+       conf_printf2 ("WaveFront Synth", hw_config->io_base, 0, -1, -1);
+
+#if defined(CONFIG_MIDI)    
+       if (wavefront_config_midi (hw, hw_config)) {
+               printk (KERN_WARNING "WaveFront: could not initialize MIDI.\n");
+       }
+#else
+       printk (KERN_WARNING
+               "WaveFront: MIDI not configured at kernel-config time.\n");
+#endif CONFIG_MIDI
+
+       return;
+}
+void
+unload_wavefront (struct address_info *hw_config)
+{
+       struct wf_config *hw;
+       int i;
+
+       if ((i = irq2hw[hw_config->irq]) == -1) {
+           printk (KERN_ERR "WaveFront: unloading unrecognized device!\n");
+           return;
+       }
+       hw = &wfs[i];
+
+       /* the first two are freed by the wf_mpu code */
+       release_region (hw_config->io_base+2, 6);
+       release_region (hw_config->io_base+8, 8);
+       sound_unload_synthdev (hw->synthdev);
+#if defined(CONFIG_MIDI)
+       unload_wf_mpu (hw_config);
+#endif
+}
+\f
+/***********************************************************************/
+/*   WaveFront FX control                                              */
+/***********************************************************************/
+
+#include "yss225.h"
+
+/* Control bits for the Load Control Register
+ */
+
+#define FX_LSB_TRANSFER 0x01    /* transfer after DSP LSB byte written */
+#define FX_MSB_TRANSFER 0x02    /* transfer after DSP MSB byte written */
+#define FX_AUTO_INCR    0x04    /* auto-increment DSP address after transfer */
+
+static int
+wffx_idle (struct wf_config *hw) 
+    
+{
+       int i;
+       unsigned int x = 0x80;
+    
+       for (i = 0; i < 1000; i++) {
+               x = inb (hw->fx_status);
+               if ((x & 0x80) == 0) {
+                       break;
+               }
+       }
+    
+       if (x & 0x80) {
+               printk (KERN_ERR "WaveFront: FX device never idle.\n");
+               return 0;
+       }
+    
+       return (1);
+}
+
+static void
+wffx_mute (struct wf_config *hw, int onoff)
+    
+{
+       if (!wffx_idle(hw)) {
+               return;
+       }
+    
+       outb (onoff ? 0x02 : 0x00, hw->fx_op);
+}
+
+static int
+wffx_memset (struct wf_config *hw, int page,
+            int addr, int cnt, unsigned short *data)
+{
+       if (page < 0 || page > 7) {
+               printk (KERN_ERR "WaveFront: FX memset: "
+                       "page must be >= 0 and <= 7\n");
+               return -EINVAL;
+       }
+
+       if (addr < 0 || addr > 0x7f) {
+               printk (KERN_ERR "WaveFront: FX memset: "
+                       "addr must be >= 0 and <= 7f\n");
+               return -EINVAL;
+       }
+
+       if (cnt == 1) {
+
+               outb (FX_LSB_TRANSFER, hw->fx_lcr);
+               outb (page, hw->fx_dsp_page);
+               outb (addr, hw->fx_dsp_addr);
+               outb ((data[0] >> 8), hw->fx_dsp_msb);
+               outb ((data[0] & 0xff), hw->fx_dsp_lsb);
+
+               printk (KERN_INFO "WaveFront: FX: addr %d:%x set to 0x%x\n",
+                       page, addr, data[0]);
+       
+       } else {
+               int i;
+
+               outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+               outb (page, hw->fx_dsp_page);
+               outb (addr, hw->fx_dsp_addr);
+
+               for (i = 0; i < cnt; i++) {
+                       outb ((data[i] >> 8), hw->fx_dsp_msb);
+                       outb ((data[i] & 0xff), hw->fx_dsp_lsb);
+                       if (!wffx_idle (hw)) {
+                               break;
+                       }
+               }
+
+               if (i != cnt) {
+                       printk (KERN_WARNING
+                               "WaveFront: FX memset "
+                               "(0x%x, 0x%x, 0x%x, %d) incomplete\n",
+                               page, addr, (int) data, cnt);
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+static int
+wffx_ioctl (struct wf_config *hw, wavefront_fx_info *r)
+
+{
+       unsigned short page_data[256];
+       unsigned short *pd;
+
+       switch (r->request) {
+       case WFFX_MUTE:
+               wffx_mute (hw, r->data[0]);
+               return 0;
+
+       case WFFX_MEMSET:
+
+               if (r->data[2] <= 0) {
+                       printk (KERN_ERR "WaveFront: cannot write "
+                               "<= 0 bytes to FX\n");
+                       return -EINVAL;
+               } else if (r->data[2] == 1) {
+                       pd = (unsigned short *) &r->data[3];
+               } else {
+                       if (r->data[2] > sizeof (page_data)) {
+                               printk (KERN_ERR
+                                       "WaveFront: cannot write "
+                                       "> 255 bytes to FX\n");
+                               return -EINVAL;
+                       }
+                       COPY_FROM_USER(page_data, (unsigned char *) r->data[3],
+                                      r->data[2]);
+                       pd = page_data;
+               }
+
+               return wffx_memset (hw,
+                                   r->data[0], /* page */
+                                   r->data[1], /* addr */
+                                   r->data[2], /* cnt */
+                                   pd);
+
+       default:
+               printk (KERN_WARNING
+                       "WaveFront: FX: ioctl %d not yet supported\n",
+                       r->request);
+               return -EINVAL;
+       }
+}
+
+/* YSS225 initialization.
+
+   This code was developed using DOSEMU. The Turtle Beach SETUPSND
+   utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
+   of the port I/O done, using the Yamaha faxback document as a guide
+   to add more logic to the code. Its really pretty wierd.
+
+   There was an alternative approach of just dumping the whole I/O
+   sequence as a series of port/value pairs and a simple loop
+   that output it. However, I hope that eventually I'll get more
+   control over what this code does, and so I tried to stick with
+   a somewhat "algorithmic" approach.
+*/
+
+static int
+wffx_init (struct wf_config *hw)
+
+{
+       int i;
+       int j;
+
+       /* Set all bits for all channels on the MOD unit to zero */
+       /* XXX But why do this twice ? */
+
+       for (j = 0; j < 2; j++) {
+               for (i = 0x10; i <= 0xff; i++) {
+           
+                       if (!wffx_idle (hw)) {
+                               return (-1);
+                       }
+           
+                       outb (i, hw->fx_mod_addr);
+                       outb (0x0, hw->fx_mod_data);
+               }
+       }
+
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x02, hw->fx_op);                        /* mute on */
+
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x44, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x42, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x43, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x7c, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x7e, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x46, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x49, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x47, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x4a, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+
+       /* either because of stupidity by TB's programmers, or because it
+          actually does something, rezero the MOD page.
+       */
+       for (i = 0x10; i <= 0xff; i++) {
+       
+               if (!wffx_idle (hw)) {
+                       return (-1);
+               }
+       
+               outb (i, hw->fx_mod_addr);
+               outb (0x0, hw->fx_mod_data);
+       }
+       /* load page zero */
+
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x00, hw->fx_dsp_page);
+       outb (0x00, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_zero); i += 2) {
+               outb (page_zero[i], hw->fx_dsp_msb);
+               outb (page_zero[i+1], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       /* Now load page one */
+
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x01, hw->fx_dsp_page);
+       outb (0x00, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_one); i += 2) {
+               outb (page_one[i], hw->fx_dsp_msb);
+               outb (page_one[i+1], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x02, hw->fx_dsp_page);
+       outb (0x00, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_two); i++) {
+               outb (page_two[i], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x03, hw->fx_dsp_page);
+       outb (0x00, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_three); i++) {
+               outb (page_three[i], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x04, hw->fx_dsp_page);
+       outb (0x00, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_four); i++) {
+               outb (page_four[i], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       /* Load memory area (page six) */
+    
+       outb (FX_LSB_TRANSFER, hw->fx_lcr); 
+       outb (0x06, hw->fx_dsp_page); 
+
+       for (i = 0; i < sizeof (page_six); i += 3) {
+               outb (page_six[i], hw->fx_dsp_addr);
+               outb (page_six[i+1], hw->fx_dsp_msb);
+               outb (page_six[i+2], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x00, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_seven); i += 2) {
+               outb (page_seven[i], hw->fx_dsp_msb);
+               outb (page_seven[i+1], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       /* Now setup the MOD area. We do this algorithmically in order to
+          save a little data space. It could be done in the same fashion
+          as the "pages".
+       */
+
+       for (i = 0x00; i <= 0x0f; i++) {
+               outb (0x01, hw->fx_mod_addr);
+               outb (i, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+               outb (0x02, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0xb0; i <= 0xbf; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x20, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0xf0; i <= 0xff; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x20, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0x10; i <= 0x1d; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0xff, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x1e, hw->fx_mod_addr);
+       outb (0x40, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       for (i = 0x1f; i <= 0x2d; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0xff, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x2e, hw->fx_mod_addr);
+       outb (0x00, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       for (i = 0x2f; i <= 0x3e; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x3f, hw->fx_mod_addr);
+       outb (0x20, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       for (i = 0x40; i <= 0x4d; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x4e, hw->fx_mod_addr);
+       outb (0x0e, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x4f, hw->fx_mod_addr);
+       outb (0x0e, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+
+       for (i = 0x50; i <= 0x6b; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x6c, hw->fx_mod_addr);
+       outb (0x40, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       outb (0x6d, hw->fx_mod_addr);
+       outb (0x00, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       outb (0x6e, hw->fx_mod_addr);
+       outb (0x40, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       outb (0x6f, hw->fx_mod_addr);
+       outb (0x40, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       for (i = 0x70; i <= 0x7f; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0xc0, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       for (i = 0x80; i <= 0xaf; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0xc0; i <= 0xdd; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0xde, hw->fx_mod_addr);
+       outb (0x10, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0xdf, hw->fx_mod_addr);
+       outb (0x10, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+
+       for (i = 0xe0; i <= 0xef; i++) {
+               outb (i, hw->fx_mod_addr);
+               outb (0x00, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0x00; i <= 0x0f; i++) {
+               outb (0x01, hw->fx_mod_addr);
+               outb (i, hw->fx_mod_data);
+               outb (0x02, hw->fx_mod_addr);
+               outb (0x01, hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x02, hw->fx_op); /* mute on */
+
+       /* Now set the coefficients and so forth for the programs above */
+
+       for (i = 0; i < sizeof (coefficients); i += 4) {
+               outb (coefficients[i], hw->fx_dsp_page);
+               outb (coefficients[i+1], hw->fx_dsp_addr);
+               outb (coefficients[i+2], hw->fx_dsp_msb);
+               outb (coefficients[i+3], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       /* Some settings (?) that are too small to bundle into loops */
+
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x1e, hw->fx_mod_addr);
+       outb (0x14, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0xde, hw->fx_mod_addr);
+       outb (0x20, hw->fx_mod_data);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0xdf, hw->fx_mod_addr);
+       outb (0x20, hw->fx_mod_data);
+    
+       /* some more coefficients */
+
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x06, hw->fx_dsp_page);
+       outb (0x78, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x40, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x03, hw->fx_dsp_addr);
+       outb (0x0f, hw->fx_dsp_msb);
+       outb (0xff, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x0b, hw->fx_dsp_addr);
+       outb (0x0f, hw->fx_dsp_msb);
+       outb (0xff, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x02, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x0a, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x46, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+       if (!wffx_idle(hw)) return (-1);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x49, hw->fx_dsp_addr);
+       outb (0x00, hw->fx_dsp_msb);
+       outb (0x00, hw->fx_dsp_lsb);
+    
+       /* Now, for some strange reason, lets reload every page
+          and all the coefficients over again. I have *NO* idea
+          why this is done. I do know that no sound is produced
+          is this phase is omitted.
+       */
+
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x00, hw->fx_dsp_page);  
+       outb (0x10, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_zero_v2); i += 2) {
+               outb (page_zero_v2[i], hw->fx_dsp_msb);
+               outb (page_zero_v2[i+1], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x01, hw->fx_dsp_page);
+       outb (0x10, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_one_v2); i += 2) {
+               outb (page_one_v2[i], hw->fx_dsp_msb);
+               outb (page_one_v2[i+1], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       if (!wffx_idle(hw)) return (-1);
+       if (!wffx_idle(hw)) return (-1);
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x02, hw->fx_dsp_page);
+       outb (0x10, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_two_v2); i++) {
+               outb (page_two_v2[i], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x03, hw->fx_dsp_page);
+       outb (0x10, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_three_v2); i++) {
+               outb (page_three_v2[i], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x04, hw->fx_dsp_page);
+       outb (0x10, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_four_v2); i++) {
+               outb (page_four_v2[i], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+    
+       outb (FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x06, hw->fx_dsp_page);
+
+       /* Page six v.2 is algorithmic */
+    
+       for (i = 0x10; i <= 0x3e; i += 2) {
+               outb (i, hw->fx_dsp_addr);
+               outb (0x00, hw->fx_dsp_msb);
+               outb (0x00, hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
+       outb (0x07, hw->fx_dsp_page);
+       outb (0x10, hw->fx_dsp_addr);
+
+       for (i = 0; i < sizeof (page_seven_v2); i += 2) {
+               outb (page_seven_v2[i], hw->fx_dsp_msb);
+               outb (page_seven_v2[i+1], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0x00; i < sizeof(mod_v2); i += 2) {
+               outb (mod_v2[i], hw->fx_mod_addr);
+               outb (mod_v2[i+1], hw->fx_mod_data);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       for (i = 0; i < sizeof (coefficients2); i += 4) {
+               outb (coefficients2[i], hw->fx_dsp_page);
+               outb (coefficients2[i+1], hw->fx_dsp_addr);
+               outb (coefficients2[i+2], hw->fx_dsp_msb);
+               outb (coefficients2[i+3], hw->fx_dsp_lsb);
+               if (!wffx_idle(hw)) return (-1);
+       }
+
+       outb (0x00, hw->fx_op);
+       if (!wffx_idle(hw)) return (-1);
+    
+       for (i = 0; i < sizeof (coefficients3); i += 2) {
+               int x;
+
+               outb (0x07, hw->fx_dsp_page);
+               x = (i % 4) ? 0x4e : 0x4c;
+               outb (x, hw->fx_dsp_addr);
+               outb (coefficients3[i], hw->fx_dsp_msb);
+               outb (coefficients3[i+1], hw->fx_dsp_lsb);
+       }
+
+       outb (0x00, hw->fx_op); /* mute off */
+
+       return 0;
+}
+
+EXPORT_NO_SYMBOLS;
+struct address_info cfg;
+
+int io = -1;
+int irq = -1;
+
+MODULE_PARM(io,"i");
+MODULE_PARM(irq,"i");
+
+int init_module (void)
+
+{
+       printk ("Turtle Beach WaveFront Driver\n"
+               "Copyright (C) by Hannu Solvainen, "
+               "Paul Barton-Davis 1993-1998.\n");
+
+       if (io == -1 || irq == -1) {
+               printk (KERN_INFO "WaveFront: irq and io "
+                       "options must be set.\n");
+               return -EINVAL;
+       }
+       cfg.io_base = io;
+       cfg.irq = irq;
+
+       if (probe_wavefront (&cfg) == 0) {
+               return -ENODEV;
+       } 
+       attach_wavefront (&cfg);
+       SOUND_LOCK;
+       return 0;
+}
+
+void cleanup_module (void)
+
+{
+       unload_wavefront (&cfg);
+       SOUND_LOCK_END;
+}
+
+#endif MODULE   
+#endif CONFIG_SOUND_WAVEFRONT 
+
+
diff --git a/drivers/sound/wf_midi.c b/drivers/sound/wf_midi.c
new file mode 100644 (file)
index 0000000..c525abc
--- /dev/null
@@ -0,0 +1,984 @@
+/*
+ * sound/wf_midi.c
+ *
+ * The low level driver for the WaveFront ICS2115 MIDI interface(s)
+ * Note that there is also an MPU-401 emulation (actually, a UART-401
+ * emulation) on the CS4232 on the Tropez Plus. This code has nothing
+ * to do with that interface at all.
+ *
+ * The interface is essentially just a UART-401, but is has the
+ * interesting property of supporting what Turtle Beach called
+ * "Virtual MIDI" mode. In this mode, there are effectively *two*
+ * MIDI buses accessible via the interface, one that is routed
+ * solely to/from the external WaveFront synthesizer and the other
+ * corresponding to the pin/socket connector used to link external
+ * MIDI devices to the board.
+ *
+ * This driver fully supports this mode, allowing two distinct
+ * midi devices (/dev/midiNN and /dev/midiNN+1) to be used
+ * completely independently, giving 32 channels of MIDI routing,
+ * 16 to the WaveFront synth and 16 to the external MIDI bus.
+ *
+ * Switching between the two is accomplished externally by the driver
+ * using the two otherwise unused MIDI bytes. See the code for more details.
+ *
+ * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
+ *
+ * The main reason to turn off Virtual MIDI mode is when you want to
+ * tightly couple the WaveFront synth with an external MIDI
+ * device. You won't be able to distinguish the source of any MIDI
+ * data except via SysEx ID, but thats probably OK, since for the most
+ * part, the WaveFront won't be sending any MIDI data at all.
+ *  
+ * The main reason to turn on Virtual MIDI Mode is to provide two
+ * completely independent 16-channel MIDI buses, one to the
+ * WaveFront and one to any external MIDI devices. Given the 32
+ * voice nature of the WaveFront, its pretty easy to find a use
+ * for all 16 channels driving just that synth.
+ *
+ */
+
+/*
+ * Copyright (C) by Paul Barton-Davis 1998
+ * Substantial portions of this file are derived from work that is:
+ *
+ *    Copyright (C) by Hannu Savolainen 1993-1996
+ *
+ * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.
+ */
+
+#include <linux/config.h>
+#include "sound_config.h"
+#include "soundmodule.h"
+
+#include <linux/wavefront.h>
+
+#if (defined(CONFIG_WAVEFRONT) && defined(CONFIG_MIDI)) || defined(MODULE)
+
+struct wf_mpu_config {
+       int             base;   /* I/O base */
+       int             irq;
+       int             opened; /* Open mode */
+       int             devno;
+       int             synthno;
+       int             mode;
+#define MODE_MIDI      1
+#define MODE_SYNTH     2
+
+       void            (*inputintr) (int dev, unsigned char data);
+    
+       /* Virtual MIDI support */
+    
+       char configured_for_virtual;   /* setup for virtual completed */
+       char isvirtual;                /* do virtual I/O stuff */
+       char isexternal;               /* i am an external interface */
+       int internal;                  /* external interface midi_devno */
+       int external;                  /* external interface midi_devno */
+};
+
+#define        DATAPORT(base)   (base)
+#define        COMDPORT(base)   (base+1)
+#define        STATPORT(base)   (base+1)
+
+static void     start_uart_mode (struct wf_mpu_config *devc);
+
+static int 
+wf_mpu_status (struct wf_mpu_config *devc)
+{
+       return inb (STATPORT (devc->base));
+}
+
+static void 
+wf_mpu_cmd (struct wf_mpu_config *devc, unsigned char cmd)
+{
+       outb ((cmd), COMDPORT(devc->base));
+}
+
+#define input_avail(devc)              (!(wf_mpu_status(devc)&INPUT_AVAIL))
+#define output_ready(devc)             (!(wf_mpu_status(devc)&OUTPUT_READY))
+
+static int 
+read_data (struct wf_mpu_config *devc)
+{
+       return inb (DATAPORT (devc->base));
+}
+
+static void 
+write_data (struct wf_mpu_config *devc, unsigned char byte)
+{
+       outb (byte, DATAPORT (devc->base));
+}
+
+#define        OUTPUT_READY    0x40
+#define        INPUT_AVAIL     0x80
+#define        MPU_ACK         0xFE
+#define        MPU_RESET       0xFF
+#define        UART_MODE_ON    0x3F
+
+static struct wf_mpu_config dev_conf[MAX_MIDI_DEV] =
+{
+       {0}
+};
+
+static volatile int irq2dev[17] =
+{-1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+static struct synth_info wf_mpu_synth_info_proto =
+{"WaveFront MPU-401 interface", 0,
+ SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
+
+static struct synth_info wf_mpu_synth_info[MAX_MIDI_DEV];
+
+/*
+ * States for the input scanner (should be in dev_table.h)
+ */
+
+#define MST_SYSMSG             100     /* System message (sysx etc). */
+#define MST_MTC                        102     /* Midi Time Code (MTC) qframe msg */
+#define MST_SONGSEL            103     /* Song select */
+#define MST_SONGPOS            104     /* Song position pointer */
+#define MST_TIMED              105     /* Leading timing byte rcvd */
+
+/* buffer space check for input scanner */
+
+#define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \
+{printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \
+       mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
+
+static unsigned char len_tab[] =       /* # of data bytes following a status
+                                        */
+{
+       2,                              /* 8x */
+       2,                              /* 9x */
+       2,                              /* Ax */
+       2,                              /* Bx */
+       1,                              /* Cx */
+       1,                              /* Dx */
+       2,                              /* Ex */
+       0                               /* Fx */
+};
+
+static int
+wf_mpu_input_scanner (struct wf_mpu_config *devc, unsigned char midic)
+{
+       struct midi_input_info *mi;
+
+       mi = &midi_devs[devc->devno]->in_info;
+
+       switch (mi->m_state) {
+       case MST_INIT:
+               switch (midic) {
+               case 0xf8:
+                       /* Timer overflow */
+                       break;
+               
+               case 0xfc:
+                       break;
+               
+               case 0xfd:
+                       /* XXX do something useful with this. If there is
+                          an external MIDI timer (e.g. a hardware sequencer,
+                          a useful timer can be derived ...
+                  
+                          For now, no timer support.
+                       */
+                       break;
+               
+               case 0xfe:
+                       return MPU_ACK;
+                       break;
+               
+               case 0xf0:
+               case 0xf1:
+               case 0xf2:
+               case 0xf3:
+               case 0xf4:
+               case 0xf5:
+               case 0xf6:
+               case 0xf7:
+                       break;
+               
+               case 0xf9:
+                       break;
+               
+               case 0xff:
+                       mi->m_state = MST_SYSMSG;
+                       break;
+               
+               default:
+                       if (midic <= 0xef) {
+                               mi->m_state = MST_TIMED;
+                       }
+                       else
+                               printk (KERN_ERR "<MPU: Unknown event %02x> ",
+                                       midic);
+               }
+               break;
+         
+       case MST_TIMED:
+       {
+               int             msg = ((int) (midic & 0xf0) >> 4);
+         
+               mi->m_state = MST_DATA;
+         
+               if (msg < 8) {  /* Data byte */
+             
+                       msg = ((int) (mi->m_prev_status & 0xf0) >> 4);
+                       msg -= 8;
+                       mi->m_left = len_tab[msg] - 1;
+             
+                       mi->m_ptr = 2;
+                       mi->m_buf[0] = mi->m_prev_status;
+                       mi->m_buf[1] = midic;
+
+                       if (mi->m_left <= 0) {
+                               mi->m_state = MST_INIT;
+                               do_midi_msg (devc->synthno, mi->m_buf,
+                                            mi->m_ptr);
+                               mi->m_ptr = 0;
+                       }
+               } else if (msg == 0xf) {        /* MPU MARK */
+             
+                       mi->m_state = MST_INIT;
+
+                       switch (midic) {
+                       case 0xf8:
+                               break;
+                   
+                       case 0xf9:
+                               break;
+                   
+                       case 0xfc:
+                               break;
+                   
+                       default:
+                       }
+               } else {
+                       mi->m_prev_status = midic;
+                       msg -= 8;
+                       mi->m_left = len_tab[msg];
+             
+                       mi->m_ptr = 1;
+                       mi->m_buf[0] = midic;
+             
+                       if (mi->m_left <= 0) {
+                               mi->m_state = MST_INIT;
+                               do_midi_msg (devc->synthno, mi->m_buf,
+                                            mi->m_ptr);
+                               mi->m_ptr = 0;
+                       }
+               }
+       }
+       break;
+
+       case MST_SYSMSG:
+               switch (midic) {
+               case 0xf0:
+                       mi->m_state = MST_SYSEX;
+                       break;
+           
+               case 0xf1:
+                       mi->m_state = MST_MTC;
+                       break;
+
+               case 0xf2:
+                       mi->m_state = MST_SONGPOS;
+                       mi->m_ptr = 0;
+                       break;
+           
+               case 0xf3:
+                       mi->m_state = MST_SONGSEL;
+                       break;
+           
+               case 0xf6:
+                       mi->m_state = MST_INIT;
+           
+                       /*
+                        *    Real time messages
+                        */
+               case 0xf8:
+                       /* midi clock */
+                       mi->m_state = MST_INIT;
+                       /* XXX need ext MIDI timer support */
+                       break;
+           
+               case 0xfA:
+                       mi->m_state = MST_INIT;
+                       /* XXX need ext MIDI timer support */
+                       break;
+           
+               case 0xFB:
+                       mi->m_state = MST_INIT;
+                       /* XXX need ext MIDI timer support */
+                       break;
+           
+               case 0xFC:
+                       mi->m_state = MST_INIT;
+                       /* XXX need ext MIDI timer support */
+                       break;
+           
+               case 0xFE:
+                       /* active sensing */
+                       mi->m_state = MST_INIT;
+                       break;
+           
+               case 0xff:
+                       mi->m_state = MST_INIT;
+                       break;
+
+               default:
+                       printk (KERN_ERR "unknown MIDI sysmsg %0x\n", midic);
+                       mi->m_state = MST_INIT;
+               }
+               break;
+
+       case MST_MTC:
+               mi->m_state = MST_INIT;
+               break;
+
+       case MST_SYSEX:
+               if (midic == 0xf7) {
+                       mi->m_state = MST_INIT;
+               } else {
+                       /* XXX fix me */
+               }
+               break;
+
+       case MST_SONGPOS:
+               BUFTEST (mi);
+               mi->m_buf[mi->m_ptr++] = midic;
+               if (mi->m_ptr == 2) {
+                       mi->m_state = MST_INIT;
+                       mi->m_ptr = 0;
+                       /* XXX need ext MIDI timer support */
+               }
+               break;
+
+       case MST_DATA:
+               BUFTEST (mi);
+               mi->m_buf[mi->m_ptr++] = midic;
+               if ((--mi->m_left) <= 0) {
+                       mi->m_state = MST_INIT;
+                       do_midi_msg (devc->synthno, mi->m_buf, mi->m_ptr);
+                       mi->m_ptr = 0;
+               }
+               break;
+
+       default:
+               printk (KERN_ERR "Bad state %d ", mi->m_state);
+               mi->m_state = MST_INIT;
+       }
+
+       return 1;
+}
+
+void
+wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
+{
+       struct wf_mpu_config *devc;
+       int             dev;
+       static struct wf_mpu_config *isrc = 0;
+       int             n;
+       struct midi_input_info *mi;
+       static int cnt = 0;
+
+       if (irq < 0 || irq > 15) {
+               printk (KERN_ERR "WF-MPU: bogus interrupt #%d", irq);
+               return;
+       }
+       dev = irq2dev[irq];
+       mi = &midi_devs[dev]->in_info;
+       if (mi->m_busy) return;
+       mi->m_busy = 1;
+       sti (); 
+
+       n = 50;
+
+       /* guarantee that we're working with the "real" (internal)
+          interface before doing anything physical.
+       */
+
+       devc = &dev_conf[dev];
+       devc = &dev_conf[devc->internal];
+
+       if (isrc == 0) {
+      
+               /* This is just an initial setting. If Virtual MIDI mode is
+                  enabled on the ICS2115, we'll get a switch char before
+                  anything else, and if it isn't, then the guess will be
+                  correct for our purposes.
+               */
+      
+               isrc = &dev_conf[devc->internal];
+       }
+  
+       while (input_avail (devc) && n-- > 0) {
+               unsigned char c = read_data (devc);
+      
+               if (devc->isvirtual) {
+                       if (c == WF_EXTERNAL_SWITCH) {
+                               isrc = &dev_conf[devc->external];
+                               continue;
+                       } else if (c == WF_INTERNAL_SWITCH) { 
+                               isrc = &dev_conf[devc->internal];
+                               continue;
+                       } /* else just leave it as it is */
+               } else {
+                       isrc = &dev_conf[devc->internal];
+               }
+
+               if (isrc->mode == MODE_SYNTH) {
+         
+                       wf_mpu_input_scanner (isrc, c);
+         
+               } else if (isrc->opened & OPEN_READ) {
+         
+                       if (isrc->inputintr) {
+                               isrc->inputintr (isrc->devno, c);
+                       } 
+               }
+       }
+
+       mi->m_busy = 0;
+}
+
+static int
+wf_mpu_open (int dev, int mode,
+            void            (*input) (int dev, unsigned char data),
+            void            (*output) (int dev)
+       )
+{
+       struct wf_mpu_config *devc;
+
+       if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
+               return -ENXIO;
+
+       devc = &dev_conf[dev];
+
+       if (devc->opened) {
+               return -EBUSY;
+       }
+
+       devc->mode = MODE_MIDI;
+       devc->opened = mode;
+       devc->synthno = 0;
+
+       devc->inputintr = input;
+       return 0;
+}
+static void
+wf_mpu_close (int dev)
+{
+       struct wf_mpu_config *devc;
+
+       devc = &dev_conf[dev];
+       devc->mode = 0;
+       devc->inputintr = NULL;
+       devc->opened = 0;
+}
+
+static int
+wf_mpu_out (int dev, unsigned char midi_byte)
+{
+       int             timeout;
+       unsigned long   flags;
+       static int lastoutdev = -1;
+
+       struct wf_mpu_config *devc;
+       unsigned char switchch;
+
+       /* The actual output has to occur using the "internal" config info
+        */
+  
+       devc = &dev_conf[dev_conf[dev].internal];
+  
+       if (devc->isvirtual && lastoutdev != dev) {
+      
+               if (dev == devc->internal) { 
+                       switchch = WF_INTERNAL_SWITCH;
+               } else if (dev == devc->external) { 
+                       switchch = WF_EXTERNAL_SWITCH;
+               } else {
+                       printk (KERN_ERR "WF-MPU: bad device number %d", dev);
+                       return (0);
+               }
+      
+               for (timeout = 30000; timeout > 0 && !output_ready (devc);
+                    timeout--);
+      
+               save_flags (flags);
+               cli ();
+      
+               if (!output_ready (devc)) {
+                       printk (KERN_WARNING "WF-MPU: Send switch "
+                               "byte timeout\n");
+                       restore_flags (flags);
+                       return 0;
+               }
+      
+               write_data (devc, switchch);
+               restore_flags (flags);
+       } 
+
+       lastoutdev = dev;
+
+       /*
+        * Sometimes it takes about 30000 loops before the output becomes ready
+        * (After reset). Normally it takes just about 10 loops.
+        */
+
+       for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+       save_flags (flags);
+       cli ();
+       if (!output_ready (devc)) {
+               printk (KERN_WARNING "WF-MPU: Send data timeout\n");
+               restore_flags (flags);
+               return 0;
+       }
+
+       write_data (devc, midi_byte);
+       restore_flags (flags);
+
+       return 1;
+}
+
+static int
+wf_mpu_start_read (int dev)
+{
+       return 0;
+}
+
+static int
+wf_mpu_end_read (int dev)
+{
+       return 0;
+}
+
+static int
+wf_mpu_ioctl (int dev, unsigned cmd, caddr_t arg)
+{
+       printk (KERN_WARNING
+               "WF-MPU: Intelligent mode not supported by hardware.\n");
+       return -(EINVAL);
+}
+
+static void
+wf_mpu_kick (int dev)
+{
+}
+
+static int
+wf_mpu_buffer_status (int dev)
+{
+       return 0;                       /*
+                                        * No data in buffers
+                                        */
+}
+
+static int
+wf_mpu_synth_ioctl (int dev,
+                   unsigned int cmd, caddr_t arg)
+{
+       int             midi_dev;
+
+       midi_dev = synth_devs[dev]->midi_dev;
+
+       if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
+               return -(ENXIO);
+
+       switch (cmd) {
+
+       case SNDCTL_SYNTH_INFO:
+               copy_to_user (&((char *) arg)[0],
+                             &wf_mpu_synth_info[midi_dev],
+                             sizeof (struct synth_info));
+       
+               return 0;
+               break;
+       
+       case SNDCTL_SYNTH_MEMAVL:
+               return 0x7fffffff;
+               break;
+       
+       default:
+               return -(EINVAL);
+       }
+}
+
+static int
+wf_mpu_synth_open (int dev, int mode)
+{
+       int             midi_dev;
+       struct wf_mpu_config *devc;
+
+       midi_dev = synth_devs[dev]->midi_dev;
+
+       if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) {
+               return -(ENXIO);
+       }
+  
+       devc = &dev_conf[midi_dev];
+       if (devc->opened) {
+               return -(EBUSY);
+       }
+  
+       devc->mode = MODE_SYNTH;
+       devc->synthno = dev;
+       devc->opened = mode;
+       devc->inputintr = NULL;
+       return 0;
+}
+
+static void
+wf_mpu_synth_close (int dev)
+{
+       int             midi_dev;
+       struct wf_mpu_config *devc;
+
+       midi_dev = synth_devs[dev]->midi_dev;
+
+       devc = &dev_conf[midi_dev];
+       devc->inputintr = NULL;
+       devc->opened = 0;
+       devc->mode = 0;
+}
+
+#define MIDI_SYNTH_NAME        "WaveFront (MIDI)"
+#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
+#include "midi_synth.h"
+
+static struct synth_operations wf_mpu_synth_proto =
+{
+       "WaveFront (ICS2115)",
+       NULL,  /* info field, filled in during configuration */
+       0,     /* MIDI dev XXX should this be -1 ? */
+       SYNTH_TYPE_MIDI,
+       SAMPLE_TYPE_WAVEFRONT,
+       wf_mpu_synth_open,
+       wf_mpu_synth_close,
+       wf_mpu_synth_ioctl,
+       midi_synth_kill_note,
+       midi_synth_start_note,
+       midi_synth_set_instr,
+       midi_synth_reset,
+       midi_synth_hw_control,
+       midi_synth_load_patch,
+       midi_synth_aftertouch,
+       midi_synth_controller,
+       midi_synth_panning,
+       NULL,
+       midi_synth_bender,
+       NULL,                           /* alloc */
+       midi_synth_setup_voice,
+       midi_synth_send_sysex
+};
+
+static struct synth_operations wf_mpu_synth_operations[WAVEFRONT_MAX_DEVICES*2];
+static struct midi_operations  wf_mpu_midi_operations[WAVEFRONT_MAX_DEVICES*2];
+static int wfmpu_cnt = 0;
+
+static struct midi_operations wf_mpu_midi_proto =
+{
+       {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
+       NULL,  /*converter*/
+       {0},   /* in_info */
+       wf_mpu_open,
+       wf_mpu_close,
+       wf_mpu_ioctl,
+       wf_mpu_out,
+       wf_mpu_start_read,
+       wf_mpu_end_read,
+       wf_mpu_kick,
+       NULL,
+       wf_mpu_buffer_status,
+       NULL
+};
+
+
+static int
+config_wf_mpu (int dev, struct address_info *hw_config)
+
+{
+       struct wf_mpu_config *devc;
+       int                internal;
+
+       if (wfmpu_cnt >= WAVEFRONT_MAX_DEVICES * 2) {
+               printk (KERN_ERR "WF-MPU: eh ? more MPU devices "
+                       "than cards ?!!\n");
+               return (-1);
+       }
+  
+       /* There is no synth available on the external interface,
+          so do the synth stuff to the internal interface only.
+       */
+
+       internal = dev_conf[dev].internal;
+       devc = &dev_conf[internal];
+
+       if (!dev_conf[dev].isexternal) {
+               memcpy ((char *) &wf_mpu_synth_operations[wfmpu_cnt],
+                       (char *) &wf_mpu_synth_proto,
+                       sizeof (struct synth_operations));
+       }
+
+       memcpy ((char *) &wf_mpu_midi_operations[wfmpu_cnt],
+               (char *) &wf_mpu_midi_proto,
+               sizeof (struct midi_operations));
+  
+       if (dev_conf[dev].isexternal) {
+               wf_mpu_midi_operations[wfmpu_cnt].converter = NULL;
+       } else {
+               wf_mpu_midi_operations[wfmpu_cnt].converter =
+                       &wf_mpu_synth_operations[wfmpu_cnt];
+       }
+
+       memcpy ((char *) &wf_mpu_synth_info[dev],
+               (char *) &wf_mpu_synth_info_proto,
+               sizeof (struct synth_info));
+
+       strcpy (wf_mpu_synth_info[dev].name, hw_config->name);
+       strcpy (wf_mpu_midi_operations[wfmpu_cnt].info.name, hw_config->name);
+
+       conf_printf (hw_config->name, hw_config);
+
+       if (!dev_conf[dev].isexternal) {
+               wf_mpu_synth_operations[wfmpu_cnt].midi_dev = dev;
+       }
+       wf_mpu_synth_operations[wfmpu_cnt].info = &wf_mpu_synth_info[dev];
+
+       midi_devs[dev] = &wf_mpu_midi_operations[wfmpu_cnt];
+
+       dev_conf[dev].opened = 0;
+       dev_conf[dev].mode = 0;
+       dev_conf[dev].configured_for_virtual = 0;
+       dev_conf[dev].devno = dev;
+
+       midi_devs[dev]->in_info.m_busy = 0;
+       midi_devs[dev]->in_info.m_state = MST_INIT;
+       midi_devs[dev]->in_info.m_ptr = 0;
+       midi_devs[dev]->in_info.m_left = 0;
+       midi_devs[dev]->in_info.m_prev_status = 0;
+
+       wfmpu_cnt++;
+
+       return (0);
+}
+
+int
+virtual_midi_enable (int dev, struct address_info *hw_config)
+
+{
+       int idev;
+       int edev;
+       struct wf_mpu_config *devc;
+
+       devc = &dev_conf[dev];
+       
+       if (devc->configured_for_virtual) {
+
+               idev = devc->internal;
+               edev = devc->external;
+
+       } else {
+
+               if (hw_config == NULL) {
+                       printk (KERN_ERR
+                               "WF-MPU: virtual midi first "
+                               "enabled without hw_config!\n");
+                       return -EINVAL;
+               }
+
+               idev = devc->internal;
+
+               if ((edev = sound_alloc_mididev()) == -1) {
+                       printk (KERN_ERR
+                               "WF-MPU: too many midi devices detected\n");
+                       return -1;
+               }
+
+               hw_config->slots[WF_EXTERNAL_MIDI_SLOT] = edev;
+       }
+
+       dev_conf[edev].isvirtual = 1;
+       dev_conf[idev].isvirtual = 1;
+    
+       if (dev_conf[idev].configured_for_virtual) {
+               return 0;
+       } 
+
+       /* Configure external interface struct */
+
+       devc = &dev_conf[edev];
+       devc->internal = idev;
+       devc->external = edev;
+       devc->isexternal = 1;
+
+       /* Configure external interface struct 
+          (devc->isexternal and devc->internal set in attach_wf_mpu())
+       */
+
+       devc = &dev_conf[idev];
+       devc->external = edev;
+
+       /* Configure the tables for the external */
+
+       if (config_wf_mpu (edev, hw_config)) {
+               printk (KERN_WARNING "WF-MPU: configuration for MIDI "
+                       "device %d failed\n", edev);
+               return (-1);
+       }
+
+       /* Don't bother to do this again if we are toggled back and
+          forth between virtual MIDI mode and "normal" operation.
+       */
+
+       dev_conf[edev].configured_for_virtual = 1;
+       dev_conf[idev].configured_for_virtual = 1;
+
+       return 0;
+}
+
+void
+virtual_midi_disable (int dev)
+
+{
+       struct wf_mpu_config *devc;
+       unsigned long flags;
+
+       save_flags (flags);
+       cli();
+
+       /* Assumes for logical purposes that the caller has taken
+          care of fiddling with WaveFront hardware commands to
+          turn off Virtual MIDI mode. 
+       */
+    
+       devc = &dev_conf[dev];
+
+       devc = &dev_conf[devc->internal];
+       devc->isvirtual = 0;
+
+       devc = &dev_conf[devc->external];
+       devc->isvirtual = 0;
+
+       restore_flags (flags);
+}
+
+void
+attach_wf_mpu (struct address_info *hw_config)
+{
+       int m;
+       struct wf_mpu_config *devc;
+
+       if (request_irq (hw_config->irq, wf_mpuintr,
+                        0, "WaveFront MIDI", NULL) < 0) {
+               printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
+                       hw_config->irq);
+               return;
+       }
+
+       if ((m = sound_alloc_mididev()) == -1){
+               printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
+               free_irq (hw_config->irq, NULL);
+               release_region (hw_config->io_base, 2);
+               return;
+       }
+
+       request_region (hw_config->io_base, 2, "WaveFront MPU");
+
+       hw_config->slots[WF_INTERNAL_MIDI_SLOT] = m;
+       devc = &dev_conf[m];
+       devc->base = hw_config->io_base;
+       devc->irq = hw_config->irq;
+       devc->isexternal = 0;
+       devc->internal = m;
+       devc->external = -1;
+       devc->isvirtual = 0;
+
+       irq2dev[devc->irq] = m;
+
+       if (config_wf_mpu (m, hw_config)) {
+               printk (KERN_WARNING
+                       "WF-MPU: configuration for MIDI device %d failed\n", m);
+               sound_unload_mididev (m);
+       }
+
+       /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
+          to switch it into UART (dumb) mode, because otherwise, it
+          won't do anything at all.
+       */
+  
+       start_uart_mode (devc);
+
+}
+
+int
+probe_wf_mpu (struct address_info *hw_config)
+
+{
+       if (hw_config->irq < 0 || hw_config->irq > 16) {
+               printk (KERN_WARNING "WF-MPU: bogus IRQ value requested (%d)\n",
+                       hw_config->irq);
+               return 0;
+       }
+
+       if (check_region (hw_config->io_base, 2)) {
+               printk (KERN_WARNING "WF-MPU: I/O port %x already in use\n\n",
+                       hw_config->io_base);
+               return 0;
+       }
+
+       if (inb (hw_config->io_base + 1) == 0xff) { /* Just bus float? */
+               printk ("WF-MPU: Port %x looks dead.\n", hw_config->io_base);
+               return 0;
+       }
+
+       return 1;
+}
+
+void
+unload_wf_mpu (struct address_info *hw_config)
+{
+
+       release_region (hw_config->io_base, 2); 
+       sound_unload_mididev (hw_config->slots[WF_INTERNAL_MIDI_SLOT]);
+       if (hw_config->irq > 0) {
+               free_irq (hw_config->irq, NULL);
+       }
+       if (hw_config->slots[WF_EXTERNAL_MIDI_SLOT] > 0) {
+               sound_unload_mididev (hw_config->slots[WF_EXTERNAL_MIDI_SLOT]);
+       }
+}
+
+static void
+start_uart_mode (struct wf_mpu_config *devc)
+{
+       int             ok, timeout;
+       unsigned long   flags;
+
+       save_flags (flags);
+       cli ();
+
+       for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);
+
+       wf_mpu_cmd (devc, UART_MODE_ON);
+
+       for (ok = 0, timeout = 50000; timeout > 0 && !ok; timeout--) {
+               if (input_avail (devc)) {
+                       if (read_data (devc) == MPU_ACK) {
+                               ok = 1;
+                       }
+               }
+       }
+
+       restore_flags (flags);
+}
+
+#endif
+
+
diff --git a/drivers/sound/yss225.c b/drivers/sound/yss225.c
new file mode 100644 (file)
index 0000000..e5d7ec0
--- /dev/null
@@ -0,0 +1,317 @@
+unsigned char page_zero[] = {
+0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00,
+0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00,
+0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19,
+0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01,
+0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00,
+0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02,
+0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17,
+0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00,
+0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00,
+0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02,
+0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40,
+0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02,
+0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00,
+0x1d, 0x02, 0xdf
+};    
+
+unsigned char page_one[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
+0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00,
+0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01,
+0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00,
+0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7,
+0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0,
+0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00,
+0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0,
+0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03,
+0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00,
+0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02,
+0x60, 0x00, 0x1b
+};
+
+unsigned char page_two[] = {
+0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4,
+0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07,
+0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46,
+0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46,
+0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07,
+0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05,
+0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05,
+0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44
+};
+
+unsigned char page_three[] = {
+0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
+0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
+0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40,
+0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00,
+0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40
+};
+
+unsigned char page_four[] = {
+0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00,
+0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60,
+0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00,
+0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22,
+0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01
+};
+
+unsigned char page_six[] = {
+0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00,
+0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e,
+0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00,
+0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00,
+0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24,
+0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00,
+0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00,
+0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a,
+0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d,
+0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50,
+0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00,
+0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17,
+0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66,
+0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c,
+0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00,
+0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c,
+0x80, 0x00, 0x7e, 0x80, 0x80
+};
+
+unsigned char page_seven[] = {
+0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f,
+0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff,
+0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f,
+0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38,
+0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06,
+0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b,
+0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06,
+0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55,
+0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14,
+0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93,
+0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x00
+};
+
+unsigned char page_zero_v2[] = {
+0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+unsigned char page_one_v2[] = {
+0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+unsigned char page_two_v2[] = {
+0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00
+};
+unsigned char page_three_v2[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00
+};
+unsigned char page_four_v2[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00
+};
+
+unsigned char page_seven_v2[] = {
+0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+unsigned char mod_v2[] = {
+0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02,
+0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05,
+0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0,
+0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20,
+0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3,
+0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff,
+0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16,
+0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff,
+0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31,
+0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00,
+0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44,
+0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00,
+0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
+0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00,
+0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72,
+0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0,
+0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85,
+0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00,
+0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0,
+0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00,
+0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
+0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00,
+0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6,
+0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00,
+0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02,
+0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03,
+0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01,
+0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01
+};
+unsigned char coefficients[] = {
+0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03,
+0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49,
+0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01,
+0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00,
+0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00,
+0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47,
+0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00,
+0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01,
+0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43,
+0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07,
+0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00,
+0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02,
+0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44,
+0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07,
+0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40,
+0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a,
+0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56,
+0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07,
+0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda,
+0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05,
+0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79,
+0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07,
+0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52,
+0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03,
+0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a,
+0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06,
+0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3,
+0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20,
+0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c,
+0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06,
+0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48,
+0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02,
+0xba
+};
+unsigned char coefficients2[] = {
+0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f,
+0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d,
+0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07,
+0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00,
+0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00
+};
+unsigned char coefficients3[] = { 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00,
+0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc,
+0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01,
+0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99,
+0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02,
+0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f,
+0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03,
+0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c,
+0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03,
+0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51,
+0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04,
+0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e,
+0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05,
+0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14,
+0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06,
+0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1,
+0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07,
+0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7,
+0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08,
+0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3,
+0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09,
+0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99,
+0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a,
+0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66,
+0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a,
+0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c,
+0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b,
+0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28,
+0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c,
+0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e,
+0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d,
+0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb,
+0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e,
+0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1,
+0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f,
+0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae,
+0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff
+};
+
diff --git a/drivers/sound/yss225.h b/drivers/sound/yss225.h
new file mode 100644 (file)
index 0000000..7e4cd65
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __yss255_h__
+#define __yss255_h__
+
+extern unsigned char page_zero[256];
+extern unsigned char page_one[256];
+extern unsigned char page_two[128];
+extern unsigned char page_three[128];
+extern unsigned char page_four[128];
+extern unsigned char page_six[192];
+extern unsigned char page_seven[256];
+extern unsigned char page_zero_v2[96];
+extern unsigned char page_one_v2[96];
+extern unsigned char page_two_v2[48];
+extern unsigned char page_three_v2[48];
+extern unsigned char page_four_v2[48];
+extern unsigned char page_seven_v2[96];
+extern unsigned char mod_v2[304];
+extern unsigned char coefficients[364];
+extern unsigned char coefficients2[56];
+extern unsigned char coefficients3[404];
+
+
+#endif __ys225_h__
+
index bd8b629371f6ea12882e7412e262157a4998691e..bad74c83a6046e7a0e7e4cc764a59ce09e2bc453 100644 (file)
@@ -31,15 +31,14 @@ if [ "$CONFIG_FB" = "y" ]; then
   fi
   if [ "$CONFIG_PPC" = "y" ]; then
     bool 'Open Firmware frame buffer device support' CONFIG_FB_OF
-    bool 'S3 Trio frame buffer device support' CONFIG_FB_S3TRIO
     if [ "$CONFIG_FB_OF" = "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
+      bool 'Chips 65550 display support' CONFIG_FB_CT65550
+      bool 'S3 Trio display support' CONFIG_FB_S3TRIO
     fi
   fi
   if [ "$CONFIG_MAC" = "y" ]; then
@@ -58,20 +57,23 @@ if [ "$CONFIG_FB" = "y" ]; then
     tristate 'TGA framebuffer support' CONFIG_FB_TGA
   fi
   if [ "$ARCH" = "i386" ]; then
-    if [ "$CONFIG_VGA_CONSOLE" != "y" ]; then
-      bool 'VESA VGA graphics console' CONFIG_FB_VESA
-      define_bool CONFIG_VIDEO_SELECT y
-    fi
+    bool 'VESA VGA graphics console' CONFIG_FB_VESA
+    define_bool CONFIG_VIDEO_SELECT y
     tristate 'MDA dual-headed support' CONFIG_FB_MDA
   fi
   if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
-    bool 'PROM framebuffer' CONFIG_FB_PROM
     bool 'SBUS and UPA framebuffers' CONFIG_FB_SBUS
     if [ "$CONFIG_FB_SBUS" != "n" ]; then
       if [ "$ARCH" = "sparc64" ]; then
-       bool 'Creator/Creator3D support' CONFIG_FB_CREATOR
+       bool '  Creator/Creator3D support' CONFIG_FB_CREATOR
+      fi
+      bool '  CGsix (GX,GXplus) support' CONFIG_FB_CGSIX
+    fi
+    if [ "$CONFIG_PCI" != "n" ]; then
+      bool 'PCI framebuffers' CONFIG_FB_PCI
+      if [ "$CONFIG_FB_PCI" != "n" ]; then
+        bool '  ATI Mach64 display support' CONFIG_FB_ATY
       fi
-      bool 'CGsix (GX,GXplus) support' CONFIG_FB_CGSIX
     fi
   fi
   tristate 'Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL
@@ -143,10 +145,10 @@ if [ "$CONFIG_FB" = "y" ]; then
        define_bool CONFIG_FBCON_CFB16 m
       fi
     fi
-    if [ "$CONFIG_FB_VIRTUAL" = "y" ]; then
+    if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then
       define_bool CONFIG_FBCON_CFB24 y
     else
-      if [ "$CONFIG_FB_VIRTUAL" = "m" ]; then
+      if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
        define_bool CONFIG_FBCON_CFB24 m
       fi
     fi
index 6bea86ae5c916319208ec070eae351da9ae39fb8..869170c6d5a3a421cf20006c244b16fa20eb107f 100644 (file)
@@ -29,9 +29,14 @@ ifeq ($(CONFIG_DUMMY_CONSOLE),y)
   L_OBJS += dummycon.o
 endif
 
+ifeq ($(CONFIG_PROM_CONSOLE),y)
+  L_OBJS += promcon.o
+endif
+
 ifeq ($(CONFIG_FB),y)
-  L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o font_6x11.o font_sun8x16.o
-  OX_OBJS += fbcon.o fbcmap.o fbgen.o
+  L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o font_6x11.o font_sun8x16.o font_sun12x22.o
+  OX_OBJS += fbcon.o fbcmap.o
+# fbgen is not compiled by default since nobody uses it yet
 endif
 
 # Frame Buffer Devices
@@ -60,6 +65,10 @@ ifeq ($(CONFIG_FB_ATY),y)
 L_OBJS += atyfb.o
 endif
 
+ifeq ($(CONFIG_FB_CT65550),y)
+L_OBJS += chipsfb.o
+endif
+
 ifeq ($(CONFIG_FB_CYBER),y)
 L_OBJS += cyberfb.o
 else
@@ -77,7 +86,7 @@ L_OBJS += hpfb.o
 endif
 
 ifeq ($(CONFIG_FB_OF),y)
-L_OBJS += offb.o
+L_OBJS += offb.o macmodes.o
 endif
 
 ifeq ($(CONFIG_FB_RETINAZ3),y)
@@ -132,14 +141,6 @@ else
   endif
 endif
 
-ifeq ($(CONFIG_FB_PROM),y)
-L_OBJS += promfb.o
-else
-  ifeq ($(CONFIG_FB_PROM),m)
-  M_OBJS += promfb.o
-  endif
-endif
-
 ifeq ($(CONFIG_FB_SBUS),y)
 L_OBJS += sbusfb.o
   ifeq ($(CONFIG_FB_CREATOR),y)
@@ -318,12 +319,6 @@ ifdef CONFIG_VGA_CONSOLE
 L_OBJS += vgacon.o
 endif
 
-# Console Wrapper
-
-ifdef CONFIG_ABSCON_COMPAT
-L_OBJS += compatcon.o
-endif
-
 include $(TOPDIR)/Rules.make
 
 gspcore.c: gspcore.gsp
index 8880aa6b007cd8ebc47a2b8c69d4237b0ff4b1d1..3287820445e598ce920d0da1aa0b58d095f6f16f 100644 (file)
@@ -94,14 +94,6 @@ static int s3trio_pan_display(struct fb_var_screeninfo *var, int con,
 static int s3trio_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 struct fb_info *console_fb_info;
-extern int (*console_setmode_ptr)(struct vc_mode *, int);
-extern int (*console_set_cmap_ptr)(struct fb_cmap *, int, int,
-                                  struct fb_info *);
-static int s3trio_console_setmode(struct vc_mode *mode, int doit);
-#endif /* CONFIG_FB_COMPAT_XPMAC */
 
     /*
      *  Interface to the low level console driver
@@ -616,8 +608,6 @@ __initfunc(void s3triofb_init_of(struct device_node *dp))
        display_info.cmap_adr_address = address + 0x1008000 + 0x3c8;
        display_info.cmap_data_address = address + 0x1008000 + 0x3c9;
        console_fb_info = &fb_info;
-       console_setmode_ptr = s3trio_console_setmode;
-       console_set_cmap_ptr = s3trio_set_cmap;
     }
 #endif /* CONFIG_FB_COMPAT_XPMAC) */
 
@@ -730,51 +720,6 @@ static void do_install_cmap(int con, struct fb_info *info)
                    &fb_display[con].var, 1, s3trio_setcolreg, &fb_info);
 }
 
-#ifdef CONFIG_FB_COMPAT_XPMAC
-
-    /*
-     *  Backward compatibility mode for Xpmac
-     */
-
-static int s3trio_console_setmode(struct vc_mode *mode, int doit)
-{
-#if 1
-    return -EINVAL;
-#else
-    int err;
-    struct fb_var_screeninfo var;
-    struct s3trio_par par;
-
-    if (mode->mode <= 0 || mode->mode > VMODE_MAX )
-        return -EINVAL;
-    par.video_mode = mode->mode;
-
-    switch (mode->depth) {
-        case 24:
-        case 32:
-            par.color_mode = CMODE_32;
-            break;
-        case 16:
-            par.color_mode = CMODE_16;
-            break;
-        case 8:
-        case 0:                        /* (default) */
-            par.color_mode = CMODE_8;
-            break;
-        default:
-            return -EINVAL;
-    }
-    encode_var(&var, &par);
-    if ((err = decode_var(&var, &par)))
-        return err;
-    if (doit)
-        s3trio_set_var(&var, currcon, 0);
-    return 0;
-#endif
-}
-
-#endif /* CONFIG_FB_COMPAT_XPMAC */
-
 void s3triofb_setup(char *options, int *ints) {
 
         return;
@@ -933,6 +878,6 @@ static void fbcon_trio8_revc(struct display *p, int xx, int yy)
 
 static struct display_switch fbcon_trio8 = {
    fbcon_cfb8_setup, fbcon_trio8_bmove, fbcon_trio8_clear, fbcon_trio8_putc,
-   fbcon_trio8_putcs, fbcon_trio8_revc, NULL
+   fbcon_trio8_putcs, fbcon_trio8_revc, NULL, NULL, FONTWIDTH(8)
 };
 #endif
index 3689fe53a577a44975b7f08c03e081ea0cc73245..6733924f2a4f7984fa0fddfd009ec4152e623012 100644 (file)
@@ -2671,7 +2671,7 @@ check_default_par( int detected_mode )
                        sprintf(default_name,"default%d",i);
                        default_par=get_video_mode(default_name);
                        if (! default_par)
-                               panic("can't set default video mode\n");
+                               panic("can't set default video mode");
                        var=atafb_predefined[default_par-1];
                        var.activate = FB_ACTIVATE_TEST;
                        if (! do_fb_set_var(&var,1))
@@ -2768,7 +2768,7 @@ __initfunc(void atafb_init(void))
 #else /* ATAFB_STE */
                /* no default driver included */
                /* Nobody will ever see this message :-) */
-               panic("Cannot initialize video hardware\n");
+               panic("Cannot initialize video hardware");
 #endif
        } while (0);
 
@@ -2791,6 +2791,8 @@ __initfunc(void atafb_init(void))
                mem_req = ((mem_req + PAGE_SIZE - 1) & PAGE_MASK) + PAGE_SIZE;
                screen_base = (unsigned long)atari_stram_alloc(mem_req, NULL,
                                                               "atafb");
+               if (!screen_base)
+                       panic("Cannot allocate screen memory");
                memset((char *) screen_base, 0, mem_req);
                pad = ((screen_base + PAGE_SIZE-1) & PAGE_MASK) - screen_base;
                screen_base+=pad;
index 778a9c26099116c91d778cdc9bfb577f15b74b5a..313d2d1750b82e931825086f3556577ba06757a9 100644 (file)
@@ -53,6 +53,9 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #endif
+#ifdef __sparc__
+#include <asm/pbm.h>
+#endif
 
 #include "aty.h"
 #include "fbcon.h"
@@ -239,12 +242,21 @@ struct rage_regvals {
     u32 h_sync_neg, v_sync_neg;
 };
 
+struct pci_mmap_map {
+    unsigned long voff;
+    unsigned long poff;
+    unsigned long size;
+    unsigned long prot_flag;
+    unsigned long prot_mask;
+};
+
 struct fb_info_aty {
     struct fb_info fb_info;
     unsigned long ati_regbase_phys;
     unsigned long ati_regbase;
     unsigned long frame_buffer_phys;
     unsigned long frame_buffer;
+    struct pci_mmap_map *mmap_map;
     u8 chip_class;
     u8 pixclock_lim_8; /* ps, <= 8 bpp */
     u8 pixclock_lim_hi;        /* ps, > 8 bpp */
@@ -387,6 +399,10 @@ 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 __sparc__
+static int atyfb_mmap(struct fb_info *info, struct file *file,
+                     struct vm_area_struct *vma);
+#endif
 
 
     /*
@@ -428,7 +444,7 @@ static int atyfb_console_setmode(struct vc_mode *, int);
      */
 
 static int aty_init(struct fb_info_aty *info, const char *name);
-#ifndef CONFIG_FB_OF
+#ifdef CONFIG_ATARI
 static int store_video_par(char *videopar, unsigned char m64_num);
 static char *strtoke(char *s, const char *ct);
 #endif
@@ -442,7 +458,12 @@ 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
+    atyfb_get_cmap, atyfb_set_cmap, atyfb_pan_display, atyfb_ioctl,
+#ifdef __sparc__
+    atyfb_mmap
+#else
+    NULL
+#endif
 };
 
 
@@ -785,7 +806,7 @@ static void set_off_pitch(const struct atyfb_par *par,
 
 static void atyfb_set_par(struct atyfb_par *par, struct fb_info_aty *info)
 {
-    int i, j, hres;
+    int i, j = 0, hres;
     struct aty_regvals *init = get_aty_struct(par->hw.gx.vmode, info);
     int vram_type = aty_ld_le32(CONFIG_STAT0, info) & 7;
 
@@ -911,8 +932,22 @@ static void atyfb_set_par(struct atyfb_par *par, struct fb_info_aty *info)
            j = 0x47052100;
            break;
 
-       case CLASS_CT:
        case CLASS_VT:
+           if (vram_type == 4) {
+               /*
+                * What to do here? - The contents of MEM_CNTL do not
+                * seem to match my documentation, and touching this
+                * register makes the output unusable.
+                * (green bars across the screen and similar effects).
+                *
+                * Eddie C. Dost  (ecd@skynet.be)
+                */
+               j = 0x87010184;
+               break;
+            }
+            /* fallthrough */
+
+       case CLASS_CT:
            aty_st_le32(BUS_CNTL, 0x680000f9, info);
            switch (info->total_vram) {
                case 0x00100000:
@@ -1208,7 +1243,7 @@ static int encode_var(struct fb_var_screeninfo *var,
     u_int h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
     u_int v_total, v_disp;
     u_int v_sync_strt, v_sync_wid, v_sync_pol;
-    u_int xtalin, vclk;
+    u_int xtalin, vclk = 0;
     u8 pll_ref_div, vclk_fb_div, vclk_post_div, pll_ext_cntl;
 
     memset(var, 0, sizeof(struct fb_var_screeninfo));
@@ -1476,6 +1511,7 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
                    display->dispsw = NULL;
                    break;
            }
+           display->scrollmode = accel ? 0 : SCROLL_YREDRAW;
            if (info->changevar)
                (*info->changevar)(con);
        }
@@ -1564,6 +1600,112 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
     return -EINVAL;
 }
 
+#ifdef __sparc__
+static int atyfb_mmap(struct fb_info *info, struct file *file,
+                     struct vm_area_struct *vma)
+{
+       struct fb_info_aty *fb = (struct fb_info_aty *)info;
+       unsigned int size, page, map_size = 0;
+       unsigned long map_offset = 0;
+       int i;
+
+       if (!fb->mmap_map)
+               return -ENXIO;
+
+       size = vma->vm_end - vma->vm_start;
+       if (vma->vm_offset & ~PAGE_MASK)
+               return -ENXIO;
+
+       /* To stop the swapper from even considering these pages. */
+       vma->vm_flags |= (VM_SHM | VM_LOCKED);
+
+#ifdef __sparc_v9__
+       /* Align it as much as desirable */
+       {
+               int j, max = -1, align;
+               
+               map_offset = vma->vm_offset+size;
+               for (i = 0; fb->mmap_map[i].size; i++) {
+                       if (fb->mmap_map[i].voff < vma->vm_offset)
+                               continue;
+                       if (fb->mmap_map[i].voff >= map_offset)
+                               break;
+                       if (max < 0 ||
+                           fb->mmap_map[i].size > fb->mmap_map[max].size)
+                               max = i;
+               }
+               if (max >= 0) {
+                       j = fb->mmap_map[max].size;
+                       if (fb->mmap_map[max].voff + j > map_offset)
+                               j = map_offset - fb->mmap_map[max].voff;
+                       for (align = 0x400000; align > PAGE_SIZE; align >>= 3)
+                               if (j >= align &&
+                                   !(fb->mmap_map[max].poff & (align - 1)))
+                                       break;
+                       if (align > PAGE_SIZE) {
+                               j = align;
+                               align = j - ((vma->vm_start
+                                             + fb->mmap_map[max].voff
+                                             - vma->vm_offset) & (j - 1));
+                               if (align != j) {
+                                       struct vm_area_struct *vmm;
+
+                                       vmm = find_vma(current->mm,
+                                                      vma->vm_start);
+                                       if (!vmm || vmm->vm_start
+                                                   >= vma->vm_end + align) {
+                                               vma->vm_start += align;
+                                               vma->vm_end += align;
+                                       }
+                               }
+                       }
+               }
+       }
+#endif 
+
+       /* Each page, see which map applies */
+       for (page = 0; page < size; ) {
+               map_size = 0;
+               for (i = 0; fb->mmap_map[i].size; i++) {
+                       unsigned long start = fb->mmap_map[i].voff;
+                       unsigned long end = start + fb->mmap_map[i].size;
+                       unsigned long offset = vma->vm_offset + page;
+
+                       if (start > offset)
+                               continue;
+                       if (offset > end)
+                               continue;
+
+                       map_size = fb->mmap_map[i].size - (offset - start);
+                       map_offset = fb->mmap_map[i].poff + (offset - start);
+                       break;
+               }
+               if (!map_size) {
+                       page += PAGE_SIZE;
+                       continue;
+               }
+               if (page + map_size > size)
+                       map_size = size - page;
+
+               pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
+               pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
+
+               if (remap_page_range(vma->vm_start + page, map_offset,
+                                    map_size, vma->vm_page_prot))
+                       return -EAGAIN;
+
+               page += map_size;
+       }
+
+       if (!map_size)
+               return -EINVAL;
+
+       vma->vm_file = file;
+       file->f_count++;
+       vma->vm_flags |= VM_IO;
+       return 0;
+}
+#endif /* __sparc__ */
 
     /*
      *  Initialisation
@@ -1667,7 +1809,9 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
 #endif
 
     sense = read_aty_sense(info);
+#if 0
     printk("monitor sense = %x\n", sense);
+#endif
 #if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
     if (default_vmode == VMODE_NVRAM) {
        default_vmode = nvram_read_byte(NV_VMODE);
@@ -1774,7 +1918,204 @@ __initfunc(void atyfb_init(void))
     /* We don't want to be called like this. */
     /* We rely on Open Firmware (offb) instead. */
 #elif defined(CONFIG_PCI)
-    /* Anyone who wants to do a PCI probe for an ATI chip? */
+    struct pci_dev *pdev;
+    struct fb_info_aty *info;
+    unsigned long addr;
+    int i, j;
+    u16 tmp;
+
+    for (pdev = pci_devices; pdev; pdev = pdev->next) {
+       if (((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
+           (pdev->vendor == PCI_VENDOR_ID_ATI)) {
+
+           info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
+           if (!info) {
+               printk("atyfb_init: can't alloc fb_info_aty\n");
+               return;
+           }
+
+           addr = pdev->base_address[0];
+           if ((addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+               addr = pdev->base_address[1];
+           if (!addr)
+               continue;
+
+#ifdef __sparc__
+           /*
+            * Map memory-mapped registers.
+            */
+           info->ati_regbase = addr + 0x7ffc00;
+           info->ati_regbase_phys = __pa(addr + 0x7ffc00);
+
+           /*
+            * Map in big-endian aperture.
+            */
+           info->frame_buffer = (unsigned long)(addr + 0x800000);
+           info->frame_buffer_phys = __pa(addr + 0x800000);
+
+           /*
+            * Figure mmap addresses from PCI config space.
+            * Split Framebuffer in big- and little-endian halfs.
+            */
+           for (i = 0; i < 6 && pdev->base_address[i]; i++)
+               /* nothing */;
+           j = i + 1;
+
+            info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
+           if (!info->mmap_map) {
+               printk("atyfb_init: can't alloc mmap_map\n");
+               kfree(info);
+           }
+
+           memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
+           for (i = j = 0; i < 6 && pdev->base_address[i]; i++) {
+               int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
+               unsigned long base;
+               u32 size, pbase;
+
+               base = pdev->base_address[i];
+
+               io = (base & PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO;
+
+               pci_read_config_dword(pdev, breg, &pbase);
+               pci_write_config_dword(pdev, breg, 0xffffffff);
+               pci_read_config_dword(pdev, breg, &size);
+               pci_write_config_dword(pdev, breg, pbase);
+
+               if (io)
+                       size &= ~1;
+               size = ~(size) + 1;
+
+               if (base == addr) {
+                       info->mmap_map[j].voff = (pbase + 0x800000)
+                                                               & PAGE_MASK;
+                       info->mmap_map[j].poff = __pa((base + 0x800000)
+                                                               & PAGE_MASK);
+                       info->mmap_map[j].size = 0x800000;
+                       info->mmap_map[j].prot_mask = _PAGE_CACHE;
+                       info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
+                       size -= 0x800000;
+                       j++;
+               }
+
+               info->mmap_map[j].voff = pbase & PAGE_MASK;
+               info->mmap_map[j].poff = __pa(base & PAGE_MASK);
+               info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
+               info->mmap_map[j].prot_mask = _PAGE_CACHE;
+               info->mmap_map[j].prot_flag = _PAGE_E;
+               j++;
+           }
+
+           /*
+            * Fix PROMs idea of MEM_CNTL settings...
+            */
+           tmp = aty_ld_le32(CONFIG_CHIP_ID, info) & CFG_CHIP_TYPE;
+           if (tmp == MACH64_VT_ID) {
+               u32 mem = aty_ld_le32(MEM_CNTL, info);
+               switch (mem & 0x0f) {
+                   case 3:
+                       mem = (mem & ~(0x0f)) | 2;
+                       break;
+                   case 7:
+                       mem = (mem & ~(0x0f)) | 3;
+                       break;
+                   case 9:
+                       mem = (mem & ~(0x0f)) | 4;
+                       break;
+                   case 11:
+                       mem = (mem & ~(0x0f)) | 5;
+                       break;
+                   default:
+                       break;
+               }
+               mem &= ~(0x00f00000);
+               aty_st_le32(MEM_CNTL, mem, info);
+           }
+
+           /*
+            * Set default vmode and cmode from PROM properties.
+            */
+           {
+               struct pcidev_cookie *cookie = pdev->sysdata;
+               int node = cookie->prom_node;
+               int width = prom_getintdefault(node, "width", 1024);
+               int height = prom_getintdefault(node, "height", 768);
+               int depth = prom_getintdefault(node, "depth", 8);
+
+               switch (depth) {
+                   case 8:
+                       default_cmode = CMODE_8;
+                       break;
+                   case 16:
+                       default_cmode = CMODE_16;
+                       break;
+                   case 32:
+                       default_cmode = CMODE_32;
+                       break;
+                   default:
+                       break;
+               }
+
+               switch (width) {
+                   case 1024:
+                       if (height == 768)
+                           default_vmode = VMODE_1024_768_75;
+                       break;
+                   case 1152:
+                       if (height == 870)
+                           default_vmode = VMODE_1152_870_75;
+                       break;
+                   case 1280:
+                       if (height == 960)
+                           default_vmode = VMODE_1280_960_75;
+                       else if (height == 1024)
+                           default_vmode = VMODE_1280_1024_75;
+                       break;
+                   default:
+                       break;
+               }
+           }
+
+#else /* __sparc__ */
+
+           info->ati_regbase = (unsigned long)
+                               ioremap(0x7ff000 + addr, 0x1000) + 0xc00;
+
+           info->ati_regbase_phys = 0x7ff000 + addr;
+           info->ati_regbase = (unsigned long)
+                               ioremap(info->ati_regbase_phys, 0x1000);
+
+           info->ati_regbase_phys += 0xc00;
+           info->ati_regbase += 0xc00;
+
+           /*
+            * Enable memory-space accesses using config-space
+            * command register.
+            */
+           pci_read_config_word(pdev, PCI_COMMAND, &tmp);
+           if (!(tmp & PCI_COMMAND_MEMORY)) {
+               tmp |= PCI_COMMAND_MEMORY;
+               pci_write_config_word(pdev, PCI_COMMAND, tmp);
+           }
+
+#ifdef __BIG_ENDIAN
+           /* Use the big-endian aperture */
+           addr += 0x800000;
+#endif
+
+           /* Map in frame buffer */
+           info->frame_buffer_phys = addr;
+           info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
+
+#endif /* __sparc__ */
+
+           if (!aty_init(info, "PCI")) {
+               if (info->mmap_map)
+                   kfree(info->mmap_map);
+               kfree(info);
+           }
+       }
+    }
 #elif defined(CONFIG_ATARI)
     int m64_num;
     struct fb_info_aty *info;
@@ -1979,7 +2320,7 @@ __initfunc(static char *strtoke(char *s, const char *ct))
     ssave = send;
     return sbegin;
 }
-#endif /* !CONFIG_FB_OF */
+#endif /* CONFIG_ATARI */
 
 static int atyfbcon_switch(int con, struct fb_info *info)
 {
@@ -2021,14 +2362,20 @@ static void atyfbcon_blank(int blank, struct fb_info *info)
     u8 gen_cntl;
 
     gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info2);
+#ifndef __sparc__
     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;
+#endif
     if (blank == VESA_NO_BLANKING)
            gen_cntl &= ~(0x4c);
+#ifdef __sparc__
+    else
+           gen_cntl |= 0x40;
+#endif
     aty_st_8(CRTC_GEN_CNTL, gen_cntl, info2);
 }
 
@@ -2237,7 +2584,7 @@ static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
 
 static struct display_switch fbcon_aty8 = {
     fbcon_cfb8_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty8_putc,
-    fbcon_aty8_putcs, fbcon_cfb8_revc, NULL
+    fbcon_aty8_putcs, fbcon_cfb8_revc, NULL, NULL, FONTWIDTH(8)
 };
 #endif
 
@@ -2258,7 +2605,7 @@ static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
 
 static struct display_switch fbcon_aty16 = {
     fbcon_cfb16_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty16_putc,
-    fbcon_aty16_putcs, fbcon_cfb16_revc, NULL
+    fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, FONTWIDTH(8)
 };
 #endif
 
@@ -2279,7 +2626,7 @@ static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
 
 static struct display_switch fbcon_aty32 = {
     fbcon_cfb32_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty32_putc,
-    fbcon_aty32_putcs, fbcon_cfb32_revc, NULL
+    fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, FONTWIDTH(8)
 };
 #endif
 
index 7b3fcf791eb7f8340861d898186299cc1a68647e..12afba9a8c15f8137939c91be2387254e7a8e47e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.1 1998/07/06 15:51:09 jj Exp $
+/* $Id: cgsixfb.c,v 1.2 1998/07/13 12:47:14 jj Exp $
  * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -226,37 +226,6 @@ static void cg6_setup(struct display *p)
        p->next_plane = 0;
 }
 
-static void cg6_bmove(struct display *p, int sy, int sx, int dy, int dx,
-                          int height, int width)
-{
-#if 0
-       int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
-       u8 *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;
-               }
-       }
-#endif 
-}
-
 static void cg6_clear(struct vc_data *conp, struct display *p, int sy, int sx,
                      int height, int width)
 {
@@ -310,113 +279,160 @@ static void cg6_fill(struct fb_info_sbusfb *fb, int s,
 
 static void cg6_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
 {
-#if 0
        struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
        register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-       int i, xy;
+       int i, xy;
        u8 *fd;
 
-       if (p->fontheight == 16) {
-               xy = (yy << (16 + 4));
-               fd = p->fontdata + ((c & 0xff) << 4);
+       if (p->fontheightlog) {
+               y = fb->y_margin + (yy << p->fontheightlog);
+               i = ((c & 0xff) << p->fontheightlog);
        } else {
-               xy = ((yy * p->fontheight) << 16);
-               fd = p->fontdata + (c & 0xff) * p->fontheight;
+               y = fb->y_margin + (yy * p->fontheight);
+               i = (c & 0xff) * p->fontheight;
+       }
+       if (p->fontwidth <= 8)
+               fd = p->fontdata + i;
+       else
+               fd = p->fontdata + (i << 1);
+       if (p->fontwidthlog)
+               x = fb->x_margin + (xx << p->fontwidthlog);
+       else
+               x = fb->x_margin + (xx * p->fontwidth);
+       do {
+               i = fbc->s;
+       } while (i & 0x10000000);
+       fbc->fg = attr_fg_col(c);
+       fbc->bg = attr_bg_col(c);
+       fbc->mode = 0x140000;
+       fbc->alu = 0xe880fc30;
+       fbc->pixelm = ~(0);
+       fbc->s = 0;
+       fbc->clip = 0;
+       fbc->pm = 0xff;
+       fbc->incx = 0;
+       fbc->incy = 1;
+       fbc->x0 = x;
+       fbc->x1 = x + p->fontwidth - 1;
+       fbc->y0 = y;
+       if (p->fontwidth <= 8) {
+               for (i = 0; i < p->fontheight; i++)
+                       fbc->font = *fd++ << 24;
+       } else {
+               for (i = 0; i < p->fontheight; i++) {
+                       fbc->font = *(u16 *)fd << 16;
+                       fd += 2;
+               }
        }
-       xy += (xx << 3) + fb->s.cg6.xy_margin;
-       fbc->ppc = 0x203;
-       fbc->fg = cg6_cmap[attr_fg_col(c)];
-       fbc->fbc = 0x2000707f;
-       fbc->rop = 0x83;
-       fbc->pmask = 0xffffffff;
-       fbc->bg = cg6_cmap[attr_bg_col(c)];
-       fbc->fontw = 8;
-       fbc->fontinc = 0x10000;
-       fbc->fontxy = xy;
-       for (i = 0; i < p->fontheight; i++)
-               fbc->font = *fd++ << 24;
-#endif         
 }
 
 static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
                      int count, int yy, int xx)
 {
-#if 0
        struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
        register struct cg6_fbc *fbc = fb->s.cg6.fbc;
-       int i, xy;
+       int i, xy;
        u8 *fd1, *fd2, *fd3, *fd4;
 
-       fbc->ppc = 0x203;
-       fbc->fg = cg6_cmap[attr_fg_col(*s)];
-       fbc->fbc = 0x2000707f;
-       fbc->rop = 0x83;
-       fbc->pmask = 0xffffffff;
-       fbc->bg = cg6_cmap[attr_bg_col(*s)];
-       if (p->fontheight == 16) {
-               xy = (yy << (16 + 4)) + (xx << 3) + fb->s.cg6.xy_margin;
+       do {
+               i = fbc->s;
+       } while (i & 0x10000000);
+       fbc->fg = attr_fg_col(*s);
+       fbc->bg = attr_bg_col(*s);
+       fbc->mode = 0x140000;
+       fbc->alu = 0xe880fc30;
+       fbc->pixelm = ~(0);
+       fbc->s = 0;
+       fbc->clip = 0;
+       fbc->pm = 0xff;
+       x = fb->x_margin;
+       y = fb->y_margin;
+       if (p->fontwidthlog)
+               x += (xx << p->fontwidthlog);
+       else
+               x += xx * p->fontwidth;
+       if (p->fontheightlog)
+               y += (yy << p->fontheightlog);
+       else
+               y += (yy * p->fontheight);
+       if (p->fontwidth <= 8) {
                while (count >= 4) {
                        count -= 4;
-                       fbc->fontw = 32;
-                       fbc->fontinc = 0x10000;
-                       fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) << 4);
-                       fd2 = p->fontdata + ((*s++ & 0xff) << 4);
-                       fd3 = p->fontdata + ((*s++ & 0xff) << 4);
-                       fd4 = p->fontdata + ((*s++ & 0xff) << 4);
-                       for (i = 0; i < 16; i++)
-                               fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
-                       xy += 32;
-               }
-               while (count) {
-                       count--;
-                       fbc->fontw = 8;
-                       fbc->fontinc = 0x10000;
-                       fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) << 4);
-                       for (i = 0; i < 16; i++)
-                               fbc->font = *fd1++ << 24;
-                       xy += 8;
+                       fbc->incx = 0;
+                       fbc->incy = 1;
+                       fbc->x0 = x;
+                       fbc->x1 = (x += 4 * p->fontwidth) - 1;
+                       fbc->y0 = y;
+                       if (p->fontheightlog) {
+                               fd1 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                               fd2 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                               fd3 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                               fd4 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                       } else {
+                               fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                               fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                               fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                               fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                       }
+                       if (p->fontwidth == 8) {
+                               for (i = 0; i < p->fontheight; i++)
+                                       fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
+                                               << 8)) << 8)) << 8);
+                       } else {
+                               for (i = 0; i < p->fontheight; i++)
+                                       fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
+                                               << p->fontwidth)) << p->fontwidth)) << p->fontwidth)) << (24 - 3 * p->fontwidth);
+                       }
                }
        } else {
-               xy = ((yy * p->fontheight) << 16) + (xx << 3) + fb->s.cg6.xy_margin;
-               while (count >= 4) {
-                       count -= 4;
-                       fbc->fontw = 32;
-                       fbc->fontinc = 0x10000;
-                       fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       for (i = 0; i < p->fontheight; i++)
-                               fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
-                       xy += 32;
+               while (count >= 2) {
+                       count -= 2;
+                       fbc->incx = 0;
+                       fbc->incy = 1;
+                       fbc->x0 = x;
+                       fbc->x1 = (x += 2 * p->fontwidth) - 1;
+                       fbc->y0 = y;
+                       if (p->fontheightlog) {
+                               fd1 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+                               fd2 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+                       } else {
+                               fd1 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+                               fd2 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+                       }
+                       for (i = 0; i < p->fontheight; i++) {
+                               fbc->font = ((((u32)*(u16 *)fd1) << p->fontwidth) | ((u32)*(u16 *)fd2)) << (16 - p->fontwidth);
+                               fd1 += 2; fd2 += 2;
+                       }
                }
-               while (count) {
-                       count--;
-                       fbc->fontw = 8;
-                       fbc->fontinc = 0x10000;
-                       fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       for (i = 0; i < 16; i++)
+       }
+       while (count) {
+               count--;
+               fbc->incx = 0;
+               fbc->incy = 1;
+               fbc->x0 = x;
+               fbc->x1 = (x += p->fontwidth) - 1;
+               fbc->y0 = y;
+               if (p->fontheightlog)
+                       i = ((*s++ & 0xff) << p->fontheightlog);
+               else
+                       i = ((*s++ & 0xff) * p->fontheight);
+               if (p->fontwidth <= 8) {
+                       fd1 = p->fontdata + i;
+                       for (i = 0; i < p->fontheight; i++)
                                fbc->font = *fd1++ << 24;
-                       xy += 8;
+               } else {
+                       fd1 = p->fontdata + (i << 1);
+                       for (i = 0; i < p->fontheight; i++) {
+                               fbc->font = *(u16 *)fd1 << 16;
+                               fd1 += 2;
+                       }
                }
        }
-#endif
 }
 
 static void cg6_revc(struct display *p, int xx, int yy)
 {
-       u8 *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;
-       }
+       /* Not used if hw cursor */
 }
 
 static void cg6_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
@@ -433,7 +449,8 @@ static void cg6_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
 }
 
 static struct display_switch cg6_dispsw __initdata = {
-       cg6_setup, cg6_bmove, cg6_clear, cg6_putc, cg6_putcs, cg6_revc, NULL
+       cg6_setup, fbcon_redraw_bmove, cg6_clear, cg6_putc, cg6_putcs, cg6_revc, 
+       NULL, NULL, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
 };
 
 static void cg6_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
@@ -477,6 +494,63 @@ static void cg6_setcursor (struct fb_info_sbusfb *fb)
        fb->s.cg6.thc->thc_cursxy = v;
 }
 
+static void cg6_blank (struct fb_info_sbusfb *fb)
+{
+       fb->s.cg6.thc->thc_misc &= ~CG6_THC_MISC_VIDEO;
+}
+
+static void cg6_unblank (struct fb_info_sbusfb *fb)
+{
+       fb->s.cg6.thc->thc_misc |= CG6_THC_MISC_VIDEO;
+}
+
+static void cg6_reset (struct fb_info_sbusfb *fb)
+{
+       unsigned int rev, conf;
+       
+       /* Turn off stuff in the Transform Engine. */
+       fb->s.cg6.tec->tec_matrix = 0;
+       fb->s.cg6.tec->tec_clip = 0;
+       fb->s.cg6.tec->tec_vdc = 0;
+
+       /* Take care of bugs in old revisions. */
+       rev = (*(fb->s.cg6.fhc) >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK;
+       if (rev < 5) {
+               conf = (*(fb->s.cg6.fhc) & CG6_FHC_RES_MASK) |
+                       CG6_FHC_CPU_68020 | CG6_FHC_TEST |
+                       (11 << CG6_FHC_TEST_X_SHIFT) |
+                       (11 << CG6_FHC_TEST_Y_SHIFT);
+               if (rev < 2)
+                       conf |= CG6_FHC_DST_DISABLE;
+               *(fb->s.cg6.fhc) = conf;
+       }
+
+       /* Set things in the FBC. */
+       fb->s.cg6.fbc->mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK |
+                           CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK |
+                           CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK |
+                           CG6_FBC_BDISP_MASK);
+       fb->s.cg6.fbc->mode |= (CG6_FBC_BLIT_SRC | CG6_FBC_MODE_COLOR8 |
+                          CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE |
+                          CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 |
+                          CG6_FBC_BDISP_0);
+       fb->s.cg6.fbc->clip = 0;
+       fb->s.cg6.fbc->offx = 0;
+       fb->s.cg6.fbc->offy = 0;
+       fb->s.cg6.fbc->clipminx = 0;
+       fb->s.cg6.fbc->clipminy = 0;
+       fb->s.cg6.fbc->clipmaxx = fb->type.fb_width - 1;
+       fb->s.cg6.fbc->clipmaxy = fb->type.fb_height - 1;
+       /* Enable cursor in Brooktree DAC. */
+       fb->s.cg6.bt->addr = 0x06 << 24;
+       fb->s.cg6.bt->control |= 0x03 << 24;
+}
+
+static void cg6_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
+{
+       p->screen_base += (y_margin - fb->y_margin) * p->line_length + (x_margin - fb->x_margin);
+}
+
 static char idstring[60] __initdata = { 0 };
 
 __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
@@ -504,8 +578,10 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
                disp->screen_base = (char *)sparc_alloc_io(phys + CG6_RAM_OFFSET, 0, 
                        type->fb_size, "cgsix_ram", fb->iospace, 0);
        disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
-       fb->s.cg6.fbc = (struct cg6_fbc *)(char *)sparc_alloc_io(phys + CG6_FBC_OFFSET, 0, 
+       fb->s.cg6.fbc = (struct cg6_fbc *)sparc_alloc_io(phys + CG6_FBC_OFFSET, 0, 
                        4096, "cgsix_fbc", fb->iospace, 0);
+       fb->s.cg6.tec = (struct cg6_tec *)sparc_alloc_io(phys + CG6_TEC_OFFSET, 0, 
+                       sizeof(struct cg6_tec), "cgsix_tec", fb->iospace, 0);
        fb->s.cg6.thc = (struct cg6_thc *)sparc_alloc_io(phys + CG6_THC_OFFSET, 0, 
                                sizeof(struct cg6_thc), "cgsix_thc", fb->iospace, 0);
        fb->s.cg6.bt = (struct bt_regs *)sparc_alloc_io(phys + CG6_BROOKTREE_OFFSET, 0, 
@@ -514,11 +590,15 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
                                sizeof(u32), "cgsix_fhc", fb->iospace, 0);
        fb->dispsw = cg6_dispsw;
 
+       fb->margins = cg6_margins;
        fb->loadcmap = cg6_loadcmap;
        fb->setcursor = cg6_setcursor;
        fb->setcursormap = cg6_setcursormap;
        fb->setcurshape = cg6_setcurshape;
        fb->fill = cg6_fill;
+       fb->blank = cg6_blank;
+       fb->unblank = cg6_unblank;
+       fb->reset = cg6_reset;
        
        fb->physbase = phys;
        fb->mmap_map = cg6_mmap_map;
@@ -544,5 +624,7 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
                    (fb->s.cg6.thc->thc_misc >> CG6_THC_MISC_REV_SHIFT) & CG6_THC_MISC_REV_MASK,
                    p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK);
                    
+       cg6_reset(fb);
+                   
        return idstring;
 }
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
new file mode 100644 (file)
index 0000000..300dad7
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ *  drivers/video/chipsfb.c -- frame buffer device for
+ *  Chips & Technologies 65550 chip.
+ *
+ *  Copyright (C) 1998 Paul Mackerras
+ *
+ *  This file is derived from the Powermac "chips" driver:
+ *  Copyright (C) 1997 Fabio Riccardi.
+ *  And from the frame buffer device for Open Firmware-initialized devices:
+ *  Copyright (C) 1997 Geert Uytterhoeven.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#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>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/adb.h>
+#include <asm/pmu.h>
+
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+
+static int currcon = 0;
+
+struct fb_info_chips {
+       struct fb_info info;
+       struct fb_fix_screeninfo fix;
+       struct fb_var_screeninfo var;
+       struct display disp;
+       struct {
+               __u8 red, green, blue;
+       } palette[256];
+       __u8 *frame_buffer;
+       __u8 *blitter_regs;
+       __u8 *io_base;
+       unsigned long chips_base_phys;
+       unsigned long chips_io_phys;
+       struct fb_info_chips *next;
+#ifdef CONFIG_PMAC_PBOOK
+       unsigned char *save_framebuffer;
+#endif
+};
+
+#define write_xr(num,val)      { out_8(p->io_base + 0x3D6, num); out_8(p->io_base + 0x3D7, val); }
+#define read_xr(num,var)       { out_8(p->io_base + 0x3D6, num); var = in_8(p->io_base + 0x3D7); }
+#define write_fr(num,val)      { out_8(p->io_base + 0x3D0, num); out_8(p->io_base + 0x3D1, val); }
+#define read_fr(num,var)       { out_8(p->io_base + 0x3D0, num); var = in_8(p->io_base + 0x3D1); }
+#define write_cr(num,val)      { out_8(p->io_base + 0x3D4, num); out_8(p->io_base + 0x3D5, val); }
+#define read_cr(num,var)       { out_8(p->io_base + 0x3D4, num); var = in_8(p->io_base + 0x3D5); }
+
+
+static struct fb_info_chips *all_chips;
+
+#ifdef CONFIG_PMAC_PBOOK
+int chips_sleep_notify(struct notifier_block *, unsigned long, void *);
+static struct notifier_block chips_sleep_notifier = {
+       chips_sleep_notify, NULL, 0
+};
+#endif
+
+/*
+ * Exported functions
+ */
+void chips_init(void);
+void chips_of_init(struct device_node *dp);
+
+static int chips_open(struct fb_info *info, int user);
+static int chips_release(struct fb_info *info, int user);
+static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
+                        struct fb_info *info);
+static int chips_get_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info);
+static int chips_set_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info);
+static int chips_pan_display(struct fb_var_screeninfo *var, int con,
+                            struct fb_info *info);
+static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                         struct fb_info *info);
+static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                         struct fb_info *info);
+static int chips_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                      u_long arg, int con, struct fb_info *info);
+
+static struct fb_ops chipsfb_ops = {
+       chips_open,
+       chips_release,
+       chips_get_fix,
+       chips_get_var,
+       chips_set_var,
+       chips_get_cmap,
+       chips_set_cmap,
+       chips_pan_display,
+       chips_ioctl
+};
+
+static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
+                            u_int *blue, u_int *transp, struct fb_info *info);
+static int chipsfb_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 void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp);
+
+
+static int chips_open(struct fb_info *info, int user)
+{
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static int chips_release(struct fb_info *info, int user)
+{
+       MOD_DEC_USE_COUNT;
+       return 0;
+}
+
+static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
+                        struct fb_info *info)
+{
+       struct fb_info_chips *cp = (struct fb_info_chips *) info;
+
+       *fix = cp->fix;
+       return 0;
+}
+
+static int chips_get_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info)
+{
+       struct fb_info_chips *cp = (struct fb_info_chips *) info;
+
+       *var = cp->var;
+       return 0;
+}
+
+static int chips_set_var(struct fb_var_screeninfo *var, int con,
+                        struct fb_info *info)
+{
+       struct fb_info_chips *cp = (struct fb_info_chips *) info;
+       struct display *disp = (con >= 0)? &fb_display[con]: &cp->disp;
+
+       if (var->xres > 800 || var->yres > 600
+           || var->xres_virtual > 800 || var->yres_virtual > 600
+           || (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
+           || var->nonstd
+           || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+               return -EINVAL;
+
+       if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&
+               var->bits_per_pixel != disp->var.bits_per_pixel) {
+               chips_set_bitdepth(cp, disp, con, var->bits_per_pixel);
+       }
+
+       return 0;
+}
+
+static int chips_pan_display(struct fb_var_screeninfo *var, int con,
+                            struct fb_info *info)
+{
+       if (var->xoffset != 0 || var->yoffset != 0)
+               return -EINVAL;
+       return 0;
+}
+
+static int chips_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,
+                                  chipsfb_getcolreg, info);
+       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(256), cmap, kspc? 0: 2);
+       return 0;
+}
+
+static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                        struct fb_info *info)
+{
+       struct display *disp = &fb_display[con];
+       int err;
+
+       if (disp->cmap.len == 0) {
+               err = fb_alloc_cmap(&disp->cmap, 256, 0);
+               if (err)
+                       return err;
+       }
+
+       if (con == currcon)
+               return fb_set_cmap(cmap, &disp->var, kspc, chipsfb_setcolreg,
+                                  info);
+       fb_copy_cmap(cmap, &disp->cmap, kspc==0);
+       return 0;
+}
+
+static int chips_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                      u_long arg, int con, struct fb_info *info)
+{
+       return -EINVAL;
+}
+
+static int chipsfb_switch(int con, struct fb_info *info)
+{
+       struct fb_info_chips *p = (struct fb_info_chips *) info;
+       struct display* old_disp = &fb_display[currcon];
+       struct display* new_disp = &fb_display[con];
+       int     bit_depth;
+
+       if (fb_display[currcon].cmap.len)
+               fb_get_cmap(&old_disp->cmap,
+                           &old_disp->var, 1, chipsfb_getcolreg,
+                           info);
+
+       bit_depth = new_disp->var.bits_per_pixel;
+       if (old_disp->var.bits_per_pixel != bit_depth)
+       {
+         currcon = con;
+         chips_set_bitdepth(p, new_disp, con, bit_depth);
+       }
+       else
+         currcon = con;
+       
+       do_install_cmap(con, info);
+       return 0;
+}
+
+static int chipsfb_updatevar(int con, struct fb_info *info)
+{
+       return 0;
+}
+
+static void chipsfb_blank(int blank, struct fb_info *info)
+{
+       struct fb_info_chips *p = (struct fb_info_chips *) info;
+       int i;
+
+       if (blank > 1) {
+               pmu_enable_backlight(0);
+       } else if (blank) {
+               for (i = 0; i < 256; ++i) {
+                       out_8(p->io_base + 0x3c8, i);
+                       udelay(1);
+                       out_8(p->io_base + 0x3c9, 0);
+                       out_8(p->io_base + 0x3c9, 0);
+                       out_8(p->io_base + 0x3c9, 0);
+               }
+       } else {
+               pmu_enable_backlight(1);
+               do_install_cmap(currcon, info);
+       }
+}
+
+static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
+                            u_int *blue, u_int *transp, struct fb_info *info)
+{
+       struct fb_info_chips *p = (struct fb_info_chips *) info;
+
+       if (regno > 255)
+               return 1;
+       *red = p->palette[regno].red;
+       *green = p->palette[regno].green;
+       *blue = p->palette[regno].blue;
+       return 0;
+}
+
+static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                            u_int transp, struct fb_info *info)
+{
+       struct fb_info_chips *p = (struct fb_info_chips *) info;
+
+       if (regno > 255)
+               return 1;
+       p->palette[regno].red = red;
+       p->palette[regno].green = green;
+       p->palette[regno].blue = blue;
+       out_8(p->io_base + 0x3c8, regno);
+       udelay(1);
+       out_8(p->io_base + 0x3c9, red);
+       out_8(p->io_base + 0x3c9, green);
+       out_8(p->io_base + 0x3c9, blue);
+
+#ifdef CONFIG_FBCON_CFB16
+    if (regno < 16)
+               fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue;            
+#endif
+
+    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,
+                           chipsfb_setcolreg, info);
+       else
+               fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), &fb_display[con].var, 1,
+                           chipsfb_setcolreg, info);
+}
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+/* from drivers/macintosh/pmac-cons.h */
+#define VMODE_800_600_60       10      /* 800x600, 60Hz */
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp)
+{
+       int err;
+       struct fb_fix_screeninfo* fix = &p->fix;
+       struct fb_var_screeninfo* var = &p->var;
+       
+       if (bpp == 16) {
+               if (con == currcon) {
+                       write_cr(0x13, 200);            // 16 bit display width (decimal)
+                       write_xr(0x81, 0x14);           // 15 bit (TrueColor) color mode
+                       write_xr(0x82, 0x00);           // disable palettes
+                       write_xr(0x20, 0x10);           // 16 bit blitter mode
+               }
+
+               fix->line_length = 800*2;
+               fix->visual = FB_VISUAL_TRUECOLOR;
+
+               var->red.offset = 10;
+               var->green.offset = 5;
+               var->blue.offset = 0;
+               var->red.length = var->green.length = var->blue.length = 5;
+               
+               disp->dispsw = &fbcon_cfb16;
+    } else if (bpp == 8) {
+               if (con == currcon) {
+                       write_cr(0x13, 100);            // 8 bit display width (decimal)
+                       write_xr(0x81, 0x12);           // 8 bit color mode
+                       write_xr(0x82, 0x08);           // Graphics gamma enable
+                       write_xr(0x20, 0x00);           // 8 bit blitter mode
+               }
+
+               fix->line_length = 800;
+               fix->visual = FB_VISUAL_PSEUDOCOLOR;            
+
+               var->red.offset = var->green.offset = var->blue.offset = 0;
+               var->red.length = var->green.length = var->blue.length = 8;
+               
+               disp->dispsw = &fbcon_cfb8;
+       }
+
+       var->bits_per_pixel = bpp;
+       disp->line_length = p->fix.line_length;
+       disp->visual = fix->visual;
+       disp->var = *var;
+
+#ifdef CONFIG_PMAC_PBOOK
+       display_info.depth = bpp;
+       display_info.pitch = fix->line_length;
+#endif
+       
+       if (p->info.changevar)
+               (*p->info.changevar)(con);
+
+       if ((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
+               return;
+       do_install_cmap(con, (struct fb_info *)p);
+}
+
+__initfunc(static void init_chips(struct fb_info_chips *p))
+{
+       int i;
+
+       memset(&p->fix, 0, sizeof(p->fix));
+       strcpy(p->fix.id, "C&T 65550");
+       p->fix.smem_start = (char *) p->chips_base_phys;
+       p->fix.smem_len = 800 * 600;
+       p->fix.mmio_start = (char *) p->chips_io_phys;
+       p->fix.type = FB_TYPE_PACKED_PIXELS;
+       p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+       p->fix.line_length = 800;
+
+       memset(&p->var, 0, sizeof(p->var));
+       p->var.xres = 800;
+       p->var.yres = 600;
+       p->var.xres_virtual = 800;
+       p->var.yres_virtual = 600;
+       p->var.bits_per_pixel = 8;
+       p->var.red.length = p->var.green.length = p->var.blue.length = 8;
+       p->var.height = p->var.width = -1;
+       p->var.vmode = FB_VMODE_NONINTERLACED;
+       p->var.pixclock = 10000;
+       p->var.left_margin = p->var.right_margin = 16;
+       p->var.upper_margin = p->var.lower_margin = 16;
+       p->var.hsync_len = p->var.vsync_len = 8;
+
+       memset(&p->disp, 0, sizeof(p->disp));
+       p->disp.var = p->var;
+       p->disp.cmap.red = NULL;
+       p->disp.cmap.green = NULL;
+       p->disp.cmap.blue = NULL;
+       p->disp.cmap.transp = NULL;
+       p->disp.screen_base = (char *) p->frame_buffer;
+       p->disp.visual = p->fix.visual;
+       p->disp.type = p->fix.type;
+       p->disp.type_aux = p->fix.type_aux;
+       p->disp.line_length = p->fix.line_length;
+       p->disp.can_soft_blank = 1;
+       p->disp.dispsw = &fbcon_cfb8;
+       p->disp.scrollmode = SCROLL_YREDRAW;
+
+       strcpy(p->info.modename, p->fix.id);
+       p->info.node = -1;
+       p->info.fbops = &chipsfb_ops;
+       p->info.disp = &p->disp;
+       p->info.fontname[0] = 0;
+       p->info.changevar = NULL;
+       p->info.switch_con = &chipsfb_switch;
+       p->info.updatevar = &chipsfb_updatevar;
+       p->info.blank = &chipsfb_blank;
+
+       for (i = 0; i < 16; ++i) {
+               int j = color_table[i];
+               p->palette[i].red = default_red[j];
+               p->palette[i].green = default_grn[j];
+               p->palette[i].blue = default_blu[j];
+       }
+
+       if (register_framebuffer(&p->info) < 0) {
+               kfree(p);
+               return;
+       }
+
+       printk("fb%d: Chips 65550 frame buffer\n", GET_FB_IDX(p->info.node));
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+       if (!console_fb_info) {
+               display_info.height = p->var.yres;
+               display_info.width = p->var.xres;
+               display_info.depth = 8;
+               display_info.pitch = p->fix.line_length;
+               display_info.mode = VMODE_800_600_60;
+               strncpy(display_info.name, "chips65550",
+                       sizeof(display_info.name));
+               display_info.fb_address = p->chips_base_phys + 0x800000;
+               display_info.cmap_adr_address = p->chips_io_phys + 0x3c8;
+               display_info.cmap_data_address = p->chips_io_phys + 0x3c9;
+               display_info.disp_reg_address = p->chips_base_phys + 0xc00000;
+               console_fb_info = &p->info;
+       }
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+#ifdef CONFIG_PMAC_PBOOK
+       if (all_chips == NULL)
+               notifier_chain_register(&sleep_notifier_list,
+                                       &chips_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+       p->next = all_chips;
+       all_chips = p;
+}
+
+__initfunc(void chips_init(void))
+{
+#ifndef CONFIG_FB_OF
+       struct device_node *dp;
+
+       dp = find_devices("chips65550");
+       if (dp != 0)
+               chips_of_init(dp);
+#endif /* CONFIG_FB_OF */
+}
+
+__initfunc(void chips_of_init(struct device_node *dp))
+{
+       struct fb_info_chips *p;
+       unsigned long addr;
+       unsigned char bus, devfn;
+       unsigned short cmd;
+
+       if (dp->n_addrs == 0)
+               return;
+       p = kmalloc(sizeof(*p), GFP_ATOMIC);
+       if (p == 0)
+               return;
+       addr = dp->addrs[0].address;
+       p->chips_base_phys = addr;
+       p->frame_buffer = __ioremap(addr+0x800000, 0x100000, _PAGE_NO_CACHE);
+       p->blitter_regs = ioremap(addr + 0xC00000, 0x1000);
+
+       if (pci_device_loc(dp, &bus, &devfn) == 0) {
+               pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
+               cmd |= 3;       /* enable memory and IO space */
+               pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+               p->io_base = (unsigned char *) pci_io_base(bus);
+               /* XXX really want the physical address here */
+               p->chips_io_phys = (unsigned long) pci_io_base(bus);
+       }
+
+       /* Clear the entire framebuffer */
+       memset(p->frame_buffer, 0, 0x100000);
+
+       /* turn on the backlight */
+       pmu_enable_backlight(1);
+
+       init_chips(p);
+}
+
+#ifdef CONFIG_PMAC_PBOOK
+/*
+ * Save the contents of the frame buffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
+int
+chips_sleep_notify(struct notifier_block *this, unsigned long code, void *x)
+{
+       struct fb_info_chips *p;
+
+       for (p = all_chips; p != NULL; p = p->next) {
+               int nb = p->var.yres * p->fix.line_length;
+
+               switch (code) {
+               case PBOOK_SLEEP:
+                       p->save_framebuffer = vmalloc(nb);
+                       if (p->save_framebuffer)
+                               memcpy(p->save_framebuffer,
+                                      p->frame_buffer, nb);
+                       break;
+               case PBOOK_WAKE:
+                       if (p->save_framebuffer) {
+                               memcpy(p->frame_buffer,
+                                      p->save_framebuffer, nb);
+                               vfree(p->save_framebuffer);
+                               p->save_framebuffer = 0;
+                       }
+                       break;
+               }
+       }
+       return NOTIFY_DONE;
+}
+#endif /* CONFIG_PMAC_PBOOK */
diff --git a/drivers/video/compatcon.c b/drivers/video/compatcon.c
deleted file mode 100644 (file)
index 9dac4f0..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- *  linux/drivers/video/compatcon.c -- Console wrapper
- *
- *     Created 26 Apr 1998 by Geert Uytterhoeven
- *
- *  This will be removed once there are frame buffer devices for all supported
- *  graphics hardware
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-#include <linux/console_struct.h>
-#include <linux/string.h>
-#include <linux/kd.h>
-#include <linux/malloc.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/linux_logo.h>
-
-#include <linux/console_compat.h>
-
-
-    /*
-     *  Interface used by the world
-     */
-
-static const char *compatcon_startup(void);
-static void compatcon_init(struct vc_data *conp);
-static void compatcon_deinit(struct vc_data *conp);
-static void compatcon_clear(struct vc_data *conp, int sy, int sx, int height,
-                           int width);
-static void compatcon_putc(struct vc_data *conp, int c, int ypos, int xpos);
-static void compatcon_putcs(struct vc_data *conp, const unsigned short *s, int count,
-                           int ypos, int xpos);
-static void compatcon_cursor(struct vc_data *conp, int mode);
-static int compatcon_scroll(struct vc_data *conp, int t, int b, int dir,
-                           int count);
-static void compatcon_bmove(struct vc_data *conp, int sy, int sx, int dy,
-                           int dx, int height, int width);
-static int compatcon_switch(struct vc_data *conp);
-static int compatcon_blank(int blank);
-static int compatcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
-static int compatcon_set_font(struct vc_data *conp, int w, int h, char *data);
-static int compatcon_set_palette(struct vc_data *conp, unsigned char *table);
-static int compatcon_scrolldelta(struct vc_data *conp, int lines);
-
-
-    /*
-     *  Internal routines
-     */
-
-unsigned long video_num_columns;
-unsigned long video_num_lines;
-unsigned long video_size_row;
-unsigned char video_type;
-unsigned long video_mem_base;
-unsigned long video_mem_term;
-unsigned long video_screen_size;
-int can_do_color;
-
-extern void set_cursor(int currcons);
-extern void hide_cursor(void);
-extern int set_get_cmap(unsigned char *arg, int set);
-extern void set_palette(void);
-extern int set_get_font(unsigned char *arg, int set, int ch512);
-extern void set_vesa_blanking(unsigned long arg);
-extern void vesa_blank(void);
-extern void vesa_powerdown(void);
-extern int con_adjust_height(unsigned long fontheight);
-extern void con_type_init(const char **);
-extern void con_type_init_finish(void);
-
-#define BLANK  0x0020
-
-
-__initfunc(static const char *compatcon_startup(void))
-{
-    const char *display_desc = "????";
-
-    video_num_lines = ORIG_VIDEO_LINES;
-    video_num_columns = ORIG_VIDEO_COLS;
-    video_size_row = 2*video_num_columns;
-    video_screen_size = video_num_lines*video_size_row;
-
-    con_type_init(&display_desc);
-    return display_desc;
-}
-
-
-static void compatcon_init(struct vc_data *conp)
-{
-    static int first = 1;
-
-    conp->vc_cols = video_num_columns;
-    conp->vc_rows = video_num_lines;
-    conp->vc_can_do_color = can_do_color;
-    if (first) {
-       con_type_init_finish();
-       first = 0;
-    }
-}
-
-static void compatcon_deinit(struct vc_data *conp)
-{
-}
-
-
-static void compatcon_clear(struct vc_data *conp, int sy, int sx, int height,
-                           int width)
-{
-    int rows;
-    unsigned long dest;
-
-    if (console_blanked)
-       return;
-
-    dest = video_mem_base+sy*video_size_row+sx*2;
-    if (sx == 0 && width == video_num_columns)      
-       memsetw((void *)dest, conp->vc_video_erase_char, height*video_size_row);
-    else
-       for (rows = height; rows-- ; dest += video_size_row)
-           memsetw((void *)dest, conp->vc_video_erase_char, width*2);
-}
-
-
-static void compatcon_putc(struct vc_data *conp, int c, int ypos, int xpos)
-{
-    u16 *p;
-
-    if (console_blanked)
-       return;
-
-    p = (u16 *)(video_mem_base+ypos*video_size_row+xpos*2);
-    scr_writew(c, p);
-}
-
-
-static void compatcon_putcs(struct vc_data *conp, const unsigned short *s, int count,
-                           int ypos, int xpos)
-{
-    u16 *p;
-    u16 sattr;
-
-    if (console_blanked)
-       return;
-
-    p = (u16 *)(video_mem_base+ypos*video_size_row+xpos*2);
-    while (count--)
-       scr_writew(*s++, p++);
-}
-
-
-static void compatcon_cursor(struct vc_data *conp, int mode)
-{
-    switch (mode) {
-       case CM_ERASE:
-           hide_cursor();
-           break;
-
-       case CM_MOVE:
-       case CM_DRAW:
-           set_cursor(conp->vc_num);
-           break;
-    }
-}
-
-
-static int compatcon_scroll(struct vc_data *conp, int t, int b, int dir,
-                           int count)
-{
-    if (console_blanked)
-       return 0;
-
-    compatcon_cursor(conp, CM_ERASE);
-
-    switch (dir) {
-       case SM_UP:
-           if (count > conp->vc_rows)  /* Maximum realistic size */
-               count = conp->vc_rows;
-           compatcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
-           compatcon_clear(conp, b-count, 0, count, conp->vc_cols);
-           break;
-
-       case SM_DOWN:
-           if (count > conp->vc_rows)  /* Maximum realistic size */
-               count = conp->vc_rows;
-           /*
-            *  Fixed bmove() should end Arno's frustration with copying?
-            *  Confucius says:
-            *  Man who copies in wrong direction, end up with trashed
-            *  data
-            */
-           compatcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
-           compatcon_clear(conp, t, 0, count, conp->vc_cols);
-           break;
-
-       case SM_LEFT:
-           compatcon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
-           compatcon_clear(conp, 0, b-count, conp->vc_rows, count);
-           break;
-
-       case SM_RIGHT:
-           compatcon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
-           compatcon_clear(conp, 0, t, conp->vc_rows, count);
-           break;
-    }
-    return 0;
-}
-
-
-static inline void memmovew(u16 *to, u16 *from, unsigned int count)
-{
-    if ((unsigned long)to < (unsigned long)from)
-       memcpyw(to, from, count);
-    else {
-       count /= 2;
-       to += count;
-       from += count;
-       while (count) {
-           count--;
-           scr_writew(scr_readw(--from), --to);
-       }
-    }
-}
-
-static void compatcon_bmove(struct vc_data *conp, int sy, int sx, int dy,
-                           int dx, int height, int width)
-{
-    unsigned long src, dst;
-    int rows;
-
-    if (console_blanked)
-       return;
-
-    if (sx == 0 && dx == 0 && width == video_num_columns) {
-       src = video_mem_base+sy*video_size_row;
-       dst = video_mem_base+dy*video_size_row;
-       memmovew((u16 *)dst, (u16 *)src, height*video_size_row);
-    } else if (dy < sy || (dy == sy && dx < sx)) {
-       src = video_mem_base+sy*video_size_row+sx*2;
-       dst = video_mem_base+dy*video_size_row+dx*2;
-       for (rows = height; rows-- ;) {
-           memmovew((u16 *)dst, (u16 *)src, width*2);
-           src += video_size_row;
-           dst += video_size_row;
-       }
-    } else {
-       src = video_mem_base+(sy+height-1)*video_size_row+sx*2;
-       dst = video_mem_base+(dy+height-1)*video_size_row+dx*2;
-       for (rows = height; rows-- ;) {
-           memmovew((u16 *)dst, (u16 *)src, width*2);
-           src -= video_size_row;
-           dst -= video_size_row;
-       }
-    }
-}
-
-
-static int compatcon_switch(struct vc_data *conp)
-{
-    return 1;
-}
-
-
-static int compatcon_blank(int blank)
-{
-    if (blank) {
-       set_vesa_blanking(blank-1);
-       if (blank-1 == 0)
-           vesa_blank();
-       else
-           vesa_powerdown();
-       return 0;
-    } else {
-       /* Tell console.c that it has to restore the screen itself */
-       return 1;
-    }
-    return 0;
-}
-
-
-static int compatcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
-{
-    /* this is not supported: data already points to a kernel space copy */
-    return -ENOSYS;
-}
-
-
-static int compatcon_set_font(struct vc_data *conp, int w, int h, char *data)
-{
-    /* this is not supported: data already points to a kernel space copy */
-    return -ENOSYS;
-}
-
-static int compatcon_set_palette(struct vc_data *conp, unsigned char *table)
-{
-    if (console_blanked || vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
-       return -EINVAL;
-    set_palette();
-    return 0;
-}
-
-static int compatcon_scrolldelta(struct vc_data *conp, int lines)
-{
-    /* TODO */
-    return -ENOSYS;
-}
-
-    /*
-     *  The console `switch' structure for the console wrapper
-     */
-
-struct consw compat_con = {
-    compatcon_startup, compatcon_init, compatcon_deinit, compatcon_clear,
-    compatcon_putc, compatcon_putcs, compatcon_cursor, compatcon_scroll,
-    compatcon_bmove, compatcon_switch, compatcon_blank, compatcon_get_font,
-    compatcon_set_font, compatcon_set_palette, compatcon_scrolldelta,
-    NULL, NULL
-};
index 49db05b06f69b1a1f8246cdb0e75972c6b08dec9..513a3f0a8d3e55e2a5c37181cbee96da4efc58dd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.4 1998/07/06 15:51:10 jj Exp $
+/* $Id: creatorfb.c,v 1.5 1998/07/13 12:47:12 jj Exp $
  * creatorfb.c: Creator/Creator3D frame buffer driver
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -177,35 +177,6 @@ static void ffb_setup(struct display *p)
        p->next_plane = 0;
 }
 
-static void ffb_bmove(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;
-       u8 *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 ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
                      int height, int width)
 {
@@ -221,12 +192,16 @@ static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
        fbc->unk2 = 8;
 
        /* FIXME: Optimize this by allowing 8/16 fontheigh only and introduce p->fontheightlog */
-       if (p->fontheight == 16) {
-               y = sy << 4; h = height << 4;
+       if (p->fontheightlog) {
+               y = sy << p->fontheightlog; h = height << p->fontheightlog;
        } else {
                y = sy * p->fontheight; h = height * p->fontheight;
        }
-       x = sx << 3; w = width << 3;
+       if (p->fontwidthlog) {
+               x = sx << p->fontwidthlog; w = width << p->fontwidthlog;
+       } else {
+               x = sx * p->fontwidth; w = width * p->fontwidth;
+       }
        fbc->by = y + fb->y_margin;
        fbc->bx = x + fb->x_margin;
        fbc->bh = h;
@@ -260,25 +235,39 @@ static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int
        int i, xy;
        u8 *fd;
 
-       if (p->fontheight == 16) {
-               xy = (yy << (16 + 4));
-               fd = p->fontdata + ((c & 0xff) << 4);
+       if (p->fontheightlog) {
+               xy = (yy << (16 + p->fontheightlog));
+               i = ((c & 0xff) << p->fontheightlog);
        } else {
                xy = ((yy * p->fontheight) << 16);
-               fd = p->fontdata + (c & 0xff) * p->fontheight;
+               i = (c & 0xff) * p->fontheight;
        }
-       xy += (xx << 3) + fb->s.ffb.xy_margin;
+       if (p->fontwidth <= 8)
+               fd = p->fontdata + i;
+       else
+               fd = p->fontdata + (i << 1);
+       if (p->fontwidthlog)
+               xy += (xx << p->fontwidthlog) + fb->s.ffb.xy_margin;
+       else
+               xy += (xx * p->fontwidth) + fb->s.ffb.xy_margin;
        fbc->ppc = 0x203;
        fbc->fg = ffb_cmap[attr_fg_col(c)];
        fbc->fbc = 0x2000707f;
        fbc->rop = 0x83;
        fbc->pmask = 0xffffffff;
        fbc->bg = ffb_cmap[attr_bg_col(c)];
-       fbc->fontw = 8;
+       fbc->fontw = p->fontwidth;
        fbc->fontinc = 0x10000;
        fbc->fontxy = xy;
-       for (i = 0; i < p->fontheight; i++)
-               fbc->font = *fd++ << 24;
+       if (p->fontwidth <= 8) {
+               for (i = 0; i < p->fontheight; i++)
+                       fbc->font = *fd++ << 24;
+       } else {
+               for (i = 0; i < p->fontheight; i++) {
+                       fbc->font = *(u16 *)fd << 16;
+                       fd += 2;
+               }
+       }
 }
 
 static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
@@ -295,75 +284,91 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh
        fbc->rop = 0x83;
        fbc->pmask = 0xffffffff;
        fbc->bg = ffb_cmap[attr_bg_col(*s)];
-       if (p->fontheight == 16) {
-               xy = (yy << (16 + 4)) + (xx << 3) + fb->s.ffb.xy_margin;
+       xy = fb->s.ffb.xy_margin;
+       if (p->fontwidthlog)
+               xy += (xx << p->fontwidthlog);
+       else
+               xy += xx * p->fontwidth;
+       if (p->fontheightlog)
+               xy += (yy << (16 + p->fontheightlog));
+       else
+               xy += ((yy * p->fontheight) << 16);
+       if (p->fontwidth <= 8) {
                while (count >= 4) {
                        count -= 4;
-                       fbc->fontw = 32;
+                       fbc->fontw = 4 * p->fontwidth;
                        fbc->fontinc = 0x10000;
                        fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) << 4);
-                       fd2 = p->fontdata + ((*s++ & 0xff) << 4);
-                       fd3 = p->fontdata + ((*s++ & 0xff) << 4);
-                       fd4 = p->fontdata + ((*s++ & 0xff) << 4);
-                       for (i = 0; i < 16; i++)
-                               fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
-                       xy += 32;
-               }
-               while (count) {
-                       count--;
-                       fbc->fontw = 8;
-                       fbc->fontinc = 0x10000;
-                       fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) << 4);
-                       for (i = 0; i < 16; i++)
-                               fbc->font = *fd1++ << 24;
-                       xy += 8;
+                       if (p->fontheightlog) {
+                               fd1 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                               fd2 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                               fd3 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                               fd4 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+                       } else {
+                               fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                               fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                               fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                               fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+                       }
+                       if (p->fontwidth == 8) {
+                               for (i = 0; i < p->fontheight; i++)
+                                       fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
+                                               << 8)) << 8)) << 8);
+                               xy += 32;
+                       } else {
+                               for (i = 0; i < p->fontheight; i++)
+                                       fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
+                                               << p->fontwidth)) << p->fontwidth)) << p->fontwidth)) << (24 - 3 * p->fontwidth);
+                               xy += 4 * p->fontwidth;
+                       }
                }
        } else {
-               xy = ((yy * p->fontheight) << 16) + (xx << 3) + fb->s.ffb.xy_margin;
-               while (count >= 4) {
-                       count -= 4;
-                       fbc->fontw = 32;
+               while (count >= 2) {
+                       count -= 2;
+                       fbc->fontw = 2 * p->fontwidth;
                        fbc->fontinc = 0x10000;
                        fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       for (i = 0; i < p->fontheight; i++)
-                               fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
-                       xy += 32;
+                       if (p->fontheightlog) {
+                               fd1 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+                               fd2 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+                       } else {
+                               fd1 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+                               fd2 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+                       }
+                       for (i = 0; i < p->fontheight; i++) {
+                               fbc->font = ((((u32)*(u16 *)fd1) << p->fontwidth) | ((u32)*(u16 *)fd2)) << (16 - p->fontwidth);
+                               fd1 += 2; fd2 += 2;
+                       }
+                       xy += 2 * p->fontwidth;
                }
-               while (count) {
-                       count--;
-                       fbc->fontw = 8;
-                       fbc->fontinc = 0x10000;
-                       fbc->fontxy = xy;
-                       fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-                       for (i = 0; i < 16; i++)
+       }
+       while (count) {
+               count--;
+               fbc->fontw = p->fontwidth;
+               fbc->fontinc = 0x10000;
+               fbc->fontxy = xy;
+               if (p->fontheightlog)
+                       i = ((*s++ & 0xff) << p->fontheightlog);
+               else
+                       i = ((*s++ & 0xff) * p->fontheight);
+               if (p->fontwidth <= 8) {
+                       fd1 = p->fontdata + i;
+                       for (i = 0; i < p->fontheight; i++)
                                fbc->font = *fd1++ << 24;
-                       xy += 8;
+               } else {
+                       fd1 = p->fontdata + (i << 1);
+                       for (i = 0; i < p->fontheight; i++) {
+                               fbc->font = *(u16 *)fd1 << 16;
+                               fd1 += 2;
+                       }
                }
+               xy += p->fontwidth;
        }
 }
 
 static void ffb_revc(struct display *p, int xx, int yy)
 {
-       u8 *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;
-       }
+       /* Not used if hw cursor */
 }
 
 static void ffb_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
@@ -384,9 +389,16 @@ static void ffb_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
 }
 
 static struct display_switch ffb_dispsw __initdata = {
-       ffb_setup, ffb_bmove, ffb_clear, ffb_putc, ffb_putcs, ffb_revc, NULL
+       ffb_setup, fbcon_redraw_bmove, ffb_clear, ffb_putc, ffb_putcs, ffb_revc, 
+       NULL, NULL, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
 };
 
+static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
+{
+       fb->s.ffb.xy_margin = (y_margin << 16) + x_margin;
+       p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
+}
+
 static inline void ffb_curs_enable (struct fb_info_sbusfb *fb, int enable)
 {
        struct ffb_dac *dac = fb->s.ffb.dac;
@@ -478,6 +490,7 @@ __initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb))
        fb->s.ffb.dac = (struct ffb_dac *)((char *)__va(regs[0].phys_addr) + FFB_DAC_POFF);
        fb->dispsw = ffb_dispsw;
 
+       fb->margins = ffb_margins;
        fb->loadcmap = ffb_loadcmap;
        fb->setcursor = ffb_setcursor;
        fb->setcursormap = ffb_setcursormap;
index 647e8ab2142f00bbaf4d820b822a81e34c939e5d..fe743abe2682390d4521bab0ddc9af31dc57a615 100644 (file)
@@ -1174,7 +1174,7 @@ static void fbcon_cyber8_revc(struct display *p, int xx, int yy)
 
 static struct display_switch fbcon_cyber8 = {
    fbcon_cfb8_setup, fbcon_cyber8_bmove, fbcon_cyber8_clear, fbcon_cyber8_putc,
-   fbcon_cyber8_putcs, fbcon_cyber8_revc, NULL
+   fbcon_cyber8_putcs, fbcon_cyber8_revc, NULL, NULL, FONTWIDTH(8)
 };
 #endif
 
index 146226a82f77c2e51aa9aed30d9c86412792d4ac..4ed094a1013f09583bc2fd3617303dcf34254e29 100644 (file)
@@ -412,7 +412,7 @@ void fbcon_afb_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_afb = {
     fbcon_afb_setup, fbcon_afb_bmove, fbcon_afb_clear, fbcon_afb_putc,
-    fbcon_afb_putcs, fbcon_afb_revc, NULL
+    fbcon_afb_putcs, fbcon_afb_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index 45424bcbc9c19c843a5274806d40c8bb55f22a6a..8bbd1113f708066f7cce36a6d970aa19c4ddba16 100644 (file)
@@ -179,7 +179,7 @@ void fbcon_cfb16_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_cfb16 = {
     fbcon_cfb16_setup, fbcon_cfb16_bmove, fbcon_cfb16_clear, fbcon_cfb16_putc,
-    fbcon_cfb16_putcs, fbcon_cfb16_revc, NULL
+    fbcon_cfb16_putcs, fbcon_cfb16_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index 449a0c597e370aed905997d7cb59e7652b7c16e0..a103e4f7771149df527625d0ebfe0d6416d833a4 100644 (file)
@@ -185,7 +185,7 @@ void fbcon_cfb2_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_cfb2 = {
     fbcon_cfb2_setup, fbcon_cfb2_bmove, fbcon_cfb2_clear, fbcon_cfb2_putc,
-    fbcon_cfb2_putcs, fbcon_cfb2_revc, NULL
+    fbcon_cfb2_putcs, fbcon_cfb2_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index 11208fe8b421dee04b5efc07ca4afb5654921808..ce514d165bf1b9ce08cee2875dd5261ca3a5922f 100644 (file)
@@ -199,7 +199,7 @@ void fbcon_cfb24_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_cfb24 = {
     fbcon_cfb24_setup, fbcon_cfb24_bmove, fbcon_cfb24_clear, fbcon_cfb24_putc,
-    fbcon_cfb24_putcs, fbcon_cfb24_revc, NULL
+    fbcon_cfb24_putcs, fbcon_cfb24_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index ab5c802c546184f0ca82beb9a1659a92dcc3d5cb..d1ace4222187697d8e185cde0f8929ef4d3497f5 100644 (file)
@@ -184,7 +184,7 @@ void fbcon_cfb32_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_cfb32 = {
     fbcon_cfb32_setup, fbcon_cfb32_bmove, fbcon_cfb32_clear, fbcon_cfb32_putc,
-    fbcon_cfb32_putcs, fbcon_cfb32_revc, NULL
+    fbcon_cfb32_putcs, fbcon_cfb32_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index e12a6431ad3fc18d931b0efaacff0aa29f98136f..5f07813dcfa34fdd15b42a1f83648306e68fb96b 100644 (file)
@@ -188,7 +188,7 @@ void fbcon_cfb4_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_cfb4 = {
     fbcon_cfb4_setup, fbcon_cfb4_bmove, fbcon_cfb4_clear, fbcon_cfb4_putc,
-    fbcon_cfb4_putcs, fbcon_cfb4_revc, NULL
+    fbcon_cfb4_putcs, fbcon_cfb4_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index 1371d04eeef2d98c0fbe5cc73d34d1af94e98251..11ca0f7f93f9a48fec621c25d9966b22110884fd 100644 (file)
@@ -51,23 +51,30 @@ void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
     int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
     u8 *src,*dst;
 
-    if (sx == 0 && dx == 0 && width * 8 == bytes)
+    if (sx == 0 && dx == 0 && width * p->fontwidth == 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 * 8;
-       dst = p->screen_base + dy * linesize + dx * 8;
+       return;
+    }
+    if (p->fontwidthlog) {
+       sx <<= p->fontwidthlog; dx <<= p->fontwidthlog; width <<= p->fontwidthlog;
+    } else {
+       sx *= p->fontwidth; dx *= p->fontwidth; width *= p->fontwidth;
+    }
+    if (dy < sy || (dy == sy && dx < sx)) {
+       src = p->screen_base + sy * linesize + sx;
+       dst = p->screen_base + dy * linesize + dx;
        for (rows = height * p->fontheight ; rows-- ;) {
-           mymemmove(dst, src, width * 8);
+           mymemmove(dst, src, width);
            src += bytes;
            dst += bytes;
        }
     } else {
-       src = p->screen_base + (sy+height) * linesize + sx * 8 - bytes;
-       dst = p->screen_base + (dy+height) * linesize + dx * 8 - bytes;
+       src = p->screen_base + (sy+height) * linesize + sx - bytes;
+       dst = p->screen_base + (dy+height) * linesize + dx - bytes;
        for (rows = height * p->fontheight ; rows-- ;) {
-           mymemmove(dst, src, width * 8);
+           mymemmove(dst, src, width);
            src -= bytes;
            dst -= bytes;
        }
@@ -77,32 +84,20 @@ void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
 void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx,
                      int height, int width)
 {
-    u8 *dest0,*dest;
-    int bytes=p->next_line,lines=height * p->fontheight, rows, i;
-    u32 bgx;
+    u8 *dest;
+    int bytes=p->next_line,lines=height * p->fontheight, rows;
+    u8 bgx;
 
-    dest = p->screen_base + sy * p->fontheight * bytes + sx * 8;
+    dest = p->screen_base + sy * p->fontheight * bytes + sx * p->fontwidth;
 
     bgx=attr_bgcol_ec(p,conp);
-    bgx |= (bgx << 8);
-    bgx |= (bgx << 16);
 
-    if (sx == 0 && width * 8 == bytes)
-       for (i = 0 ; i < lines * width ; i++) {
-           ((u32 *)dest)[0]=bgx;
-           ((u32 *)dest)[1]=bgx;
-           dest+=8;
-       }
+    if (sx == 0 && p->fontwidth == 8 && width * 8 == bytes)
+        memset(dest, bgx, lines * width * p->fontwidth);
     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;
-               dest+=8;
-           }
-       }
+       width *= p->fontwidth;
+       for (rows = lines; rows-- ; dest += bytes)
+           memset(dest, bgx, width);
     }
 }
 
@@ -114,7 +109,10 @@ void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
     u32 eorx,fgx,bgx;
 
     dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
-    cdat = p->fontdata + (c & 0xff) * p->fontheight;
+    if (p->fontwidth <= 8)
+       cdat = p->fontdata + (c & 0xff) * p->fontheight;
+    else
+       cdat = p->fontdata + ((c & 0xff) * p->fontheight << 1);
 
     fgx=attr_fgcol(p,c);
     bgx=attr_bgcol(p,c);
@@ -124,9 +122,28 @@ void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
     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;
+    switch (p->fontwidth) {
+    case 4:
+       for (rows = p->fontheight ; rows-- ; dest += bytes)
+           ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx;
+        break;
+    case 8:
+       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;
+        }
+        break;
+    case 12:
+    case 16:
+       for (rows = p->fontheight ; rows-- ; dest += bytes) {
+           ((u32 *)dest)[0]= (nibbletab_cfb8[*(u16 *)cdat >> 12] & eorx) ^ bgx;
+           ((u32 *)dest)[1]= (nibbletab_cfb8[(*(u16 *)cdat >> 8) & 0xf] & eorx) ^ bgx;
+           ((u32 *)dest)[2]= (nibbletab_cfb8[(*(u16 *)cdat >> 4) & 0xf] & eorx) ^ bgx;
+           if (p->fontwidth == 16)
+               ((u32 *)dest)[3]= (nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx;
+           cdat += 2;
+        }
+        break;
     }
 }
 
@@ -145,15 +162,46 @@ void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
     bgx |= (bgx << 8);
     bgx |= (bgx << 16);
     eorx = fgx ^ bgx;
-    while (count--) {
-       c = *s++;
-       cdat = p->fontdata + c * p->fontheight;
+    switch (p->fontwidth) {
+    case 4:
+       while (count--) {
+           c = *s++;
+           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;
+           for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes)
+               ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx;
+           dest0+=4;
+        }
+        break;
+    case 8:
+       while (count--) {
+           c = *s++;
+           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;
+        }
+        break;
+    case 12:
+    case 16:
+       while (count--) {
+           c = *s++;
+           cdat = p->fontdata + (c * p->fontheight << 1);
+
+           for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+               ((u32 *)dest)[0]= (nibbletab_cfb8[*(u16 *)cdat >> 12] & eorx) ^ bgx;
+               ((u32 *)dest)[1]= (nibbletab_cfb8[(*(u16 *)cdat >> 8) & 0xf] & eorx) ^ bgx;
+               ((u32 *)dest)[2]= (nibbletab_cfb8[(*(u16 *)cdat >> 4) & 0xf] & eorx) ^ bgx;
+               if (p->fontwidth == 16)
+                   ((u32 *)dest)[3]= (nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx;
+               cdat += 2;
+           }
+           dest0+=p->fontwidth;
+        }
+        break;
     }
 }
 
@@ -162,10 +210,15 @@ void fbcon_cfb8_revc(struct display *p, int xx, int yy)
     u8 *dest;
     int bytes=p->next_line, rows;
 
-    dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+    dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth;
     for (rows = p->fontheight ; rows-- ; dest += bytes) {
-       ((u32 *)dest)[0] ^= 0x0f0f0f0f;
-       ((u32 *)dest)[1] ^= 0x0f0f0f0f;
+       switch (p->fontwidth) {
+       case 16: ((u32 *)dest)[3] ^= 0x0f0f0f0f; /* FALL THROUGH */
+       case 12: ((u32 *)dest)[2] ^= 0x0f0f0f0f; /* FALL THROUGH */
+       case 8: ((u32 *)dest)[1] ^= 0x0f0f0f0f;  /* FALL THROUGH */
+       case 4: ((u32 *)dest)[0] ^= 0x0f0f0f0f;  /* FALL THROUGH */
+       default: break;
+       }
     }
 }
 
@@ -176,7 +229,8 @@ void fbcon_cfb8_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_cfb8 = {
     fbcon_cfb8_setup, fbcon_cfb8_bmove, fbcon_cfb8_clear, fbcon_cfb8_putc,
-    fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL
+    fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, 
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 
 
index d142fffc43b563be9ac6de6cf48d50ac3193ac1f..6f69dd31c1ddebbe40ce6a957169a732389bf432 100644 (file)
@@ -260,7 +260,7 @@ void fbcon_ilbm_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_ilbm = {
     fbcon_ilbm_setup, fbcon_ilbm_bmove, fbcon_ilbm_clear, fbcon_ilbm_putc,
-    fbcon_ilbm_putcs, fbcon_ilbm_revc, NULL
+    fbcon_ilbm_putcs, fbcon_ilbm_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index 670f91c3ad320dfb3019ffe90b6c02af583d4930..4fdbb1f1dd5e4447c87ca36fc05f9988e4229e3f 100644 (file)
@@ -374,7 +374,8 @@ void fbcon_iplan2p2_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_iplan2p2 = {
     fbcon_iplan2p2_setup, fbcon_iplan2p2_bmove, fbcon_iplan2p2_clear,
-    fbcon_iplan2p2_putc, fbcon_iplan2p2_putcs, fbcon_iplan2p2_revc, NULL
+    fbcon_iplan2p2_putc, fbcon_iplan2p2_putcs, fbcon_iplan2p2_revc, NULL,
+    NULL, FONTWIDTH(8)
 };
 
 
index 27916af9ff4a5b38ca4c307d516149ead5462983..b49dbee58087fb0908a6ffac51860ded1ea9794b 100644 (file)
@@ -394,7 +394,8 @@ void fbcon_iplan2p4_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_iplan2p4 = {
     fbcon_iplan2p4_setup, fbcon_iplan2p4_bmove, fbcon_iplan2p4_clear,
-    fbcon_iplan2p4_putc, fbcon_iplan2p4_putcs, fbcon_iplan2p4_revc, NULL
+    fbcon_iplan2p4_putc, fbcon_iplan2p4_putcs, fbcon_iplan2p4_revc, NULL,
+    NULL, FONTWIDTH(8)
 };
 
 
index cc1d04ed1f723c82bdbfd674cd5a93318da9431c..2acabe90aaf9ef98749d7b4dcc9b7b0b197e1d69 100644 (file)
@@ -431,7 +431,8 @@ void fbcon_iplan2p8_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_iplan2p8 = {
     fbcon_iplan2p8_setup, fbcon_iplan2p8_bmove, fbcon_iplan2p8_clear,
-    fbcon_iplan2p8_putc, fbcon_iplan2p8_putcs, fbcon_iplan2p8_revc, NULL
+    fbcon_iplan2p8_putc, fbcon_iplan2p8_putcs, fbcon_iplan2p8_revc, NULL,
+    NULL, FONTWIDTH(8)
 };
 
 
index bd1fcb7b7d479d9ed8067bbb6ffa0d528233a426..0e65bfb99dfe2188290ebf77210b2cdfe5dd7b7a 100644 (file)
@@ -497,7 +497,7 @@ static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y)
 
 struct display_switch fbcon_mac = {
     fbcon_mac_setup, fbcon_mac_bmove, fbcon_mac_clear, fbcon_mac_putc,
-    fbcon_mac_putcs, fbcon_mac_revc, NULL
+    fbcon_mac_putcs, fbcon_mac_revc, NULL, NULL, FONTWIDTHRANGE(1,8)
 };
 
 
index c53d82ae50a5aedfcc153102ff4f9040c5437e85..55177d85c00491d605f268c5b6e78d1ab0817e73 100644 (file)
@@ -153,7 +153,7 @@ void fbcon_mfb_revc(struct display *p, int xx, int yy)
 
 struct display_switch fbcon_mfb = {
     fbcon_mfb_setup, fbcon_mfb_bmove, fbcon_mfb_clear, fbcon_mfb_putc,
-    fbcon_mfb_putcs, fbcon_mfb_revc, NULL
+    fbcon_mfb_putcs, fbcon_mfb_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index 2e87377edebce4f8065bad3a1d7a322206f85352..09c0b5fcf372a3392f81f2bf9895d8dccacad0cd 100644 (file)
@@ -178,7 +178,7 @@ void fbcon_vga_revc(struct display *p, int x, int y)
 
 struct display_switch fbcon_vga = {
     fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
-    fbcon_vga_putcs, fbcon_vga_revc, NULL
+    fbcon_vga_putcs, fbcon_vga_revc, NULL, NULL, FONTWIDTH(8)
 };
 
 
index fdc5c92044c59168646f412c2a8c921bee789e1d..8ada8e7ea1cf1ac963f2fb0ba940823aeaa40db4 100644 (file)
@@ -25,7 +25,8 @@
  *                        Andreas Schwab
  *
  *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
- *  Smart redraw scrolling added by Jakub Jelinek (jj@ultra.linux.cz)
+ *  Smart redraw scrolling, arbitrary font width support added by 
+ *                         Jakub Jelinek (jj@ultra.linux.cz)
  *
  *
  *  The low level operations for the various display memory organizations are
@@ -132,13 +133,10 @@ static int vbl_cursor_cnt = 0;
 static int cursor_on = 0;
 static int cursor_blink_rate;
 
-static __inline__ int CURSOR_UNDRAWN(void)
+static __inline__ void CURSOR_UNDRAWN(void)
 {
-    int cursor_was_drawn;
     vbl_cursor_cnt = 0;
-    cursor_was_drawn = cursor_drawn;
     cursor_drawn = 0;
-    return cursor_was_drawn;
 }
 #endif
 
@@ -168,7 +166,7 @@ static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
 static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
                        int height, int width);
 static int fbcon_switch(struct vc_data *conp);
-static int fbcon_blank(int blank);
+static int fbcon_blank(struct vc_data *conp, int blank);
 static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
 static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data);
 static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
@@ -330,6 +328,9 @@ static void fbcon_init(struct vc_data *conp, int init)
     info = registered_fb[(int)con2fb_map[unit]];
 
     info->changevar = &fbcon_changevar;
+    conp->vc_display_fg = &info->display_fg;
+    if (!info->display_fg)
+        info->display_fg = conp;
     fb_display[unit] = *(info->disp);  /* copy from default */
     DPRINTK("mode:   %s\n",info->modename);
     DPRINTK("visual: %d\n",fb_display[unit].visual);
@@ -374,6 +375,20 @@ static __inline__ void updatescrollmode(struct display *p)
        p->scrollmode = SCROLL_YMOVE;
 }
 
+static void fbcon_font_widths(struct display *p)
+{
+    int i;
+    p->fontwidthlog = 0;
+    for (i = 2; i <= 6; i++)
+       if (p->fontwidth == (1 << i))
+           p->fontwidthlog = i;
+    p->fontheightlog = 0;
+    for (i = 2; i <= 6; i++)
+       if (p->fontheight == (1 << i))
+           p->fontheightlog = i;
+}
+
+#define fontwidthvalid(p,w) ((p)->dispsw->fontwidthmask & FONTWIDTH(w))
 
 static void fbcon_setup(int con, int init, int logo)
 {
@@ -381,6 +396,8 @@ static void fbcon_setup(int con, int init, int logo)
     struct vc_data *conp = p->conp;
     int nr_rows, nr_cols;
     int old_rows, old_cols;
+    unsigned short *save = NULL, *r, *q;
+    int logo_lines = 0;
     /* Only if not module */
     extern int initmem_freed;
     
@@ -391,10 +408,12 @@ static void fbcon_setup(int con, int init, int logo)
 
     if (!p->fb_info->fontname[0] ||
        !findsoftfont(p->fb_info->fontname, &p->fontwidth, &p->fontheight,
-                     &p->fontdata) || p->fontwidth != 8)
+                     &p->fontdata) || !fontwidthvalid(p,p->fontwidth))
        getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
                       &p->fontheight, &p->fontdata);
-    if (p->fontwidth != 8) {
+
+    fbcon_font_widths(p);
+    if (!fontwidthvalid(p,p->fontwidth)) {
 #ifdef CONFIG_MAC
        if (MACH_IS_MAC)
            /* ++Geert: hack to make 6x11 fonts work on mac */
@@ -403,44 +422,58 @@ static void fbcon_setup(int con, int init, int logo)
 #endif
        {
            /* ++Geert: changed from panic() to `correct and continue' */
-           printk(KERN_ERR "fbcon_setup: No support for fontwidth != 8");
+           printk(KERN_ERR "fbcon_setup: No support for fontwidth %d\n", p->fontwidth);
            p->dispsw = &fbcon_dummy;
        }
     }
+    if (p->dispsw->set_font)
+       p->dispsw->set_font(p, p->fontwidth, p->fontheight);
     updatescrollmode(p);
     
+    old_cols = conp->vc_cols;
+    old_rows = conp->vc_rows;
+    
+    nr_cols = p->var.xres/p->fontwidth;
+    nr_rows = p->var.yres/p->fontheight;
+    
     if (logo) {
        /* Need to make room for the logo */
-       int logo_lines = (LOGO_H + p->fontheight - 1) / p->fontheight;
-       unsigned short *q = (unsigned short *)(conp->vc_origin + 
-                               conp->vc_size_row * conp->vc_rows);
-       unsigned short *r;
+       int cnt;
+       int step;
     
-       for (r = q - logo_lines * conp->vc_cols; r < q; r++)
+       logo_lines = (LOGO_H + p->fontheight - 1) / p->fontheight;
+       q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
+       step = logo_lines * old_cols;
+       for (r = q - logo_lines * old_cols; r < q; r++)
            if (*r != conp->vc_video_erase_char)
                break;
+       if (r != q && nr_rows >= old_rows + logo_lines) {
+           save = kmalloc(logo_lines * nr_cols * 2, GFP_KERNEL);
+           if (save) {
+               int i = old_cols < nr_cols ? old_cols : nr_cols;
+               scr_memsetw(save, conp->vc_video_erase_char, logo_lines * nr_cols * 2);
+               r = q - step;
+               for (cnt = 0; cnt < logo_lines; cnt++, r += i)
+                       scr_memcpyw(save + cnt * nr_cols, r, 2 * i);
+               r = q;
+           }
+       }
        if (r == q) {
            /* We can scroll screen down */
-           int cnt;
-           int step = logo_lines * conp->vc_cols;
-
-           r = q - step - conp->vc_cols;
-           for (cnt = conp->vc_rows - logo_lines; cnt > 0; cnt--) {
+           r = q - step - old_cols;
+           for (cnt = old_rows - logo_lines; cnt > 0; cnt--) {
                scr_memcpyw(r + step, r, conp->vc_size_row);
-               r -= conp->vc_cols;
+               r -= old_cols;
+           }
+           if (!save) {
+               conp->vc_y += logo_lines;
+               conp->vc_pos += logo_lines * conp->vc_size_row;
            }
-           conp->vc_y += logo_lines;
-           conp->vc_pos += logo_lines * conp->vc_size_row;
        }
        scr_memsetw((unsigned short *)conp->vc_origin, conp->vc_video_erase_char, 
                conp->vc_size_row * logo_lines);
     }
     
-    old_cols = conp->vc_cols;
-    old_rows = conp->vc_rows;
-    
-    nr_cols = p->var.xres/p->fontwidth;
-    nr_rows = p->var.yres/p->fontheight;
     /*
      *  ++guenther: console.c:vc_allocate() relies on initializing
      *  vc_{cols,rows}, but we must not set those if we are only
@@ -465,8 +498,14 @@ static void fbcon_setup(int con, int init, int logo)
 
     if (!init) {
        vc_resize_con(nr_rows, nr_cols, con);
-       if (con == fg_console &&
-           old_rows == nr_rows && old_cols == nr_cols)
+       if (save) {
+           q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
+           scr_memcpyw(q, save, logo_lines * nr_cols * 2);
+           conp->vc_y += logo_lines;
+           conp->vc_pos += logo_lines * conp->vc_size_row;
+           kfree(save);
+       }
+       if (con == fg_console)
            update_screen(con); /* So that we set origin correctly */
     }
        
@@ -515,6 +554,7 @@ static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
     int unit = conp->vc_num;
     struct display *p = &fb_display[unit];
     u_int y_break;
+    int redraw_cursor = 0;
 
     if (!p->can_soft_blank && console_blanked)
        return;
@@ -523,8 +563,10 @@ static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
        return;
 
     if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
-       (sx <= p->cursor_x) && (p->cursor_x < sx+width))
+       (sx <= p->cursor_x) && (p->cursor_x < sx+width)) {
        CURSOR_UNDRAWN();
+       redraw_cursor = 1;
+    }
 
     /* Split blits that cross physical y_wrap boundary */
 
@@ -535,6 +577,9 @@ static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
        p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);
     } else
        p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);
+
+    if (redraw_cursor)
+       vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
 
 
@@ -542,14 +587,20 @@ static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos)
 {
     int unit = conp->vc_num;
     struct display *p = &fb_display[unit];
+    int redraw_cursor = 0;
 
     if (!p->can_soft_blank && console_blanked)
            return;
 
-    if ((p->cursor_x == xpos) && (p->cursor_y == ypos))
+    if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
            CURSOR_UNDRAWN();
+           redraw_cursor = 1;
+    }
 
     p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos);
+
+    if (redraw_cursor)
+           vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
 
 
@@ -558,14 +609,19 @@ static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count
 {
     int unit = conp->vc_num;
     struct display *p = &fb_display[unit];
+    int redraw_cursor = 0;
 
     if (!p->can_soft_blank && console_blanked)
            return;
 
     if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
-       (p->cursor_x < (xpos + count)))
+       (p->cursor_x < (xpos + count))) {
            CURSOR_UNDRAWN();
+           redraw_cursor = 1;
+    }
     p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos);
+    if (redraw_cursor)
+           vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
 
 
@@ -613,19 +669,16 @@ static void fbcon_cursor(struct vc_data *conp, int mode)
 static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
 {
     struct display *p;
-    static int _vbl_cursor_cnt = 1, _vbl_cursor_drawn;
 
-    if (!--_vbl_cursor_cnt) {
-       _vbl_cursor_cnt = cursor_blink_rate;
-       _vbl_cursor_drawn = !_vbl_cursor_drawn;
-    }
+    if (!cursor_on)
+       return;
 
-    if (cursor_on && vbl_cursor_cnt) {
-       if (cursor_drawn != _vbl_cursor_drawn) {
-           p = &fb_display[fg_console];
-           p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
-       }
-       cursor_drawn = _vbl_cursor_drawn;
+    if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
+       p = &fb_display[fg_console];
+       if (p->dispsw->revc)
+               p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
+       cursor_drawn ^= 1;
+       vbl_cursor_cnt = cursor_blink_rate;
     }
 }
 #endif
@@ -759,6 +812,53 @@ static void fbcon_redraw(struct vc_data *conp, struct display *p,
     }
 }
 
+/* This cannot be used together with ypan or ywrap */
+void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h, int w)
+{
+    if (sy != dy)
+       panic("fbcon_redraw_bmove width sy != dy");
+    /* h will be always 1, but it does not matter if we are more generic */
+    while (h-- > 0) {
+       struct vc_data *conp = p->conp;
+       unsigned short *d = (unsigned short *)
+               (conp->vc_origin + conp->vc_size_row * dy + dx * 2);
+       unsigned short *s = d + (dx - sx);
+       unsigned short *start = d;
+       unsigned short *ls = d;
+       unsigned short *le = d + w;
+       unsigned short c;
+       int x = dx;
+       unsigned short attr = 1;
+
+       do {
+           c = scr_readw(d);
+           if (attr != (c & 0xff00)) {
+               attr = c & 0xff00;
+               if (d > start) {
+                   p->dispsw->putcs(conp, p, start, d - start, dy, x);
+                   x += d - start;
+                   start = d;
+               }
+           }
+           if (s >= ls && s < le && c == scr_readw(s)) {
+               if (d > start) {
+                   p->dispsw->putcs(conp, p, start, d - start, dy, x);
+                   x += d - start + 1;
+                   start = d + 1;
+               } else {
+                   x++;
+                   start++;
+               }
+           }
+           s++;
+           d++;
+       } while (d < le);
+       if (d > start)
+           p->dispsw->putcs(conp, p, start, d - start, dy, x);
+       sy++;
+       dy++;
+    }
+}
 
 static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
                        int count)
@@ -1007,11 +1107,14 @@ static int fbcon_switch(struct vc_data *conp)
 }
 
 
-static int fbcon_blank(int blank)
+static int fbcon_blank(struct vc_data *conp, int blank)
 {
-    struct display *p = &fb_display[fg_console];
+    struct display *p = &fb_display[conp->vc_num];
     struct fb_info *info = p->fb_info;
 
+    if (blank < 0)     /* Entering graphics mode */
+       return 0;
+
     fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
 
     if (!p->can_soft_blank) {
@@ -1030,7 +1133,7 @@ static int fbcon_blank(int blank)
                             p->var.xres_virtual*p->var.yres_virtual*
                             p->var.bits_per_pixel>>3);
             } else
-                p->dispsw->clear(p->conp, p, 0, 0, p->conp->vc_rows, p->conp->vc_cols);
+                p->dispsw->clear(conp, p, 0, 0, p->conp->vc_rows, p->conp->vc_cols);
            return 0;
        } else {
            /* Tell console.c that it has to restore the screen itself */
@@ -1065,6 +1168,7 @@ static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
 
 
 #define REFCOUNT(fd)   (((int *)(fd))[-1])
+#define FNTSIZE(fd)    (((int *)(fd))[-2])
 
 static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
 {
@@ -1080,15 +1184,12 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
 
     if (w == 0) {
        /* engage predefined font, name in 'data' */
-       char name[MAX_FONT_NAME+1];
-
-       if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
-           return i;
-       copy_from_user( name, data, MAX_FONT_NAME );
-       name[sizeof(name)-1] = 0;
+       unsigned short width, height;
+       data[MAX_FONT_NAME] = 0;
 
-       if (!findsoftfont( name, &w, &h, (u8 **)&data ))
+       if (!findsoftfont( data, &width, &height, (u8 **)&data ))
            return -ENOENT;
+       w = width; h = height;
        userspace = 0;
     } else if (w == 1) {
        /* copy font from some other console in 'h'*/
@@ -1109,12 +1210,14 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
        p->fontdata = op->fontdata;
        w = p->fontwidth = op->fontwidth;
        h = p->fontheight = op->fontheight;
+       p->fontwidthlog = op->fontwidthlog;
+       p->fontheightlog = op->fontheightlog;
        if ((p->userfont = op->userfont))
            REFCOUNT(p->fontdata)++;    /* increment usage counter */
        goto activate;
     }
 
-    if (w != 8)
+    if (!fontwidthvalid(p,w))
        /* Currently only fontwidth == 8 supported */
        return -ENXIO;
 
@@ -1125,9 +1228,10 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
        old_data = p->fontdata;
 
     if (userspace) {
-       if (!(new_data = kmalloc( sizeof(int)+size, GFP_USER )))
+       if (!(new_data = kmalloc( 2*sizeof(int)+size, GFP_USER )))
            return -ENOMEM;
-       new_data += sizeof(int);
+       new_data += 2*sizeof(int);
+       FNTSIZE(new_data) = size;
        REFCOUNT(new_data) = 1; /* usage counter */
 
        for (i = 0; i < 256; i++)
@@ -1142,13 +1246,17 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
     }
     p->fontwidth = w;
     p->fontheight = h;
+    fbcon_font_widths(p);
 
 activate:
     if (resize) {
        /* reset wrap/pan */
        p->var.xoffset = p->var.yoffset = p->yscroll = 0;
-       /* Adjust the virtual screen-size to fontheight*rows */
-       p->var.yres_virtual = (p->var.yres/h)*h;
+       if (!p->dispsw->set_font || 
+           !p->dispsw->set_font(p, p->fontwidth, p->fontheight)) {
+           /* Adjust the virtual screen-size to fontheight*rows */
+           p->var.yres_virtual = (p->var.yres/h)*h;
+       }
        p->vrows = p->var.yres_virtual/h;
        updatescrollmode(p);
        vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
@@ -1156,7 +1264,7 @@ activate:
        update_screen( unit );
 
     if (old_data && (--REFCOUNT(old_data) == 0))
-       kfree( old_data - sizeof(int) );
+       kfree( old_data - 2*sizeof(int) );
 
     return 0;
 }
index 42473bd745647d79fd6cc1e5bdaf735b3a1fc94b..8ceeae5094a03d6ee5b59fca79efe6ed74eb9ad6 100644 (file)
@@ -30,8 +30,15 @@ struct display_switch {
                  int count, int yy, int xx);     
     void (*revc)(struct display *p, int xx, int yy);
     void (*cursor)(struct display *p, int mode, int xx, int yy);
+    int  (*set_font)(struct display *p, int width, int height);
+    unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
 }; 
 
+/* fontwidth w is supported by dispsw */
+#define FONTWIDTH(w)   (1 << ((w) - 1))
+/* fontwidths w1-w2 inclusive are supported by dispsw */
+#define FONTWIDTHRANGE(w1,w2)  (FONTWIDTH(w2+1) - FONTWIDTH(w1))
+
 
     /*
      *  Attribute Decoding
@@ -64,6 +71,8 @@ struct display_switch {
 #define SCROLL_YMOVE   (2)
 #define SCROLL_YREDRAW (3)
 
+extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
+
 
 /* ================================================================= */
 /*                      Utility Assembler Functions                  */
index b020fcdc9142ef4caa8f03f6d274a12e48cc6279..60cb2dc6727e9baded4e49a3eb71bfaab66665c3 100644 (file)
     *    Find a font with a specific name
     */
 
-extern int findsoftfont(char *name, int *width, int *height, u_char *data[]);
+extern int findsoftfont(char *name, unsigned short *width, unsigned short *height, u_char *data[]);
 
 
    /*
     *    Get the default font for a specific screen size
     */
 
-extern void getdefaultfont(int xres, int yres, char *name[], int *width,
-                           int *height, u_char *data[]);
+extern void getdefaultfont(int xres, int yres, char *name[], unsigned short *width,
+                           unsigned short *height, u_char *data[]);
 
 
 /* Max. length for the name of a predefined font */
diff --git a/drivers/video/font_sun12x22.c b/drivers/video/font_sun12x22.c
new file mode 100644 (file)
index 0000000..96e96d7
--- /dev/null
@@ -0,0 +1,6210 @@
+#define FONTDATAMAX 5632
+
+char fontname_sun12x22[] = "SUN12x22";
+
+int  fontheight_sun12x22 = 22;
+int  fontwidth_sun12x22  = 12;
+
+unsigned short fontdata_sun12x22[FONTDATAMAX] = {
+
+       /* 0 0x00 '^@' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 1 0x01 '^A' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 2 0x02 '^B' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 3 0x03 '^C' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 4 0x04 '^D' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 5 0x05 '^E' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 6 0x06 '^F' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 7 0x07 '^G' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 8 0x08 '^H' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 9 0x09 '^I' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 10 0x0a '^J' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 11 0x0b '^K' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 12 0x0c '^L' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 13 0x0d '^M' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 14 0x0e '^N' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 15 0x0f '^O' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 16 0x10 '^P' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 17 0x11 '^Q' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 18 0x12 '^R' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 19 0x13 '^S' */
+       0x0000, /* 000000000000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 20 0x14 '^T' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1ff0, /* 000111111111 */
+       0x3cc0, /* 001111001100 */
+       0x7cc0, /* 011111001100 */
+       0x7cc0, /* 011111001100 */
+       0x7cc0, /* 011111001100 */
+       0x3cc0, /* 001111001100 */
+       0x1cc0, /* 000111001100 */
+       0x0cc0, /* 000011001100 */
+       0x0cc0, /* 000011001100 */
+       0x0cc0, /* 000011001100 */
+       0x0cc0, /* 000011001100 */
+       0x0cc0, /* 000011001100 */
+       0x0cc0, /* 000011001100 */
+       0x1ce0, /* 000111001110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 21 0x15 '^U' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f00, /* 000111110000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x1f00, /* 000111110000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x1f00, /* 000111110000 */
+       0x0180, /* 000000011000 */
+       0x0180, /* 000000011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 22 0x16 '^V' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 23 0x17 '^W' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 24 0x18 '^X' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 25 0x19 '^Y' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 26 0x1a '^Z' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 27 0x1b '^[' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 28 0x1c '^\' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 29 0x1d '^]' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 30 0x1e '^^' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 31 0x1f '^_' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 32 0x20 ' ' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 33 0x21 '!' */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 34 0x22 '"' */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 35 0x23 '#' */
+       0x0000, /* 000000000000 */
+       0x0330, /* 000000110011 */
+       0x0330, /* 000000110011 */
+       0x0330, /* 000000110011 */
+       0x0660, /* 000001100110 */
+       0x1ff0, /* 000111111111 */
+       0x1ff0, /* 000111111111 */
+       0x0cc0, /* 000011001100 */
+       0x0cc0, /* 000011001100 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x7fc0, /* 011111111100 */
+       0x7fc0, /* 011111111100 */
+       0x3300, /* 001100110000 */
+       0x6600, /* 011001100000 */
+       0x6600, /* 011001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 36 0x24 '$' */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x3fc0, /* 001111111100 */
+       0x66e0, /* 011001101110 */
+       0x6660, /* 011001100110 */
+       0x6600, /* 011001100000 */
+       0x3e00, /* 001111100000 */
+       0x1f80, /* 000111111000 */
+       0x07c0, /* 000001111100 */
+       0x0660, /* 000001100110 */
+       0x0660, /* 000001100110 */
+       0x6660, /* 011001100110 */
+       0x7fc0, /* 011111111100 */
+       0x3f80, /* 001111111000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 37 0x25 '%' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x38c0, /* 001110001100 */
+       0x4cc0, /* 010011001100 */
+       0x4580, /* 010001011000 */
+       0x6580, /* 011001011000 */
+       0x3b00, /* 001110110000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x0dc0, /* 000011011100 */
+       0x1a60, /* 000110100110 */
+       0x1a20, /* 000110100010 */
+       0x3320, /* 001100110010 */
+       0x31c0, /* 001100011100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 38 0x26 '&' */
+       0x0000, /* 000000000000 */
+       0x0700, /* 000001110000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x18c0, /* 000110001100 */
+       0x18c0, /* 000110001100 */
+       0x0f80, /* 000011111000 */
+       0x1e00, /* 000111100000 */
+       0x3e00, /* 001111100000 */
+       0x7700, /* 011101110000 */
+       0x6360, /* 011000110110 */
+       0x61e0, /* 011000011110 */
+       0x61c0, /* 011000011100 */
+       0x6180, /* 011000011000 */
+       0x3fe0, /* 001111111110 */
+       0x1e60, /* 000111100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 39 0x27 ''' */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x1000, /* 000100000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 40 0x28 '(' */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0180, /* 000000011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 41 0x29 ')' */
+       0x0000, /* 000000000000 */
+       0x1800, /* 000110000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 42 0x2a '*' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x0600, /* 000001100000 */
+       0x6660, /* 011001100110 */
+       0x76e0, /* 011101101110 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x76e0, /* 011101101110 */
+       0x6660, /* 011001100110 */
+       0x0600, /* 000001100000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 43 0x2b '+' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 44 0x2c ',' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x1000, /* 000100000000 */
+       0x0000, /* 000000000000 */
+
+       /* 45 0x2d '-' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 46 0x2e '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0c00, /* 000011000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 47 0x2f '/' */
+       0x0000, /* 000000000000 */
+       0x0060, /* 000000000110 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0180, /* 000000011000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x6000, /* 011000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 48 0x30 '0' */
+       0x0000, /* 000000000000 */
+       0x0700, /* 000001110000 */
+       0x0f80, /* 000011111000 */
+       0x1180, /* 000100011000 */
+       0x10c0, /* 000100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x3080, /* 001100001000 */
+       0x1880, /* 000110001000 */
+       0x1f00, /* 000111110000 */
+       0x0e00, /* 000011100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 49 0x31 '1' */
+       0x0000, /* 000000000000 */
+       0x0200, /* 000000100000 */
+       0x0600, /* 000001100000 */
+       0x0e00, /* 000011100000 */
+       0x1e00, /* 000111100000 */
+       0x3600, /* 001101100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 50 0x32 '2' */
+       0x0000, /* 000000000000 */
+       0x1f00, /* 000111110000 */
+       0x3f80, /* 001111111000 */
+       0x61c0, /* 011000011100 */
+       0x40c0, /* 010000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x3020, /* 001100000010 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 51 0x33 '3' */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x1fc0, /* 000111111100 */
+       0x20e0, /* 001000001110 */
+       0x4060, /* 010000000110 */
+       0x0060, /* 000000000110 */
+       0x00e0, /* 000000001110 */
+       0x07c0, /* 000001111100 */
+       0x0fc0, /* 000011111100 */
+       0x00e0, /* 000000001110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x4060, /* 010000000110 */
+       0x6040, /* 011000000100 */
+       0x3f80, /* 001111111000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 52 0x34 '4' */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0380, /* 000000111000 */
+       0x0380, /* 000000111000 */
+       0x0580, /* 000001011000 */
+       0x0580, /* 000001011000 */
+       0x0980, /* 000010011000 */
+       0x0980, /* 000010011000 */
+       0x1180, /* 000100011000 */
+       0x1180, /* 000100011000 */
+       0x2180, /* 001000011000 */
+       0x3fe0, /* 001111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0180, /* 000000011000 */
+       0x0180, /* 000000011000 */
+       0x0180, /* 000000011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 53 0x35 '5' */
+       0x0000, /* 000000000000 */
+       0x0fc0, /* 000011111100 */
+       0x0fc0, /* 000011111100 */
+       0x1000, /* 000100000000 */
+       0x1000, /* 000100000000 */
+       0x2000, /* 001000000000 */
+       0x3f80, /* 001111111000 */
+       0x31c0, /* 001100011100 */
+       0x00e0, /* 000000001110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x4060, /* 010000000110 */
+       0x6060, /* 011000000110 */
+       0x30c0, /* 001100001100 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 54 0x36 '6' */
+       0x0000, /* 000000000000 */
+       0x0700, /* 000001110000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x6000, /* 011000000000 */
+       0x6780, /* 011001111000 */
+       0x6fc0, /* 011011111100 */
+       0x70e0, /* 011100001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7040, /* 011100000100 */
+       0x3f80, /* 001111111000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 55 0x37 '7' */
+       0x0000, /* 000000000000 */
+       0x1fe0, /* 000111111110 */
+       0x3fe0, /* 001111111110 */
+       0x6040, /* 011000000100 */
+       0x0040, /* 000000000100 */
+       0x00c0, /* 000000001100 */
+       0x0080, /* 000000001000 */
+       0x0080, /* 000000001000 */
+       0x0180, /* 000000011000 */
+       0x0100, /* 000000010000 */
+       0x0100, /* 000000010000 */
+       0x0300, /* 000000110000 */
+       0x0200, /* 000000100000 */
+       0x0200, /* 000000100000 */
+       0x0600, /* 000001100000 */
+       0x0400, /* 000001000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 56 0x38 '8' */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x1180, /* 000100011000 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x1880, /* 000110001000 */
+       0x0d00, /* 000011010000 */
+       0x0600, /* 000001100000 */
+       0x0b00, /* 000010110000 */
+       0x1180, /* 000100011000 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x1880, /* 000110001000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 57 0x39 '9' */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x70e0, /* 011100001110 */
+       0x3f60, /* 001111110110 */
+       0x1e60, /* 000111100110 */
+       0x0060, /* 000000000110 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0180, /* 000000011000 */
+       0x0700, /* 000001110000 */
+       0x3c00, /* 001111000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 58 0x3a ':' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0c00, /* 000011000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0c00, /* 000011000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 59 0x3b ';' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0c00, /* 000011000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x1000, /* 000100000000 */
+       0x0000, /* 000000000000 */
+
+       /* 60 0x3c '<' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0060, /* 000000000110 */
+       0x01c0, /* 000000011100 */
+       0x0700, /* 000001110000 */
+       0x1c00, /* 000111000000 */
+       0x7000, /* 011100000000 */
+       0x7000, /* 011100000000 */
+       0x1c00, /* 000111000000 */
+       0x0700, /* 000001110000 */
+       0x01c0, /* 000000011100 */
+       0x0060, /* 000000000110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 61 0x3d '=' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 62 0x3e '>' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x6000, /* 011000000000 */
+       0x3800, /* 001110000000 */
+       0x0e00, /* 000011100000 */
+       0x0380, /* 000000111000 */
+       0x00e0, /* 000000001110 */
+       0x00e0, /* 000000001110 */
+       0x0380, /* 000000111000 */
+       0x0e00, /* 000011100000 */
+       0x3800, /* 001110000000 */
+       0x6000, /* 011000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 63 0x3f '?' */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x1f80, /* 000111111000 */
+       0x39c0, /* 001110011100 */
+       0x20c0, /* 001000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 64 0x40 '@' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x3fc0, /* 001111111100 */
+       0x3060, /* 001100000110 */
+       0x6060, /* 011000000110 */
+       0x6720, /* 011001110010 */
+       0x6fa0, /* 011011111010 */
+       0x6ca0, /* 011011001010 */
+       0x6ca0, /* 011011001010 */
+       0x67e0, /* 011001111110 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x3fe0, /* 001111111110 */
+       0x0fe0, /* 000011111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 65 0x41 'A' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0b00, /* 000010110000 */
+       0x0b00, /* 000010110000 */
+       0x0900, /* 000010010000 */
+       0x1180, /* 000100011000 */
+       0x1180, /* 000100011000 */
+       0x1080, /* 000100001000 */
+       0x3fc0, /* 001111111100 */
+       0x20c0, /* 001000001100 */
+       0x2040, /* 001000000100 */
+       0x4060, /* 010000000110 */
+       0x4060, /* 010000000110 */
+       0xe0f0, /* 111000001111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 66 0x42 'B' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xff00, /* 111111110000 */
+       0x6080, /* 011000001000 */
+       0x60c0, /* 011000001100 */
+       0x60c0, /* 011000001100 */
+       0x60c0, /* 011000001100 */
+       0x6180, /* 011000011000 */
+       0x7f80, /* 011111111000 */
+       0x60c0, /* 011000001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x60c0, /* 011000001100 */
+       0xff80, /* 111111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 67 0x43 'C' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0fc0, /* 000011111100 */
+       0x1060, /* 000100000110 */
+       0x2020, /* 001000000010 */
+       0x2000, /* 001000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x2000, /* 001000000000 */
+       0x3020, /* 001100000010 */
+       0x1840, /* 000110000100 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 68 0x44 'D' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xff00, /* 111111110000 */
+       0x61c0, /* 011000011100 */
+       0x60c0, /* 011000001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6040, /* 011000000100 */
+       0x6180, /* 011000011000 */
+       0xfe00, /* 111111100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 69 0x45 'E' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fc0, /* 011111111100 */
+       0x3040, /* 001100000100 */
+       0x3040, /* 001100000100 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3080, /* 001100001000 */
+       0x3f80, /* 001111111000 */
+       0x3080, /* 001100001000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3020, /* 001100000010 */
+       0x3020, /* 001100000010 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 70 0x46 'F' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fc0, /* 011111111100 */
+       0x3040, /* 001100000100 */
+       0x3040, /* 001100000100 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3080, /* 001100001000 */
+       0x3f80, /* 001111111000 */
+       0x3080, /* 001100001000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x7800, /* 011110000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 71 0x47 'G' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0fc0, /* 000011111100 */
+       0x1060, /* 000100000110 */
+       0x2020, /* 001000000010 */
+       0x2000, /* 001000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x61f0, /* 011000011111 */
+       0x6060, /* 011000000110 */
+       0x2060, /* 001000000110 */
+       0x3060, /* 001100000110 */
+       0x1860, /* 000110000110 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 72 0x48 'H' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf0f0, /* 111100001111 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7fe0, /* 011111111110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0xf0f0, /* 111100001111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 73 0x49 'I' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f80, /* 000111111000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 74 0x4a 'J' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f80, /* 000111111000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0400, /* 000001000000 */
+       0x3800, /* 001110000000 */
+       0x3000, /* 001100000000 */
+       0x0000, /* 000000000000 */
+
+       /* 75 0x4b 'K' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf0e0, /* 111100001110 */
+       0x6180, /* 011000011000 */
+       0x6300, /* 011000110000 */
+       0x6600, /* 011001100000 */
+       0x6c00, /* 011011000000 */
+       0x7800, /* 011110000000 */
+       0x7800, /* 011110000000 */
+       0x7c00, /* 011111000000 */
+       0x6e00, /* 011011100000 */
+       0x6700, /* 011001110000 */
+       0x6380, /* 011000111000 */
+       0x61c0, /* 011000011100 */
+       0x60e0, /* 011000001110 */
+       0xf070, /* 111100000111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 76 0x4c 'L' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7800, /* 011110000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3020, /* 001100000010 */
+       0x3020, /* 001100000010 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 77 0x4d 'M' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xe070, /* 111000000111 */
+       0x60e0, /* 011000001110 */
+       0x70e0, /* 011100001110 */
+       0x70e0, /* 011100001110 */
+       0x70e0, /* 011100001110 */
+       0x5960, /* 010110010110 */
+       0x5960, /* 010110010110 */
+       0x5960, /* 010110010110 */
+       0x4d60, /* 010011010110 */
+       0x4e60, /* 010011100110 */
+       0x4e60, /* 010011100110 */
+       0x4460, /* 010001000110 */
+       0x4460, /* 010001000110 */
+       0xe4f0, /* 111001001111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 78 0x4e 'N' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xc070, /* 110000000111 */
+       0x6020, /* 011000000010 */
+       0x7020, /* 011100000010 */
+       0x7820, /* 011110000010 */
+       0x5820, /* 010110000010 */
+       0x4c20, /* 010011000010 */
+       0x4620, /* 010001100010 */
+       0x4720, /* 010001110010 */
+       0x4320, /* 010000110010 */
+       0x41a0, /* 010000011010 */
+       0x40e0, /* 010000001110 */
+       0x40e0, /* 010000001110 */
+       0x4060, /* 010000000110 */
+       0xe030, /* 111000000011 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 79 0x4f 'O' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x11c0, /* 000100011100 */
+       0x20c0, /* 001000001100 */
+       0x2060, /* 001000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x2040, /* 001000000100 */
+       0x3040, /* 001100000100 */
+       0x1880, /* 000110001000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 80 0x50 'P' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7f80, /* 011111111000 */
+       0x30c0, /* 001100001100 */
+       0x3060, /* 001100000110 */
+       0x3060, /* 001100000110 */
+       0x3060, /* 001100000110 */
+       0x30c0, /* 001100001100 */
+       0x3780, /* 001101111000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x7800, /* 011110000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 81 0x51 'Q' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x11c0, /* 000100011100 */
+       0x20c0, /* 001000001100 */
+       0x2060, /* 001000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x3040, /* 001100000100 */
+       0x3840, /* 001110000100 */
+       0x1f80, /* 000111111000 */
+       0x0e00, /* 000011100000 */
+       0x1f00, /* 000111110000 */
+       0x2390, /* 001000111001 */
+       0x01e0, /* 000000011110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 82 0x52 'R' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xff00, /* 111111110000 */
+       0x6180, /* 011000011000 */
+       0x60c0, /* 011000001100 */
+       0x60c0, /* 011000001100 */
+       0x60c0, /* 011000001100 */
+       0x6080, /* 011000001000 */
+       0x7f00, /* 011111110000 */
+       0x7c00, /* 011111000000 */
+       0x6e00, /* 011011100000 */
+       0x6700, /* 011001110000 */
+       0x6380, /* 011000111000 */
+       0x61c0, /* 011000011100 */
+       0x60e0, /* 011000001110 */
+       0xf070, /* 111100000111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 83 0x53 'S' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1fe0, /* 000111111110 */
+       0x3060, /* 001100000110 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x7000, /* 011100000000 */
+       0x3c00, /* 001111000000 */
+       0x1e00, /* 000111100000 */
+       0x0780, /* 000001111000 */
+       0x01c0, /* 000000011100 */
+       0x00e0, /* 000000001110 */
+       0x4060, /* 010000000110 */
+       0x4060, /* 010000000110 */
+       0x60c0, /* 011000001100 */
+       0x7f80, /* 011111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 84 0x54 'T' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x4620, /* 010001100010 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 85 0x55 'U' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf070, /* 111100000111 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x7040, /* 011100000100 */
+       0x3fc0, /* 001111111100 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 86 0x56 'V' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xe0e0, /* 111000001110 */
+       0x6040, /* 011000000100 */
+       0x3080, /* 001100001000 */
+       0x3080, /* 001100001000 */
+       0x3080, /* 001100001000 */
+       0x1900, /* 000110010000 */
+       0x1900, /* 000110010000 */
+       0x1900, /* 000110010000 */
+       0x0a00, /* 000010100000 */
+       0x0e00, /* 000011100000 */
+       0x0e00, /* 000011100000 */
+       0x0400, /* 000001000000 */
+       0x0400, /* 000001000000 */
+       0x0400, /* 000001000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 87 0x57 'W' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfef0, /* 111111101111 */
+       0x6620, /* 011001100010 */
+       0x6620, /* 011001100010 */
+       0x6620, /* 011001100010 */
+       0x7620, /* 011101100010 */
+       0x7740, /* 011101110100 */
+       0x3340, /* 001100110100 */
+       0x3740, /* 001101110100 */
+       0x3bc0, /* 001110111100 */
+       0x3b80, /* 001110111000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 88 0x58 'X' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf070, /* 111100000111 */
+       0x6020, /* 011000000010 */
+       0x3040, /* 001100000100 */
+       0x3880, /* 001110001000 */
+       0x1880, /* 000110001000 */
+       0x0d00, /* 000011010000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0b00, /* 000010110000 */
+       0x1180, /* 000100011000 */
+       0x11c0, /* 000100011100 */
+       0x20c0, /* 001000001100 */
+       0x4060, /* 010000000110 */
+       0xe0f0, /* 111000001111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 89 0x59 'Y' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf070, /* 111100000111 */
+       0x6020, /* 011000000010 */
+       0x3040, /* 001100000100 */
+       0x1880, /* 000110001000 */
+       0x1880, /* 000110001000 */
+       0x0d00, /* 000011010000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 90 0x5a 'Z' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fe0, /* 001111111110 */
+       0x20c0, /* 001000001100 */
+       0x00c0, /* 000000001100 */
+       0x0180, /* 000000011000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x1820, /* 000110000010 */
+       0x3fe0, /* 001111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 91 0x5b '[' */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x0f80, /* 000011111000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0f80, /* 000011111000 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 92 0x5c '\' */
+       0x0000, /* 000000000000 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0180, /* 000000011000 */
+       0x0180, /* 000000011000 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0060, /* 000000000110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 93 0x5d ']' */
+       0x0000, /* 000000000000 */
+       0x1f00, /* 000111110000 */
+       0x1f00, /* 000111110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x1f00, /* 000111110000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 94 0x5e '^' */
+       0x0000, /* 000000000000 */
+       0x0400, /* 000001000000 */
+       0x0e00, /* 000011100000 */
+       0x1b00, /* 000110110000 */
+       0x3180, /* 001100011000 */
+       0x60c0, /* 011000001100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 95 0x5f '_' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 96 0x60 '`' */
+       0x0000, /* 000000000000 */
+       0x0100, /* 000000010000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0780, /* 000001111000 */
+       0x0780, /* 000001111000 */
+       0x0300, /* 000000110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 97 0x61 'a' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x10c0, /* 000100001100 */
+       0x03c0, /* 000000111100 */
+       0x1cc0, /* 000111001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1ee0, /* 000111101110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 98 0x62 'b' */
+       0x0000, /* 000000000000 */
+       0x2000, /* 001000000000 */
+       0x6000, /* 011000000000 */
+       0xe000, /* 111000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6780, /* 011001111000 */
+       0x6fc0, /* 011011111100 */
+       0x70e0, /* 011100001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7060, /* 011100000110 */
+       0x78c0, /* 011110001100 */
+       0x4f80, /* 010011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 99 0x63 'c' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f80, /* 000111111000 */
+       0x31c0, /* 001100011100 */
+       0x20c0, /* 001000001100 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x7040, /* 011100000100 */
+       0x30c0, /* 001100001100 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 100 0x64 'd' */
+       0x0000, /* 000000000000 */
+       0x0060, /* 000000000110 */
+       0x00e0, /* 000000001110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x0f60, /* 000011110110 */
+       0x31e0, /* 001100011110 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x70e0, /* 011100001110 */
+       0x3960, /* 001110010110 */
+       0x1e70, /* 000111100111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 101 0x65 'e' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x30c0, /* 001100001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7fe0, /* 011111111110 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x1860, /* 000110000110 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 102 0x66 'f' */
+       0x0000, /* 000000000000 */
+       0x0380, /* 000000111000 */
+       0x04c0, /* 000001001100 */
+       0x04c0, /* 000001001100 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x3f80, /* 001111111000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x1e00, /* 000111100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 103 0x67 'g' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f20, /* 000111110010 */
+       0x31e0, /* 001100011110 */
+       0x60c0, /* 011000001100 */
+       0x60c0, /* 011000001100 */
+       0x60c0, /* 011000001100 */
+       0x3180, /* 001100011000 */
+       0x3f00, /* 001111110000 */
+       0x6000, /* 011000000000 */
+       0x7fc0, /* 011111111100 */
+       0x3fe0, /* 001111111110 */
+       0x2060, /* 001000000110 */
+       0x4020, /* 010000000010 */
+       0x4020, /* 010000000010 */
+       0x7fc0, /* 011111111100 */
+       0x3f80, /* 001111111000 */
+       0x0000, /* 000000000000 */
+
+       /* 104 0x68 'h' */
+       0x0000, /* 000000000000 */
+       0x1000, /* 000100000000 */
+       0x3000, /* 001100000000 */
+       0x7000, /* 011100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3780, /* 001101111000 */
+       0x39c0, /* 001110011100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x79e0, /* 011110011110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 105 0x69 'i' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 106 0x6a 'j' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x03c0, /* 000000111100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x20c0, /* 001000001100 */
+       0x30c0, /* 001100001100 */
+       0x3880, /* 001110001000 */
+       0x1f00, /* 000111110000 */
+       0x0e00, /* 000011100000 */
+       0x0000, /* 000000000000 */
+
+       /* 107 0x6b 'k' */
+       0x0000, /* 000000000000 */
+       0x6000, /* 011000000000 */
+       0xe000, /* 111000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x61c0, /* 011000011100 */
+       0x6300, /* 011000110000 */
+       0x6600, /* 011001100000 */
+       0x7c00, /* 011111000000 */
+       0x7800, /* 011110000000 */
+       0x7c00, /* 011111000000 */
+       0x6e00, /* 011011100000 */
+       0x6700, /* 011001110000 */
+       0x6380, /* 011000111000 */
+       0xf1e0, /* 111100011110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 108 0x6c 'l' */
+       0x0000, /* 000000000000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 109 0x6d 'm' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xddc0, /* 110111011100 */
+       0x6ee0, /* 011011101110 */
+       0x6660, /* 011001100110 */
+       0x6660, /* 011001100110 */
+       0x6660, /* 011001100110 */
+       0x6660, /* 011001100110 */
+       0x6660, /* 011001100110 */
+       0x6660, /* 011001100110 */
+       0x6660, /* 011001100110 */
+       0xef70, /* 111011110111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 110 0x6e 'n' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x2780, /* 001001111000 */
+       0x79c0, /* 011110011100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x79e0, /* 011110011110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 111 0x6f 'o' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7040, /* 011100000100 */
+       0x3880, /* 001110001000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 112 0x70 'p' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xef80, /* 111011111000 */
+       0x71c0, /* 011100011100 */
+       0x60e0, /* 011000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6040, /* 011000000100 */
+       0x7080, /* 011100001000 */
+       0x7f00, /* 011111110000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0xf000, /* 111100000000 */
+       0x0000, /* 000000000000 */
+
+       /* 113 0x71 'q' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f20, /* 000011110010 */
+       0x11e0, /* 000100011110 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7060, /* 011100000110 */
+       0x38e0, /* 001110001110 */
+       0x1fe0, /* 000111111110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x0060, /* 000000000110 */
+       0x00f0, /* 000000001111 */
+       0x0000, /* 000000000000 */
+
+       /* 114 0x72 'r' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7380, /* 011100111000 */
+       0x34c0, /* 001101001100 */
+       0x38c0, /* 001110001100 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x7800, /* 011110000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 115 0x73 's' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1fc0, /* 000111111100 */
+       0x30c0, /* 001100001100 */
+       0x3040, /* 001100000100 */
+       0x3800, /* 001110000000 */
+       0x1e00, /* 000111100000 */
+       0x0780, /* 000001111000 */
+       0x01c0, /* 000000011100 */
+       0x20c0, /* 001000001100 */
+       0x30c0, /* 001100001100 */
+       0x3f80, /* 001111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 116 0x74 't' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0400, /* 000001000000 */
+       0x0400, /* 000001000000 */
+       0x0c00, /* 000011000000 */
+       0x7fc0, /* 011111111100 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c00, /* 000011000000 */
+       0x0c20, /* 000011000010 */
+       0x0e40, /* 000011100100 */
+       0x0780, /* 000001111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 117 0x75 'u' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x79e0, /* 011110011110 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1e60, /* 000111100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 118 0x76 'v' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf070, /* 111100000111 */
+       0x6020, /* 011000000010 */
+       0x3040, /* 001100000100 */
+       0x3040, /* 001100000100 */
+       0x1880, /* 000110001000 */
+       0x1880, /* 000110001000 */
+       0x0d00, /* 000011010000 */
+       0x0d00, /* 000011010000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 119 0x77 'w' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xff70, /* 111111110111 */
+       0x6620, /* 011001100010 */
+       0x6620, /* 011001100010 */
+       0x6620, /* 011001100010 */
+       0x3740, /* 001101110100 */
+       0x3b40, /* 001110110100 */
+       0x3b40, /* 001110110100 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 120 0x78 'x' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf8f0, /* 111110001111 */
+       0x7040, /* 011100000100 */
+       0x3880, /* 001110001000 */
+       0x1d00, /* 000111010000 */
+       0x0e00, /* 000011100000 */
+       0x0700, /* 000001110000 */
+       0x0b80, /* 000010111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0xf1f0, /* 111100011111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 121 0x79 'y' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf0f0, /* 111100001111 */
+       0x6020, /* 011000000010 */
+       0x3040, /* 001100000100 */
+       0x3040, /* 001100000100 */
+       0x1880, /* 000110001000 */
+       0x1880, /* 000110001000 */
+       0x0d00, /* 000011010000 */
+       0x0d00, /* 000011010000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0400, /* 000001000000 */
+       0x0c00, /* 000011000000 */
+       0x0800, /* 000010000000 */
+       0x7800, /* 011110000000 */
+       0x7000, /* 011100000000 */
+       0x0000, /* 000000000000 */
+
+       /* 122 0x7a 'z' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x60e0, /* 011000001110 */
+       0x41c0, /* 010000011100 */
+       0x0380, /* 000000111000 */
+       0x0700, /* 000001110000 */
+       0x0e00, /* 000011100000 */
+       0x1c00, /* 000111000000 */
+       0x3820, /* 001110000010 */
+       0x7060, /* 011100000110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 123 0x7b '{' */
+       0x0000, /* 000000000000 */
+       0x0380, /* 000000111000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x3800, /* 001110000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0380, /* 000000111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 124 0x7c '|' */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+
+       /* 125 0x7d '}' */
+       0x0000, /* 000000000000 */
+       0x1c00, /* 000111000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x01c0, /* 000000011100 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1c00, /* 000111000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 126 0x7e '~' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1c20, /* 000111000010 */
+       0x3e60, /* 001111100110 */
+       0x67c0, /* 011001111100 */
+       0x4380, /* 010000111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 127 0x7f '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 128 0x80 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0fc0, /* 000011111100 */
+       0x1060, /* 000100000110 */
+       0x2020, /* 001000000010 */
+       0x2000, /* 001000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x2000, /* 001000000000 */
+       0x3020, /* 001100000010 */
+       0x1840, /* 000110000100 */
+       0x0f80, /* 000011111000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0180, /* 000000011000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 129 0x81 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x79e0, /* 011110011110 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1e60, /* 000111100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 130 0x82 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x30c0, /* 001100001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7fe0, /* 011111111110 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x1860, /* 000110000110 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 131 0x83 '.' */
+       0x0000, /* 000000000000 */
+       0x0200, /* 000000100000 */
+       0x0700, /* 000001110000 */
+       0x0d80, /* 000011011000 */
+       0x18c0, /* 000110001100 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x10c0, /* 000100001100 */
+       0x03c0, /* 000000111100 */
+       0x1cc0, /* 000111001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1ee0, /* 000111101110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 132 0x84 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x10c0, /* 000100001100 */
+       0x03c0, /* 000000111100 */
+       0x1cc0, /* 000111001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1ee0, /* 000111101110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 133 0x85 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x10c0, /* 000100001100 */
+       0x03c0, /* 000000111100 */
+       0x1cc0, /* 000111001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1ee0, /* 000111101110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 134 0x86 '.' */
+       0x0000, /* 000000000000 */
+       0x0700, /* 000001110000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0700, /* 000001110000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x10c0, /* 000100001100 */
+       0x03c0, /* 000000111100 */
+       0x1cc0, /* 000111001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1ee0, /* 000111101110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 135 0x87 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f80, /* 000111111000 */
+       0x31c0, /* 001100011100 */
+       0x20c0, /* 001000001100 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x7040, /* 011100000100 */
+       0x30c0, /* 001100001100 */
+       0x1f80, /* 000111111000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0180, /* 000000011000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 136 0x88 '.' */
+       0x0000, /* 000000000000 */
+       0x0200, /* 000000100000 */
+       0x0700, /* 000001110000 */
+       0x0d80, /* 000011011000 */
+       0x18c0, /* 000110001100 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x30c0, /* 001100001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7fe0, /* 011111111110 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x1860, /* 000110000110 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 137 0x89 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x30c0, /* 001100001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7fe0, /* 011111111110 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x1860, /* 000110000110 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 138 0x8a '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x30c0, /* 001100001100 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7fe0, /* 011111111110 */
+       0x6000, /* 011000000000 */
+       0x6000, /* 011000000000 */
+       0x3000, /* 001100000000 */
+       0x1860, /* 000110000110 */
+       0x0f80, /* 000011111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 139 0x8b '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 140 0x8c '.' */
+       0x0000, /* 000000000000 */
+       0x0400, /* 000001000000 */
+       0x0e00, /* 000011100000 */
+       0x1b00, /* 000110110000 */
+       0x3180, /* 001100011000 */
+       0x0000, /* 000000000000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 141 0x8d '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1800, /* 000110000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 142 0x8e '.' */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0400, /* 000001000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0b00, /* 000010110000 */
+       0x0b00, /* 000010110000 */
+       0x1980, /* 000110011000 */
+       0x1180, /* 000100011000 */
+       0x3fc0, /* 001111111100 */
+       0x20c0, /* 001000001100 */
+       0x6060, /* 011000000110 */
+       0x4060, /* 010000000110 */
+       0xe0f0, /* 111000001111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 143 0x8f '.' */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x1980, /* 000110011000 */
+       0x0f00, /* 000011110000 */
+       0x0400, /* 000001000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0b00, /* 000010110000 */
+       0x0b00, /* 000010110000 */
+       0x1980, /* 000110011000 */
+       0x1180, /* 000100011000 */
+       0x3fc0, /* 001111111100 */
+       0x20c0, /* 001000001100 */
+       0x6060, /* 011000000110 */
+       0x4060, /* 010000000110 */
+       0xe0f0, /* 111000001111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 144 0x90 '.' */
+       0x0000, /* 000000000000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0800, /* 000010000000 */
+       0x7fe0, /* 011111111110 */
+       0x3020, /* 001100000010 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3080, /* 001100001000 */
+       0x3f80, /* 001111111000 */
+       0x3080, /* 001100001000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3020, /* 001100000010 */
+       0x3020, /* 001100000010 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 145 0x91 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3de0, /* 001111011110 */
+       0x6630, /* 011001100011 */
+       0x4630, /* 010001100011 */
+       0x0630, /* 000001100011 */
+       0x3ff0, /* 001111111111 */
+       0x6600, /* 011001100000 */
+       0xc600, /* 110001100000 */
+       0xc600, /* 110001100000 */
+       0xe730, /* 111001110011 */
+       0x7de0, /* 011111011110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 146 0x92 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x03f0, /* 000000111111 */
+       0x0710, /* 000001110001 */
+       0x0710, /* 000001110001 */
+       0x0b00, /* 000010110000 */
+       0x0b00, /* 000010110000 */
+       0x0b20, /* 000010110010 */
+       0x13e0, /* 000100111110 */
+       0x1320, /* 000100110010 */
+       0x3f00, /* 001111110000 */
+       0x2300, /* 001000110000 */
+       0x2300, /* 001000110000 */
+       0x4310, /* 010000110001 */
+       0x4310, /* 010000110001 */
+       0xe7f0, /* 111001111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 147 0x93 '.' */
+       0x0000, /* 000000000000 */
+       0x0200, /* 000000100000 */
+       0x0700, /* 000001110000 */
+       0x0d80, /* 000011011000 */
+       0x18c0, /* 000110001100 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7040, /* 011100000100 */
+       0x3880, /* 001110001000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 148 0x94 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7040, /* 011100000100 */
+       0x3880, /* 001110001000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 149 0x95 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0300, /* 000000110000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7040, /* 011100000100 */
+       0x3880, /* 001110001000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 150 0x96 '.' */
+       0x0000, /* 000000000000 */
+       0x0200, /* 000000100000 */
+       0x0700, /* 000001110000 */
+       0x0d80, /* 000011011000 */
+       0x18c0, /* 000110001100 */
+       0x0000, /* 000000000000 */
+       0x79e0, /* 011110011110 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1e60, /* 000111100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 151 0x97 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1800, /* 000110000000 */
+       0x0c00, /* 000011000000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x79e0, /* 011110011110 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1e60, /* 000111100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 152 0x98 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xf0f0, /* 111100001111 */
+       0x6020, /* 011000000010 */
+       0x3040, /* 001100000100 */
+       0x3040, /* 001100000100 */
+       0x1880, /* 000110001000 */
+       0x1880, /* 000110001000 */
+       0x0d00, /* 000011010000 */
+       0x0d00, /* 000011010000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0400, /* 000001000000 */
+       0x0c00, /* 000011000000 */
+       0x0800, /* 000010000000 */
+       0x7800, /* 011110000000 */
+       0x7000, /* 011100000000 */
+       0x0000, /* 000000000000 */
+
+       /* 153 0x99 '.' */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20c0, /* 001000001100 */
+       0x2060, /* 001000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x2040, /* 001000000100 */
+       0x3040, /* 001100000100 */
+       0x1880, /* 000110001000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 154 0x9a '.' */
+       0x0000, /* 000000000000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0xe030, /* 111000000011 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x6020, /* 011000000010 */
+       0x7040, /* 011100000100 */
+       0x3fc0, /* 001111111100 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 155 0x9b '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x36c0, /* 001101101100 */
+       0x26c0, /* 001001101100 */
+       0x6600, /* 011001100000 */
+       0x6600, /* 011001100000 */
+       0x6600, /* 011001100000 */
+       0x6600, /* 011001100000 */
+       0x7640, /* 011101100100 */
+       0x36c0, /* 001101101100 */
+       0x1f80, /* 000111111000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 156 0x9c '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x1cc0, /* 000111001100 */
+       0x18c0, /* 000110001100 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x7e00, /* 011111100000 */
+       0x7e00, /* 011111100000 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x1800, /* 000110000000 */
+       0x3e20, /* 001111100010 */
+       0x7fe0, /* 011111111110 */
+       0x61c0, /* 011000011100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 157 0x9d '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x30c0, /* 001100001100 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0f00, /* 000011110000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 158 0x9e '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 159 0x9f '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 160 0xa0 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x18c0, /* 000110001100 */
+       0x10c0, /* 000100001100 */
+       0x03c0, /* 000000111100 */
+       0x1cc0, /* 000111001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1ee0, /* 000111101110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 161 0xa1 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x1e00, /* 000111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x1f80, /* 000111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 162 0xa2 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0f80, /* 000011111000 */
+       0x11c0, /* 000100011100 */
+       0x20e0, /* 001000001110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x6060, /* 011000000110 */
+       0x7040, /* 011100000100 */
+       0x3880, /* 001110001000 */
+       0x1f00, /* 000111110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 163 0xa3 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0180, /* 000000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x79e0, /* 011110011110 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x1e60, /* 000111100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 164 0xa4 '.' */
+       0x0000, /* 000000000000 */
+       0x1c40, /* 000111000100 */
+       0x3fc0, /* 001111111100 */
+       0x2380, /* 001000111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x2780, /* 001001111000 */
+       0x79c0, /* 011110011100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x79e0, /* 011110011110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 165 0xa5 '.' */
+       0x0000, /* 000000000000 */
+       0x1c40, /* 000111000100 */
+       0x3fc0, /* 001111111100 */
+       0x2380, /* 001000111000 */
+       0xc070, /* 110000000111 */
+       0x6020, /* 011000000010 */
+       0x7020, /* 011100000010 */
+       0x7820, /* 011110000010 */
+       0x5c20, /* 010111000010 */
+       0x4e20, /* 010011100010 */
+       0x4720, /* 010001110010 */
+       0x43a0, /* 010000111010 */
+       0x41e0, /* 010000011110 */
+       0x40e0, /* 010000001110 */
+       0x4060, /* 010000000110 */
+       0xe030, /* 111000000011 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 166 0xa6 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1f00, /* 000111110000 */
+       0x3180, /* 001100011000 */
+       0x0180, /* 000000011000 */
+       0x0780, /* 000001111000 */
+       0x1980, /* 000110011000 */
+       0x3180, /* 001100011000 */
+       0x3180, /* 001100011000 */
+       0x3380, /* 001100111000 */
+       0x1dc0, /* 000111011100 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 167 0xa7 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0700, /* 000001110000 */
+       0x1980, /* 000110011000 */
+       0x10c0, /* 000100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x3080, /* 001100001000 */
+       0x1980, /* 000110011000 */
+       0x0e00, /* 000011100000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 168 0xa8 '.' */
+       0x0000, /* 000000000000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0300, /* 000000110000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1800, /* 000110000000 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x3040, /* 001100000100 */
+       0x39c0, /* 001110011100 */
+       0x1f80, /* 000111111000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 169 0xa9 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 170 0xaa '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x00c0, /* 000000001100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 171 0xab '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1000, /* 000100000000 */
+       0x3000, /* 001100000000 */
+       0x1000, /* 000100000000 */
+       0x1040, /* 000100000100 */
+       0x1080, /* 000100001000 */
+       0x1100, /* 000100010000 */
+       0x3a00, /* 001110100000 */
+       0x05c0, /* 000001011100 */
+       0x0a20, /* 000010100010 */
+       0x1020, /* 000100000010 */
+       0x20c0, /* 001000001100 */
+       0x4100, /* 010000010000 */
+       0x0200, /* 000000100000 */
+       0x03e0, /* 000000111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 172 0xac '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x1000, /* 000100000000 */
+       0x3000, /* 001100000000 */
+       0x1000, /* 000100000000 */
+       0x1040, /* 000100000100 */
+       0x1080, /* 000100001000 */
+       0x1100, /* 000100010000 */
+       0x3a40, /* 001110100100 */
+       0x04c0, /* 000001001100 */
+       0x0940, /* 000010010100 */
+       0x1240, /* 000100100100 */
+       0x2440, /* 001001000100 */
+       0x47e0, /* 010001111110 */
+       0x0040, /* 000000000100 */
+       0x0040, /* 000000000100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 173 0xad '.' */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 174 0xae '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0660, /* 000001100110 */
+       0x0cc0, /* 000011001100 */
+       0x1980, /* 000110011000 */
+       0x3300, /* 001100110000 */
+       0x6600, /* 011001100000 */
+       0x3300, /* 001100110000 */
+       0x1980, /* 000110011000 */
+       0x0cc0, /* 000011001100 */
+       0x0660, /* 000001100110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 175 0xaf '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x6600, /* 011001100000 */
+       0x3300, /* 001100110000 */
+       0x1980, /* 000110011000 */
+       0x0cc0, /* 000011001100 */
+       0x0660, /* 000001100110 */
+       0x0cc0, /* 000011001100 */
+       0x1980, /* 000110011000 */
+       0x3300, /* 001100110000 */
+       0x6600, /* 011001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 176 0xb0 '.' */
+       0x0c30, /* 000011000011 */
+       0x0820, /* 000010000010 */
+       0x6180, /* 011000011000 */
+       0x2080, /* 001000001000 */
+       0x0c30, /* 000011000011 */
+       0x0820, /* 000010000010 */
+       0x6180, /* 011000011000 */
+       0x2080, /* 001000001000 */
+       0x0c30, /* 000011000011 */
+       0x0820, /* 000010000010 */
+       0x6180, /* 011000011000 */
+       0x2080, /* 001000001000 */
+       0x0c30, /* 000011000011 */
+       0x0820, /* 000010000010 */
+       0x6180, /* 011000011000 */
+       0x2080, /* 001000001000 */
+       0x0c30, /* 000011000011 */
+       0x0820, /* 000010000010 */
+       0x6180, /* 011000011000 */
+       0x2080, /* 001000001000 */
+       0x0c30, /* 000011000011 */
+       0x0820, /* 000010000010 */
+
+       /* 177 0xb1 '.' */
+       0x7770, /* 011101110111 */
+       0x2220, /* 001000100010 */
+       0x8880, /* 100010001000 */
+       0xddd0, /* 110111011101 */
+       0x8880, /* 100010001000 */
+       0x2220, /* 001000100010 */
+       0x7770, /* 011101110111 */
+       0x2220, /* 001000100010 */
+       0x8880, /* 100010001000 */
+       0xddd0, /* 110111011101 */
+       0x8880, /* 100010001000 */
+       0x2220, /* 001000100010 */
+       0x7770, /* 011101110111 */
+       0x2220, /* 001000100010 */
+       0x8880, /* 100010001000 */
+       0xddd0, /* 110111011101 */
+       0x8880, /* 100010001000 */
+       0x2220, /* 001000100010 */
+       0x7770, /* 011101110111 */
+       0x2220, /* 001000100010 */
+       0x8880, /* 100010001000 */
+       0xddd0, /* 110111011101 */
+
+       /* 178 0xb2 '.' */
+       0xf3c0, /* 111100111100 */
+       0xf7d0, /* 111101111101 */
+       0x9e70, /* 100111100111 */
+       0xdf70, /* 110111110111 */
+       0xf3c0, /* 111100111100 */
+       0xf7d0, /* 111101111101 */
+       0x9e70, /* 100111100111 */
+       0xdf70, /* 110111110111 */
+       0xf3c0, /* 111100111100 */
+       0xf7d0, /* 111101111101 */
+       0x9e70, /* 100111100111 */
+       0xdf70, /* 110111110111 */
+       0xf3c0, /* 111100111100 */
+       0xf7d0, /* 111101111101 */
+       0x9e70, /* 100111100111 */
+       0xdf70, /* 110111110111 */
+       0xf3c0, /* 111100111100 */
+       0xf7d0, /* 111101111101 */
+       0x9e70, /* 100111100111 */
+       0xdf70, /* 110111110111 */
+       0xf3c0, /* 111100111100 */
+       0xf7d0, /* 111101111101 */
+
+       /* 179 0xb3 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 180 0xb4 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 181 0xb5 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 182 0xb6 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfd80, /* 111111011000 */
+       0xfd80, /* 111111011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 183 0xb7 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xff80, /* 111111111000 */
+       0xff80, /* 111111111000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 184 0xb8 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 185 0xb9 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfd80, /* 111111011000 */
+       0xfd80, /* 111111011000 */
+       0x0180, /* 000000011000 */
+       0xfd80, /* 111111011000 */
+       0xfd80, /* 111111011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 186 0xba '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 187 0xbb '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xff80, /* 111111111000 */
+       0xff80, /* 111111111000 */
+       0x0180, /* 000000011000 */
+       0xfd80, /* 111111011000 */
+       0xfd80, /* 111111011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 188 0xbc '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfd80, /* 111111011000 */
+       0xfd80, /* 111111011000 */
+       0x0180, /* 000000011000 */
+       0xff80, /* 111111111000 */
+       0xff80, /* 111111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 189 0xbd '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xff80, /* 111111111000 */
+       0xff80, /* 111111111000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 190 0xbe '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 191 0xbf '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 192 0xc0 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 193 0xc1 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 194 0xc2 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 195 0xc3 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 196 0xc4 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 197 0xc5 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 198 0xc6 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 199 0xc7 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0df0, /* 000011011111 */
+       0x0df0, /* 000011011111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 200 0xc8 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0df0, /* 000011011111 */
+       0x0df0, /* 000011011111 */
+       0x0c00, /* 000011000000 */
+       0x0ff0, /* 000011111111 */
+       0x0ff0, /* 000011111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 201 0xc9 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0ff0, /* 000011111111 */
+       0x0ff0, /* 000011111111 */
+       0x0c00, /* 000011000000 */
+       0x0df0, /* 000011011111 */
+       0x0df0, /* 000011011111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 202 0xca '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfdf0, /* 111111011111 */
+       0xfdf0, /* 111111011111 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 203 0xcb '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0xfdf0, /* 111111011111 */
+       0xfdf0, /* 111111011111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 204 0xcc '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0df0, /* 000011011111 */
+       0x0df0, /* 000011011111 */
+       0x0c00, /* 000011000000 */
+       0x0df0, /* 000011011111 */
+       0x0df0, /* 000011011111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 205 0xcd '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 206 0xce '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfdf0, /* 111111011111 */
+       0xfdf0, /* 111111011111 */
+       0x0000, /* 000000000000 */
+       0xfdf0, /* 111111011111 */
+       0xfdf0, /* 111111011111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 207 0xcf '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 208 0xd0 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 209 0xd1 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 210 0xd2 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 211 0xd3 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0ff0, /* 000011111111 */
+       0x0ff0, /* 000011111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 212 0xd4 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 213 0xd5 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 214 0xd6 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0ff0, /* 000011111111 */
+       0x0ff0, /* 000011111111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 215 0xd7 '.' */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+       0x0d80, /* 000011011000 */
+
+       /* 216 0xd8 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0600, /* 000001100000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 217 0xd9 '.' */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0xfe00, /* 111111100000 */
+       0xfe00, /* 111111100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 218 0xda '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x07f0, /* 000001111111 */
+       0x07f0, /* 000001111111 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+
+       /* 219 0xdb '.' */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+
+       /* 220 0xdc '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+
+       /* 221 0xdd '.' */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+       0xfc00, /* 111111000000 */
+
+       /* 222 0xde '.' */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+       0x03f0, /* 000000111111 */
+
+       /* 223 0xdf '.' */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0xfff0, /* 111111111111 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 224 0xe0 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 225 0xe1 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x1980, /* 000110011000 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x3180, /* 001100011000 */
+       0x3780, /* 001101111000 */
+       0x3180, /* 001100011000 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x3180, /* 001100011000 */
+       0x7700, /* 011101110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 226 0xe2 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 227 0xe3 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 228 0xe4 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 229 0xe5 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 230 0xe6 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x30c0, /* 001100001100 */
+       0x39c0, /* 001110011100 */
+       0x36e0, /* 001101101110 */
+       0x3000, /* 001100000000 */
+       0x3000, /* 001100000000 */
+       0x6000, /* 011000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 231 0xe7 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 232 0xe8 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 233 0xe9 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 234 0xea '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 235 0xeb '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 236 0xec '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 237 0xed '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 238 0xee '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 239 0xef '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 240 0xf0 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 241 0xf1 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 242 0xf2 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 243 0xf3 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 244 0xf4 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 245 0xf5 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 246 0xf6 '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x7fe0, /* 011111111110 */
+       0x7fe0, /* 011111111110 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 247 0xf7 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 248 0xf8 '.' */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x1980, /* 000110011000 */
+       0x0f00, /* 000011110000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 249 0xf9 '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 250 0xfa '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0600, /* 000001100000 */
+       0x0f00, /* 000011110000 */
+       0x0f00, /* 000011110000 */
+       0x0600, /* 000001100000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 251 0xfb '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 252 0xfc '.' */
+       /* FIXME */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 253 0xfd '.' */
+       0x0000, /* 000000000000 */
+       0x0f00, /* 000011110000 */
+       0x1f80, /* 000111111000 */
+       0x3180, /* 001100011000 */
+       0x2180, /* 001000011000 */
+       0x0300, /* 000000110000 */
+       0x0600, /* 000001100000 */
+       0x0c00, /* 000011000000 */
+       0x1840, /* 000110000100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 254 0xfe '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x3fc0, /* 001111111100 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+       /* 255 0xff '.' */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+       0x0000, /* 000000000000 */
+
+};
+
index afdcb516daea01865ff0df38d2b6d12f132d828a..36adfabfe3de8fd98b2328ab72cdeb2f6bb547b3 100644 (file)
@@ -47,6 +47,11 @@ extern char fontname_sun8x16[];
 extern int fontwidth_sun8x16, fontheight_sun8x16;
 extern u8 fontdata_sun8x16[];
 
+/* SUN12x22 */
+extern char fontname_sun12x22[];
+extern int fontwidth_sun12x22, fontheight_sun12x22;
+extern u8 fontdata_sun12x22[];
+
 
 
    /*
@@ -66,6 +71,7 @@ struct softfontdesc {
 #define PEARL8x8_IDX   2
 #define VGA6x11_IDX    3
 #define SUN8x16_IDX    4
+#define SUN12x22_IDX   5
 
 static struct softfontdesc softfonts[] = {
    { VGA8x8_IDX, fontname_8x8, &fontwidth_8x8, &fontheight_8x8, fontdata_8x8 },
@@ -77,6 +83,8 @@ static struct softfontdesc softfonts[] = {
 #else
    { SUN8x16_IDX, fontname_sun8x16, &fontwidth_sun8x16, &fontheight_sun8x16, 
      fontdata_sun8x16 },
+   { SUN12x22_IDX, fontname_sun12x22, &fontwidth_sun12x22, &fontheight_sun12x22, 
+     fontdata_sun12x22 },
 #endif
 };
 
@@ -87,7 +95,7 @@ static unsigned int numsoftfonts = sizeof(softfonts)/sizeof(*softfonts);
     *    Find a font with a specific name
     */
 
-int findsoftfont(char *name, int *width, int *height, u8 *data[])
+int findsoftfont(char *name, unsigned short *width, unsigned short *height, u8 *data[])
 {
    unsigned int i;
 
@@ -109,7 +117,7 @@ int findsoftfont(char *name, int *width, int *height, u8 *data[])
     *    Get the default font for a specific screen size
     */
 
-void getdefaultfont(int xres, int yres, char *name[], int *width, int *height,
+void getdefaultfont(int xres, int yres, char *name[], unsigned short *width, unsigned short *height,
                     u8 *data[])
 {
     int i, j;
index 37930944b2008724608cc39fe28bcd844c4aeaf1..32f0977eaae06ddfcdad5a325acbdf6f1c995201 100644 (file)
@@ -43,7 +43,7 @@ static struct fb_var_screeninfo macfb_defined={
        {0,0,0},        /* transparency */
        0,              /* standard pixel format */
        FB_ACTIVATE_NOW,
-       274,195,        /* 14" monitor *Mikael Nykvist's anyway* */
+       274,195,        /* 14" monitor - the late Mikael Nykvist's anyway */
        0,              /* The only way to accelerate a mac is .. */
        0L,0L,0L,0L,0L,
        0L,0L,0,        /* No sync info */
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
new file mode 100644 (file)
index 0000000..9b3b667
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ *  linux/drivers/video/macmodes.c -- Standard MacOS video modes
+ *
+ *     Copyright (C) 1998 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/config.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/string.h>
+#include <asm/vc_ioctl.h>
+
+
+    /*
+     *  Video mode values.
+     *  These are supposed to be the same as the values that Apple uses in
+     *  MacOS.
+     */
+
+#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 CMODE_8                        0       /* 8 bits/pixel */
+#define CMODE_16               1       /* 16 (actually 15) bits/pixel */
+#define CMODE_32               2       /* 32 (actually 24) bits/pixel */
+
+
+struct mac_mode {
+    int number;
+    u32 xres;
+    u32 yres;
+    u32 pixclock;
+    u32 left_margin;
+    u32 right_margin;
+    u32 upper_margin;
+    u32 lower_margin;
+    u32 hsync_len;
+    u32 vsync_len;
+    u32 sync;
+    u32 vmode;
+};
+
+
+    /* 512x384, 60Hz, Interlaced (NTSC) */
+
+#if 0
+static const struct mac_mode mac_mode_1 = {
+    VMODE_512_384_60I, 512, 384,
+    pixclock, left, right, upper, lower, hslen, vslen,
+    sync, FB_VMODE_INTERLACED
+};
+#endif
+
+    /* 512x384, 60Hz, Non-Interlaced */
+
+#if 0
+static const struct mac_mode mac_mode_2 = {
+    VMODE_512_384_60, 512, 384,
+    pixclock, left, right, upper, lower, hslen, vslen,
+    sync, FB_VMODE_NONINTERLACED
+};
+#endif
+
+    /* 640x480, 50Hz, Interlaced (PAL) */
+
+#if 0
+static const struct mac_mode mac_mode_3 = {
+    VMODE_640_480_50I, 640, 480,
+    pixclock, left, right, upper, lower, hslen, vslen,
+    sync, FB_VMODE_INTERLACED
+};
+#endif
+
+    /* 640x480, 60Hz, Interlaced (NTSC) */
+
+#if 0
+static const struct mac_mode mac_mode_4 = {
+    VMODE_640_480_60I, 640, 480,
+    pixclock, left, right, upper, lower, hslen, vslen,
+    sync, FB_VMODE_INTERLACED
+};
+#endif
+
+    /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+
+static const struct mac_mode mac_mode_5 = {
+    VMODE_640_480_60, 640, 480,
+    39722, 32, 32, 33, 10, 96, 2,
+    0, FB_VMODE_NONINTERLACED
+};
+
+    /* 640x480, 67Hz, Non-Interlaced (30.0 MHz dotclock) */
+
+static const struct mac_mode mac_mode_6 = {
+    VMODE_640_480_67, 640, 480,
+    33334, 80, 80, 39, 3, 64, 3,
+    0, FB_VMODE_NONINTERLACED
+};
+
+    /* 640x870, 75Hz (portrait), Non-Interlaced */
+
+#if 0
+static const struct mac_mode mac_mode_7 = {
+    VMODE_640_870_75P, 640, 870,
+    pixclock, left, right, upper, lower, hslen, vslen,
+    sync, FB_VMODE_NONINTERLACED
+};
+#endif
+
+    /* 768x576, 50Hz (PAL full frame), Interlaced */
+
+#if 0
+static const struct mac_mode mac_mode_8 = {
+    VMODE_768_576_50I, 768, 576,
+    pixclock, left, right, upper, lower, hslen, vslen,
+    sync, FB_VMODE_INTERLACED
+};
+#endif
+
+    /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_9 = {
+    VMODE_800_600_56, 800, 600,
+    27778, 112, 40, 22, 1, 72, 2,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_10 = {
+    VMODE_800_600_60, 800, 600,
+    25000, 72, 56, 23, 1, 128, 4,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 800x600, 72 Hz, Non-Interlaced (50.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_11 = {
+    VMODE_800_600_72, 800, 600,
+    20000, 48, 72, 23, 37, 120, 6,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock) */
+
+static const struct mac_mode mac_mode_12 = {
+    VMODE_800_600_75, 800, 600,
+    20203, 144, 32, 21, 1, 80, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 832x624, 75Hz, Non-Interlaced (57.6 MHz */
+
+static const struct mac_mode mac_mode_13 = {
+    VMODE_832_624_75, 832, 624,
+    17362, 208, 48, 39, 1, 64, 3,
+    0, FB_VMODE_NONINTERLACED
+};
+
+    /* 1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_14 = {
+    VMODE_1024_768_60, 1024, 768,
+    15385, 144, 40, 29, 3, 136, 6,
+    0, FB_VMODE_NONINTERLACED
+};
+
+    /* 1024x768, 72 Hz, Non-Interlaced (75.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_15 = {
+    VMODE_1024_768_70, 1024, 768,
+    13334, 128, 40, 29, 3, 136, 6,
+    0, FB_VMODE_NONINTERLACED
+};
+
+    /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+
+static const struct mac_mode mac_mode_16 = {
+    VMODE_1024_768_75V, 1024, 768,
+    12699, 176, 16, 28, 1, 96, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+
+static const struct mac_mode mac_mode_17 = {
+    VMODE_1024_768_75, 1024, 768,
+    12699, 160, 32, 28, 1, 96, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 1152x870, 75 Hz, Non-Interlaced (100.0 MHz dotclock) */
+
+static const struct mac_mode mac_mode_18 = {
+    VMODE_1152_870_75, 1152, 870,
+    10000, 128, 48, 39, 3, 128, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+    /* 1280x960, 75 Hz, Non-Interlaced (126.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_19 = {
+    VMODE_1280_960_75, 1280, 960,
+    7937, 224, 32, 36, 1, 144, 3,
+    0, FB_VMODE_NONINTERLACED
+};
+
+    /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
+
+static const struct mac_mode mac_mode_20 = {
+    VMODE_1280_1024_75, 1280, 1024,
+    7408, 232, 64, 38, 1, 112, 3,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+
+static const struct mac_mode *mac_modes[20] = {
+    NULL,              /* 512x384, 60Hz interlaced (NTSC) */
+    NULL,              /* 512x384, 60Hz */
+    NULL,              /* 640x480, 50Hz interlaced (PAL) */
+    NULL,              /* 640x480, 60Hz interlaced (NTSC) */
+    &mac_mode_5,       /* 640x480, 60Hz (VGA) */
+    &mac_mode_6,       /* 640x480, 67Hz */
+    NULL,              /* 640x870, 75Hz (portrait) */
+    NULL,              /* 768x576, 50Hz (PAL full frame) */
+    &mac_mode_9,       /* 800x600, 56Hz */
+    &mac_mode_10,      /* 800x600, 60Hz */
+    &mac_mode_11,      /* 800x600, 72Hz */
+    &mac_mode_12,      /* 800x600, 75Hz */
+    &mac_mode_13,      /* 832x624, 75Hz */
+    &mac_mode_14,      /* 1024x768, 60Hz */
+    &mac_mode_15,      /* 1024x768, 70Hz (or 72Hz?) */
+    &mac_mode_16,      /* 1024x768, 75Hz (VESA) */
+    &mac_mode_17,      /* 1024x768, 75Hz */
+    &mac_mode_18,      /* 1152x870, 75Hz */
+    &mac_mode_19,      /* 1280x960, 75Hz */
+    &mac_mode_20,      /* 1280x1024, 75Hz */
+};
+
+static const struct mac_mode *mac_modes_inv[] = {
+    &mac_mode_6,       /* 640x480, 67Hz */
+    &mac_mode_5,       /* 640x480, 60Hz (VGA) */
+    &mac_mode_12,      /* 800x600, 75Hz */
+    &mac_mode_11,      /* 800x600, 72Hz */
+    &mac_mode_10,      /* 800x600, 60Hz */
+    &mac_mode_9,       /* 800x600, 56Hz */
+    &mac_mode_13,      /* 832x624, 75Hz */
+    &mac_mode_17,      /* 1024x768, 75Hz */
+    &mac_mode_16,      /* 1024x768, 75Hz (VESA) */
+    &mac_mode_15,      /* 1024x768, 70Hz (or 72Hz?) */
+    &mac_mode_14,      /* 1024x768, 60Hz */
+    &mac_mode_18,      /* 1152x870, 75Hz */
+    &mac_mode_19,      /* 1280x960, 75Hz */
+    &mac_mode_20,      /* 1280x1024, 75Hz */
+};
+
+
+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" */
+    { 0x73f, VMODE_640_480_67 },       /* no sense lines connected at all */
+    { -1,    VMODE_640_480_60 },       /* catch-all, must be last */
+};
+
+
+    /*
+     *  Convert a MacOS vmode/cmode pair to a frame buffer video mode structure
+     */
+
+int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var)
+{
+    const struct mac_mode *mode = NULL;
+
+    if (vmode > 0 && vmode <= VMODE_MAX)
+       mode = mac_modes[vmode-1];
+
+    if (!mode)
+       return -EINVAL;
+
+    memset(var, 0, sizeof(struct fb_var_screeninfo));
+    switch (cmode) {
+       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;
+           break;
+
+       case CMODE_16:
+           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;
+           break;
+
+       case CMODE_32:
+           var->bits_per_pixel = 32;
+           var->red.offset = 16;
+           var->red.length = 8;
+           var->green.offset = 8;
+           var->green.length = 8;
+           var->blue.offset = 0;
+           var->blue.length = 8;
+           var->transp.offset = 24;
+           var->transp.length = 8;
+           break;
+
+       default:
+           return -EINVAL;
+    }
+    var->xres = mode->xres;
+    var->yres = mode->yres;
+    var->xres_virtual = mode->xres;
+    var->yres_virtual = mode->yres;
+    var->height = -1;
+    var->width = -1;
+    var->pixclock = mode->pixclock;
+    var->left_margin = mode->left_margin;
+    var->right_margin = mode->right_margin;
+    var->upper_margin = mode->upper_margin;
+    var->lower_margin = mode->lower_margin;
+    var->hsync_len = mode->hsync_len;
+    var->vsync_len = mode->vsync_len;
+    var->sync = mode->sync;
+    var->vmode = mode->vmode;
+    return 0;
+}
+
+
+    /*
+     *  Convert a frame buffer video mode structure to a MacOS vmode/cmode pair
+     */
+
+int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
+                    int *cmode)
+{
+    int i = 0;
+
+    if (var->bits_per_pixel <= 8)
+       *cmode = CMODE_8;
+    else if (var->bits_per_pixel <= 16)
+       *cmode = CMODE_16;
+    else if (var->bits_per_pixel <= 32)
+       *cmode = CMODE_32;
+    else
+       return -EINVAL;
+
+    for (i = 0; i < sizeof(mac_modes_inv)/sizeof(*mac_modes_inv); i++) {
+       const struct mac_mode *mode = mac_modes_inv[i];
+       if (var->xres > mode->xres || var->yres > mode->yres)
+           continue;
+       if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres)
+           continue;
+       if (var->pixclock > mode->pixclock)
+           continue;
+       if (var->vmode != mode->vmode)
+           continue;
+       *vmode = mode->number;
+       return 0;
+    }
+    return -EINVAL;
+}
+
+
+    /*
+     *  Convert a Mac monitor sense number to a MacOS vmode number
+     */
+
+int mac_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;
+}
index e0a1cb65406fc17a94d861ea6677c178f0dbebb9..68029093a2edf165d719f6333bdef39e0e329b0b 100644 (file)
@@ -286,7 +286,7 @@ static struct fb_ops mdafb_ops = {
 
 static struct display_switch fbcon_mdafb = {
     fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
-    fbcon_vga_putcs, fbcon_vga_revc, fbcon_mdafb_cursor
+    fbcon_vga_putcs, fbcon_vga_revc, fbcon_mdafb_cursor, NULL, FONTWIDTH(8)
 };
 
 
index 6fc8b398cd6a19b0503d668e1f912559b3c42a04..c3eaf9d2d9b93b4a8b9b03bd7756919292af0772 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 
+#include "fbcon.h"
 #include "fbcon-cfb8.h"
 
 
@@ -86,9 +87,6 @@ int console_setmode(struct vc_mode *, int);
 int console_setcmap(int, unsigned char *, unsigned char *, unsigned char *);
 int console_powermode(int);
 struct fb_info *console_fb_info = NULL;
-int (*console_setmode_ptr)(struct vc_mode *, int) = NULL;
-int (*console_set_cmap_ptr)(struct fb_cmap *, int, int, struct fb_info *)
-    = NULL;
 struct vc_mode display_info;
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 
@@ -276,17 +274,13 @@ static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
 
 #ifdef CONFIG_FB_ATY
 extern void atyfb_of_init(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",
-    "ATY,XCLAIMVRPro", "ATY,mach64_3DU", "ATY,XCLAIM3DPro"
-};
 #endif /* CONFIG_FB_ATY */
 #ifdef CONFIG_FB_S3TRIO
 extern void s3triofb_init_of(struct device_node *dp);
 #endif /* CONFIG_FB_S3TRIO */
-
+#ifdef CONFIG_FB_CT65550
+extern void chips_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_CT65550 */
 
     /*
      *  Initialisation
@@ -308,10 +302,7 @@ __initfunc(void offb_init(void))
 
        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)) {
+           if (!strncmp(dp->name, "ATY", 3)) {
                atyfb_of_init(dp);
                continue;
            }
@@ -320,6 +311,12 @@ __initfunc(void offb_init(void))
             if (s3triofb_init_of(dp))
                 continue;
 #endif /* CONFIG_FB_S3TRIO */
+#ifdef CONFIG_FB_CT65550
+           if (!strcmp(dp->name, "chips65550")) {
+               chips_of_init(dp);
+               continue;
+           }
+#endif /* CONFIG_FB_CT65550 */
        }
 
        info = kmalloc(sizeof(struct fb_info_offb), GFP_ATOMIC);
@@ -414,6 +411,7 @@ __initfunc(void offb_init(void))
 #else
        disp->dispsw = NULL;
 #endif
+       disp->scrollmode = SCROLL_YREDRAW;
 
        strcpy(info->info.modename, "OFfb ");
        strncat(info->info.modename, dp->full_name,
@@ -462,7 +460,6 @@ __initfunc(void offb_init(void))
                    display_info.cmap_data_address = address + 0x7ffcc1;
            }
            console_fb_info = &info->info;
-           console_set_cmap_ptr = offb_set_cmap;
        }
 #endif /* CONFIG_FB_COMPAT_XPMAC) */
     }
@@ -596,17 +593,6 @@ static void do_install_cmap(int con, struct fb_info *info)
 
     /*
      *  Backward compatibility mode for Xpmac
-     *
-     *  To do:
-     *
-     *    - console_setmode() should fill in a struct fb_var_screeninfo (using
-     *     the MacOS video mode database) and simply call a decode_var()
-     *     function, so console_setmode_ptr is no longer needed.
-     *     console_getmode() should convert in the other direction.
-     *
-     *    - instead of using the console_* stuff (filled in by the frame
-     *      buffer), we should use the correct struct fb_info for the
-     *     foreground virtual console.
      */
 
 int console_getmode(struct vc_mode *mode)
@@ -617,12 +603,31 @@ int console_getmode(struct vc_mode *mode)
 
 int console_setmode(struct vc_mode *mode, int doit)
 {
-    int err;
-
-    if (console_setmode_ptr == NULL)
-       return -EINVAL;
+    struct fb_var_screeninfo var;
+    int cmode, err;
 
-    err = (*console_setmode_ptr)(mode, doit);
+    if (!console_fb_info)
+       return -EOPNOTSUPP;
+    switch (mode->depth) {
+       case 8:
+       case 0:         /* default */
+           cmode = 0;  /* CMODE_8 */
+           break;
+       case 16:
+           cmode = 1;  /* CMODE_16 */
+           break;
+       case 24:
+       case 32:
+           cmode = 2;  /* CMODE_32 */
+           break;
+       default:
+           return -EINVAL;
+    }
+    if ((err = mac_vmode_to_var(mode->mode, cmode, &var)))
+       return err;
+    var.activate = doit ? FB_ACTIVATE_NOW : FB_ACTIVATE_TEST;
+    err = console_fb_info->fbops->fb_set_var(&var, fg_console,
+                                            console_fb_info);
     return err;
 }
 
@@ -637,9 +642,9 @@ static struct fb_cmap palette_cmap = {
 int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
                    unsigned char *blue)
 {
-    int i, j, n;
+    int i, j, n, err;
 
-    if (console_set_cmap_ptr == NULL)
+    if (!console_fb_info)
        return -EOPNOTSUPP;
     for (i = 0; i < n_entries; i += n) {
        n = n_entries-i;
@@ -652,7 +657,10 @@ int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
            palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];
            palette_cmap.blue[j]  = (blue[i+j] << 8) | blue[i+j];
        }
-       (*console_set_cmap_ptr)(&palette_cmap, 1, fg_console, console_fb_info);
+       err = console_fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
+                                                 console_fb_info);
+       if (err)
+           return err;
     }
     return 0;
 }
diff --git a/drivers/video/promcon.c b/drivers/video/promcon.c
new file mode 100644 (file)
index 0000000..a0be44d
--- /dev/null
@@ -0,0 +1,513 @@
+/* $Id: promcon.c,v 1.3 1998/07/13 01:06:19 ecd Exp $
+ * Console driver utilizing PROM sun terminal emulation
+ *
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz)
+ */
+
+#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/delay.h>
+#include <linux/console.h>
+#include <linux/console_struct.h>
+#include <linux/selection.h>
+#include <linux/fb.h>
+
+#include <asm/oplib.h>
+
+static short pw = 80 - 1, ph = 34 - 1;
+static short px, py;
+
+static __inline__ void
+promcon_puts(char *buf, int cnt)
+{
+       prom_printf("%*.*s", cnt, cnt, buf);
+}
+
+static int
+promcon_start(struct vc_data *conp, char *b)
+{
+       unsigned short *s = (unsigned short *)
+                       (conp->vc_origin + py * conp->vc_size_row + (px << 1));
+
+       if (px == pw) {
+               unsigned short *t = s - 1;
+
+               if ((*s & 0x0800) && (*t & 0x0800))
+                       return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m",
+                                      *s, *t);
+               else if (*s & 0x0800)
+                       return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c",
+                                      *s, *t);
+               else if (*t & 0x0800)
+                       return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m",
+                                      *s, *t);
+               else
+                       return sprintf(b, "\b%c\b\033[@%c", *s, *t);
+       }
+
+       if (*s & 0x0800)
+               return sprintf(b, "\033[7m%c\033[m\b", *s);
+       else
+               return sprintf(b, "%c\b", *s);
+}
+
+static int
+promcon_end(struct vc_data *conp, char *b)
+{
+       unsigned short *s = (unsigned short *)
+                       (conp->vc_origin + py * conp->vc_size_row + (px << 1));
+       char *p = b;
+
+       b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
+
+       if (px == pw) {
+               unsigned short *t = s - 1;
+
+               if ((*s & 0x0800) && (*t & 0x0800))
+                       b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", *s, *t);
+               else if (*s & 0x0800)
+                       b += sprintf(b, "\b%c\b\033[@%c", *s, *t);
+               else if (*t & 0x0800)
+                       b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", *s, *t);
+               else
+                       b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", *s, *t);
+               return b - p;
+       }
+
+       if (*s & 0x0800)
+               b += sprintf(b, "%c\b", *s);
+       else
+               b += sprintf(b, "\033[7m%c\033[m\b", *s);
+       return b - p;
+}
+
+__initfunc(const char *promcon_startup(void))
+{
+       const char *display_desc = "PROM";
+       int node;
+       char buf[40];
+       
+       node = prom_getchild(prom_root_node);
+       node = prom_searchsiblings(node, "options");
+       if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {
+               pw = simple_strtoul(buf, NULL, 0);
+               if (pw < 10 || pw > 256)
+                       pw = 80;
+               pw--;
+       }
+       if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {
+               ph = simple_strtoul(buf, NULL, 0);
+               if (ph < 10 || ph > 256)
+                       ph = 34;
+               ph--;
+       }
+       promcon_puts("\033[H\033[J", 6);
+       return display_desc;
+}
+
+static void
+promcon_init(struct vc_data *conp, int init)
+{
+       conp->vc_can_do_color = 0;
+       conp->vc_cols = pw + 1;
+       conp->vc_rows = ph + 1;
+}
+
+static int
+promcon_switch(struct vc_data *conp)
+{
+       return 1;
+}
+
+static unsigned short *
+promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
+{
+       int cnt = pw + 1;
+       unsigned short attr = 0;
+       unsigned char *b = *bp;
+
+       while (cnt--) {
+               if (attr != (*s & 0x0800)) {
+                       attr = (*s & 0x0800);
+                       if (attr) {
+                               strcpy (b, "\033[7m");
+                               b += 4;
+                       } else {
+                               strcpy (b, "\033[m");
+                               b += 3;
+                       }
+               }
+               *b++ = *s++;
+               if (b - buf >= 224) {
+                       promcon_puts(buf, b - buf);
+                       b = buf;
+               }
+       }
+       *bp = b;
+       return s;
+}
+
+static void
+promcon_putcs(struct vc_data *conp, const unsigned short *s,
+             int count, int y, int x)
+{
+       unsigned char buf[256], *b = buf;
+       unsigned short attr = *s;
+       unsigned char save;
+       int i, last = 0;
+
+       if (console_blanked)
+               return;
+       
+       if (count <= 0)
+               return;
+
+       b += promcon_start(conp, b);
+
+       if (x + count >= pw + 1) {
+               if (count == 1) {
+                       x -= 1;
+                       save = *(unsigned short *)(conp->vc_origin
+                                                  + y * conp->vc_size_row
+                                                  + (x << 1));
+
+                       if (px != x || py != y) {
+                               b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
+                               px = x;
+                               py = y;
+                       }
+
+                       if (attr & 0x0800)
+                               b += sprintf(b, "\033[7m%c\033[m", *s++);
+                       else
+                               b += sprintf(b, "%c", *s++);
+
+                       strcpy(b, "\b\033[@");
+                       b += 4;
+
+                       if (save & 0x0800)
+                               b += sprintf(b, "\033[7m%c\033[m", save);
+                       else
+                               b += sprintf(b, "%c", save);
+
+                       px++;
+
+                       b += promcon_end(conp, b);
+                       promcon_puts(buf, b - buf);
+                       return;
+               } else {
+                       last = 1;
+                       count = pw - x - 1;
+               }
+       }
+
+       if (attr & 0x0800) {
+               strcpy(b, "\033[7m");
+               b += 4;
+       }
+
+       if (px != x || py != y) {
+               b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
+               px = x;
+               py = y;
+       }
+
+       for (i = 0; i < count; i++) {
+               if (b - buf >= 224) {
+                       promcon_puts(buf, b - buf);
+                       b = buf;
+               }
+               *b++ = *s++;
+       }
+
+       px += count;
+
+       if (last) {
+               save = *s++;
+               b += sprintf(b, "%c\b\033[@%c", *s++, save);
+               px++;
+       }
+
+       if (attr & 0x0800) {
+               strcpy(b, "\033[m");
+               b += 3;
+       }
+
+       b += promcon_end(conp, b);
+       promcon_puts(buf, b - buf);
+}
+
+static void
+promcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+       unsigned short s = c;
+
+       if (console_blanked)
+               return;
+       
+       promcon_putcs(conp, &s, 1, y, x);
+}
+
+static void
+promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
+{
+       unsigned char buf[256], *b = buf;
+       int i, j;
+
+       if (console_blanked)
+               return;
+       
+       b += promcon_start(conp, b);
+
+       if (!sx && width == pw + 1) {
+
+               if (!sy && height == ph + 1) {
+                       strcpy(b, "\033[H\033[J");
+                       b += 6;
+                       b += promcon_end(conp, b);
+                       promcon_puts(buf, b - buf);
+                       return;
+               } else if (sy + height == ph + 1) {
+                       b += sprintf(b, "\033[%dH\033[J", sy + 1);
+                       b += promcon_end(conp, b);
+                       promcon_puts(buf, b - buf);
+                       return;
+               }
+
+               b += sprintf(b, "\033[%dH", sy + 1);
+               for (i = 1; i < height; i++) {
+                       strcpy(b, "\033[K\n");
+                       b += 4;
+               }
+
+               strcpy(b, "\033[K");
+               b += 3;
+
+               b += promcon_end(conp, b);
+               promcon_puts(buf, b - buf);
+               return;
+
+       } else if (sx + width == pw + 1) {
+
+               b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
+               for (i = 1; i < height; i++) {
+                       strcpy(b, "\033[K\n");
+                       b += 4;
+               }
+
+               strcpy(b, "\033[K");
+               b += 3;
+
+               b += promcon_end(conp, b);
+               promcon_puts(buf, b - buf);
+               return;
+       }
+
+       for (i = sy + 1; i <= sy + height; i++) {
+               b += sprintf(b, "\033[%d;%dH", i, sx + 1);
+               for (j = 0; j < width; j++)
+                       *b++ = ' ';
+               if (b - buf + width >= 224) {
+                       promcon_puts(buf, b - buf);
+                       b = buf;
+               }
+       }
+
+       b += promcon_end(conp, b);
+       promcon_puts(buf, b - buf);
+}
+                        
+static void
+promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+             int height, int width)
+{
+       char buf[256], *b = buf;
+
+       if (console_blanked)
+               return;
+       
+       b += promcon_start(conp, b);
+       if (sy == dy && height == 1) {
+               if (dx > sx && dx + width == conp->vc_cols)
+                       b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
+                                    sy + 1, sx + 1, dx - sx, py + 1, px + 1);
+               else if (dx < sx && sx + width == conp->vc_cols)
+                       b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
+                                    dy + 1, dx + 1, sx - dx, py + 1, px + 1);
+
+               b += promcon_end(conp, b);
+               promcon_puts(buf, b - buf);
+               return;
+       }
+
+       /*
+        * FIXME: What to do here???
+        * Current console.c should not call it like that ever.
+        */
+       prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
+}
+
+static void
+promcon_cursor(struct vc_data *conp, int mode)
+{
+       char buf[32], *b = buf;
+
+       switch (mode) {
+       case CM_ERASE:
+               break;
+
+       case CM_MOVE:
+       case CM_DRAW:
+               b += promcon_start(conp, b);
+               if (px != conp->vc_x || py != conp->vc_y) {
+                       px = conp->vc_x;
+                       py = conp->vc_y;
+                       b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
+               }
+               promcon_puts(buf, b - buf);
+               break;
+       }
+}
+
+static int
+promcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+       return -ENOSYS;
+}
+        
+static int
+promcon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+       return -ENOSYS;
+}
+
+static int
+promcon_blank(int blank)
+{
+       if (blank) {
+               promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
+               return 0;
+       } else {
+               /* Let console.c redraw */
+               return 1;
+       }
+}
+
+static int
+promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+       unsigned char buf[256], *p = buf;
+       unsigned short *s;
+       int i;
+
+       if (console_blanked)
+               return 0;
+       
+       p += promcon_start(conp, p);
+
+       switch (dir) {
+       case SM_UP:
+               if (b == ph + 1) {
+                       p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
+                       px = 0;
+                       py = t;
+                       p += promcon_end(conp, p);
+                       promcon_puts(buf, p - buf);
+                       break;
+               }
+
+               s = (unsigned short *)(conp->vc_origin
+                                      + (t + count) * conp->vc_size_row);
+
+               p += sprintf(p, "\033[%dH", t + 1);
+
+               for (i = t; i < b - count; i++)
+                       s = promcon_repaint_line(s, buf, &p);
+
+               for (; i < b - 1; i++) {
+                       strcpy(p, "\033[K\n");
+                       p += 4;
+                       if (p - buf >= 224) {
+                               promcon_puts(buf, p - buf);
+                               p = buf;
+                       }
+               }
+
+               strcpy(p, "\033[K");
+               p += 3;
+
+               p += promcon_end(conp, p);
+               promcon_puts(buf, p - buf);
+               break;
+
+       case SM_DOWN:
+               if (b == ph + 1) {
+                       p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
+                       px = 0;
+                       py = t;
+                       p += promcon_end(conp, p);
+                       promcon_puts(buf, p - buf);
+                       break;
+               }
+
+               s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
+
+               p += sprintf(p, "\033[%dH", t + 1);
+
+               for (i = t; i < t + count; i++) {
+                       strcpy(p, "\033[K\n");
+                       p += 4;
+                       if (p - buf >= 224) {
+                               promcon_puts(buf, p - buf);
+                               p = buf;
+                       }
+               }
+
+               for (; i < b; i++)
+                       s = promcon_repaint_line(s, buf, &p);
+
+               p += promcon_end(conp, p);
+               promcon_puts(buf, p - buf);
+               break;
+       }
+
+       return 0;
+}
+
+/*
+ *  The console 'switch' structure for the VGA based console
+ */
+
+static int promcon_dummy(void)
+{
+        return 0;
+}
+
+#define DUMMY (void *) promcon_dummy
+
+struct consw prom_con = {
+       con_startup:            promcon_startup,
+       con_init:               promcon_init,
+       con_deinit:             DUMMY,
+       con_clear:              promcon_clear,
+       con_putc:               promcon_putc,
+       con_putcs:              promcon_putcs,
+       con_cursor:             promcon_cursor,
+       con_scroll:             promcon_scroll,
+       con_bmove:              promcon_bmove,
+       con_switch:             promcon_switch,
+       con_blank:              promcon_blank,
+       con_get_font:           promcon_get_font,
+       con_set_font:           promcon_set_font,
+       con_set_palette:        DUMMY,
+       con_scrolldelta:        DUMMY,
+       con_set_origin:         NULL,
+       con_save_screen:        NULL,
+};
diff --git a/drivers/video/promfb.c b/drivers/video/promfb.c
deleted file mode 100644 (file)
index d4cac93..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/* $Id: promfb.c,v 1.3 1998/07/08 07:36:49 ecd Exp $
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#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/console.h>
-#include <linux/fb.h>
-
-#include "promfb.h"
-
-extern int prom_stdout;
-
-#define PROM_FONT_HEIGHT       22
-#define PROM_FONT_WIDTH                12
-
-void promfb_init(void);
-void promfb_setup(char *options, int *ints);
-
-
-static int
-promfb_open(struct fb_info *info, int user)
-{
-       MOD_INC_USE_COUNT;
-       return 0;
-}
-
-static int
-promfb_release(struct fb_info *info, int user)
-{
-       MOD_DEC_USE_COUNT;
-       return 0;
-}
-
-static int
-promfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-{
-       struct fb_info_promfb *fb = promfbinfo(info);
-
-       memcpy(fix, &fb->fix, sizeof(struct fb_fix_screeninfo));
-       return 0;
-}
-
-static int
-promfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-       struct fb_info_promfb *fb = promfbinfo(info);
-
-       memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
-       return 0;
-}
-
-static int
-promfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-       return -EINVAL;
-}
-
-static int
-promfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
-       return 0;
-}
-
-static int
-promfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-{
-       return -EINVAL;
-}
-
-static int
-promfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-{
-       if (var->xoffset || var->yoffset)
-               return -EINVAL;
-       return 0;
-}
-
-static int
-promfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-            u_long arg, int con, struct fb_info *info)
-{
-       return -EINVAL;
-}
-
-static int
-promfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
-{
-       return -EINVAL;
-}
-
-static struct fb_ops promfb_ops = {
-       promfb_open,
-       promfb_release,
-       promfb_get_fix,
-       promfb_get_var,
-       promfb_set_var,
-       promfb_get_cmap,
-       promfb_set_cmap,
-       promfb_pan_display,
-       promfb_ioctl,
-       promfb_mmap
-};
-
-
-static int
-promfbcon_switch(int con, struct fb_info *info)
-{
-       return 0;
-}
-
-static int
-promfbcon_updatevar(int con, struct fb_info *info)
-{
-       return 0;
-}
-
-static void
-promfbcon_blank(int blank, struct fb_info *info)
-{
-       /* nothing */
-}
-
-
-static void
-prom_start(struct fb_info_promfb *fb, struct display *d)
-{
-       unsigned short *dst = fb->data + d->next_line * fb->cury + fb->curx;
-
-       if (fb->curx == fb->maxx && fb->cury == fb->maxy)
-               return;
-
-       if (*dst & 0x0800)
-               prom_printf("\033[7m%c\033[m\033[%d;%dH",
-                           *dst, fb->cury + 1, fb->curx + 1);
-       else
-               prom_printf("%c\033[%d;%dH",
-                           *dst, fb->cury + 1, fb->curx + 1);
-}
-
-static void
-prom_stop(struct fb_info_promfb *fb, struct display *d)
-{
-       unsigned short *dst = fb->data + d->next_line * fb->cury + fb->curx;
-
-       if (fb->curx == fb->maxx && fb->cury == fb->maxy)
-               return;
-
-       if (*dst & 0x0800)
-               prom_printf("\033[%d;%dH%c\033[%d;%dH",
-                           fb->cury + 1, fb->curx + 1, *dst,
-                           fb->cury + 1, fb->curx + 1);
-       else
-               prom_printf("\033[%d;%dH\033[7m%c\033[m\033[%d;%dH",
-                           fb->cury + 1, fb->curx + 1, *dst,
-                           fb->cury + 1, fb->curx + 1);
-}
-
-static void
-fbcon_prom_setup(struct display *d)
-{
-       d->next_line = d->line_length;
-       d->next_plane = 0;
-}
-
-static void
-fbcon_prom_putc(struct vc_data *con, struct display *d, int c, int y, int x)
-{
-       struct fb_info_promfb *fb = promfbinfod(d);
-       unsigned short *dst;
-
-       dst = fb->data + y * d->line_length + x;
-       if (*dst != (c & 0xffff)) {
-               *dst = c & 0xffff;
-
-               prom_start(fb, d);
-
-               if (fb->curx != x || fb->cury != y) {
-                       prom_printf("\033[%d;%dH", y + 1, x + 1);
-                       fb->curx = x;
-                       fb->cury = y;
-               }
-
-               if (x == fb->maxx && y == fb->maxy)
-                       /* Sorry */ return;
-
-               if (c & 0x0800)
-                       prom_printf("\033[7m%c\033[m", c);
-               else
-                       prom_putchar(c);
-
-               prom_stop(fb, d);
-       }
-}
-
-static void
-fbcon_prom_putcs(struct vc_data *con, struct display *d,
-                const unsigned short *s, int count, int y, int x)
-{
-       struct fb_info_promfb *fb = promfbinfod(d);
-       unsigned short *dst;
-       unsigned short attr = *s;
-       int i;
-
-       dst = fb->data + y * d->line_length + x;
-
-       prom_start(fb, d);
-
-       if (attr & 0x0800)
-               prom_printf("\033[7m");
-
-       for (i = 0; i < count; i++) {
-               if (*dst != *s) {
-                       *dst = *s;
-
-                       if (fb->curx != x + i || fb->cury != y) {
-                               prom_printf("\033[%d;%dH", y + 1, x + i + 1);
-                               fb->curx = x + i;
-                               fb->cury = y;
-                       }
-
-                       if (fb->curx == fb->maxx && fb->cury == fb->maxy)
-                               /* Sorry */ goto out;
-
-                       prom_putchar(*s);
-
-                       if (i < count - 1)
-                               fb->curx++;
-               }
-               dst++;
-               s++;
-       }
-out:
-       if (attr & 0x0800)
-               prom_printf("\033[m");
-
-       prom_stop(fb, d);
-}
-
-static void
-fbcon_prom_clear(struct vc_data *con, struct display *d, int sy, int sx,
-                int h, int w)
-{
-       int x, y;
-
-       for (y = sy; y < sy + h; y++)
-               for (x = sx; x < sx + w; x++)
-                       fbcon_prom_putc(con, d, con->vc_video_erase_char, y, x);
-}
-
-static void
-fbcon_prom_bmove(struct display *d, int sy, int sx, int dy, int dx,
-                int h, int w)
-{
-       struct fb_info_promfb *fb = promfbinfod(d);
-       int linesize = d->next_line;
-       unsigned short *src, *dst;
-       int x, y;
-
-       if (dx == 0 && sx == 0 && dy == 0 && sy == 1 &&
-           w == linesize && h == fb->maxy) {
-               memcpy(fb->data, fb->data + linesize, 2 * linesize * fb->maxy);
-               prom_start(fb, d);
-               prom_printf("\033[%d;%dH", fb->maxy + 1, fb->maxx + 1);
-               prom_putchar(*(fb->data + linesize * fb->maxy + fb->maxx));
-               fb->curx = 0;
-               fb->cury = fb->maxy;
-               prom_stop(fb, d);
-       } else if (dy < sy || (dy == sy && dx < sx)) {
-               src = fb->data + sy * linesize + sx;
-               dst = fb->data + dy * linesize + dx;
-               for (y = dy; y < dy + h; y++) {
-                       for (x = dx; x < dx + w; x++) {
-                               if (*src != *dst)
-                                       fbcon_prom_putc(d->conp, d, *src, y, x);
-                               src++;
-                               dst++;
-                       }
-               }
-       } else {
-               src = fb->data + (sy + h - 1) * linesize + sx + w - 1;
-               dst = fb->data + (dy + h - 1) * linesize + dx + w - 1;
-               for (y = dy + h - 1; y >= dy; y--) {
-                       for (x = dx + w - 1; x >= dx; x--) {
-                               if (*src != *dst)
-                                       fbcon_prom_putc(d->conp, d, *src, y, x);
-                               src--;
-                               dst--;
-                       }
-               }
-       }
-}
-
-static void
-fbcon_prom_revc(struct display *d, int x, int y)
-{
-       struct fb_info_promfb *fb = promfbinfod(d);
-       unsigned short *dst = fb->data + y * d->next_line + x;
-       unsigned short val = *dst ^ 0x0800;
-
-       fbcon_prom_putc(d->conp, d, val, y, x);
-}
-
-static void
-fbcon_prom_cursor(struct display *d, int mode, int x, int y)
-{
-       struct fb_info_promfb *fb = promfbinfod(d);
-
-       switch (mode) {
-               case CM_ERASE:
-                       break;
-
-               case CM_MOVE:
-               case CM_DRAW:
-                       prom_start(fb, d);
-                       if (fb->curx != x || fb->cury != y) {
-                               prom_printf("\033[%d;%dH", y + 1, x + 1);
-                               fb->curx = x;
-                               fb->cury = y;
-                       }
-                       break;
-       }
-}
-
-static struct display_switch fbcon_promfb = {
-       fbcon_prom_setup,
-       fbcon_prom_bmove,
-       fbcon_prom_clear,
-       fbcon_prom_putc,
-       fbcon_prom_putcs,
-       fbcon_prom_revc,
-       fbcon_prom_cursor
-};
-
-
-struct promfb_size {
-       int xres, yres;
-       int width, height;
-       int x_margin, y_margin;
-} promfb_sizes[] __initdata = {
-       { 1024, 768, 80, 34, 32, 10 },
-       { 80 * PROM_FONT_WIDTH, 24 * PROM_FONT_HEIGHT, 80, 24, 0, 0 },
-       { 0 }
-};
-
-__initfunc(void promfb_init(void))
-{
-       extern int con_is_present(void);
-       struct fb_info_promfb *fb;
-       struct fb_fix_screeninfo *fix;
-       struct fb_var_screeninfo *var;
-       struct display *disp;
-       struct promfb_size *size;
-       int i, w, h;
-
-       if (!con_is_present())
-               return;
-
-       fb = kmalloc(sizeof(struct fb_info_promfb), GFP_ATOMIC);
-       if (!fb) {
-               prom_printf("Could not allocate promfb structure\n");
-               return;
-       }
-
-       memset(fb, 0, sizeof(struct fb_info_promfb));
-       fix = &fb->fix;
-       var = &fb->var;
-       disp = &fb->disp;
-
-       fb->node = prom_inst2pkg(prom_stdout);
-       w = prom_getintdefault(fb->node, "width", 80 * PROM_FONT_WIDTH);
-       h = prom_getintdefault(fb->node, "height", 24 * PROM_FONT_HEIGHT);
-
-       size = promfb_sizes;
-       while (size->xres) {
-               if (size->xres == w && size->yres == h)
-                       break;
-               size++;
-       }
-       if (!size->xres) {
-               size->xres = w;
-               size->yres = h;
-               size->width = w / PROM_FONT_WIDTH;
-               size->height = h / PROM_FONT_HEIGHT;
-               size->x_margin = (w - size->width * PROM_FONT_WIDTH) >> 1;
-               size->y_margin = (h - size->width * PROM_FONT_HEIGHT) >> 1;
-       }
-
-       fb->data = kmalloc(2 * size->width * size->height, GFP_ATOMIC);
-       if (!fb->data) {
-               kfree(fb);
-               return;
-       }
-
-       fb->maxx = size->width - 1;
-       fb->maxy = size->height - 1;
-
-       strcpy(fb->info.modename, "PROM pseudo");
-       fb->info.node = -1;
-       fb->info.fbops = &promfb_ops;
-       fb->info.disp = disp;
-       fb->info.fontname[0] = '\0';
-       fb->info.changevar = NULL;
-       fb->info.switch_con = promfbcon_switch;
-       fb->info.updatevar = promfbcon_updatevar;
-       fb->info.blank = promfbcon_blank;
-
-       strcpy(fix->id, "PROM pseudo");
-       fix->type = FB_TYPE_TEXT;
-       fix->type_aux = FB_AUX_TEXT_MDA;
-       fix->visual = FB_VISUAL_MONO01;
-       fix->xpanstep = 0;
-       fix->ypanstep = 16;
-       fix->ywrapstep = 0;
-       fix->line_length = size->width;
-       fix->accel = FB_ACCEL_NONE;
-
-       var->xres = size->width * 8;
-       var->yres = size->height * 16;
-       var->xres_virtual = var->xres;
-       var->yres_virtual = var->yres;
-       var->bits_per_pixel = 1;
-       var->xoffset = 0;
-       var->yoffset = 0;
-       var->activate = 0;
-       var->height = -1;
-       var->width = -1;
-       var->accel_flags = FB_ACCELF_TEXT;
-       var->vmode = FB_VMODE_NONINTERLACED;
-
-       disp->var = *var;
-       disp->visual = fix->visual;
-       disp->type = fix->type;
-       disp->type_aux = fix->type_aux;
-       disp->ypanstep = fix->ypanstep;
-       disp->ywrapstep = fix->ywrapstep;
-       disp->line_length = fix->line_length;
-       disp->can_soft_blank = 1;
-       disp->dispsw = &fbcon_promfb;
-
-       for (i = 0; i < fb->maxy * size->width + fb->maxx; i++)
-               fb->data[i] = ' ';
-       prom_printf("\033[H\033[J");
-
-       if (register_framebuffer(&fb->info) < 0) {
-               kfree(fb->data);
-               kfree(fb);
-               return;
-       }
-
-       printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb->info.node),
-              fb->info.modename);
-       MOD_INC_USE_COUNT;
-}
-
-__initfunc(void promfb_setup(char *options, int *ints)) {}
-
-void
-promfb_cleanup(struct fb_info *info)
-{
-       struct fb_info_promfb *fb = promfbinfo(info);
-
-       unregister_framebuffer(info);
-       kfree(fb->data);
-       kfree(fb);
-}
-
-#ifdef MODULE
-int init_module(void)
-{
-       promfb_init();
-       return 0
-}
-
-void cleanup_module(void)
-{
-       promfb_cleanup();
-}
-#endif /* MODULE */
-
diff --git a/drivers/video/promfb.h b/drivers/video/promfb.h
deleted file mode 100644 (file)
index 71a7b70..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* $Id: promfb.h,v 1.1 1998/07/05 22:50:43 ecd Exp $
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _PROMFB_H
-#define _PROMFB_H 1
-
-#include <asm/oplib.h>
-
-#include "fbcon.h"
-
-struct fb_info_promfb {
-       struct fb_info info;
-       struct fb_fix_screeninfo fix;
-       struct fb_var_screeninfo var;
-       struct display disp;
-       struct display_switch dispsw;
-       int node;
-       unsigned short *data;
-       int curx, cury;
-       int maxx, maxy;
-};
-
-#define promfbinfo(info)       ((struct fb_info_promfb *)(info))
-#define promfbinfod(disp)      ((struct fb_info_promfb *)(disp->fb_info))
-
-#endif /* !(_PROM_FB_H) */
index a8d8328fd2e7e73c1450b012136684f9f84be931..0457a7031a16b02731121629059386cb55cc9bc7 100644 (file)
@@ -1676,6 +1676,7 @@ static void fbcon_retz3_8_clear(struct vc_data *conp, struct display *p, int
 
 static struct display_switch fbcon_retz3_8 = {
     fbcon_cfb8_setup, fbcon_retz3_8_bmove, fbcon_retz3_8_clear,
-    fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc
+    fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL,
+    NULL, FONTWIDTH(8)
 };
 #endif
index 833c888ad938ea6273f90a4888a3531843e667e7..d4ecc9899959cba151c784dc36eb89a63fb1374f 100644 (file)
@@ -51,12 +51,14 @@ void sbusfb_init(void);
 void sbusfb_setup(char *options, int *ints);
 
 static int currcon;
-static int nomargins __initdata = 0;
+static int defx_margin = -1, defy_margin = -1;
+static int disable __initdata = 0;
+static char fontname[40] __initdata = { 0 };
 static struct {
        int depth;
        int xres, yres;
        int x_margin, y_margin;
-} def_margins [] __initdata = {
+} def_margins [] = {
        { 8, 1280, 1024, 64, 80 },
        { 8, 1152, 1024, 64, 80 },
        { 8, 1152, 900,  64, 18 },
@@ -145,6 +147,8 @@ static int sbusfb_release(struct fb_info *info, int user)
                        if (fb->mmaped)
                                sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
                }
+               if (fb->reset)
+                       fb->reset(fb);
                fb->open = 0;
        } else
                fb->consolecnt--;
@@ -337,39 +341,7 @@ static int sbusfb_get_var(struct fb_var_screeninfo *var, int con,
 static int sbusfb_set_var(struct fb_var_screeninfo *var, int con,
                        struct fb_info *info)
 {
-#if 1
        return -EINVAL;
-#else
-    struct display *display;
-    int oldbpp = -1, err;
-    int activate = var->activate;
-    struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
-    if (con >= 0)
-       display = &fb_display[con];
-    else
-       display = &fb->disp;    /* used during initialization */
-
-    if (var->xres > fb->var.xres || var->yres > fb->var.yres ||
-       var->xres_virtual > fb->var.xres_virtual ||
-       var->yres_virtual > fb->var.yres_virtual ||
-       var->bits_per_pixel > fb->var.bits_per_pixel ||
-       var->nonstd ||
-       (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-       return -EINVAL;
-    memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
-
-    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, info);
-    }
-    return 0;
-#endif
 }
 
     /*
@@ -487,9 +459,12 @@ static void sbusfb_cursor(struct display *p, int mode, int x, int y)
                        (*fb->setcurshape) (fb);
                        fb->hw_cursor_shown = 1;
                }
-               fb->cursor.cpos.fbx = (x << 3) + fb->x_margin; /* x * p->fontwidth */
-               if (p->fontheight == 16)
-                       fb->cursor.cpos.fby = (y << 4) + fb->y_margin;
+               if (p->fontwidthlog)
+                       fb->cursor.cpos.fbx = (x << p->fontwidthlog) + fb->x_margin;
+               else
+                       fb->cursor.cpos.fbx = (x * p->fontwidth) + fb->x_margin;
+               if (p->fontheightlog)
+                       fb->cursor.cpos.fby = (y << p->fontheightlog) + fb->y_margin;
                else
                        fb->cursor.cpos.fby = (y * p->fontheight) + fb->y_margin;
                (*fb->setcursor)(fb);
@@ -591,7 +566,7 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
        case FBIOGVIDEO:
                put_user_ret(fb->blanked, (int *) arg, -EFAULT);
                break;
-       case FBIOGETCMAP: {
+       case FBIOGETCMAP_SPARC: {
                char *rp, *gp, *bp;
                int end, count, index;
                struct fbcmap *cmap;
@@ -623,7 +598,7 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                (*fb->loadcmap)(fb, index, count);
                break;                  
        }
-       case FBIOPUTCMAP: {     /* load color map entries */
+       case FBIOPUTCMAP_SPARC: {       /* load color map entries */
                char *rp, *gp, *bp;
                int end, count, index;
                struct fbcmap *cmap;
@@ -696,19 +671,63 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
      *  Setup: parse used options
      */
 
-void sbusfb_setup(char *options, int *ints)
+__initfunc(void sbusfb_setup(char *options, int *ints))
 {
-       if (!strncmp(options, "nomargins", 9))
-               nomargins = 1;
+       char *p;
+       
+       for (p = options;;) {
+               if (!strncmp(p, "nomargins", 9)) {
+                       defx_margin = 0; defy_margin = 0;
+               } else if (!strncmp(p, "margins=", 8)) {
+                       int i, j;
+                       char *q;
+                       
+                       i = simple_strtoul(p+8,&q,10);
+                       if (i >= 0 && *q == 'x') {
+                           j = simple_strtoul(q+1,&q,10);
+                           if (j >= 0 && (*q == ' ' || !*q)) {
+                               defx_margin = i; defy_margin = j;
+                           }
+                       }
+               } else if (!strncmp(p, "disable", 7))
+                       disable = 1;
+               else if (!strncmp(p, "font=", 5)) {
+                       int i;
+                       
+                       for (i = 0; i < sizeof(fontname) - 1; i++)
+                               if (p[i+5] == ' ' || !p[i+5])
+                                       break;
+                       memcpy(fontname, p+5, i);
+                       fontname[i] = 0;
+               }
+               while (*p && *p != ' ' && *p != ',') p++;
+               if (*p != ',') break;
+               p++;
+       }
 }
 
 static int sbusfbcon_switch(int con, struct fb_info *info)
 {
+       int x_margin, y_margin;
+       struct fb_info_sbusfb *fb = sbusfbinfo(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, sbusfb_getcolreg, info);
 
-       sbusfbinfo(info)->lastconsole = con;
+       if (fb->lastconsole != con && 
+           (fb_display[fb->lastconsole].fontwidth != fb_display[con].fontwidth ||
+            fb_display[fb->lastconsole].fontheight != fb_display[con].fontheight))
+               fb->hw_cursor_shown = 0;
+       fb->lastconsole = con;
+       x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
+       y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
+       if (fb->margins)
+               fb->margins(fb, &fb_display[con], x_margin, y_margin);
+       if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
+               fb->x_margin = x_margin; fb->y_margin = y_margin;
+               sbusfb_clear_margin(&fb_display[con], 0);
+       }
        currcon = con;
        /* Install new colormap */
        do_install_cmap(con, info);
@@ -731,23 +750,12 @@ static int sbusfbcon_updatevar(int con, struct fb_info *info)
 
 static void sbusfbcon_blank(int blank, struct fb_info *info)
 {
-#if 0
     struct fb_info_sbusfb *fb = sbusfbinfo(info);
-    int i, j;
-
-    if (!fb->cmap_adr)
-       return;
-
-    if (blank)
-       for (i = 0; i < 256; i++) {
-           *fb->cmap_adr = i;
-           for (j = 0; j < 3; j++) {
-               *fb->cmap_data = 0;
-           }
-       }
-    else
-       do_install_cmap(currcon, info);
-#endif
+    
+    if (blank && fb->blank)
+       return fb->blank(fb);
+    else if (!blank && fb->unblank)
+       return fb->unblank(fb);
 }
 
     /*
@@ -805,6 +813,48 @@ static void do_install_cmap(int con, struct fb_info *info)
                (*fb->loadcmap)(fb, 0, 256);
 }
 
+static int sbusfb_set_font(struct display *p, int width, int height)
+{
+       int margin;
+       int w = p->var.xres_virtual, h = p->var.yres_virtual;
+       int depth = p->var.bits_per_pixel;
+       struct fb_info_sbusfb *fb = sbusfbinfod(p);
+       int x_margin, y_margin;
+       
+       if (depth > 8) depth = 8;
+       x_margin = 0;
+       y_margin = 0;
+       if (defx_margin < 0 || defy_margin < 0) {
+               for (margin = 0; def_margins[margin].depth; margin++)
+                       if (w == def_margins[margin].xres &&
+                           h == def_margins[margin].yres &&
+                           depth == def_margins[margin].depth) {
+                               x_margin = def_margins[margin].x_margin;
+                               y_margin = def_margins[margin].y_margin;
+                               break;
+                       }
+       } else {
+               x_margin = defx_margin;
+               y_margin = defy_margin;
+       }
+       x_margin += ((w - 2*x_margin) % width) / 2;
+       y_margin += ((h - 2*y_margin) % height) / 2;
+
+       p->var.xres = w - 2*x_margin;
+       p->var.yres = h - 2*y_margin;
+       
+       fb->hw_cursor_shown = 0;
+       
+       if (fb->margins)
+               fb->margins(fb, p, x_margin, y_margin);
+       if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
+               fb->x_margin = x_margin; fb->y_margin = y_margin;
+               sbusfb_clear_margin(p, 0);
+       }
+
+       return 1;
+}
+
     /*
      *  Initialisation
      */
@@ -852,7 +902,7 @@ __initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
        linebytes = prom_getintdefault(node, "linebytes", w * depth / 8);
        type->fb_size   = PAGE_ALIGN((linebytes) * h);
        
-       if (!nomargins)
+       if (defx_margin < 0 || defy_margin < 0) {
                for (margin = 0; def_margins[margin].depth; margin++)
                        if (w == def_margins[margin].xres &&
                            h == def_margins[margin].yres &&
@@ -861,7 +911,11 @@ __initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
                                fb->y_margin = def_margins[margin].y_margin;
                                break;
                        }
-       fb->x_margin += ((w - 2*fb->x_margin) & 15) / 2;
+       } else {
+               fb->x_margin = defx_margin;
+               fb->y_margin = defy_margin;
+       }
+       fb->x_margin += ((w - 2*fb->x_margin) & 7) / 2;
        fb->y_margin += ((h - 2*fb->y_margin) & 15) / 2;
 
        var->xres_virtual = w;
@@ -883,7 +937,7 @@ __initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
        fb->info.node = -1;
        fb->info.fbops = &sbusfb_ops;
        fb->info.disp = disp;
-       fb->info.fontname[0] = '\0';
+       strcpy(fb->info.fontname, fontname);
        fb->info.changevar = NULL;
        fb->info.switch_con = &sbusfbcon_switch;
        fb->info.updatevar = &sbusfbcon_updatevar;
@@ -934,6 +988,7 @@ __initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
        disp->dispsw = &fb->dispsw;
        if (fb->setcursor)
                fb->dispsw.cursor = sbusfb_cursor;
+       fb->dispsw.set_font = sbusfb_set_font;
        fb->setup = fb->dispsw.setup;
        fb->dispsw.setup = sbusfb_disp_setup;
 
@@ -942,6 +997,9 @@ __initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
        disp->type = fix->type;
        disp->type_aux = fix->type_aux;
        disp->line_length = fix->line_length;
+       
+       if (fb->blank)
+               disp->can_soft_blank = 1;
 
        sbusfb_set_var(var, -1, &fb->info);
 
@@ -978,7 +1036,10 @@ __initfunc(void sbusfb_init(void))
        struct linux_sbus_device *sbdp;
        struct linux_sbus *sbus;
        char prom_name[40];
-    
+       extern int con_is_present(void);
+       
+       if (!con_is_present() || disable) return;
+       
 #ifdef CONFIG_FB_CREATOR
        root = prom_getchild(prom_root_node);
        for (node = prom_searchsiblings(root, "SUNW,ffb"); node;
index 86d43a152327ea2193a9675351ea555180d6a052..b7400e57bb8fb77379c169669384b8b9f261698d 100644 (file)
@@ -21,6 +21,7 @@ struct fb_info_cgsix {
        struct bt_regs *bt;
        struct cg6_fbc *fbc;
        struct cg6_thc *thc;
+       struct cg6_tec *tec;
        volatile u32 *fhc;
 };
 
@@ -76,6 +77,7 @@ struct fb_info_sbusfb {
        void (*loadcmap)(struct fb_info_sbusfb *, int, int);
        void (*blank)(struct fb_info_sbusfb *);
        void (*unblank)(struct fb_info_sbusfb *);
+       void (*margins)(struct fb_info_sbusfb *, struct display *, int, int);
        void (*reset)(struct fb_info_sbusfb *);
        void (*fill)(struct fb_info_sbusfb *, int, int, unsigned short *);
        void (*switch_from_graph)(struct fb_info_sbusfb *);
index c6a31e1c98e72dd3f631035bd0f80d2f15b312f7..86ef76341370d22db14704b5184ffc040eeafbdf 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/selection.h>
 #include <asm/io.h>
 
+#include "fbcon.h"
 #include "fbcon-cfb8.h"
 #include "fbcon-cfb32.h"
 
@@ -743,12 +744,14 @@ __initfunc(void tgafb_init(void))
 #ifdef CONFIG_FBCON_CFB8
        case 0: /* 8-plane */
            disp.dispsw = &fbcon_cfb8;
+           disp.scrollmode = SCROLL_YREDRAW;
            break;
 #endif
 #ifdef CONFIG_FBCON_CFB32
        case 1: /* 24-plane */
        case 3: /* 24plusZ */
            disp.dispsw = &fbcon_cfb32;
+           disp.scrollmode = SCROLL_YREDRAW;
            break;
 #endif
        default:
index 141c8298c872e26f63d88ca5500b29f3473bc251..8887b571b18dd66ec6ad08996a0460fd9df3b208 100644 (file)
@@ -74,23 +74,13 @@ static struct fb_var_screeninfo vesafb_defined = {
        {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 struct { u_char red, green, blue, pad; } palette[256];
 
 static int inverse = 0;
 
-struct vesafb_par
-{
-       void *unused;
-};
-
 static int currcon = 0;
-static int current_par_valid = 0;
-struct vesafb_par current_par;
 
 /* --------------------------------------------------------------------- */
 /* speed up scrolling                                                    */
@@ -98,19 +88,9 @@ struct vesafb_par current_par;
 #define USE_REDRAW   1
 #define USE_MEMMOVE  2
   
-static vesafb_scroll = USE_REDRAW;
+static int vesafb_scroll = USE_REDRAW;
 static struct display_switch vesafb_sw;
 
-void vesafb_bmove(struct display *p, int sy, int sx, int dy, int dx,
-                 int height, int width)
-{
-       /*
-        * this is really faster than memmove (at least with my box)
-        *    read access to video memory is slow...
-        */
-       update_screen(currcon);
-}
-
 /* --------------------------------------------------------------------- */
 
        /*
@@ -132,33 +112,13 @@ static int vesafb_release(struct fb_info *info, int user)
        return(0);
 }
 
-static void vesafb_encode_var(struct fb_var_screeninfo *var, 
-                               struct vesafb_par *par)
-{
-       memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
-}
-
-static void vesafb_get_par(struct vesafb_par *par)
-{
-       *par=current_par;
-}
-
 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 vesafb_par par;
-       
-       vesafb_get_par(&par);
-       vesafb_encode_var(var, &par);
-       return 0;
-}
-
-static void vesafb_encode_fix(struct fb_fix_screeninfo *fix, 
-                               struct vesafb_par *par)
+static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                        struct fb_info *info)
 {
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
        strcpy(fix->id,"VESA VGA");
@@ -171,27 +131,14 @@ static void vesafb_encode_fix(struct fb_fix_screeninfo *fix,
        fix->ypanstep=0;
        fix->ywrapstep=0;
        fix->line_length=video_linelength;
-       return;
-}
-
-static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
-                        struct fb_info *info)
-{
-       struct vesafb_par par;
-       vesafb_get_par(&par);
-       vesafb_encode_fix(fix, &par);
        return 0;
 }
 
 static int vesafb_get_var(struct fb_var_screeninfo *var, int con,
                         struct fb_info *info)
 {
-       struct vesafb_par par;
        if(con==-1)
-       {
-               vesafb_get_par(&par);
-               vesafb_encode_var(var, &par);
-       }
+               memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
        else
                *var=fb_display[con].var;
        return 0;
@@ -201,6 +148,7 @@ static void vesafb_set_disp(int con)
 {
        struct fb_fix_screeninfo fix;
        struct display *display;
+       struct display_switch *sw;
        
        if (con >= 0)
                display = &fb_display[con];
@@ -209,6 +157,7 @@ static void vesafb_set_disp(int con)
 
        vesafb_get_fix(&fix, con, 0);
 
+       memset(display, 0, sizeof(struct display));
        display->screen_base = video_vbase;
        display->visual = fix.visual;
        display->type = fix.type;
@@ -219,42 +168,40 @@ static void vesafb_set_disp(int con)
        display->next_line = fix.line_length;
        display->can_soft_blank = 0;
        display->inverse = inverse;
+       vesafb_get_var(&display->var, -1, &fb_info);
 
        switch (video_bpp) {
 #ifdef CONFIG_FBCON_CFB8
        case 8:
-               display->dispsw = &fbcon_cfb8;
+               sw = &fbcon_cfb8;
                break;
 #endif
 #ifdef CONFIG_FBCON_CFB16
        case 15:
        case 16:
-               display->dispsw = &fbcon_cfb16;
+               sw = &fbcon_cfb16;
                break;
 #endif
 #ifdef CONFIG_FBCON_CFB32
        case 32:
-               display->dispsw = &fbcon_cfb32;
+               sw = &fbcon_cfb32;
                break;
 #endif
        default:
-               display->dispsw = NULL;
-               break;
+               return;
        }
+       memcpy(&vesafb_sw, sw, sizeof(*sw));
+       display->dispsw = &vesafb_sw;
        if (vesafb_scroll == USE_REDRAW) {
-               memcpy(&vesafb_sw,display->dispsw,sizeof(vesafb_sw));
-               vesafb_sw.bmove = vesafb_bmove;
-               display->dispsw = &vesafb_sw;
+               display->scrollmode = SCROLL_YREDRAW;
+               vesafb_sw.bmove = fbcon_redraw_bmove;
        }
 }
 
 static int vesafb_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;
+       memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
        return 0;
 }
 
@@ -297,7 +244,7 @@ static int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,
        switch (video_bpp) {
 #ifdef CONFIG_FBCON_CFB8
        case 8:
-               /* Hmm, can we do it _allways_ this way ??? */
+               /* Hmm, can we do it _always_ this way ??? */
                outb_p(regno, dac_reg);
                outb_p(red, dac_val);
                outb_p(green, dac_val);
@@ -432,7 +379,6 @@ static int vesafb_switch(int con, struct fb_info *info)
        currcon = con;
        /* Install new colormap */
        do_install_cmap(con, info);
-       fb_update_var(con, info);
        return 0;
 }
 
@@ -515,9 +461,6 @@ __initfunc(void vesafb_init(void))
        fb_info.switch_con=&vesafb_switch;
        fb_info.updatevar=&fb_update_var;
        fb_info.blank=&vesafb_blank;
-       do_fb_set_var(&vesafb_defined,1);
-
-       vesafb_get_var(&disp.var, -1, &fb_info);
        vesafb_set_disp(-1);
 
        if (register_framebuffer(&fb_info)<0)
index 94a13dacccbd473dec12c8d4bc4f106f6c1bded8..9d1f03bb0b9231846753988ea47adf5cbb4bbb6e 100644 (file)
@@ -37,8 +37,6 @@
  *
  *     - monochrome attribute encoding (convert abscon <-> VGA style)
  *
- *     - add support for VESA blanking
- *
  *     - Cursor shape fixes
  *
  * KNOWN PROBLEMS/TO DO ==================================================== */
 
 #undef VGA_CAN_DO_64KB
 
-#define dac_reg        (0x3c8)
-#define dac_val        (0x3c9)
+#define dac_reg                0x3c8
+#define dac_val                0x3c9
+#define attrib_port    0x3c0
+#define seq_port_reg   0x3c4
+#define seq_port_val   0x3c5
+#define gr_port_reg    0x3ce
+#define gr_port_val    0x3cf
+#define video_misc_rd  0x3cc
+#define video_misc_wr  0x3c2
 
 /*
  *  Interface used by the world
 
 static const char *vgacon_startup(void);
 static void vgacon_init(struct vc_data *c, int init);
+static void vgacon_deinit(struct vc_data *c);
 static void vgacon_cursor(struct vc_data *c, int mode);
 static int vgacon_switch(struct vc_data *c);
-static int vgacon_blank(int blank);
+static int vgacon_blank(struct vc_data *c, int blank);
 static int vgacon_get_font(struct vc_data *c, int *w, int *h, char *data);
 static int vgacon_set_font(struct vc_data *c, int w, int h, char *data);
 static int vgacon_set_palette(struct vc_data *c, unsigned char *table);
@@ -103,6 +109,10 @@ static unsigned char   vga_video_type;             /* Card type */
 static unsigned char   vga_hardscroll_enabled;
 static unsigned char   vga_hardscroll_user_enable = 1;
 static unsigned char   vga_font_is_default = 1;
+static int            vga_vesa_blanked;
+static int            vga_palette_blanked;
+static int            vga_is_gfx;
+
 
 void no_scroll(char *str, int *ints)
 {
@@ -114,7 +124,6 @@ void no_scroll(char *str, int *ints)
        vga_hardscroll_user_enable = vga_hardscroll_enabled = 0;
 }
 
-
 /*
  * By replacing the four outb_p with two back to back outw, we can reduce
  * the window of opportunity to see text mislocated to the RHS of the
@@ -139,13 +148,23 @@ static inline void write_vga(unsigned char reg, unsigned int val)
 #endif
 }
 
-
 __initfunc(static const char *vgacon_startup(void))
 {
        const char *display_desc = NULL;
        u16 saved;
        u16 *p;
 
+       if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
+       no_vga:
+#ifdef CONFIG_DUMMY_CONSOLE
+               conswitchp = &dummy_con;
+               return conswitchp->con_startup();
+#else
+               return NULL;
+#endif
+       }
+
+
        vga_video_num_lines = ORIG_VIDEO_LINES;
        vga_video_num_columns = ORIG_VIDEO_COLS;
 
@@ -178,7 +197,7 @@ __initfunc(static const char *vgacon_startup(void))
                vga_video_port_val = 0x3d5;
                if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
                {
-                       int i ;
+                       int i;
 
                        vga_vram_end = 0xc0000;
 
@@ -248,12 +267,12 @@ __initfunc(static const char *vgacon_startup(void))
        scr_writew(0xAA55, p);
        if (scr_readw(p) != 0xAA55) {
                scr_writew(saved, p);
-               return NULL;
+               goto no_vga;
        }
        scr_writew(0x55AA, p);
        if (scr_readw(p) != 0x55AA) {
                scr_writew(saved, p);
-               return NULL;
+               goto no_vga;
        }
        scr_writew(saved, p);
 
@@ -271,7 +290,6 @@ __initfunc(static const char *vgacon_startup(void))
        return display_desc;
 }
 
-
 static void vgacon_init(struct vc_data *c, int init)
 {
        /* We cannot be loaded as a module, therefore init is always 1 */
@@ -280,13 +298,16 @@ static void vgacon_init(struct vc_data *c, int init)
        c->vc_rows = vga_video_num_lines;
 }
 
+static void vgacon_deinit(struct vc_data *c)
+{
+       vgacon_set_origin(c);
+}
 
 static inline void vga_set_mem_top(struct vc_data *c)
 {
        write_vga(12, (c->vc_visible_origin-vga_vram_base)/2);
 }
 
-
 static void vgacon_cursor(struct vc_data *c, int mode)
 {
     if (c->vc_origin != c->vc_visible_origin)
@@ -303,7 +324,6 @@ static void vgacon_cursor(struct vc_data *c, int mode)
     }
 }
 
-
 static int vgacon_switch(struct vc_data *c)
 {
        /*
@@ -317,21 +337,198 @@ static int vgacon_switch(struct vc_data *c)
        return 0;       /* Redrawing not needed */
 }
 
+static void vga_set_palette(struct vc_data *c, unsigned char *table)
+{
+       int i, j ;
+
+       for (i=j=0; i<16; i++) {
+               outb_p (table[i], dac_reg) ;
+               outb_p (c->vc_palette[j++]>>2, dac_val) ;
+               outb_p (c->vc_palette[j++]>>2, dac_val) ;
+               outb_p (c->vc_palette[j++]>>2, dac_val) ;
+       }
+}
 
-static int vgacon_blank(int blank)
+static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
 {
-    /* FIXME: Implement! */
-    /* FIXME: Check if we really ignore everything when the console is blanked. */
-    if (blank) {
-       scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
+#ifdef CAN_LOAD_PALETTE
+
+       if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked)
+               return -EINVAL;
+       vga_set_palette(c, table);
        return 0;
-    } else {
-       /* Tell console.c that it has to restore the screen itself */
-       return 1;
-    }
-    return 0;
+#else
+       return -EINVAL;
+#endif
 }
 
+/* structure holding original VGA register settings */
+static struct {
+       unsigned char   SeqCtrlIndex;           /* Sequencer Index reg.   */
+       unsigned char   CrtCtrlIndex;           /* CRT-Contr. Index reg.  */
+       unsigned char   CrtMiscIO;              /* Miscellaneous register */
+       unsigned char   HorizontalTotal;        /* CRT-Controller:00h */
+       unsigned char   HorizDisplayEnd;        /* CRT-Controller:01h */
+       unsigned char   StartHorizRetrace;      /* CRT-Controller:04h */
+       unsigned char   EndHorizRetrace;        /* CRT-Controller:05h */
+       unsigned char   Overflow;               /* CRT-Controller:07h */
+       unsigned char   StartVertRetrace;       /* CRT-Controller:10h */
+       unsigned char   EndVertRetrace;         /* CRT-Controller:11h */
+       unsigned char   ModeControl;            /* CRT-Controller:17h */
+       unsigned char   ClockingMode;           /* Seq-Controller:01h */
+} vga_state;
+
+static void vga_vesa_blank(int mode)
+{
+       /* save original values of VGA controller registers */
+       if(!vga_vesa_blanked) {
+               cli();
+               vga_state.SeqCtrlIndex = inb_p(seq_port_reg);
+               vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
+               vga_state.CrtMiscIO = inb_p(video_misc_rd);
+               sti();
+
+               outb_p(0x00,vga_video_port_reg);        /* HorizontalTotal */
+               vga_state.HorizontalTotal = inb_p(vga_video_port_val);
+               outb_p(0x01,vga_video_port_reg);        /* HorizDisplayEnd */
+               vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
+               outb_p(0x04,vga_video_port_reg);        /* StartHorizRetrace */
+               vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
+               outb_p(0x05,vga_video_port_reg);        /* EndHorizRetrace */
+               vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
+               outb_p(0x07,vga_video_port_reg);        /* Overflow */
+               vga_state.Overflow = inb_p(vga_video_port_val);
+               outb_p(0x10,vga_video_port_reg);        /* StartVertRetrace */
+               vga_state.StartVertRetrace = inb_p(vga_video_port_val);
+               outb_p(0x11,vga_video_port_reg);        /* EndVertRetrace */
+               vga_state.EndVertRetrace = inb_p(vga_video_port_val);
+               outb_p(0x17,vga_video_port_reg);        /* ModeControl */
+               vga_state.ModeControl = inb_p(vga_video_port_val);
+               outb_p(0x01,seq_port_reg);              /* ClockingMode */
+               vga_state.ClockingMode = inb_p(seq_port_val);
+       }
+
+       /* assure that video is enabled */
+       /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
+       cli();
+       outb_p(0x01,seq_port_reg);
+       outb_p(vga_state.ClockingMode | 0x20,seq_port_val);
+
+       /* test for vertical retrace in process.... */
+       if ((vga_state.CrtMiscIO & 0x80) == 0x80)
+               outb_p(vga_state.CrtMiscIO & 0xef,video_misc_wr);
+
+       /*
+        * Set <End of vertical retrace> to minimum (0) and
+        * <Start of vertical Retrace> to maximum (incl. overflow)
+        * Result: turn off vertical sync (VSync) pulse.
+        */
+       if (mode & VESA_VSYNC_SUSPEND) {
+               outb_p(0x10,vga_video_port_reg);        /* StartVertRetrace */
+               outb_p(0xff,vga_video_port_val);        /* maximum value */
+               outb_p(0x11,vga_video_port_reg);        /* EndVertRetrace */
+               outb_p(0x40,vga_video_port_val);        /* minimum (bits 0..3)  */
+               outb_p(0x07,vga_video_port_reg);        /* Overflow */
+               outb_p(vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
+       }
+
+       if (mode & VESA_HSYNC_SUSPEND) {
+               /*
+                * Set <End of horizontal retrace> to minimum (0) and
+                *  <Start of horizontal Retrace> to maximum
+                * Result: turn off horizontal sync (HSync) pulse.
+                */
+               outb_p(0x04,vga_video_port_reg);        /* StartHorizRetrace */
+               outb_p(0xff,vga_video_port_val);        /* maximum */
+               outb_p(0x05,vga_video_port_reg);        /* EndHorizRetrace */
+               outb_p(0x00,vga_video_port_val);        /* minimum (0) */
+       }
+
+       /* restore both index registers */
+       outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
+       outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+       sti();
+}
+
+static void vga_vesa_unblank(void)
+{
+       /* restore original values of VGA controller registers */
+       cli();
+       outb_p(vga_state.CrtMiscIO,video_misc_wr);
+
+       outb_p(0x00,vga_video_port_reg);                /* HorizontalTotal */
+       outb_p(vga_state.HorizontalTotal,vga_video_port_val);
+       outb_p(0x01,vga_video_port_reg);                /* HorizDisplayEnd */
+       outb_p(vga_state.HorizDisplayEnd,vga_video_port_val);
+       outb_p(0x04,vga_video_port_reg);                /* StartHorizRetrace */
+       outb_p(vga_state.StartHorizRetrace,vga_video_port_val);
+       outb_p(0x05,vga_video_port_reg);                /* EndHorizRetrace */
+       outb_p(vga_state.EndHorizRetrace,vga_video_port_val);
+       outb_p(0x07,vga_video_port_reg);                /* Overflow */
+       outb_p(vga_state.Overflow,vga_video_port_val);
+       outb_p(0x10,vga_video_port_reg);                /* StartVertRetrace */
+       outb_p(vga_state.StartVertRetrace,vga_video_port_val);
+       outb_p(0x11,vga_video_port_reg);                /* EndVertRetrace */
+       outb_p(vga_state.EndVertRetrace,vga_video_port_val);
+       outb_p(0x17,vga_video_port_reg);                /* ModeControl */
+       outb_p(vga_state.ModeControl,vga_video_port_val);
+       outb_p(0x01,seq_port_reg);              /* ClockingMode */
+       outb_p(vga_state.ClockingMode,seq_port_val);
+
+       /* restore index/control registers */
+       outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
+       outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+       sti();
+}
+
+static void vga_pal_blank(void)
+{
+       int i;
+
+       for (i=0; i<16; i++) {
+               outb_p (i, dac_reg) ;
+               outb_p (0, dac_val) ;
+               outb_p (0, dac_val) ;
+               outb_p (0, dac_val) ;
+       }
+}
+
+static int vgacon_blank(struct vc_data *c, int blank)
+{
+       switch (blank) {
+       case 0:                         /* Unblank */
+               if (vga_vesa_blanked) {
+                       vga_vesa_unblank();
+                       vga_vesa_blanked = 0;
+               }
+               if (vga_palette_blanked) {
+                       vga_set_palette(c, color_table);
+                       vga_palette_blanked = 0;
+                       return 0;
+               }
+               vga_is_gfx = 0;
+               /* Tell console.c that it has to restore the screen itself */
+               return 1;
+       case 1:                         /* Normal blanking */
+               if (vga_video_type == VIDEO_TYPE_VGAC) {
+                       vga_pal_blank();
+                       vga_palette_blanked = 1;
+                       return 0;
+               }
+               scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
+               return 0;
+       case -1:                        /* Entering graphic mode */
+               scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
+               vga_is_gfx = 1;
+               return 0;
+       default:                        /* VESA blanking */
+               if (vga_video_type == VIDEO_TYPE_VGAC) {
+                       vga_vesa_blank(blank-1);
+                       vga_vesa_blanked = blank;
+               }
+               return 0;
+       }
+}
 
 /*
  * PIO_FONT support.
@@ -350,11 +547,6 @@ static int vgacon_blank(int blank)
    should use 0xA0000 for the bwmap as well.. */
 #define blackwmap 0xa0000
 #define cmapsz 8192
-#define attrib_port (0x3c0)
-#define seq_port_reg (0x3c4)
-#define seq_port_val (0x3c5)
-#define gr_port_reg (0x3ce)
-#define gr_port_val (0x3cf)
 
 static int
 vgacon_font_op(char *arg, int set)
@@ -578,26 +770,6 @@ static int vgacon_set_font(struct vc_data *c, int w, int h, char *data)
        return rc;
 }
 
-static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
-{
-#ifdef CAN_LOAD_PALETTE
-       int i, j ;
-
-       if (vga_video_type != VIDEO_TYPE_VGAC || console_blanked)
-               return -EINVAL;
-
-       for (i=j=0; i<16; i++) {
-               outb_p (table[i], dac_reg) ;
-               outb_p (c->vc_palette[j++]>>2, dac_val) ;
-               outb_p (c->vc_palette[j++]>>2, dac_val) ;
-               outb_p (c->vc_palette[j++]>>2, dac_val) ;
-       }
-       return 0;
-#else
-       return -EINVAL;
-#endif
-}
-
 static int vgacon_scrolldelta(struct vc_data *c, int lines)
 {
        /* FIXME: Better scrollback strategy, maybe move it to generic code
@@ -620,6 +792,8 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
 
 static int vgacon_set_origin(struct vc_data *c)
 {
+       if (vga_is_gfx)         /* We don't play origin tricks in graphic modes */
+               return 0;
        c->vc_origin = c->vc_visible_origin = vga_vram_base;
        vga_set_mem_top(c);
        return 1;
@@ -645,7 +819,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
 {
        unsigned long oldo;
        
-       if (t || b != c->vc_rows)
+       if (t || b != c->vc_rows || vga_is_gfx)
                return 0;
 
        if (c->vc_origin != c->vc_visible_origin)
@@ -672,7 +846,6 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
 }
 
 
-
 /*
  *  The console `switch' structure for the VGA based console
  */
@@ -687,7 +860,7 @@ static int vgacon_dummy(struct vc_data *c)
 struct consw vga_con = {
        vgacon_startup,
        vgacon_init,
-       DUMMY,                          /* con_deinit */
+       vgacon_deinit,
        DUMMY,                          /* con_clear */
        DUMMY,                          /* con_putc */
        DUMMY,                          /* con_putcs */
index d502c4768150b8bcdb09270c7c7f40208e261bab..c12ba23f8d257470ebf4ea4529601cab8bcb74be 100644 (file)
@@ -745,7 +745,7 @@ static void do_install_cmap(int con, struct fb_info *info)
 
 static struct display_switch fbcon_vgafb = {
     fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
-    fbcon_vga_putcs, fbcon_vga_revc, fbcon_vgafb_cursor
+    fbcon_vga_putcs, fbcon_vga_revc, fbcon_vgafb_cursor, NULL, FONTWIDTH(8)
 };
 
 
index e88f02854b3dc5ecc329a049542bec6044b3b74c..85b3cfc61b76ffa8f7732dcfb8d9478a21a9f4cc 100644 (file)
@@ -1163,7 +1163,7 @@ static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
 
 static struct display_switch fbcon_virge8 = {
    fbcon_cfb8_setup, fbcon_virge8_bmove, fbcon_virge8_clear, fbcon_cfb8_putc,
-   fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL
+   fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, FONTWIDTH(8)
 };
 #endif
 
index 565b59dd05dbfcd425cda879a5a86b62e113f7ab..7b2d9ee95a44683b0546b43cc149d37de0c1a4e2 100644 (file)
@@ -37,7 +37,7 @@
 
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS                        \       
+#define EXTRA_SERIAL_PORT_DEFNS                        \
        { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS },     /* ttyS4 */     \
        { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },     /* ttyS5 */     \
        { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },     /* ttyS6 */     \
index 1639e6d46d5a0493600ca582dec33a473e413704..0b77060c5b477c57475f094f86489d5bb52e573c 100644 (file)
@@ -159,7 +159,18 @@ DECLARE_IO(long,l,"")
        result & 0xffff;                                                        \
 })
 
-#define __outlc(v,p) __outwc((v),(p))
+#define __outlc(value,port)                                                    \
+({                                                                             \
+       unsigned long v = value;                                                \
+       if (__PORT_PCIO((port)))                                                \
+               __asm__ __volatile__(                                           \
+               "str    %0, [%1, %2]"                                           \
+               : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2));              \
+       else                                                                    \
+               __asm__ __volatile__(                                           \
+               "str    %0, [%1, %2]"                                           \
+               : : "r" (v), "r" (IO_BASE), "r" ((port) << 2));                 \
+})
 
 #define __inlc(port)                                                           \
 ({                                                                             \
index 02ffd86379a550fd4da76876674540a25720387f..314525eefd3f7398167506626eca483b70473151 100644 (file)
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
+#if 0
 #define TASK_UNMAPPED_BASE(off)        (TASK_SIZE / 3)
+#else
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+#endif
 #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
index e4dcb27e14bc251672ce73e7d85fbcd9eacbe3ba..bf1f6d384158564572b380ac12bcfd82657bbf3c 100644 (file)
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
+#if 0
 #define TASK_UNMAPPED_BASE(off)        (TASK_SIZE / 3)
+#else
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+#endif
 #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
index 8d6af3b1b21d8abd6601321519023120b56a61e5..a9bc6f0a45a9e4895f0a4b9755bc63554af31fdd 100644 (file)
  * 0xfd000000  0x78000000      Outbound write flush
  * 0xfc000000  0x79000000      PCI IACK/special space
  *
- * 0xf9030000  0x7a080000      PCI Config type 1 card 4
- * 0xf9020000  0x7a040000      PCI Config type 1 card 3
- * 0xf9010000  0x7a020000      PCI Config type 1 card 2
- * 0xf9000000  0x7a010000      PCI Config type 1 card 1
- *
- * 0xf8030000  0x7b080000      PCI Config type 0 card 4
- * 0xf8020000  0x7b040000      PCI Config type 0 card 3
- * 0xf8010000  0x7b020000      PCI Config type 0 card 2
- * 0xf8000000  0x7b010000      PCI Config type 0 card 1
+ * 0xf9000000  0x7a010000      PCI Config type 1
+ * 0xf8000000  0x7b010000      PCI Config type 0
  * 
  */
  
index 07006f82ec8920440ed7c848139e1a8d814db1e9..8e2e98ef63e85b6c7b1509f4f79be90572bb5cf6 100644 (file)
@@ -1,26 +1,25 @@
 /*
- * linux/include/asm-arm/arch-ebsa110/mmu.h
+ * linux/include/asm-arm/arch-ebsa285/mmu.h
  *
  * Copyright (c) 1996,1997,1998 Russell King.
  *
  * Changelog:
  *  20-10-1996 RMK     Created
  *  31-12-1997 RMK     Fixed definitions to reduce warnings
+ *  17-05-1998 DAG     Added __virt_to_bus and __bus_to_virt functions.
  */
 #ifndef __ASM_ARCH_MMU_H
 #define __ASM_ARCH_MMU_H
 
 /*
- * On ebsa, the dram is contiguous
+ * On ebsa285, the dram is contiguous
  */
 #define __virt_to_phys__is_a_macro
 #define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
 #define __phys_to_virt__is_a_macro
 #define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
 
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)       __virt_to_phys(x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)       __phys_to_virt(x)
+extern unsigned long __virt_to_bus(unsigned long);
+extern unsigned long __bus_to_virt(unsigned long);
 
 #endif
diff --git a/include/asm-arm/arch-ebsa285/serial.h b/include/asm-arm/arch-ebsa285/serial.h
new file mode 100644 (file)
index 0000000..e824c8d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * linux/include/asm-arm/arch-ebsa285/serial.h
+ *
+ * Copyright (c) 1996,1997,1998 Russell King.
+ *
+ * Changelog:
+ *  15-10-1996 RMK     Created
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1843200 / 16)
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+     /* UART CLK        PORT  IRQ     FLAGS        */
+#define SERIAL_PORT_DFNS \
+       { 0, BASE_BAUD, 0x3F8,  0, STD_COM_FLAGS },     /* ttyS0 */     \
+       { 0, BASE_BAUD, 0x2F8,  0, STD_COM_FLAGS },     /* ttyS1 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS2 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS3 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS4 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS5 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS6 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS7 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS8 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS9 */     \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS10 */    \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS11 */    \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS12 */    \
+       { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS13 */
+
+#endif
+
index 5068032a9419b6bbd9534fa849a80d2a207b7660..cf25a5deae6d1413aae5ac0d5679da9267e125a4 100644 (file)
@@ -4,35 +4,35 @@
  * Copyright (C) 1998 Philip Blundell
  */
 
-#define INT_RESET      ((volatile unsigned char *)0xfff00000)
-#define INT_ENABLE     ((volatile unsigned char *)0xfff00000)
-#define INT_DISABLE    ((volatile unsigned char *)0xfff00000)
+#include <asm/io.h>
 
-static __inline__ void mask_and_ack_irq(unsigned int irq)
-{
-       INT_DISABLE[irq << 2] = 0;
-       INT_RESET[irq << 2] = 0;
-}
+#define INTCONT                0xffe00000
+
+extern unsigned long soft_irq_mask;
 
 static __inline__ void mask_irq(unsigned int irq)
 {
-       INT_DISABLE[irq << 2] = 0;
+       writel((irq << 1), INTCONT);
+       soft_irq_mask &= ~(1<<irq);
 }
 
+#define mask_and_ack_irq(_x)   mask_irq(_x)
+
 static __inline__ void unmask_irq(unsigned int irq)
 {
-       INT_ENABLE[irq << 2] = 0;
+       writel((irq << 1) + 1, INTCONT);
+       soft_irq_mask |= (1<<irq);
 }
  
 static __inline__ unsigned long get_enabled_irqs(void)
 {
-       return 0;
+       return soft_irq_mask;
 }
 
 static __inline__ void irq_init_irq(void)
 {
        unsigned int i;
        /* Disable all interrupts initially. */
-       for (i = 0; i < 8; i++)
+       for (i = 0; i < NR_IRQS; i++)
                mask_irq(i);
 }
index 8b052239101dea0672049cd70f37e98460a0fc94..69af6e833b5d6b6b057703d7845a6fd5cf07fc18 100644 (file)
@@ -1,19 +1,32 @@
 /*
  * linux/include/asm-arm/arch-nexuspci/irqs.h
  *
- * Copyright (C) 1997 Philip Blundell
+ * Copyright (C) 1997, 1998 Philip Blundell
  */
 
-#define IRQ_DUART              0
-#define IRQ_PLX                1
-#define IRQ_PCI_D              2
-#define IRQ_PCI_C              3
-#define IRQ_PCI_B              4
-#define IRQ_PCI_A              5
-#define IRQ_SYSERR             6
+/* Most of the IRQ sources can generate both FIQs and IRQs.
+   The exceptions to this are the DUART, which can only generate IRQs,
+   and the PLX SYSERR output, which can only generate FIQs.  We route
+   both FIQs and IRQs through the generic IRQ handling system and the
+   choice by the driver of which to use is basically an arbitrary one.  */
+
+#define TREAT_FIQS_AS_IRQS
+
+#define FIQ_PLX                        0
+#define FIQ_PCI_D              1
+#define FIQ_PCI_C              2
+#define FIQ_PCI_B              3
+#define FIQ_PCI_A              4
+#define FIQ_SYSERR             5
+
+#define IRQ_DUART              6
+#define IRQ_PLX                7
+#define IRQ_PCI_D              8
+#define IRQ_PCI_C              9
+#define IRQ_PCI_B              10
+#define IRQ_PCI_A              11
 
 /* timer is part of the DUART */
 #define IRQ_TIMER              IRQ_DUART
 
 #define irq_cannonicalize(i)   (i)
-
index 9bccb9d6a3a10a07828a45c4547b8be3469c3d30..9ecce067f07fef6ff50d40c1aca2ab87caf05773 100644 (file)
 #define __phys_to_virt__is_a_macro
 
 /*
- * These are exactly the same as the physical memory view.
+ * On the PCI bus the DRAM appears at address 0
  */
 #define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x) __virt_to_phys(x)
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
 #define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x) __phys_to_virt(x)
+#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
 
 #endif
index 26c9bb255a585be39b6773d46b754e956324b9fe..da9fdd583c9f51b0607fd19998243ce6bbd59908 100644 (file)
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
+#if 0
 #define TASK_UNMAPPED_BASE(off)        (TASK_SIZE / 3)
+#else
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+#endif
 #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
index 1b610aaa25e696a353c820f3f3e90ab752cd4a8b..1f3fa401f7433d8ec153d3e6a04988b705605d14 100644 (file)
@@ -3,10 +3,13 @@
  *
  * Copyright (c) 1997 Phil Blundell.
  *
- * Nexus PCI card has no real-time clock.
- *
+ * Nexus PCI card has no real-time clock.  We get timer ticks from the
+ * SCC chip.
  */
 
+#define UART_BASE              0xfff00000
+#define INTCONT                        0xffe00000
+
 #define update_rtc()
 
 extern __inline__ unsigned long gettimeoffset (void)
@@ -16,12 +19,31 @@ extern __inline__ unsigned long gettimeoffset (void)
 
 extern __inline__ int reset_timer (void)
 {
-       return 0;
+       static int count = 50;
+       writeb(0x90, UART_BASE + 8);
+       if (--count == 0)
+       {
+               static int state = 1;
+               state ^= 1;
+               writeb(0x1a + state, INTCONT);
+               count = 50;
+       }
+       readb(UART_BASE + 0x14);
+       readb(UART_BASE + 0x14);
+       readb(UART_BASE + 0x14);
+       readb(UART_BASE + 0x14);
+       readb(UART_BASE + 0x14);
+       readb(UART_BASE + 0x14);
+       return 1;
 }
 
 extern __inline__ unsigned long setup_timer (void)
 {
-       reset_timer ();
+       int tick = 3686400 / 16 / 2 / 100;
+       writeb(tick & 0xff, UART_BASE + 0x1c);
+       writeb(tick >> 8, UART_BASE + 0x18);
+       writeb(0x80, UART_BASE + 8);
+       writeb(0x10, UART_BASE + 0x14);
        /*
         * Default the date to 1 Jan 1970 0:0:0
         * You will have to run a time daemon to set the
index 75e112e9861afe3403e9bcbdbacb04bb1ce06c68..706992b787ee3a9bbbc2eaf5b00e646ac4b1fe58 100644 (file)
@@ -53,7 +53,7 @@
 /*
  * Mapping areas
  */
-#define IO_END                 0xe0ffffff
+#define IO_END                 0xe1000000
 #define IO_BASE                        0xe0000000
 #define IO_SIZE                        (IO_END - IO_BASE)
 
index 60d3f0b8c2aae22bba50f1e9708c66572fc60f4b..44090e12263f06472a2d0cb21453095727fd4e38 100644 (file)
@@ -28,7 +28,11 @@ extern unsigned char ps2kbd_sysrq_xlate[NR_SCANCODES];
  * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
  *            set to 0200 if scancode indicates release
  */
+#ifdef NEW_KEYBOARD
 #define kbd_translate(sc, kcp, ufp, rm)        ps2kbd_translate(sc, kcp, ufp)
+#else
+#define kbd_translate(sc, kcp, rm) ({ unsigned int up_flag; ps2kbd_translate(sc, kcp, &up_flag); })
+#endif
 #define kbd_unexpected_up(kc)          (0200)
 #define kbd_leds(leds)                 ps2kbd_leds(leds)
 #define kbd_init_hw()                  ps2kbd_init_hw()
index 7188ec3711b1501d8fa19f7068babf65f17cf886..cdb79eeed70b3dcd2fd31a916aa3e574bca98004 100644 (file)
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
+#if 0
 #define TASK_UNMAPPED_BASE(off)        (TASK_SIZE / 3)
+#else
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+#endif
 #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
diff --git a/include/asm-arm/arch-vnc/a.out.h b/include/asm-arm/arch-vnc/a.out.h
new file mode 100644 (file)
index 0000000..0123eb2
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/a.out.h
+ *
+ * Copyright (C) 1996 Russell King
+ */
+
+#ifndef __ASM_ARCH_A_OUT_H
+#define __ASM_ARCH_A_OUT_H
+
+#ifdef __KERNEL__
+#define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
+#define LIBRARY_START_TEXT     (0x00c00000)
+#endif
+
+#endif
+
diff --git a/include/asm-arm/arch-vnc/dma.h b/include/asm-arm/arch-vnc/dma.h
new file mode 100644 (file)
index 0000000..96a2659
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/dma.h
+ *
+ * Architecture DMA routes
+ *
+ * Copyright (C) 1997.1998 Russell King
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * This is the maximum DMA address that can be DMAd to.
+ * There should not be more than (0xd0000000 - 0xc0000000)
+ * bytes of RAM.
+ */
+#define MAX_DMA_ADDRESS                0xd0000000
+
+/*
+ * DMA modes - we have two, IN and OUT
+ */
+typedef enum {
+       DMA_MODE_READ,
+       DMA_MODE_WRITE
+} dmamode_t;
+
+#define MAX_DMA_CHANNELS       8
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff --git a/include/asm-arm/arch-vnc/hardware.h b/include/asm-arm/arch-vnc/hardware.h
new file mode 100644 (file)
index 0000000..9474566
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * linux/include/asm-arm/arch-vnc/hardware.h
+ *
+ * Copyright (C) 1998 Corel Computer/Russell King.
+ *
+ * This file contains the hardware definitions of the VNC.
+ */
+
+/*    Logical    Physical
+ * 0xfff00000  0x40000000      X-Bus
+ * 0xffe00000  0x7c000000      PCI I/O space
+ *
+ * 0xfe000000  0x42000000      CSR
+ * 0xfd000000  0x78000000      Outbound write flush
+ * 0xfc000000  0x79000000      PCI IACK/special space
+ *
+ * 0xf9030000  0x7a080000      PCI Config type 1 card 4
+ * 0xf9020000  0x7a040000      PCI Config type 1 card 3
+ * 0xf9010000  0x7a020000      PCI Config type 1 card 2
+ * 0xf9000000  0x7a010000      PCI Config type 1 card 1
+ *
+ * 0xf8030000  0x7b080000      PCI Config type 0 card 4
+ * 0xf8020000  0x7b040000      PCI Config type 0 card 3
+ * 0xf8010000  0x7b020000      PCI Config type 0 card 2
+ * 0xf8000000  0x7b010000      PCI Config type 0 card 1
+ * 
+ */
+/*
+ * DEC21285
+ */
+#define CSR_SA110_CNTL         ((volatile unsigned long *)0xfe00013c)
+#define CSR_PCIADDR_EXTN       ((volatile unsigned long *)0xfe000140)
+#define CSR_PREFETCHMEMRANGE   ((volatile unsigned long *)0xfe000144)
+#define CSR_XBUS_CYCLE         ((volatile unsigned long *)0xfe000148)
+#define CSR_XBUS_IOSTROBE      ((volatile unsigned long *)0xfe00014c)
+#define CSR_DOORBELL_PCI       ((volatile unsigned long *)0xfe000150)
+#define CSR_DOORBELL_SA110     ((volatile unsigned long *)0xfe000154)
+
+
+#define CSR_UARTDR             ((volatile unsigned long *)0xfe000160)
+#define CSR_RXSTAT             ((volatile unsigned long *)0xfe000164)
+#define CSR_H_UBRLCR           ((volatile unsigned long *)0xfe000168)
+#define CSR_M_UBRLCR           ((volatile unsigned long *)0xfe00016c)
+#define CSR_L_UBRLCR           ((volatile unsigned long *)0xfe000170)
+#define CSR_UARTCON            ((volatile unsigned long *)0xfe000174)
+#define CSR_UARTFLG            ((volatile unsigned long *)0xfe000178)
+
+#define CSR_IRQ_STATUS         ((volatile unsigned long *)0xfe000180)
+#define CSR_IRQ_RAWSTATUS      ((volatile unsigned long *)0xfe000184)
+#define CSR_IRQ_ENABLE         ((volatile unsigned long *)0xfe000188)
+#define CSR_IRQ_DISABLE                ((volatile unsigned long *)0xfe00018c)
+#define CSR_IRQ_SOFT           ((volatile unsigned long *)0xfe000190)
+
+#define CSR_FIQ_STATUS         ((volatile unsigned long *)0xfe000280)
+#define CSR_FIQ_RAWSTATUS      ((volatile unsigned long *)0xfe000284)
+#define CSR_FIQ_ENABLE         ((volatile unsigned long *)0xfe000288)
+#define CSR_FIQ_DISABLE                ((volatile unsigned long *)0xfe00028c)
+#define CSR_FIQ_SOFT           ((volatile unsigned long *)0xfe000290)
+
+#define CSR_TIMER1_LOAD                ((volatile unsigned long *)0xfe000300)
+#define CSR_TIMER1_VALUE       ((volatile unsigned long *)0xfe000304)
+#define CSR_TIMER1_CNTL                ((volatile unsigned long *)0xfe000308)
+#define CSR_TIMER1_CLR         ((volatile unsigned long *)0xfe00030c)
+
+#define CSR_TIMER2_LOAD                ((volatile unsigned long *)0xfe000320)
+#define CSR_TIMER2_VALUE       ((volatile unsigned long *)0xfe000324)
+#define CSR_TIMER2_CNTL                ((volatile unsigned long *)0xfe000328)
+#define CSR_TIMER2_CLR         ((volatile unsigned long *)0xfe00032c)
+
+#define CSR_TIMER3_LOAD                ((volatile unsigned long *)0xfe000340)
+#define CSR_TIMER3_VALUE       ((volatile unsigned long *)0xfe000344)
+#define CSR_TIMER3_CNTL                ((volatile unsigned long *)0xfe000348)
+#define CSR_TIMER3_CLR         ((volatile unsigned long *)0xfe00034c)
+
+#define CSR_TIMER4_LOAD                ((volatile unsigned long *)0xfe000360)
+#define CSR_TIMER4_VALUE       ((volatile unsigned long *)0xfe000364)
+#define CSR_TIMER4_CNTL                ((volatile unsigned long *)0xfe000368)
+#define CSR_TIMER4_CLR         ((volatile unsigned long *)0xfe00036c)
+
+#define TIMER_CNTL_ENABLE      (1 << 7)
+#define TIMER_CNTL_AUTORELOAD  (1 << 6)
+#define TIMER_CNTL_DIV1                (0)
+#define TIMER_CNTL_DIV16       (1 << 2)
+#define TIMER_CNTL_DIV256      (2 << 2)
+#define TIMER_CNTL_CNTEXT      (3 << 2)
+
+/* LEDs */
+#define XBUS_LEDS              ((volatile unsigned char *)0xfff12000)
+#define XBUS_LED_AMBER         (1 << 0)
+#define XBUS_LED_GREEN         (1 << 1)
+#define XBUS_LED_RED           (1 << 2)
+#define XBUS_LED_TOGGLE                (1 << 8)
+
+/* PIC irq control */
+#define PIC_LO                 0x20
+#define PIC_MASK_LO            0x21
+#define PIC_HI                 0xA0
+#define PIC_MASK_HI            0xA1
+
+#define IO_END                 0xffffffff
+#define IO_BASE                        0xe0000000
+#define IO_SIZE                        (IO_END - IO_BASE)
+
+#define HAS_PCIO
+
+#define XBUS_SWITCH            ((volatile unsigned char *)0xfff12000)
+#define XBUS_SWITCH_SWITCH     ((*XBUS_SWITCH) & 15)
+#define XBUS_SWITCH_J17_13     ((*XBUS_SWITCH) & (1 << 4))
+#define XBUS_SWITCH_J17_11     ((*XBUS_SWITCH) & (1 << 5))
+#define XBUS_SWITCH_J17_9      ((*XBUS_SWITCH) & (1 << 6))
+
+#define PCIO_BASE              0xffe00000
+
+#define KERNTOPHYS(a)          ((unsigned long)(&a))
+
+#define PARAMS_OFFSET          0x0100
+#define PARAMS_BASE            (PAGE_OFFSET + PARAMS_OFFSET)
+
+#define SAFE_ADDR              0x50000000
+
diff --git a/include/asm-arm/arch-vnc/ide.h b/include/asm-arm/arch-vnc/ide.h
new file mode 100644 (file)
index 0000000..35eff5c
--- /dev/null
@@ -0,0 +1 @@
+/* no ide */
diff --git a/include/asm-arm/arch-vnc/io.h b/include/asm-arm/arch-vnc/io.h
new file mode 100644 (file)
index 0000000..83d25d3
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/io.h
+ *
+ * Copyright (C) 1997,1998 Russell King
+ *
+ * Modifications:
+ *  06-Dec-1997        RMK     Created.
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/*
+ * This architecture does not require any delayed IO, and
+ * has the constant-optimised IO
+ */
+#undef ARCH_IO_DELAY
+
+/*
+ * Dynamic IO functions - let the compiler
+ * optimize the expressions
+ */
+#define DECLARE_DYN_OUT(fnsuffix,instr,typ)                                    \
+extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \
+{                                                                              \
+       __asm__ __volatile__(                                                   \
+       "str" ##instr## "       %0, [%1, %2]"                                   \
+       :                                                                       \
+       : "r" (value), "r" (PCIO_BASE), typ (port));                            \
+}
+
+#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)                                  \
+extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)               \
+{                                                                              \
+       unsigned long value;                                                    \
+       __asm__ __volatile__(                                                   \
+       "ldr" ##instr## "       %0, [%1, %2]"                                   \
+       : "=&r" (value)                                                         \
+       : "r" (PCIO_BASE), typ (port));                                         \
+       return (unsigned sz)value;                                              \
+}
+
+extern __inline__ unsigned int __ioaddr (unsigned int port)                    \
+{                                                                              \
+       return (unsigned int)(PCIO_BASE + port);                                \
+}
+
+#define DECLARE_IO(sz,fnsuffix,instr,typ)      \
+       DECLARE_DYN_OUT(fnsuffix,instr,typ)     \
+       DECLARE_DYN_IN(sz,fnsuffix,instr,typ)
+
+DECLARE_IO(char,b,"b","Jr")
+DECLARE_IO(short,w,"h","r")
+DECLARE_IO(long,l,"","Jr")
+
+#undef DECLARE_IO
+#undef DECLARE_DYN_OUT
+#undef DECLARE_DYN_IN
+
+/*
+ * Constant address IO functions
+ *
+ * These have to be macros for the 'J' constraint to work -
+ * +/-4096 immediate operand.
+ */
+#define __outbc(value,port)                                                    \
+({                                                                             \
+       __asm__ __volatile__(                                                   \
+       "strb   %0, [%1, %2]"                                                   \
+       :                                                                       \
+       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
+})
+
+#define __inbc(port)                                                           \
+({                                                                             \
+       unsigned char result;                                                   \
+       __asm__ __volatile__(                                                   \
+       "ldrb   %0, [%1, %2]"                                                   \
+       : "=r" (result)                                                         \
+       : "r" (PCIO_BASE), "Jr" (port));                                        \
+       result;                                                                 \
+})
+
+#define __outwc(value,port)                                                    \
+({                                                                             \
+       __asm__ __volatile__(                                                   \
+       "strh   %0, [%1, %2]"                                                   \
+       :                                                                       \
+       : "r" (value), "r" (PCIO_BASE), "r" (port));                            \
+})
+
+#define __inwc(port)                                                           \
+({                                                                             \
+       unsigned short result;                                                  \
+       __asm__ __volatile__(                                                   \
+       "ldrh   %0, [%1, %2]"                                                   \
+       : "=r" (result)                                                         \
+       : "r" (PCIO_BASE), "r" (port));                                         \
+       result & 0xffff;                                                        \
+})
+
+#define __outlc(value,port)                                                    \
+({                                                                             \
+       __asm__ __volatile__(                                                   \
+       "str    %0, [%1, %2]"                                                   \
+       :                                                                       \
+       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
+})
+
+#define __inlc(port)                                                           \
+({                                                                             \
+       unsigned long result;                                                   \
+       __asm__ __volatile__(                                                   \
+       "ldr    %0, [%1, %2]"                                                   \
+       : "=r" (result)                                                         \
+       : "r" (PCIO_BASE), "Jr" (port));                                        \
+       result;                                                                 \
+})
+
+#define __ioaddrc(port)                                                                \
+({                                                                             \
+       unsigned long addr;                                                     \
+       addr = PCIO_BASE + port;                                                \
+       addr;                                                                   \
+})
+
+/*
+ * Translated address IO functions
+ *
+ * IO address has already been translated to a virtual address
+ */
+#define outb_t(v,p)                                                            \
+       (*(volatile unsigned char *)(p) = (v))
+
+#define inb_t(p)                                                               \
+       (*(volatile unsigned char *)(p))
+
+#define outl_t(v,p)                                                            \
+       (*(volatile unsigned long *)(p) = (v))
+
+#define inl_t(p)                                                               \
+       (*(volatile unsigned long *)(p))
+
+/*
+ * This is not sufficient... (and it's a hack anyway)
+ */
+static inline void writeb(unsigned char b, unsigned int addr)
+{
+       *(volatile unsigned char *)(0xe0000000 + (addr)) = b;
+}
+
+static inline unsigned char readb(unsigned int addr)
+{
+       return *(volatile unsigned char *)(0xe0000000 + (addr));
+}
+
+static inline void writew(unsigned short b, unsigned int addr)
+{
+       *(volatile unsigned short *)(0xe0000000 + (addr)) = b;
+}
+
+static inline unsigned short readw(unsigned int addr)
+{
+       return *(volatile unsigned short *)(0xe0000000 + (addr));
+}
+
+static inline void writew(unsigned long b, unsigned int addr)
+{
+       *(volatile unsigned long *)(0xe0000000 + (addr)) = b;
+}
+
+static inline unsigned long readw(unsigned int addr)
+{
+       return *(volatile unsigned long *)(0xe0000000 + (addr));
+}
+
+#endif
diff --git a/include/asm-arm/arch-vnc/irq.h b/include/asm-arm/arch-vnc/irq.h
new file mode 100644 (file)
index 0000000..2273d43
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * include/asm-arm/arch-vnc/irq.h
+ *
+ * Copyright (C) 1998 Russell King
+ */
+
+#include <asm/irq.h>
+
+/*
+ * FootBridge IRQ translation table
+ *  Converts form our IRQ numbers into FootBridge masks (defined in irqs.h)
+ */
+static int fb_irq_mask[16] = {
+       0,
+       IRQ_MASK_SOFTIRQ,
+       IRQ_MASK_UART_DEBUG,
+       0,
+       IRQ_MASK_TIMER0,
+       IRQ_MASK_TIMER1,
+       IRQ_MASK_TIMER2,
+       IRQ_MASK_WATCHDOG,
+       IRQ_MASK_ETHER10,
+       IRQ_MASK_ETHER100,
+       IRQ_MASK_VIDCOMP,
+       IRQ_MASK_EXTERN_IRQ,
+       IRQ_MASK_DMA1,
+       0,
+       0,
+       IRQ_MASK_PCI_ERR
+};
+
+static __inline__ void mask_and_ack_irq(unsigned int irq)
+{
+       if (irq < 16)
+               *CSR_IRQ_DISABLE = fb_irq_mask[irq];
+       else {
+               unsigned int pic_mask, mask;
+
+               if (irq < 24)
+                       pic_mask = PIC_MASK_LO;
+               else
+                       pic_mask = PIC_MASK_HI;
+
+               mask = 1 << (irq & 7);
+
+               outb(inb(pic_mask) | mask, pic_mask);
+       }
+}
+
+static __inline__ void mask_irq(unsigned int irq)
+{
+       if (irq < 16)
+               *CSR_IRQ_DISABLE = fb_irq_mask[irq];
+       else {
+               unsigned int pic_mask, mask;
+
+               if (irq < 24)
+                       pic_mask = PIC_MASK_LO;
+               else
+                       pic_mask = PIC_MASK_HI;
+
+               mask = 1 << (irq & 7);
+
+               outb(inb(pic_mask) | mask, pic_mask);
+       }
+}
+
+static __inline__ void unmask_irq(unsigned int irq)
+{
+       if (irq < 16)
+               *CSR_IRQ_ENABLE = fb_irq_mask[irq];
+       else {
+               unsigned int pic_mask, mask;
+
+               if (irq < 24)
+                       pic_mask = PIC_MASK_LO;
+               else
+                       pic_mask = PIC_MASK_HI;
+
+               mask = 1 << (irq & 7);
+
+               outb(inb(pic_mask) & ~mask, pic_mask);
+       }
+}
+static __inline__ unsigned long get_enabled_irqs(void)
+{
+       return 0;
+}
+
+static __inline__ void irq_init_irq(void)
+{
+       outb(0x11, PIC_LO);
+       outb(0x10, PIC_MASK_LO);
+       outb(0x04, PIC_MASK_LO);
+       outb(1, PIC_MASK_LO);
+
+       outb(0x11, PIC_HI);
+       outb(0x18, PIC_MASK_HI);
+       outb(0x02, PIC_MASK_HI);
+       outb(1, PIC_MASK_HI);
+
+       *CSR_IRQ_DISABLE = ~IRQ_MASK_EXTERN_IRQ;
+       *CSR_IRQ_ENABLE  = IRQ_MASK_EXTERN_IRQ;
+       *CSR_FIQ_DISABLE = -1;
+}
diff --git a/include/asm-arm/arch-vnc/irqs.h b/include/asm-arm/arch-vnc/irqs.h
new file mode 100644 (file)
index 0000000..53e01a1
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * linux/include/asm-arm/arch-vnc/irqs.h
+ *
+ * Copyright (C) 1998 Russell King
+ */
+
+#define NR_IRQS                        32
+
+/*
+ * This is a list of all interrupts that the 21285
+ * can generate
+ */
+#define IRQ_SOFTIRQ            1       /* from FB.1 */
+#define IRQ_CONRX              2       /* from FB.2 */
+#define IRQ_CONTX              3       /* from FB.3 */
+#define IRQ_TIMER0             4       /* from FB.4 */
+#define IRQ_TIMER1             5       /* from FB.5 */
+#define IRQ_TIMER2             6       /* from FB.6 */
+#define IRQ_WATCHDOG           7       /* from FB.7 */
+#define IRQ_ETHER10            8       /* from FB.8 */
+#define IRQ_ETHER100           9       /* from FB.9 */
+#define IRQ_VIDCOMP            10      /* from FB.10 */
+#define IRQ_EXTERN_IRQ         11      /* from FB.11: chain to IDE irq's */
+#define IRQ_DMA1               12      /* from future */
+#define IRQ_PCI_ERR            15      /* from FB.[28:31] */
+
+#define IRQ_TIMER4             16      /* from 553.0 */
+#define IRQ_KEYBOARD           17      /* from 553.1 */
+#define IRQ_PIC_HI             18      /* from 533.2: chained to 553.[8:15] */
+#define IRQ_UART2              19      /* from 553.3 */
+#define IRQ_UART               20      /* from 553.4 */
+#define IRQ_MOUSE              21      /* from 553.5 */
+#define IRQ_UART_IR            22      /* from 553.6 */
+#define IRQ_PRINTER            23      /* from 553.7 */
+#define IRQ_RTC_ALARM          24      /* from 553.8 */
+#define IRQ_POWERLOW           26      /* from 553.10 */
+#define IRQ_VGA                        27      /* from 553.11 */
+#define IRQ_SOUND              28      /* from 553.12 */
+#define IRQ_HARDDISK           30      /* from 553.14 */
+
+/* These defines handle the translation from the above FB #defines
+ * into physical buts for the FootBridge IRQ registers
+ */
+#define IRQ_MASK_SOFTIRQ       0x00000002
+#define IRQ_MASK_UART_DEBUG    0x0000000C
+#define IRQ_MASK_TIMER0                0x00000010
+#define IRQ_MASK_TIMER1                0x00000020
+#define IRQ_MASK_TIMER2                0x00000040
+#define IRQ_MASK_WATCHDOG      0x00000080
+#define IRQ_MASK_ETHERH10      0x00000100
+#define IRQ_MASK_ETHERH100     0x00000200
+#define IRQ_MASK_VIDCOMP       0x00000400
+#define IRQ_MASK_EXTERN_IRQ    0x00000800
+#define IRQ_MASK_DMA1          0x00030000
+#define IRQ_MASK_PCI_ERR       0xf0000000
+
+/*
+ * Now map them to the Linux interrupts
+ */
+#define IRQ_TIMER              IRQ_TIMER0
+
+#define irq_cannonicalize(i)   (i)
+
diff --git a/include/asm-arm/arch-vnc/keyboard.h b/include/asm-arm/arch-vnc/keyboard.h
new file mode 100644 (file)
index 0000000..4620ff1
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * linux/include/asm-arm/arch-ebsa285/keyboard.h
+ *
+ * Keyboard driver definitions for EBSA285 architecture
+ *
+ * (C) 1998 Russell King
+ */
+
+#include <linux/config.h>
+#include <asm/irq.h>
+
+#define NR_SCANCODES 128
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static unsigned char kbd_sysrq_xlate[NR_SCANCODES];
+#endif
+
+#define kbd_setkeycode(sc,kc)          (-EINVAL)
+#define kbd_getkeycode(sc)             (-EINVAL)
+
+/* Prototype: int kbd_pretranslate(scancode, raw_mode)
+ * Returns  : 0 to ignore scancode
+ */
+#define kbd_pretranslate(sc,rm)                (1)
+
+/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
+ * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
+ *            set to 0200 if scancode indicates release
+ */
+#define kbd_translate(sc, kcp, ufp, rm)        (1)
+#define kbd_unexpected_up(kc)          (0200)
+#define kbd_leds(leds)
+#define kbd_init_hw()
+//#define kbd_sysrq_xlate                      ps2kbd_sysrq_xlate
+#define kbd_disable_irq()
+#define kbd_enable_irq()
+
diff --git a/include/asm-arm/arch-vnc/mm-init.h b/include/asm-arm/arch-vnc/mm-init.h
new file mode 100644 (file)
index 0000000..c6937ab
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/mmap.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ */
diff --git a/include/asm-arm/arch-vnc/mmu.h b/include/asm-arm/arch-vnc/mmu.h
new file mode 100644 (file)
index 0000000..85307d7
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/mmu.h
+ *
+ * Copyright (c) 1996,1997,1998 Russell King.
+ *
+ * Changelog:
+ *  20-10-1996 RMK     Created
+ *  31-12-1997 RMK     Fixed definitions to reduce warnings
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * On ebsa, the dram is contiguous
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)       (x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)       (x)
+
+#endif
diff --git a/include/asm-arm/arch-vnc/oldlatches.h b/include/asm-arm/arch-vnc/oldlatches.h
new file mode 100644 (file)
index 0000000..8ff6ebd
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * Dummy oldlatches.h
+ *
+ * Copyright (C) 1996 Russell King
+ */
+
+#ifdef __need_oldlatches
+#error "Old latches not present in this (rpc) machine"
+#endif
diff --git a/include/asm-arm/arch-vnc/processor.h b/include/asm-arm/arch-vnc/processor.h
new file mode 100644 (file)
index 0000000..5d84ad4
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-arm/arch-vnc/processor.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * User space: 3GB
+ */
+#define TASK_SIZE      (0xc0000000UL)
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
+#define INIT_MMAP \
+{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
+
+#endif
diff --git a/include/asm-arm/arch-vnc/serial.h b/include/asm-arm/arch-vnc/serial.h
new file mode 100644 (file)
index 0000000..74fea49
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * linux/include/asm-arm/arch-vnc/serial.h
+ *
+ * Copyright (c) 1996 Russell King.
+ *
+ * Changelog:
+ *  15-10-1996 RMK     Created
+ *  03-05-1998 RMK     Modified for Corel Video NC
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/irq.h>
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1843200 / 16)
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+     /* UART CLK        PORT  IRQ     FLAGS        */
+#define SERIAL_PORT_DFNS \
+       { 0, BASE_BAUD, 0x3F8, IRQ_UART , STD_COM_FLAGS },      /* ttyS0 */     \
+       { 0, BASE_BAUD, 0x2F8, IRQ_UART2, STD_COM_FLAGS },      /* ttyS1 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS2 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS3 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS4 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS5 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS6 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS7 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS8 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS9 */     \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS10 */    \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS11 */    \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS12 */    \
+       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS13 */
+
+#endif
diff --git a/include/asm-arm/arch-vnc/shmparam.h b/include/asm-arm/arch-vnc/shmparam.h
new file mode 100644 (file)
index 0000000..9c36489
--- /dev/null
@@ -0,0 +1,5 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
diff --git a/include/asm-arm/arch-vnc/system.h b/include/asm-arm/arch-vnc/system.h
new file mode 100644 (file)
index 0000000..a3fed31
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-ebsa285/system.h
+ *
+ * Copyright (c) 1996,1997,1998 Russell King.
+ */
+#include <asm/hardware.h>
+#include <asm/leds.h>
+
+/* To reboot, we set up the 21285 watchdog and enable it.
+ * We then wait for it to timeout.
+ */
+extern __inline__ void arch_hard_reset (void)
+{
+       cli();
+       *CSR_TIMER4_LOAD = 0x8000;
+       *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+       *CSR_SA110_CNTL |= 1 << 13;
+       while(1);
+}
+
+#define ARCH_IDLE_OK
+
+#define arch_start_idle()      leds_event(led_idle_start)
+#define arch_end_idle()                leds_event(led_idle_end)
diff --git a/include/asm-arm/arch-vnc/time.h b/include/asm-arm/arch-vnc/time.h
new file mode 100644 (file)
index 0000000..73f2284
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * linux/include/asm-arm/arch-vnc/time.h
+ *
+ * Copyright (c) 1997 Corel Computer Corp.
+ * Slight modifications to bring in line with ebsa285 port.
+ *  -- Russell King.
+ */
+
+extern __inline__ unsigned long gettimeoffset (void)
+{
+       return 0;
+}
+
+extern __inline__ int reset_timer (void)
+{
+       *CSR_TIMER1_CLR = 0;
+       return 1;
+}
+
+/*
+ * We don't have a RTC to update!
+ */
+#define update_rtc()
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+extern __inline__ unsigned long setup_timer (void)
+{
+       *CSR_TIMER1_CLR  = 1;
+       *CSR_TIMER1_LOAD = LATCH;
+       *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+
+       /*
+        * Default the date to 1 Jan 1970 00:00:00
+        * You will have to run a time daemon to set the
+        * clock correctly at bootup
+        */
+       return mktime(1970, 1, 1, 0, 0, 0);
+}
diff --git a/include/asm-arm/arch-vnc/timex.h b/include/asm-arm/arch-vnc/timex.h
new file mode 100644 (file)
index 0000000..c50f118
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * linux/include/asm-arm/arch-vnc/timex.h
+ *
+ * Corel Video NC architecture timex specifications
+ *
+ * Copyright (C) 1998 Corel Computer/Russell King
+ */
+
+/*
+ * On the VNC, the clock runs at 66MHz and is divided
+ * by a 4-bit prescaler.
+ */
+#define CLOCK_TICK_RATE                (66000000 / 16)
diff --git a/include/asm-arm/arch-vnc/uncompress.h b/include/asm-arm/arch-vnc/uncompress.h
new file mode 100644 (file)
index 0000000..d5260b0
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/uncompress.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ */
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+       __asm__ __volatile__("
+       ldrb    %0, [%2], #1
+       teq     %0, #0
+       beq     3f
+1:     strb    %0, [%3]
+2:     ldrb    %1, [%3, #0x14]
+       and     %1, %1, #0x60
+       teq     %1, #0x60
+       bne     2b
+       teq     %0, #'\n'
+       moveq   %0, #'\r'
+       beq     1b
+       ldrb    %0, [%2], #1
+       teq     %0, #0
+       bne     1b
+3:     " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
index dae0cb0007555a95c7319e4a51b5d97ffd2a1a12..8dd37e0265aecd60ef8881abba362690412b0c71 100644 (file)
@@ -40,10 +40,9 @@ typedef struct { void *null; } elf_fpregset_t;
 #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
 
 /* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  This could be done in userspace,
-   but it's not easy, and we've already done it here.  */
+   instruction set this cpu supports. */
 
-#define ELF_HWCAP      (0)
+#define ELF_HWCAP      (armidlist[armidindex].hwcap)
 
 /* This yields a string that ld.so will use to load implementation
    specific libraries for optimization.  This is more specific in
@@ -52,12 +51,14 @@ typedef struct { void *null; } elf_fpregset_t;
 /* For now we just provide a fairly general string that describes the
    processor family.  This could be made more specific later if someone
    implemented optimisations that require it.  26-bit CPUs give you
-   "arm2" for ARM2 (no SWP) and "arm3" for anything else (ARM1 isn't
-   supported).  32-bit CPUs give you "arm6" for anything based on an
-   ARM6 or ARM7 core and "sa1x" for anything based on a StrongARM-1
+   "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't
+   supported).  32-bit CPUs give you "v3[lb]" for anything based on an
+   ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1
    core.  */
 
-#define ELF_PLATFORM   (armidlist[armidindex].optname)
+#define ELF_PLATFORM_SIZE 8
+extern char elf_platform[];
+#define ELF_PLATFORM   (elf_platform)
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex,ibcs2) \
index b79fe8a39789225608cc27314bf6bdf96c98e0ea..2203fa2a5b882086908984b81ef2d0d05c04974a 100644 (file)
@@ -14,3 +14,19 @@ extern int claim_fiq(struct fiq_handler *f);
 extern void release_fiq(struct fiq_handler *f);
 
 #endif
+/* Support for FIQ on ARM architectures.
+ * Written by Philip Blundell <philb@gnu.org>, 1998
+ */
+
+#ifndef __ASM_FIQ_H
+#define __ASM_FIQ_H
+
+struct fiq_handler {
+        const char *name;
+        int (*callback)(void);
+};
+
+extern int claim_fiq(struct fiq_handler *f);
+extern void release_fiq(struct fiq_handler *f);
+
+#endif
index 7c1e47360845eef3d85f43401138b432ae0617fc..5b5bbd067c9c424a294e0e56ab8ecc5898d18bc4 100644 (file)
@@ -1,24 +1,27 @@
 #ifndef _ASMARM_INIT_H
 #define _ASMARM_INIT_H
 
-#if 0
+/* C routines */
+
+#ifdef CONFIG_BINUTILS_NEW
+
 #define __init __attribute__ ((__section__ (".text.init")))
-#define __initdata __attribute__ ((__section__ (".data.init")))
 #define __initfunc(__arginit) \
        __arginit __init; \
        __arginit
-/* For assembly routines */
-#define __INIT         .section        ".text.init",@alloc,@execinstr
-#define __FINIT        .previous
-#define __INITDATA     .section        ".data.init",@alloc,@write
+
 #else
+
 #define __init
-#define __initdata
 #define __initfunc(__arginit) __arginit
-/* For assembly routines */
-#define __INIT
-#define __FINIT
-#define __INITDATA
+
 #endif
 
+#define __initdata __attribute__ ((__section__ (".data.init")))
+
+/* Assembly routines */
+#define __INIT         .section        ".text.init",@alloc,@execinstr
+#define __INITDATA     .section        ".data.init",@alloc,@write
+#define __FINIT        .previous
+
 #endif
index 4a432c03dab793bd4031a87084c03155bfb1c4ee..09713cda9173594924b837d235edeb56c6da32a2 100644 (file)
@@ -170,5 +170,20 @@ __IO(l,"",long)
 #undef ARCH_IO_DELAY
 #undef ARCH_IO_CONSTANT
 
+#ifdef __KERNEL__
+
+/*
+ * String version of IO memory access ops:
+ */
+extern void _memcpy_fromio(void *, unsigned long, unsigned long);
+extern void _memcpy_toio(unsigned long, void *, unsigned long);
+extern void _memset_io(unsigned long, int, unsigned long);
+
+#define memcpy_fromio(to,from,len)     _memcpy_fromio((to),(unsigned long)(from),(len))
+#define memcpy_toio(to,from,len)       _memcpy_toio((unsigned long)(to),(from),(len))
+#define memset_io(addr,c,len)          _memset_io((unsigned long)(addr),(c),(len))
+
+#endif
+
 #endif
 
index 5562ffd216a2a55a21b0e62fcbcbe4d1975d8db0..ef732f784bc2bbe3e59a3befb7f39a395ab41cc1 100644 (file)
@@ -117,6 +117,7 @@ extern __inline__ void update_memc_addr(struct mm_struct *mm, unsigned long addr
 #define PTRS_PER_PTE    32
 #define PTRS_PER_PMD    1
 #define PTRS_PER_PGD    32
+#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
 
 /* Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 8MB value just means that there will be a 8MB "hole" after the
@@ -450,7 +451,6 @@ extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
 #define pmd_alloc_kernel        pmd_alloc
 #define pte_alloc_kernel        pte_alloc
 
-#if 0
 extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
 {
        struct task_struct * p;
@@ -466,7 +466,6 @@ extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
        for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
                pgd[address >> PGDIR_SHIFT] = entry;
 }
-#endif
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
index 287779258fd3a4a880309bc1e7d7d869daf41954..2e861b213ed438735bbf8a340d9612b6add82d96 100644 (file)
@@ -48,12 +48,13 @@ static inline void
 alloc_init_section(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
 {
        pgd_t *pgdp;
-       pmd_t *pmdp;
+       pmd_t *pmdp, pmd;
 
        pgdp = pgd_offset_k(virt);
        pmdp = pmd_offset(pgdp, virt);
 
-       pmd_val(*pmdp) = phys | PMD_TYPE_SECT | PMD_DOMAIN(domain) | prot;
+       pmd_val(pmd) = phys | PMD_TYPE_SECT | PMD_DOMAIN(domain) | prot;
+       set_pmd(pmdp, pmd);
 }
 
 /*
@@ -78,7 +79,7 @@ static inline void
 alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
 {
        pgd_t *pgdp;
-       pmd_t *pmdp;
+       pmd_t *pmdp, pmd;
        pte_t *ptep;
 
        pgdp = pgd_offset_k(virt);
@@ -92,7 +93,8 @@ alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int
                ptep = (pte_t *)memory;
                memzero(ptep, PTE_SIZE);
 
-               pmd_val(*pmdp) = __virt_to_phys(memory) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
+               pmd_val(pmd) = __virt_to_phys(memory) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
+               set_pmd(pmdp, pmd);
 
                *mem = memory + PTE_SIZE;
        }
index 3c2cbb98ab386aa386994e7f5040585f7647e1c3..60b670fc27f5f6b8aeb22c6792d44c1e8e0de838 100644 (file)
 #define PTRS_PER_PTE    256
 #define PTRS_PER_PMD    1
 #define PTRS_PER_PGD    4096
+#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
 
 /* Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 8MB value just means that there will be a 8MB "hole" after the
 
 /*
  * We define the bits in the page tables as follows:
- *  PTE_BUFFERABLE     page is writable
- *  PTE_AP_WRITE       page is dirty
+ *  PTE_BUFFERABLE     page is dirty
+ *  PTE_AP_WRITE       page is writable
  *  PTE_AP_READ                page is a young (unsetting this causes faults for any access)
+ *  PTE_CACHEABLE       page is readable
  *
- * Any page that is mapped in is assumed to be readable...
+ * A page will not be made writable without the dirty bit set.
+ * It is not legal to have a writable non-dirty page though (it breaks).
+ *
+ * A readable page is marked as being cacheable.
+ * Youngness is indicated by hardware read.  If the page is old,
+ * then we will fault and make the page young again.
  */
-#if 0
 #define _PTE_YOUNG     PTE_AP_READ
-#define _PTE_DIRTY     PTE_AP_WRITE
-#define _PTE_READ      PTE_CACHEABLE
-#define _PTE_WRITE     PTE_BUFFERABLE
-#else
-#define _PTE_YOUNG     PTE_CACHEABLE
 #define _PTE_DIRTY     PTE_BUFFERABLE
-#define _PTE_READ      PTE_AP_READ
+#define _PTE_READ      PTE_CACHEABLE
 #define _PTE_WRITE     PTE_AP_WRITE
-#endif
 
 #define PAGE_NONE       __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG)
 #define PAGE_SHARED     __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ | _PTE_WRITE)
@@ -350,7 +350,7 @@ extern __inline__ int pmd_present(pmd_t pmd)
 
 extern __inline__ int pte_write(pte_t pte)
 {
-       return pte_val(pte) & PTE_AP_WRITE;
+       return pte_val(pte) & _PTE_WRITE;
 }
 
 extern __inline__ int pte_dirty(pte_t pte)
@@ -365,7 +365,7 @@ extern __inline__ int pte_young(pte_t pte)
 
 extern __inline__ pte_t pte_wrprotect(pte_t pte)
 {
-       pte_val(pte) &= ~PTE_AP_WRITE;
+       pte_val(pte) &= ~_PTE_WRITE;
        return pte;
 }
 
@@ -377,31 +377,31 @@ extern __inline__ pte_t pte_nocache(pte_t pte)
 
 extern __inline__ pte_t pte_mkclean(pte_t pte)
 {
-       pte_val(pte) &= ~PTE_BUFFERABLE;
+       pte_val(pte) &= ~_PTE_DIRTY;
        return pte;
 }
 
 extern __inline__ pte_t pte_mkold(pte_t pte)
 {
-       pte_val(pte) &= ~PTE_AP_READ;
+       pte_val(pte) &= ~_PTE_YOUNG;
        return pte;
 }
 
 extern __inline__ pte_t pte_mkwrite(pte_t pte)
 {
-       pte_val(pte) |= PTE_AP_WRITE;
+       pte_val(pte) |= _PTE_WRITE;
        return pte;
 }
 
 extern __inline__ pte_t pte_mkdirty(pte_t pte)
 {
-       pte_val(pte) |= PTE_BUFFERABLE;
+       pte_val(pte) |= _PTE_DIRTY;
        return pte;
 }
 
 extern __inline__ pte_t pte_mkyoung(pte_t pte)
 {
-       pte_val(pte) |= PTE_AP_READ;
+       pte_val(pte) |= _PTE_YOUNG;
        return pte;
 }
 
@@ -670,7 +670,6 @@ extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
 #define pmd_free_kernel                pmd_free
 #define pmd_alloc_kernel       pmd_alloc
 
-#if 0
 extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
 {
        struct task_struct * p;
@@ -686,7 +685,6 @@ extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
        for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
                pgd[address >> PGDIR_SHIFT] = entry;
 }
-#endif
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
index a170d1408af2fcb081a4dedf29a266fec8bd8dc1..a89b7509f41712a200a43a79a46a575a17009ba1 100644 (file)
@@ -9,25 +9,23 @@
 
 #include <asm/proc-fns.h>
 
-#define F_MEMC   (1<<0)
-#define F_MMU    (1<<1)
-#define F_32BIT  (1<<2)
-#define F_CACHE  (1<<3)
-#define F_IOEB   (1<<31)
-
 #ifndef __ASSEMBLER__
 
+#define HWCAP_SWP      (1 << 0)
+#define HWCAP_HALF     (1 << 1)
+
 struct armversions {
-       unsigned long id;               /* Processor ID                 */
-       unsigned long mask;             /* Processor ID mask            */
-       unsigned long features;         /* Features (see above)         */
+       const unsigned long id;         /* Processor ID                 */
+       const unsigned long mask;       /* Processor ID mask            */
        const char *manu;               /* Manufacturer                 */
        const char *name;               /* Processor name               */
+       const char *arch_vsn;           /* Architecture version         */
+       const char *elf_vsn;            /* ELF library version          */
+       const int hwcap;                /* ELF HWCAP                    */
        const struct processor *proc;   /* Processor-specific ASM       */
-       const char *optname;            /* Optimisation name            */
 };
 
-extern struct armversions armidlist[];
+extern const struct armversions armidlist[];
 extern int armidindex;
 
 #endif
index 6303537f6a9a70846723a34cb894b089364ec45e..d171f77bf84ea84a45acf101f658a13515513c7f 100644 (file)
@@ -6,6 +6,7 @@
 /* Avoid too many header ordering problems.  */
 struct siginfo;
 
+#ifdef __KERNEL__
 /* Most things should be clean enough to redefine this at will, if care
    is taken to make libc match.  */
 
@@ -19,6 +20,14 @@ typedef struct {
        unsigned long sig[_NSIG_WORDS];
 } sigset_t;
 
+#else
+/* Here we must cater to lics that poke about in kernel headers.  */
+
+#define NSIG           32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
 #define SIGHUP          1
 #define SIGINT          2
 #define SIGQUIT                 3
@@ -88,6 +97,15 @@ typedef struct {
 
 #define SA_RESTORER    0x04000000
 
+/* 
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    2048
+#define SIGSTKSZ       8192
+
 #ifdef __KERNEL__
 
 /*
index 376179b96edb4653e0040eaf0d1eb96e45bc5cd2..a952afe52d6f21d1bcafb483b4853bb5a335f6d1 100644 (file)
@@ -18,7 +18,7 @@ typedef struct { } spinlock_t;
 #define spin_unlock_irq(lock)  sti()
 
 #define spin_lock_irqsave(lock, flags) \
-       do { save_flags(flags); cli(); } while (0)
+       do { __save_flags_cli(flags); } while (0)
 #define spin_unlock_irqrestore(lock, flags) \
        restore_flags(flags)
 
@@ -45,11 +45,11 @@ typedef struct { } rwlock_t;
 #define write_unlock_irq(lock) sti()
 
 #define read_lock_irqsave(lock, flags) \
-       do { save_flags(flags); cli(); } while (0)
+       do { __save_flags_cli(flags); } while (0)
 #define read_unlock_irqrestore(lock, flags) \
        restore_flags(flags)
 #define write_lock_irqsave(lock, flags)        \
-       do { save_flags(flags); cli(); } while (0)
+       do { __save_flags_cli(flags); } while (0)
 #define write_unlock_irqrestore(lock, flags) \
        restore_flags(flags)
 
index 2ad6a16cd00f93efdd895c238b9ef00101d66bff..88148d4cd4a26ac2dafaa36537b9aa1cdd6f4cc4 100644 (file)
@@ -29,5 +29,7 @@ extern void arm_invalidptr(const char *, int);
 #define mb() __asm__ __volatile__ ("" : : : "memory")
 #define nop() __asm__ __volatile__("mov r0,r0\n\t");
 
+extern asmlinkage void __backtrace(void);
+
 #endif
 
index 5131de37b5badf19d675723691aa6b96bc2c8ecd..8f85672766058db06d7f6a7afe34d8a47ae04a0d 100644 (file)
@@ -35,7 +35,7 @@ struct consw {
        int     (*con_scroll)(struct vc_data *, int, int, int, int);
        void    (*con_bmove)(struct vc_data *, int, int, int, int, int, int);
        int     (*con_switch)(struct vc_data *);
-       int     (*con_blank)(int);
+       int     (*con_blank)(struct vc_data *, int);
        int     (*con_get_font)(struct vc_data *, int *, int *, char *);
        int     (*con_set_font)(struct vc_data *, int, int, char *);
        int     (*con_set_palette)(struct vc_data *, unsigned char *);
@@ -52,6 +52,8 @@ extern struct consw vga_con;  /* VGA text console */
 extern struct consw compat_con;        /* console wrapper */
 extern struct consw prom_con;  /* SPARC PROM console */
 
+void take_over_console(struct consw *sw, int first, int last, int deflt);
+
 /* flag bits */
 #define CON_INITED  (1)
 
diff --git a/include/linux/console_compat.h b/include/linux/console_compat.h
deleted file mode 100644 (file)
index 529e39a..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  linux/include/linux/console_compat.h -- Abstract console wrapper
- *
- *     Copyright (C) 1998 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/config.h>
-
-#ifndef _LINUX_CONSOLE_COMPAT_H_
-#define _LINUX_CONSOLE_COMPAT_H_
-
-#undef video_num_columns
-#undef video_num_lines
-#undef video_size_row
-#undef video_type
-#undef video_mem_base
-#undef video_mem_term
-#undef video_screen_size
-#undef can_do_color
-#undef scr_writew
-#undef scr_readw
-#undef scr_memsetw
-#undef scr_memcpyw
-#undef set_cursor
-#undef hide_cursor
-#undef set_get_cmap
-#undef set_palette
-#undef set_get_font
-#undef set_vesa_blanking
-#undef vesa_blank
-#undef vesa_powerdown
-#undef con_adjust_height
-#undef con_type_init
-#undef con_type_init_finish
-
-#define video_num_columns      compat_video_num_columns
-#define video_num_lines                compat_video_num_lines
-#define video_size_row         compat_video_size_row
-#define video_type             compat_video_type
-#define video_mem_base         compat_video_mem_base
-#define video_mem_term         compat_video_mem_term
-#define video_screen_size      compat_video_screen_size
-#define can_do_color           compat_can_do_color
-#define scr_writew             compat_scr_writew
-#define scr_readw              compat_scr_readw
-#define scr_memsetw            compat_memsetw
-#define scr_memcpyw            compat_memcpyw
-#define set_cursor             compat_set_cursor
-#define hide_cursor            compat_hide_cursor
-#define set_get_cmap           compat_set_get_cmap
-#define set_palette            compat_set_palette
-#define set_get_font           compat_set_get_font
-#define set_vesa_blanking      compat_set_vesa_blanking
-#define vesa_blank             compat_vesa_blank
-#define vesa_powerdown         compat_vesa_powerdown
-#define con_adjust_height      compat_con_adjust_height
-#define con_type_init          compat_con_type_init
-#define con_type_init_finish   compat_con_type_init_finish
-
-extern unsigned long compat_video_num_columns; 
-extern unsigned long compat_video_num_lines;
-extern unsigned long compat_video_size_row;    
-extern unsigned char compat_video_type;
-extern unsigned long compat_video_mem_base;
-extern unsigned long compat_video_mem_term;
-extern unsigned long compat_video_screen_size;
-extern int compat_can_do_color;
-extern void compat_set_cursor(int currcons);
-extern void compat_hide_cursor(void);
-extern int compat_set_get_cmap(unsigned char *arg, int set);
-extern void compat_set_palette(void);
-extern int compat_set_get_font(unsigned char * arg, int set, int ch512);
-extern void compat_set_vesa_blanking(unsigned long arg);
-extern void compat_vesa_blank(void);
-extern void compat_vesa_powerdown(void);
-extern int compat_con_adjust_height(unsigned long fontheight);
-extern void compat_con_type_init(const char **);
-extern void compat_con_type_init_finish(void);
-
-#if defined(CONFIG_SUN_CONSOLE)
-       void (*memsetw)(void *, unsigned short, unsigned int);
-       void (*memcpyw)(unsigned short *, unsigned short *, unsigned int);
-       void (*scr_writew)(unsigned short, unsigned short *);
-       unsigned short (*scr_readw)(unsigned short *);
-       void (*get_scrmem)(int);
-       void (*set_scrmem)(int, long);
-       void (*set_origin)(unsigned short);
-       void (*hide_cursor)(void);
-       void (*set_cursor)(int);
-       int (*set_get_font)(char *, int, int);
-       int (*con_adjust_height)(unsigned long);
-       int (*set_get_cmap)(unsigned char *, int);
-       void (*set_palette)(void);
-       void (*set_other_palette)(int);
-       void (*console_restore_palette)(void);
-       void (*con_type_init)(const char **);
-       void (*con_type_init_finish)(void);
-
-       /* VESA powerdown methods */
-       void (*vesa_blank)(void);
-       void (*vesa_unblank)(void);
-       void (*set_vesa_blanking)(const unsigned long);
-       void (*vesa_powerdown)(void);
-
-       void (*clear_screen)(void);
-       void (*render_screen)(void);
-       void (*clear_margin)(void);
-};
-
-#define compat_memsetw(s,c,count)      suncons_ops.memsetw((s),(c),(count))
-#define compat_memcpyw(to,from,count)  suncons_ops.memcpyw((to),(from),(count))
-#define compat_scr_writew(val,addr)    suncons_ops.scr_writew((val),(addr))
-#define compat_scr_readw(addr)         suncons_ops.scr_readw((addr))
-
-#elif defined(CONFIG_PMAC_CONSOLE)
-extern void pmac_blitc(unsigned, unsigned long);
-extern void compat_memsetw(unsigned short *p, unsigned short c, unsigned count);
-extern void compat_memcpyw(unsigned short *to, unsigned short *from, unsigned count);
-
-static inline void compat_scr_writew(unsigned short val, unsigned short * addr)
-{
-       if ((unsigned long)addr < video_mem_term &&
-           (unsigned long)addr >= video_mem_base) {
-               if (*addr != val) {
-                       *addr = val;
-                       pmac_blitc(val, (unsigned long) addr);
-               }
-       } else
-               *addr = val;
-}
-
-static inline unsigned short compat_scr_readw(unsigned short * addr)
-{
-       return *addr;
-}
-#endif
-
-#if !defined(CONFIG_SUN_CONSOLE) && !defined(CONFIG_PMAC_CONSOLE)
-static inline void compat_memsetw(void * s, unsigned short c, unsigned int count)
-{
-       unsigned short * addr = (unsigned short *) s;
-
-       count /= 2;
-       while (count) {
-               count--;
-               scr_writew(c, addr++);
-       }
-}
-
-static inline void compat_memcpyw(unsigned short *to, unsigned short *from,
-                                 unsigned int count)
-{
-       count /= 2;
-       while (count) {
-               count--;
-               scr_writew(scr_readw(from++), to++);
-       }
-}
-#endif
-
-#endif /* _LINUX_CONSOLE_COMPAT_H_ */
index afb2ef775322ac9e0d885e7e2f16f7a5474cbf8d..e21e51f41f4510ce676fbbf21b0a03e3eb2c1a26 100644 (file)
@@ -10,6 +10,8 @@
  */
 #define CUR_DEFAULT CUR_UNDERLINE
 
+#include <linux/config.h>
+
 #define NPAR 16
 
 struct vc_data {
@@ -77,6 +79,7 @@ struct vc_data {
        unsigned int    vc_bell_pitch;          /* Console bell pitch */
        unsigned int    vc_bell_duration;       /* Console bell duration */
        unsigned int    vc_cursor_type;
+       struct vc_data **vc_display_fg;         /* Ptr to var holding fg console for this display */
        /* additional information is in vt_kern.h */
 };
 
index 4e3ae06b93ca78e1ddb799077bf3c88d06a10e46..2c7fc1de1c516420ca5ee8013b003e7691383b46 100644 (file)
@@ -257,20 +257,22 @@ struct display {
    struct vc_data *conp;            /* pointer to console data */
    struct fb_info *fb_info;         /* frame buffer for this console */
    int vrows;                       /* number of virtual rows */
-   int cursor_x;                    /* current cursor position */
-   int cursor_y;
+   unsigned short cursor_x;        /* current cursor position */
+   unsigned short cursor_y;
    int fgcol;                       /* text colors */
    int bgcol;
    u_long next_line;                /* offset to one line below */
    u_long next_plane;               /* offset to next plane */
    u_char *fontdata;                /* Font associated to this display */
-   int fontheight;
-   int fontwidth;
+   unsigned short fontheightlog;
+   unsigned short fontwidthlog;
+   unsigned short fontheight;
+   unsigned short fontwidth;
    int userfont;                    /* != 0 if fontdata kmalloc()ed */
    struct display_switch *dispsw;   /* low level operations */
    u_short scrollmode;              /* Scroll Method */
    short yscroll;                   /* Hardware scrolling */
-}; 
+};
 
 
 struct fb_info {
@@ -279,6 +281,7 @@ struct fb_info {
    struct fb_ops *fbops;
    struct fb_monspecs monspecs;
    struct display *disp;               /* initial display variable */
+   struct vc_data *display_fg;         /* Console visible on this display */
    char fontname[40];                  /* default font name */
    int (*changevar)(int);              /* tell console var has changed */
    int (*switch_con)(int, struct fb_info*);
index 8286b0974de2d0b7c6cba33ec8df24b8000a7cec..c42e43d9dec2a37f08809f14bb2e30b34b0a0bcb 100644 (file)
@@ -189,10 +189,15 @@ struct device
        unsigned int            irq;            /* device IRQ number    */
        
        /* Low-level status flags. */
-       volatile unsigned char  start,          /* start an operation   */
-                               interrupt;      /* interrupt arrived    */
-       unsigned long           tbusy;          /* transmitter busy must be
-                                                  long for bitops      */
+       volatile unsigned char  start;          /* start an operation   */
+       /*
+        * These two are just single-bit flags, but due to atomicity
+        * reasons they have to be inside a "unsigned long". However,
+        * they should be inside the SAME unsigned long instead of
+        * this wasteful use of memory..
+        */
+       unsigned long           interrupt;      /* bitops.. */
+       unsigned long           tbusy;          /* transmitter busy */
        
        struct device           *next;
        
index 91e7d88d1d3e03fe7cd02ebf0ef4735a9babc1e9..13062e0b4711cc7895be79ca9e80d300a3abf9a6 100644 (file)
@@ -127,6 +127,7 @@ struct parport_operations {
 
        void (*inc_use_count)(void);
        void (*dec_use_count)(void);
+       void (*fill_inode)(struct inode *inode, int fill);
 };
 
 struct parport_device_info {
index 069be1d05a6ddb09b8cd78d1d5bf2e439ed3035a..c4dbc828ace31978b5017deb536a012f5f41687d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: pci.h,v 1.72 1998/05/12 07:35:54 mj Exp $
+ *     $Id: pci.h,v 1.76 1998/07/15 20:34:50 mj Exp $
  *
  *     PCI defines and function prototypes
  *     Copyright 1994, Drew Eckhardt
@@ -76,7 +76,7 @@
  * 1 bits are decoded.
  */
 #define PCI_BASE_ADDRESS_0     0x10    /* 32 bits */
-#define PCI_BASE_ADDRESS_1     0x14    /* 32 bits */
+#define PCI_BASE_ADDRESS_1     0x14    /* 32 bits [htype 0,1 only] */
 #define PCI_BASE_ADDRESS_2     0x18    /* 32 bits [htype 0 only] */
 #define PCI_BASE_ADDRESS_3     0x1c    /* 32 bits */
 #define PCI_BASE_ADDRESS_4     0x20    /* 32 bits */
 #define  PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
 #define  PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
 
-/* Header type 2 (CardBus bridges) -- detailed info welcome */
-#define PCI_CB_CARDBUS_BASE    0x10    /* CardBus Socket/ExCa base address */
-#define  PCI_CB_CARDBUS_BASE_TYPE_MASK 0xfff
-#define  PCI_CB_CARDBUS_BASE_MASK ~0xfff
-#define PCI_CB_CAPABILITIES    0x14    /* Offset of list of capabilities in cfg space */
-/* 0x15 reserved */
+/* Header type 2 (CardBus bridges) */
+/* 0x14-0x15 reserved */
 #define PCI_CB_SEC_STATUS      0x16    /* Secondary status */
-#define PCI_CB_BUS_NUMBER      0x18    /* PCI bus number */
-#define PCI_CB_CARDBUS_NUMBER  0x19    /* CardBus bus number */
+#define PCI_CB_PRIMARY_BUS     0x18    /* PCI bus number */
+#define PCI_CB_CARD_BUS                0x19    /* CardBus bus number */
 #define PCI_CB_SUBORDINATE_BUS 0x1a    /* Subordinate bus number */
-#define PCI_CB_CARDBUS_LATENCY 0x1b    /* CardBus latency timer */
+#define PCI_CB_LATENCY_TIMER   0x1b    /* CardBus latency timer */
 #define PCI_CB_MEMORY_BASE_0   0x1c
 #define PCI_CB_MEMORY_LIMIT_0  0x20
 #define PCI_CB_MEMORY_BASE_1   0x24
 #define PCI_CB_IO_BASE_1_HI    0x36
 #define PCI_CB_IO_LIMIT_1      0x38
 #define PCI_CB_IO_LIMIT_1_HI   0x3a
+#define  PCI_CB_IO_RANGE_MASK  ~0x03
 /* 0x3c-0x3d are same as for htype 0 */
-/* 0x3e-0x3f are same as for htype 1 */
+#define PCI_CB_BRIDGE_CONTROL  0x3e
+#define  PCI_CB_BRIDGE_CTL_PARITY      0x01    /* Similar to standard bridge control register */
+#define  PCI_CB_BRIDGE_CTL_SERR                0x02
+#define  PCI_CB_BRIDGE_CTL_ISA         0x04
+#define  PCI_CB_BRIDGE_CTL_VGA         0x08
+#define  PCI_CB_BRIDGE_CTL_MASTER_ABORT        0x20
+#define  PCI_CB_BRIDGE_CTL_CB_RESET    0x40    /* CardBus reset */
+#define  PCI_CB_BRIDGE_CTL_16BIT_INT   0x80    /* Enable interrupt for 16-bit cards */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
+#define  PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define  PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
 #define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
 #define PCI_CB_SUBSYSTEM_ID    0x42
 #define PCI_CB_LEGACY_MODE_BASE        0x44    /* 16-bit PC Card legacy mode base address (ExCa) */
 
 #include <linux/types.h>
 
-/*
- * Error values that may be returned by the PCI bios.
- */
-#define PCIBIOS_SUCCESSFUL             0x00
-#define PCIBIOS_FUNC_NOT_SUPPORTED     0x81
-#define PCIBIOS_BAD_VENDOR_ID          0x83
-#define PCIBIOS_DEVICE_NOT_FOUND       0x86
-#define PCIBIOS_BAD_REGISTER_NUMBER    0x87
-#define PCIBIOS_SET_FAILED             0x88
-#define PCIBIOS_BUFFER_TOO_SMALL       0x89
-
-/* Direct configuration space access */
-
-int pcibios_present (void);
-void pcibios_init(void);
-void pcibios_fixup(void);
-char *pcibios_setup (char *str);
-int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn,
-                             unsigned char where, unsigned char *val);
-int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn,
-                             unsigned char where, unsigned short *val);
-int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn,
-                              unsigned char where, unsigned int *val);
-int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn,
-                              unsigned char where, unsigned char val);
-int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn,
-                              unsigned char where, unsigned short val);
-int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
-                               unsigned char where, unsigned int val);
-
-/* Don't use these in new code, use pci_find_... instead */
-
-int pcibios_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, unsigned char *dev_fn);
-int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
-                        unsigned short index, unsigned char *bus,
-                        unsigned char *dev_fn);
-
 /*
  * There is one pci_dev structure for each slot-number/function-number
  * combination:
@@ -1131,6 +1101,46 @@ struct pci_bus {
 extern struct pci_bus  pci_root;       /* root bus */
 extern struct pci_dev  *pci_devices;   /* list of all devices */
 
+/*
+ * Error values that may be returned by the PCI bios.
+ */
+#define PCIBIOS_SUCCESSFUL             0x00
+#define PCIBIOS_FUNC_NOT_SUPPORTED     0x81
+#define PCIBIOS_BAD_VENDOR_ID          0x83
+#define PCIBIOS_DEVICE_NOT_FOUND       0x86
+#define PCIBIOS_BAD_REGISTER_NUMBER    0x87
+#define PCIBIOS_SET_FAILED             0x88
+#define PCIBIOS_BUFFER_TOO_SMALL       0x89
+
+/* Low-level architecture-dependent routines */
+
+int pcibios_present (void);
+void pcibios_init(void);
+void pcibios_fixup(void);
+void pcibios_fixup_bus(struct pci_bus *);
+char *pcibios_setup (char *str);
+int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn,
+                             unsigned char where, unsigned char *val);
+int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn,
+                             unsigned char where, unsigned short *val);
+int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn,
+                              unsigned char where, unsigned int *val);
+int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn,
+                              unsigned char where, unsigned char val);
+int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn,
+                              unsigned char where, unsigned short val);
+int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
+                               unsigned char where, unsigned int val);
+
+/* Don't use these in new code, use pci_find_... instead */
+
+int pcibios_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, unsigned char *dev_fn);
+int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
+                        unsigned short index, unsigned char *bus,
+                        unsigned char *dev_fn);
+
+/* Generic PCI interface functions */
+
 void pci_init(void);
 void pci_setup(char *str, int *ints);
 void pci_quirks_init(void);
index 5e4c6d211fa52626df0fed0cb47b4e98b374033c..e1e108a65503452efda4cd3f7f8802826a537773 100644 (file)
@@ -136,6 +136,7 @@ enum net_directory_inos {
        PROC_NET_DN_ADJ,
        PROC_NET_DN_L1,
        PROC_NET_DN_L2,
+       PROC_NET_DN_CACHE,
        PROC_NET_DN_SKT,
        PROC_NET_NETSTAT,
        PROC_NET_IPFW_CHAINS,
index a3976733eb4eb2c92d38adcdf113ceccd84636b0..7d8a9b435e195aae5234d1a14c1c4f509e05fd9b 100644 (file)
@@ -199,6 +199,8 @@ struct video_key
 #define VID_HARDWARE_AZTECH    7
 #define VID_HARDWARE_SF16MI    8
 #define VID_HARDWARE_RTRACK    9
+#define VID_HARDWARE_ZOLTRIX   10
+#define VID_HARDWARE_SAA7146    11
 
 /*
  *     Initialiser list
index bd427fb316fae77995e24d15bba8e7e73eeba6eb..78faf6afea702f34f0a33b13491c52516d4a0e70 100644 (file)
@@ -99,7 +99,7 @@ typedef struct
        unsigned serial : 1;            /* serial mode (C11) */
        unsigned notfound : 1;          /* /FOUND */
        unsigned pblf : 1;              /* PBLF */
-       unsigned hamming : 1;           /* hamming-error occured */
+       unsigned hamming : 1;           /* hamming-error occurred */
 }
 vtx_pageinfo_t;
 
index f8dc418fbbcba86457d08ecc95ea5401cc4d91ef..d04f2ad054ae116a96d4568c380a5fec7ab4cb0e 100644 (file)
@@ -6,7 +6,6 @@
  * with information needed by the vt package
  */
 
-#include <linux/config.h>
 #include <linux/vt.h>
 
 /*
@@ -61,15 +60,6 @@ void scrollfront(int);
 struct tty_struct;
 int tioclinux(struct tty_struct *tty, unsigned long arg);
 
-#if defined(CONFIG_PMAC_CONSOLE) || defined(CONFIG_FB_COMPAT_XPMAC)
-#include <asm/vc_ioctl.h>
-extern int console_getmode(struct vc_mode *);
-extern int console_setmode(struct vc_mode *, int);
-extern int console_setcmap(int, unsigned char *,
-                          unsigned char *, unsigned char *);
-extern int console_powermode(int);
-#endif
-
 /* consolemap.c */
 
 struct unimapinit;
diff --git a/include/linux/wavefront.h b/include/linux/wavefront.h
new file mode 100644 (file)
index 0000000..147ec3e
--- /dev/null
@@ -0,0 +1,670 @@
+#ifndef __wavefront_h__
+#define __wavefront_h__
+
+/* WaveFront header file.
+ *   
+ * Copyright (C) by Paul Barton-Davis 1998
+ *
+ * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.  
+ */
+
+#if (!defined(__GNUC__) && !defined(__GNUG__))
+
+     You will not be able to compile this file correctly without gcc, because
+     it is necessary to pack the "wavefront_alias" structure to a size
+     of 22 bytes, corresponding to 16-bit alignment (as would have been
+     the case on the original platform, MS-DOS). If this is not done,
+     then WavePatch-format files cannot be read/written correctly.
+     The method used to do this here ("__attribute__((packed)") is
+     completely compiler dependent.
+     
+     All other wavefront_* types end up aligned to 32 bit values and
+     still have the same (correct) size.
+
+#else
+
+     /* However, note that as of G++ 2.7.3.2, g++ was unable to
+       correctly parse *type* __attribute__ tags. It will do the
+       right thing if we use the "packed" attribute on each struct
+       member, which has the same semantics anyway. 
+     */
+
+#endif __GNUC__
+
+/***************************** WARNING ********************************
+  PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO 
+  BE USED WITH EITHER C *OR* C++.
+ **********************************************************************/
+
+#ifndef NUM_MIDIKEYS 
+#define NUM_MIDIKEYS 128
+#endif  NUM_MIDIKEYS
+
+#ifndef NUM_MIDICHANNELS
+#define NUM_MIDICHANNELS 16
+#endif  NUM_MIDICHANNELS
+
+/* These are very useful/important. the original wavefront interface
+   was developed on a 16 bit system, where sizeof(int) = 2
+   bytes. Defining things like this makes the code much more portable, and
+   easier to understand without having to toggle back and forth
+   between a 16-bit view of the world and a 32-bit one. 
+ */   
+
+typedef short INT16;
+typedef unsigned short UINT16;
+typedef int INT32;
+typedef unsigned int UINT32;
+typedef char CHAR8;
+typedef unsigned char UCHAR8;
+
+/* Pseudo-commands not part of the WaveFront command set.
+   These are used for various driver controls and direct
+   hardware control.
+ */
+
+#define WFC_DEBUG_DRIVER                0
+#define WFC_FX_IOCTL                    1
+#define WFC_PATCH_STATUS                2
+#define WFC_PROGRAM_STATUS              3
+#define WFC_SAMPLE_STATUS               4
+#define WFC_DISABLE_INTERRUPTS          5
+#define WFC_ENABLE_INTERRUPTS           6
+#define WFC_INTERRUPT_STATUS            7
+#define WFC_ROMSAMPLES_RDONLY           8
+#define WFC_IDENTIFY_SLOT_TYPE          9
+
+/* Wavefront synth commands
+ */
+
+#define WFC_DOWNLOAD_SAMPLE            0x80
+#define WFC_DOWNLOAD_BLOCK             0x81
+#define WFC_DOWNLOAD_MULTISAMPLE       0x82
+#define WFC_DOWNLOAD_SAMPLE_ALIAS      0x83
+#define WFC_DELETE_SAMPLE              0x84
+#define WFC_REPORT_FREE_MEMORY         0x85
+#define WFC_DOWNLOAD_PATCH             0x86
+#define WFC_DOWNLOAD_PROGRAM           0x87
+#define WFC_SET_SYNTHVOL               0x89
+#define WFC_SET_NVOICES                        0x8B
+#define WFC_DOWNLOAD_DRUM              0x90
+#define WFC_GET_SYNTHVOL               0x92
+#define WFC_GET_NVOICES                        0x94
+#define WFC_DISABLE_CHANNEL            0x9A
+#define WFC_ENABLE_CHANNEL             0x9B
+#define WFC_MISYNTH_OFF                        0x9D
+#define WFC_MISYNTH_ON                 0x9E
+#define WFC_FIRMWARE_VERSION           0x9F
+#define WFC_GET_NSAMPLES               0xA0
+#define WFC_DISABLE_DRUM_PROGRAM       0xA2
+#define WFC_UPLOAD_PATCH               0xA3
+#define WFC_UPLOAD_PROGRAM             0xA4
+#define WFC_SET_TUNING                 0xA6
+#define WFC_GET_TUNING                 0xA7
+#define WFC_VMIDI_ON                   0xA8
+#define WFC_VMIDI_OFF                  0xA9
+#define WFC_MIDI_STATUS                        0xAA
+#define WFC_GET_CHANNEL_STATUS         0xAB
+#define WFC_DOWNLOAD_SAMPLE_HEADER     0xAC
+#define WFC_UPLOAD_SAMPLE_HEADER       0xAD
+#define WFC_UPLOAD_MULTISAMPLE         0xAE
+#define WFC_UPLOAD_SAMPLE_ALIAS                0xAF
+#define WFC_IDENTIFY_SAMPLE_TYPE       0xB0
+#define WFC_DOWNLOAD_EDRUM_PROGRAM     0xB1
+#define WFC_UPLOAD_EDRUM_PROGRAM       0xB2
+#define WFC_SET_EDRUM_CHANNEL          0xB3
+#define WFC_INSTOUT_LEVELS             0xB4
+#define WFC_PEAKOUT_LEVELS             0xB5
+#define WFC_REPORT_CHANNEL_PROGRAMS    0xB6
+#define WFC_HARDWARE_VERSION           0xCF
+#define WFC_UPLOAD_SAMPLE_PARAMS       0xD7
+#define WFC_DOWNLOAD_OS                        0xF1
+#define WFC_NOOP                        0xFF
+
+#define WF_MAX_SAMPLE   512
+#define WF_MAX_PATCH    256
+#define WF_MAX_PROGRAM  128
+
+#define WF_SECTION_MAX  44   /* longest OS section length */
+
+/* # of bytes we send to the board when sending it various kinds of
+   substantive data, such as samples, patches and programs.
+*/
+
+#define WF_PROGRAM_BYTES 32
+#define WF_PATCH_BYTES 132
+#define WF_SAMPLE_BYTES 27
+#define WF_SAMPLE_HDR_BYTES 25
+#define WF_ALIAS_BYTES 25
+#define WF_DRUM_BYTES 9
+#define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
+
+#define WF_ACK     0x80
+#define WF_DMA_ACK 0x81
+
+/* OR-values for MIDI status bits */
+
+#define WF_MIDI_VIRTUAL_ENABLED 0x1
+#define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
+#define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
+
+/* See wavefront.c for details */
+
+#define WAVEFRONT_MAX_DEVICES 1 /* How many WaveFront cards we can handle */
+
+/* slot indexes for struct address_info: makes code a little more mnemonic */
+
+#define WF_SYNTH_SLOT         0
+#define WF_INTERNAL_MIDI_SLOT 1
+#define WF_EXTERNAL_MIDI_SLOT 2
+
+/* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
+   emulation. Note these NEVER show up in output from the device and
+   should NEVER be used in input unless Virtual MIDI mode has been 
+   disabled. If they do show up as input, the results are unpredictable.
+*/
+
+#define WF_EXTERNAL_SWITCH  0xFD
+#define WF_INTERNAL_SWITCH  0xF9
+
+/* Debugging flags */
+
+#define WF_DEBUG_CMD 0x1
+#define WF_DEBUG_DATA 0x2
+#define WF_DEBUG_LOAD_PATCH 0x4
+#define WF_DEBUG_IO 0x8
+
+/* WavePatch file format stuff */
+
+#define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
+#define WF_MAX_COMMENT           64    /*  Comment length */
+#define WF_NUM_LAYERS            4
+#define WF_NAME_LENGTH           32
+#define WF_SOURCE_LENGTH         260
+
+#define BankFileID     "Bank"
+#define DrumkitFileID  "DrumKit"
+#define ProgramFileID  "Program"
+
+struct wf_envelope
+{
+    UCHAR8 attack_time:7;
+    UCHAR8 Unused1:1;
+
+    UCHAR8 decay1_time:7;
+    UCHAR8 Unused2:1;
+
+    UCHAR8 decay2_time:7;
+    UCHAR8 Unused3:1;
+
+    UCHAR8 sustain_time:7;
+    UCHAR8 Unused4:1;
+
+    UCHAR8 release_time:7;
+    UCHAR8 Unused5:1;
+
+    UCHAR8 release2_time:7;
+    UCHAR8 Unused6:1;
+
+    CHAR8 attack_level;
+    CHAR8 decay1_level;
+    CHAR8 decay2_level;
+    CHAR8 sustain_level;
+    CHAR8 release_level;
+
+    UCHAR8 attack_velocity:7;
+    UCHAR8 Unused7:1;
+
+    UCHAR8 volume_velocity:7;
+    UCHAR8 Unused8:1;
+
+    UCHAR8 keyboard_scaling:7;
+    UCHAR8 Unused9:1;
+};
+typedef struct wf_envelope wavefront_envelope;
+
+struct wf_lfo
+{
+    UCHAR8 sample_number;
+
+    UCHAR8 frequency:7;
+    UCHAR8 Unused1:1;
+
+    UCHAR8 am_src:4;
+    UCHAR8 fm_src:4;
+
+    CHAR8 fm_amount;
+    CHAR8 am_amount;
+    CHAR8 start_level;
+    CHAR8 end_level;
+
+    UCHAR8 ramp_delay:7;
+    UCHAR8 wave_restart:1; /* for LFO2 only */
+
+    UCHAR8 ramp_time:7;
+    UCHAR8 Unused2:1;
+};
+typedef struct wf_lfo wavefront_lfo;
+
+struct wf_patch
+{
+    INT16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
+
+    UCHAR8 amplitude_bias:7;
+    UCHAR8 Unused1:1;
+
+    UCHAR8 portamento:7;
+    UCHAR8 Unused2:1;
+
+    UCHAR8 sample_number;
+
+    UCHAR8 pitch_bend:4;
+    UCHAR8 sample_msb:1;
+    UCHAR8 Unused3:3;
+
+    UCHAR8 mono:1;
+    UCHAR8 retrigger:1;
+    UCHAR8 nohold:1;
+    UCHAR8 restart:1;
+    UCHAR8 filterconfig:2; /* SDK says "not used" */
+    UCHAR8 reuse:1;
+    UCHAR8 reset_lfo:1;    
+
+    UCHAR8 fm_src2:4;
+    UCHAR8 fm_src1:4;   
+
+    CHAR8 fm_amount1;
+    CHAR8 fm_amount2;
+
+    UCHAR8 am_src:4;
+    UCHAR8 Unused4:4;
+
+    CHAR8 am_amount;
+
+    UCHAR8 fc1_mode:4;
+    UCHAR8 fc2_mode:4;
+
+    CHAR8 fc1_mod_amount;
+    CHAR8 fc1_keyboard_scaling;
+    CHAR8 fc1_bias;
+    CHAR8 fc2_mod_amount;
+    CHAR8 fc2_keyboard_scaling;
+    CHAR8 fc2_bias;
+
+    UCHAR8 randomizer:7;
+    UCHAR8 Unused5:1;
+
+    struct wf_envelope envelope1;
+    struct wf_envelope envelope2;
+    struct wf_lfo lfo1;
+    struct wf_lfo lfo2;
+};
+typedef struct wf_patch wavefront_patch;
+
+struct wf_layer
+{
+    UCHAR8 patch_number;
+
+    UCHAR8 mix_level:7;
+    UCHAR8 mute:1;
+
+    UCHAR8 split_point:7;
+    UCHAR8 updown:1;
+
+    UCHAR8 pan_mod_src:2;
+    UCHAR8 pan_or_mod:1;
+    UCHAR8 pan:4;
+    UCHAR8 split_type:1;
+};
+typedef struct wf_layer wavefront_layer;
+
+struct wf_program
+{
+    struct wf_layer layer[WF_NUM_LAYERS];
+};
+typedef struct wf_program wavefront_program;
+
+struct wf_sample_offset
+{
+    INT32 Fraction:4;
+    INT32 Integer:20;
+    INT32 Unused:8;
+};
+typedef struct wf_sample_offset wavefront_sample_offset;          
+     
+/* Sample slot types */
+
+#define WF_ST_SAMPLE      0
+#define WF_ST_MULTISAMPLE 1
+#define WF_ST_ALIAS       2
+#define WF_ST_EMPTY       3
+
+/* pseudo's */
+
+#define WF_ST_DRUM        4
+#define WF_ST_PROGRAM     5
+#define WF_ST_PATCH       6
+#define WF_ST_SAMPLEHDR   7
+
+#define WF_ST_MASK        0xf
+
+/* Flags for slot status. These occupy the upper bits of the same byte
+   as a sample type.
+*/
+
+#define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
+#define WF_SLOT_FILLED    0x40
+#define WF_SLOT_ROM       0x20
+
+#define WF_SLOT_MASK      0xf0
+
+/* channel constants */
+
+#define WF_CH_MONO  0
+#define WF_CH_LEFT  1
+#define WF_CH_RIGHT 2
+
+/* Sample formats */
+
+#define LINEAR_16BIT 0
+#define WHITE_NOISE  1
+#define LINEAR_8BIT  2
+#define MULAW_8BIT   3
+
+#define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
+
+
+/* 
+
+  Because most/all of the sample data we pass in via pointers has
+  never been copied (just mmap-ed into user space straight from the
+  disk), it would be nice to allow handling of multi-channel sample
+  data without forcing user-level extraction of the relevant bytes.
+  
+  So, we need a way of specifying which channel to use (the WaveFront
+  only handles mono samples in a given slot), and the only way to do
+  this without using some struct other than wavefront_sample as the
+  interface is the awful hack of using the unused bits in a
+  wavefront_sample:
+  
+  Val      Meaning
+  ---      -------
+  0        no channel selection (use channel 1, sample is MONO)
+  1        use first channel, and skip one
+  2        use second channel, and skip one
+  3        use third channel, and skip two
+  4        use fourth channel, skip three
+  5        use fifth channel, skip four
+  6        use six channel, skip five
+
+
+  This can handle up to 4 channels, and anyone downloading >4 channels
+  of sample data just to select one of them needs to find some tools
+  like sox ...
+
+  NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is 
+  important.
+
+*/
+
+#define WF_SET_CHANNEL(samp,chn) \
+ (samp)->Unused1 = chn & 0x1; \
+ (samp)->Unused2 = chn & 0x2; \
+ (samp)->Unused3 = chn & 0x4 
+  
+#define WF_GET_CHANNEL(samp) \
+  (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
+  
+typedef struct wf_sample {
+    struct wf_sample_offset sampleStartOffset;
+    struct wf_sample_offset loopStartOffset;
+    struct wf_sample_offset loopEndOffset;
+    struct wf_sample_offset sampleEndOffset;
+    INT16 FrequencyBias;
+    UCHAR8 SampleResolution:2;  /* sample_format */
+    UCHAR8 Unused1:1;
+    UCHAR8 Loop:1;
+    UCHAR8 Bidirectional:1;
+    UCHAR8 Unused2:1;
+    UCHAR8 Reverse:1;
+    UCHAR8 Unused3:1;
+} wavefront_sample;
+
+typedef struct wf_multisample {
+    INT16 NumberOfSamples;   /* log2 of the number of samples */
+    INT16 SampleNumber[NUM_MIDIKEYS];
+} wavefront_multisample;
+
+typedef struct wf_alias {
+    INT16 OriginalSample __attribute__ ((packed));
+
+    struct wf_sample_offset sampleStartOffset __attribute__ ((packed));
+    struct wf_sample_offset loopStartOffset __attribute__ ((packed));
+    struct wf_sample_offset sampleEndOffset __attribute__ ((packed));
+    struct wf_sample_offset loopEndOffset __attribute__ ((packed));
+
+    INT16  FrequencyBias __attribute__ ((packed));
+
+    UCHAR8 SampleResolution:2  __attribute__ ((packed));
+    UCHAR8 Unused1:1  __attribute__ ((packed));
+    UCHAR8 Loop:1 __attribute__ ((packed));
+    UCHAR8 Bidirectional:1  __attribute__ ((packed));
+    UCHAR8 Unused2:1 __attribute__ ((packed));
+    UCHAR8 Reverse:1 __attribute__ ((packed));
+    UCHAR8 Unused3:1 __attribute__ ((packed)); 
+    
+    /* This structure is meant to be padded only to 16 bits on their
+       original. Of course, whoever wrote their documentation didn't
+       realize that sizeof(struct) can be >=
+       sum(sizeof(struct-fields)) and so thought that giving a C level
+       description of the structs used in WavePatch files was
+       sufficient. I suppose it was, as long as you remember the 
+       standard 16->32 bit issues.
+    */
+
+    UCHAR8 sixteen_bit_padding __attribute__ ((packed));
+} wavefront_alias;
+
+typedef struct wf_drum {
+    UCHAR8 PatchNumber;
+    UCHAR8 MixLevel:7;
+    UCHAR8 Unmute:1;
+    UCHAR8 Group:4;
+    UCHAR8 Unused1:4;
+    UCHAR8 PanModSource:2;
+    UCHAR8 PanModulated:1;
+    UCHAR8 PanAmount:4;
+    UCHAR8 Unused2:1;
+} wavefront_drum;
+
+typedef struct wf_drumkit {
+    struct wf_drum drum[NUM_MIDIKEYS];
+} wavefront_drumkit;
+
+typedef struct wf_channel_programs {
+    UCHAR8 Program[NUM_MIDICHANNELS];
+} wavefront_channel_programs;
+
+/* How to get MIDI channel status from the data returned by
+   a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
+*/
+
+#define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
+
+typedef union wf_any {
+    wavefront_sample s;
+    wavefront_multisample ms;
+    wavefront_alias a;
+    wavefront_program pr;
+    wavefront_patch p;
+    wavefront_drum d;
+} wavefront_any;
+
+/* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
+   might work for other wave-table based patch loading situations.
+   Alas, his fears were correct. The WaveFront doesn't even come with
+   just "patches", but several different kind of structures that
+   control the sound generation process.
+ */
+
+typedef struct wf_patch_info {
+    
+    INT16   key;               /* Use WAVEFRONT_PATCH here */
+    UINT16  devno;             /* fill in when sending */
+    UCHAR8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
+    UINT16  number;            /* patch/sample/prog number */
+
+    UINT32  size;              /* size of any data included in 
+                                 one of the fields in `hdrptr', or
+                                 as `dataptr'.
+
+                                 NOTE: for actual samples, this is
+                                 the size of the *SELECTED CHANNEL*
+                                 even if more data is actually available.
+                                 
+                                 So, a stereo sample (2 channels) of
+                                 6000 bytes total has `size' = 3000.
+
+                                 See the macros and comments for
+                                 WF_{GET,SET}_CHANNEL above.
+
+                              */
+    wavefront_any *hdrptr;      /* user-space ptr to hdr bytes */
+    UINT16 *dataptr;            /* actual sample data */
+
+    wavefront_any hdr;          /* kernel-space copy of hdr bytes */         
+} wavefront_patch_info;
+
+/* The maximum number of bytes we will ever move to or from user space
+   in response to a WFC_* command.  This obviously doesn't cover
+   actual sample data.
+*/
+
+#define WF_MAX_READ sizeof(wavefront_multisample)
+#define WF_MAX_WRITE sizeof(wavefront_multisample)
+
+/*
+   This allows us to execute any WF command except the download/upload
+   ones, which are handled differently due to copyin/copyout issues as
+   well as data-nybbling to/from the card.
+ */
+
+typedef struct wavefront_control {
+    int devno;                         /* from /dev/sequencer interface */
+    int cmd;                           /* WFC_* */
+    char status;                       /* return status to user-space */
+    unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
+    unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
+} wavefront_control;
+
+/* Modulator table */
+
+#define WF_MOD_LFO1      0
+#define WF_MOD_LFO2      1
+#define WF_MOD_ENV1      2
+#define WF_MOD_ENV2      3
+#define WF_MOD_KEYBOARD  4
+#define WF_MOD_LOGKEY    5
+#define WF_MOD_VELOCITY  6
+#define WF_MOD_LOGVEL    7
+#define WF_MOD_RANDOM    8
+#define WF_MOD_PRESSURE  9
+#define WF_MOD_MOD_WHEEL 10
+#define WF_MOD_1         WF_MOD_MOD_WHEEL 
+#define WF_MOD_BREATH    11
+#define WF_MOD_2         WF_MOD_BREATH
+#define WF_MOD_FOOT      12
+#define WF_MOD_4         WF_MOD_FOOT
+#define WF_MOD_VOLUME    13
+#define WF_MOD_7         WF_MOD_VOLUME
+#define WF_MOD_PAN       14
+#define WF_MOD_10        WF_MOD_PAN
+#define WF_MOD_EXPR      15
+#define WF_MOD_11        WF_MOD_EXPR
+
+/* FX-related material */
+
+typedef struct wf_fx_info {
+    int request;             /* see list below */
+    int data[4];             /* we don't need much */
+} wavefront_fx_info;
+
+/* support for each of these will be forthcoming once I or someone 
+   else has figured out which of the addresses on page 6 and page 7 of 
+   the YSS225 control each parameter. Incidentally, these come from
+   the Windows driver interface, but again, Turtle Beach didn't
+   document the API to use them.
+*/
+
+#define WFFX_SETOUTGAIN                        0
+#define WFFX_SETSTEREOOUTGAIN          1
+#define WFFX_SETREVERBIN1GAIN          2
+#define WFFX_SETREVERBIN2GAIN          3
+#define WFFX_SETREVERBIN3GAIN          4
+#define WFFX_SETCHORUSINPORT           5
+#define WFFX_SETREVERBIN1PORT          6
+#define WFFX_SETREVERBIN2PORT          7
+#define WFFX_SETREVERBIN3PORT          8
+#define WFFX_SETEFFECTPORT             9
+#define WFFX_SETAUXPORT                        10
+#define WFFX_SETREVERBTYPE             11
+#define WFFX_SETREVERBDELAY            12
+#define WFFX_SETCHORUSLFO              13
+#define WFFX_SETCHORUSPMD              14
+#define WFFX_SETCHORUSAMD              15
+#define WFFX_SETEFFECT                 16
+#define WFFX_SETBASEALL                        17
+#define WFFX_SETREVERBALL              18
+#define WFFX_SETCHORUSALL              20
+#define WFFX_SETREVERBDEF              22
+#define WFFX_SETCHORUSDEF              23
+#define WFFX_DELAYSETINGAIN            24
+#define WFFX_DELAYSETFBGAIN            25
+#define WFFX_DELAYSETFBLPF             26
+#define WFFX_DELAYSETGAIN              27
+#define WFFX_DELAYSETTIME              28
+#define WFFX_DELAYSETFBTIME            29
+#define WFFX_DELAYSETALL               30
+#define WFFX_DELAYSETDEF               32
+#define WFFX_SDELAYSETINGAIN           33
+#define WFFX_SDELAYSETFBGAIN           34
+#define WFFX_SDELAYSETFBLPF            35
+#define WFFX_SDELAYSETGAIN             36
+#define WFFX_SDELAYSETTIME             37
+#define WFFX_SDELAYSETFBTIME           38
+#define WFFX_SDELAYSETALL              39
+#define WFFX_SDELAYSETDEF              41
+#define WFFX_DEQSETINGAIN              42
+#define WFFX_DEQSETFILTER              43
+#define WFFX_DEQSETALL                 44
+#define WFFX_DEQSETDEF                 46
+#define WFFX_MUTE                      47
+#define WFFX_FLANGESETBALANCE          48      
+#define WFFX_FLANGESETDELAY            49
+#define WFFX_FLANGESETDWFFX_TH         50
+#define WFFX_FLANGESETFBGAIN           51
+#define WFFX_FLANGESETINGAIN           52
+#define WFFX_FLANGESETLFO              53
+#define WFFX_FLANGESETALL              54
+#define WFFX_FLANGESETDEF              56
+#define WFFX_PITCHSETSHIFT             57
+#define WFFX_PITCHSETBALANCE           58
+#define WFFX_PITCHSETALL               59
+#define WFFX_PITCHSETDEF               61
+#define WFFX_SRSSETINGAIN              62
+#define WFFX_SRSSETSPACE               63
+#define WFFX_SRSSETCENTER              64
+#define WFFX_SRSSETGAIN                        65
+#define WFFX_SRSSETMODE                        66
+#define WFFX_SRSSETDEF                 68
+
+/* Allow direct user-space control over FX memory/coefficient data.
+   In theory this could be used to download the FX microprogram,
+   but it would be a little slower, and involve some wierd code.
+ */
+
+#define WFFX_MEMSET              69
+
+#endif __wavefront_h__
index 0c175f0d08ed48da042aa7e146ac57ef0893aa62..4b6d2d5ee89560ca9500160163fad3a1620cb1c8 100644 (file)
@@ -448,6 +448,9 @@ struct sock {
 #if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
                struct ipx_opt          af_ipx;
 #endif
+#if defined (CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE)
+               struct dn_scp           dn;
+#endif
 #if defined (CONFIG_PACKET) || defined(CONFIG_PACKET_MODULE)
                struct packet_opt       *af_packet;
 #endif
@@ -456,16 +459,13 @@ struct sock {
 #endif
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
                ax25_cb                 *ax25;
+#endif
 #if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
                nr_cb                   *nr;
 #endif
 #if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE)
                rose_cb                 *rose;
 #endif
-#endif
-#if defined(CONFIG_DECNET) || defined(CONFIG_DECNET_MODULE)
-               dn_cb                    *dn;
-#endif
 #ifdef CONFIG_NETLINK
                struct netlink_opt      af_netlink;
 #endif
index 5abb9075bca9e935549574f53320228e0ad3d9ee..a684cde660bf0b2ef397e696daa8e093c9defe47 100644 (file)
@@ -9,10 +9,6 @@
  * Authors:    Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  */
 
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
 
 #define BUG_TRAP(x) if (!(x)) { printk("Assertion (" #x ") failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); }