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
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:
--- /dev/null
+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>
+
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
--- /dev/null
+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.
--- /dev/null
+ 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>
+
+
+
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
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);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(__memsetw);
EXPORT_SYMBOL(__constant_c_memset);
EXPORT_SYMBOL(dump_thread);
}
-void __init
-pcibios_fixup(void)
+__initfunc(void
+pcibios_fixup(void))
{
struct pci_bus *cur;
}
+__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)
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/io.h>
+##include <asm/smp.h>
/*
* BIOS32-style PCI interface:
#include <linux/malloc.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/hwrpb.h>
#include <asm/io.h>
#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>
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)
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)
COMPRESSED_HEAD = head.o
-ifeq ($(PROCESSOR),armo)
-TEXTADDR = 0x02080000
-ZTEXTADDR = 0x01800000
-ZRELADDR = 0x02080000
-endif
-
ifeq ($(CONFIG_ARCH_A5K),y)
MACHINE = a5k
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
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
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
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
(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
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
@$(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
#
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
+
/*
* 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]
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
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
* 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
#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 ();
CONFIG_ETHER1=m
CONFIG_ETHER3=m
CONFIG_ETHERH=m
-CONFIG_CDROM=y
#
# Filesystems
#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>
EXPORT_SYMBOL(ecard_address);
#endif
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+
/* processor dependencies */
EXPORT_SYMBOL(processor);
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
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);
/*
* 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)
.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
{
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,
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);
}
}
printk("DEC21285 PCI revision %02X\n", rev);
}
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
__initfunc(char *pcibios_setup(char *str))
{
return str;
#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)
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();
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) {
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))
#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,
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 |
* 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"
adreq \base, irq_prio_l
teq \irqstat, #0
- ldrneb \irqnr, [r5, \irqstat] @ get IRQ number
+ ldrneb \irqnr, [\base, \irqstat] @ get IRQ number
.endm
/*
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
.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
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
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
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
* 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
@ 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
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
.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
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
.macro busyuart,rd,rx
1002: ldrb \rd, [\rx, #0x14]
and \rd, \rd, #0x60
+ teq \rd, #0x60
bne 1002b
.endm
.macro busyuart,rd,rx
1002: ldrb \rd, [\rx, #0x14]
and \rd, \rd, #0x60
+ teq \rd, #0x60
bne 1002b
.endm
beq 1001b
.endm
-#elif defined(CONFIG_ARCH_EBSA285)
+#elif defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_VNC)
.macro addruart,rx
mov \rx, #0xfe000000
.endm
* 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>
* 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])
#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;
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;
}
*p++ = '\n';
}
+ p += sprintf(p, "FIQ: %s\n",
+ current_fiq?current_fiq->name:"unused");
return p - buf;
}
}
}
-#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;
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();
}
+
#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[];
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)
{
#include <linux/major.h>
#include <linux/utsname.h>
#include <linux/init.h>
+#include <linux/console.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
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
*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)
#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>
#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;
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;
*/
#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);
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)
* 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) &
/* 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,
{
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)
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;
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;
*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;
}
* 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>
*/
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
{
-
sigset_t saveset;
mask &= _BLOCKABLE;
lock_kernel();
if (!newsp)
newsp = regs->ARM_sp;
-
ret = do_fork(clone_flags, newsp, regs);
unlock_kernel();
return ret;
#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>
#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);
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);
}
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
/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) {
}
if ($elf) {
chomp;
- $addr = substr ($_, 0, 8);
+ $addr = substr ($_, 0, index($_, " "));
$name = substr ($_, rindex($_, " ") + 1);
$nam[hex($addr)] = $name;
}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * *** 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
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
--- /dev/null
+#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++;
+ }
+}
+
#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)
+++ /dev/null
-/*
- * arch/arm/mm/mm-a5k.c
- *
- * Extra MM routines for the Archimedes architecture
- *
- * Copyright (C) 1998 Russell King
- */
*
* Copyright (C) 1998 Russell King
*/
+#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/pgtable.h>
/*
* 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;
phys_screen_end = offset;
flush_tlb_all ();
- update_mm_cache_all ();
+ update_memc_all ();
}
return kmem;
}
-
--- /dev/null
+/*
+ * 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;
+}
+
/*
* 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"
*
* 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"
*
* 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"
*
* 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>
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"
--- /dev/null
+/*
+ * 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"
--- /dev/null
+/*
+ * 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"
*
* 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
*
* 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
--- /dev/null
+/* 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) }
+}
--- /dev/null
+/* 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) }
+}
+++ /dev/null
-/* 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) }
-}
# 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
/*
* 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
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/smp.h>
#include <asm/spinlock.h>
break;
}
}
- if (!idx) {
+ if (e == dev) {
printk("PCI: Device %02x:%02x not found by BIOS\n",
dev->bus->number, dev->devfn);
d = dev;
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
}
#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;
#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
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;
hades_fixup();
}
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
__initfunc(char *pcibios_setup(char *str))
{
return str;
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) */
}
}
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
__initfunc(char *pcibios_setup(char *str))
{
return str;
return err;
}
+__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+{
+}
+
__initfunc(char *pcibios_setup(char *str))
{
return str;
* 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>
req.baud_base = MY_BAUD_BASE;
req.irq = irq;
req.port = port;
+ req.flags = 0;
return register_serial(&req);
}
#define MY_PORT_ADDRESS(port,cardaddress) \
((cardaddress) + (port) * 8)
#include "serial-card.c"
-
* 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>
#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 },
#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); \
}
/*
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
*/
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));
/* 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:
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;
}
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;
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;
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);
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);
* 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;
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;
} 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 ++;
do {
unsigned long status;
+
/*
* Read the packet header
*/
/*
* 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;
/*
#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>
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];
if (!io[i]) {
if ((ec[i] = ecard_find (0, etherh_cids)) == NULL)
continue;
+
if (!dev)
return -ENOMEM;
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];
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
ec[i] = NULL;
}
}
+ unlock_8390_module();
}
#endif /* MODULE */
* 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>
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;
#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
* 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>
#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
*/
if (!(status & STATUS_DRQ))
continue;
- word = *addr | (*addr + 1) << 8;
+ word = *addr | *(addr + 1) << 8;
outw (info->dmaarea);
addr += 2;
length -= 2;
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;
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;
#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
* 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>
#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
*/
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;
* 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.
#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
*/
#define SCSI2_SYNC
-#undef NO_DISCONNECTS
#undef DEBUG_CONNECT
#undef DEBUG_BUSSERVICE
#undef DEBUG_FUNCTIONDONE
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)),
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);
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);
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);
}
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;
* : 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;
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
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)
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;
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);
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 {
#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;
}
return 1;
}
+ outb(CMD_RESETCHIP, REG_CMD(info));
+
outb(0, REG_CNTL3(info));
outb(CNTL2_S2FE, REG_CNTL2(info));
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 */
/* 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 */
/*
* drivers/acorn/scsi/msgqueue.c: message queue handling
*
- * Copyright (C) 1997,8 Russell King
+ * Copyright (C) 1997-1998 Russell King
*/
#include <linux/module.h>
#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
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;
#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
* 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>
#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];
/*
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;
#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;
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'
*/
#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>
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);
}
* 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,
*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
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)
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;
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;
"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},
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");
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)
}
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++;
}
}
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
}
}
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
*/
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)
{
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:
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);
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;
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))
{
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;
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)
{
}
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++;
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)
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);
ushort swidth, sheight;
short cropx, cropy;
ushort cropwidth, cropheight;
- unsigned int vidadr;
+ unsigned long vidadr;
ushort freq;
int norm;
int interlace;
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;
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)
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));
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;
}
}
-/* 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);
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;
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;
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);
/* ++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;
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 */
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);
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);
}
continue;
}
- /* FIXME: Handle tabs in a special way and use putcs for them as well */
FLUSH
do_con_trol(tty, currcons, c);
}
{
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
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);
}
/*
* 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;
}
}
currcons = fg_console = 0;
+ master_display_fg = vc_cons[currcons].d;
+ set_origin(currcons);
save_screen();
gotoxy(currcons,x,y);
csi_J(currcons, 0);
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
*/
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),
*/
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;
}
}
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;
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)
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);
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)
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
#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))
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;
#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 },
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)
{
if (first) {
first = 0;
- take_over_console(&fb_con);
+ take_over_console(&fb_con, 0, MAX_NR_CONSOLES-1, 1);
}
return 0;
#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);
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;
}
#ifdef CONFIG_FTAPE
ftape_init();
#endif
+#ifdef CONFIG_VIDEO_BT848
+ i2c_init();
+#endif
#ifdef CONFIG_VIDEO_DEV
videodev_init();
#endif
int port;
int curvol;
unsigned long curfreq;
+ int muted;
};
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
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();
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 */
}
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 */
}
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 */
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);
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;
}
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)
{
--- /dev/null
+/* 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
+++ /dev/null
-/*
- * 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;
- }
-}
#ifndef __RSF16FMI_H
#define __RSF16FMI_H
-#include <linux/radio.h>
-
int radiosf16fmi_init(void);
#endif /* __RSF16FMI_H */
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/* 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 */
#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>
#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
#ifdef MODULE
int init_module(void)
#else
-int msp3400c_init(void)
+int i2c_tuner_init(void)
#endif
{
i2c_register_driver(&i2c_driver_tuner);
#include <asm/uaccess.h>
#include <asm/system.h>
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
#define VIDEO_NUM_DEVICES 256
#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 *);
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
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 */
#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,
arc_examine_irq,
arc_inc_use_count,
- arc_dec_use_count
+ arc_dec_use_count,
+ arc_fill_inode
};
/* --- Initialisation code -------------------------------- */
#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,
parport_ax_examine_irq,
parport_ax_inc_use_count,
- parport_ax_dec_use_count
+ parport_ax_dec_use_count,
+ parport_ax_fill_inode
};
#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,
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 ------------------------------------- */
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;
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);
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");
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)
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;
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;
-/* 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.
*/
* 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++;
}
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;
#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>
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);
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)) {
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);
save_flags(flags);
cli();
- update_stats(dev->base_addr, dev);
+ update_stats(dev);
restore_flags(flags);
return &lp->stats;
}
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");
/* 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;
}
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)
{
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++ )
}
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;
/*
- * $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.
*
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;
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:
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;
/*
}
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
nhosts = 0;
try_again = 0;
- if (!pb)
- pb = parport_enumerate();
-
if (!pb) {
printk("ppa: parport reports no devices.\n");
return 0;
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
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
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
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
# 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 \
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.
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
#
--- /dev/null
+ 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>
+
+
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
*/
- int my_dev;
+ long my_dev;
char dev_name[100];
int e;
{
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 */
* 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
* anyway.
*
* Changes
- * Alan Cox Modularisation, Basic cleanups.
+ * Alan Cox Modularisation, Basic cleanups.
+ * Paul Barton-Davis Separated MPU configuration, added
+ * Tropez+ (WaveFront) support
*/
/*
#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)
}
#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
*/
{
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;
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)
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
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;
}
#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);
#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
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
#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
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);
void cleanup_module(void)
{
if (found_mpu)
- unload_mad16_mpu(&config);
+ unload_mad16_mpu(&config_mpu);
unload_mad16(&config);
SOUND_LOCK_END;
}
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)
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))
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;
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);
* 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
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;
#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];
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);
}
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);
}
break;
default:
- printk(KERN_INFO LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
+ printk(KERN_DEBUG LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
break;
}
break;
(*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);
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);
* 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
# 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
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);
}
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);
}
break;
default:
- printk(KERN_INFO LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
+ printk(KERN_DEBUG LOGNAME ": DSP message %u\n", LOBYTE(wMessage));
break;
}
break;
(*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);
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);
* 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
# 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
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);
--- /dev/null
+/*
+ * 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, §ion_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
+
+
--- /dev/null
+/*
+ * 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
+
+
--- /dev/null
+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
+};
+
--- /dev/null
+#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__
+
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
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
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
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
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
endif
ifeq ($(CONFIG_FB_OF),y)
-L_OBJS += offb.o
+L_OBJS += offb.o macmodes.o
endif
ifeq ($(CONFIG_FB_RETINAZ3),y)
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)
L_OBJS += vgacon.o
endif
-# Console Wrapper
-
-ifdef CONFIG_ABSCON_COMPAT
-L_OBJS += compatcon.o
-endif
-
include $(TOPDIR)/Rules.make
gspcore.c: gspcore.gsp
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
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) */
&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;
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
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))
#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);
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;
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#endif
+#ifdef __sparc__
+#include <asm/pbm.h>
+#endif
#include "aty.h"
#include "fbcon.h"
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 */
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
/*
*/
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
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
};
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;
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:
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));
display->dispsw = NULL;
break;
}
+ display->scrollmode = accel ? 0 : SCROLL_YREDRAW;
if (info->changevar)
(*info->changevar)(con);
}
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
#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);
/* 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;
ssave = send;
return sbegin;
}
-#endif /* !CONFIG_FB_OF */
+#endif /* CONFIG_ATARI */
static int atyfbcon_switch(int con, 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);
}
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
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
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
-/* $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)
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)
{
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, x, y;
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, x, y;
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)
}
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)
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))
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,
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;
(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;
}
--- /dev/null
+/*
+ * 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 */
+++ /dev/null
-/*
- * 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
-};
-/* $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)
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)
{
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;
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,
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)
}
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;
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;
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
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)
};
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)
};
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)
};
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)
};
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)
};
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)
};
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;
}
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);
}
}
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);
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;
}
}
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;
}
}
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;
+ }
}
}
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)
};
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)
};
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)
};
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)
};
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)
};
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)
};
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)
};
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)
};
* 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
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
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);
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);
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)
{
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;
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 */
#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
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 */
}
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;
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 */
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;
}
{
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;
}
{
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;
}
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
}
}
+/* 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)
}
-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) {
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 */
#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)
{
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'*/
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;
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++)
}
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 );
update_screen( unit );
if (old_data && (--REFCOUNT(old_data) == 0))
- kfree( old_data - sizeof(int) );
+ kfree( old_data - 2*sizeof(int) );
return 0;
}
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
#define SCROLL_YMOVE (2)
#define SCROLL_YREDRAW (3)
+extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
+
/* ================================================================= */
/* Utility Assembler Functions */
* 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 */
--- /dev/null
+#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 */
+
+};
+
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[];
+
/*
#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 },
#else
{ SUN8x16_IDX, fontname_sun8x16, &fontwidth_sun8x16, &fontheight_sun8x16,
fontdata_sun8x16 },
+ { SUN12x22_IDX, fontname_sun12x22, &fontwidth_sun12x22, &fontheight_sun12x22,
+ fontdata_sun12x22 },
#endif
};
* 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;
* 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;
{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 */
--- /dev/null
+/*
+ * 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;
+}
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)
};
#include <asm/io.h>
#include <asm/prom.h>
+#include "fbcon.h"
#include "fbcon-cfb8.h"
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 */
#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
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;
}
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);
#else
disp->dispsw = NULL;
#endif
+ disp->scrollmode = SCROLL_YREDRAW;
strcpy(info->info.modename, "OFfb ");
strncat(info->info.modename, dp->full_name,
display_info.cmap_data_address = address + 0x7ffcc1;
}
console_fb_info = &info->info;
- console_set_cmap_ptr = offb_set_cmap;
}
#endif /* CONFIG_FB_COMPAT_XPMAC) */
}
/*
* 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)
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;
}
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;
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;
}
--- /dev/null
+/* $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,
+};
+++ /dev/null
-/* $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 */
-
+++ /dev/null
-/* $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) */
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
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 },
if (fb->mmaped)
sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
}
+ if (fb->reset)
+ fb->reset(fb);
fb->open = 0;
} else
fb->consolecnt--;
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
}
/*
(*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);
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;
(*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;
* 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);
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);
}
/*
(*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
*/
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 &&
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;
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;
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;
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);
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;
struct bt_regs *bt;
struct cg6_fbc *fbc;
struct cg6_thc *thc;
+ struct cg6_tec *tec;
volatile u32 *fhc;
};
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 *);
#include <linux/selection.h>
#include <asm/io.h>
+#include "fbcon.h"
#include "fbcon-cfb8.h"
#include "fbcon-cfb32.h"
#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:
{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 */
#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);
-}
-
/* --------------------------------------------------------------------- */
/*
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");
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;
{
struct fb_fix_screeninfo fix;
struct display *display;
+ struct display_switch *sw;
if (con >= 0)
display = &fb_display[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;
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;
}
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);
currcon = con;
/* Install new colormap */
do_install_cmap(con, info);
- fb_update_var(con, info);
return 0;
}
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)
*
* - 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);
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)
{
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
#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;
vga_video_port_val = 0x3d5;
if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
{
- int i ;
+ int i;
vga_vram_end = 0xc0000;
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);
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 */
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)
}
}
-
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.
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)
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
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;
{
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)
}
-
/*
* The console `switch' structure for the VGA based console
*/
struct consw vga_con = {
vgacon_startup,
vgacon_init,
- DUMMY, /* con_deinit */
+ vgacon_deinit,
DUMMY, /* con_clear */
DUMMY, /* con_putc */
DUMMY, /* con_putcs */
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)
};
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
#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 */ \
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) \
({ \
/* 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 \
/* 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 \
* 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
*
*/
/*
- * 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
--- /dev/null
+/*
+ * 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
+
* 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);
}
/*
* 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)
-
#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
/* 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 \
*
* 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)
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
/*
* Mapping areas
*/
-#define IO_END 0xe0ffffff
+#define IO_END 0xe1000000
#define IO_BASE 0xe0000000
#define IO_SIZE (IO_END - IO_BASE)
* 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()
/* 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 \
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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 */
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/* no ide */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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()
+
--- /dev/null
+/*
+ * linux/include/asm-arm/arch-ebsa110/mmap.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Dummy oldlatches.h
+ *
+ * Copyright (C) 1996 Russell King
+ */
+
+#ifdef __need_oldlatches
+#error "Old latches not present in this (rpc) machine"
+#endif
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * linux/include/asm-arm/arch-ebsa110/shmparam.h
+ *
+ * Copyright (c) 1996 Russell King.
+ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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()
#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
/* 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) \
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
#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
#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
#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
#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;
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];
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);
}
/*
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);
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;
}
#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)
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)
extern __inline__ pte_t pte_wrprotect(pte_t pte)
{
- pte_val(pte) &= ~PTE_AP_WRITE;
+ pte_val(pte) &= ~_PTE_WRITE;
return 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;
}
#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;
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];
#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
/* 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. */
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
#define SA_RESTORER 0x04000000
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
#ifdef __KERNEL__
/*
#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)
#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)
#define mb() __asm__ __volatile__ ("" : : : "memory")
#define nop() __asm__ __volatile__("mov r0,r0\n\t");
+extern asmlinkage void __backtrace(void);
+
#endif
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 *);
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)
+++ /dev/null
-/*
- * 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_ */
*/
#define CUR_DEFAULT CUR_UNDERLINE
+#include <linux/config.h>
+
#define NPAR 16
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 */
};
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 {
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*);
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;
void (*inc_use_count)(void);
void (*dec_use_count)(void);
+ void (*fill_inode)(struct inode *inode, int fill);
};
struct parport_device_info {
/*
- * $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
* 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:
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);
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,
#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
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;
* with information needed by the vt package
*/
-#include <linux/config.h>
#include <linux/vt.h>
/*
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;
--- /dev/null
+#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__
#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
#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
* 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__); }