diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 1997-10-31 17:25:36 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 1997-10-31 17:25:36 +0000 |
commit | 915f1f5d0871c790bcb1a126ef69a6b88e2d14f2 (patch) | |
tree | df67c3471e7e50a95bb3ef4b59c66f88c64ec939 /sys/i386 | |
parent | fbb347fe32427a1b3fb420db2f83b7cfefaa7890 (diff) | |
download | src-915f1f5d0871c790bcb1a126ef69a6b88e2d14f2.tar.gz src-915f1f5d0871c790bcb1a126ef69a6b88e2d14f2.zip |
Notes
Diffstat (limited to 'sys/i386')
33 files changed, 15821 insertions, 0 deletions
diff --git a/sys/i386/isa/sound/README.FREEBSD b/sys/i386/isa/sound/README.FREEBSD new file mode 100644 index 000000000000..3603bfe040e9 --- /dev/null +++ b/sys/i386/isa/sound/README.FREEBSD @@ -0,0 +1,165 @@ +GUSPNP15 8/6//97 +ftp://rah.star-gate.com/pub/guspnp.tar.gz + +This sound driver is for FreeBSD 3.0-current . + + +Major enhancement we now support mapping the dma buffer to user +space for write operations only. This features is useful for +games like xquake . So far the mmap features seems to work +with the GUS PnP Pro and with the SB16. + +For xquake you will need: + +1. a few mods to the linux loadable module so just download it and + replace yours: +cd /sys/i386/ +tar -xzf linux_ioctl.tar.gz +cd /usr/src/lkm/linux +make +make install +modunload -i 0 (if you have the linux up and running) +linux +ftp://rah.star-gate.com/linux_ioctl.tar.gz + +2. Install the linux lib 2.4 package: +pkg_add linux_lib-2.4.tgz + +ftp://ftp.freebsd.org/pub/FreeBSD/packages-current/emulators/linux_lib-2.4.tgz + +If you don't have xquake you can get it from: + +3. ftp://ftp.freebsd.org/pub/idgames/idstuff/unsup/intel_linux_quake101.tgz + + +A simple test program mmap_test.c is provided in the sound driver directory. +So copy it to your home directory or favorite place and compile it. +cc -o mmap_test mmap_test.c + +record a sample session: +cat /dev/dsp >smpl + +now run mmap_test . You will hear a loud pop thats a test program +then the sample stream will loop . + + +Phew, now back to sound driver land 8) + + +This is a minor sound driver release for the GUS PnP Pro , GUS MAX, +AudioTrix Pro , SB16 and SB16 PnP. There is also an experimental +AWE sub model. + +Included Luigi's clean up work . Tnks! + +Randall Hopper's SB16 speed setting fix . Tnks! + +Fixed signal handling throught out the sound driver. The problem +first surfaced with the SB16 not generating an interrupt on the +last dma request and SB afficionados quickly pointed out the +bug in the driver. I had to put back the auto dma feature for +xquake :( + + +NOTE YOU DON'T NEED THE PNP DRIVER FOR THE GUS PNP SINCE THE DRIVER +HAS BUILTIN PNP SUPPORT FOR THE GUS. + +My P133 Bios supports PnP. To first figured out what my SB16 PnP +was being configured to I booted win95 and checked out what Win95 +ended up with . Alternatively, if you want to you can also down +load Sujal Patel's PnP driver: + + ftp://rah.start-gate.com/pub/FreeBSD-ISA_PnP_June8.tar.gz + +follow the instructions on how to configure your PnP soundcard or +ISA device. +Lugi also has Sujal's PnP driver . + + +--- + + http://www.iet.unipi.it/~luigi/pnp.c + http://www.iet.unipi.it/~luigi/pnp.h + + the two main files. Follow Sujal Patel's instructions + for installing pnp support. + + http://www.iet.unipi.it/~luigi/pnpinfo.tgz +--- + +This is my kernel configuration for my SB16 PnP: + +controller snd0 +device sb0 at isa? port 0x220 irq 10 conflicts drq 3 vector sbintr +device sbxvi0 at isa? port? irq? drq 5 conflicts +device opl0 at isa? port 0x388 conflicts +device sbmidi0 at isa? port 0x300 irq? conflicts + +---- + + +The difference between a GUS PnP and a GUS PnP PRO is that the Pro +comes with 512kb. I went out an got a 1mb 60ns 30pin simm and installed +it on my GUS PnP. I own a GUS PnP and a GUS PnP PRO. + + +To unpack: +cd / +mv /sys/i386/isa/sound /sys/i386/isa/sound.old +cd /sys/i386/isa/ +tar -xzf guspnp15.tar.gz + + +cd /sys/i386/conf +Edit the kernel config file in /sys/i386/conf + +IF YOU HAVE A GUS MAX or GUS add the option NOGUSPNP to the config file + OPTIONS NOGUSPNP + THEN follow the instructions for NONPNP CONFIGURATION + + +PNP CONFIGURATION +To configure your guspnp PRO if you have a motherboard which supports +PnP: + + controller snd0 + device gus0 at isa? vector gusintr + +NONPNP CONFIGURATION +To configure your guspnp PRO if your motherboard does NOT support +PnP: + +device gus0 at isa? port 0x220 irq 11 drq 1 flags 0x3 vector gusintr + + +the gus pnp is fully software configurable and the above configuration +is setup for full duplex audio. The dma channel settings are: + +drq 1 --- DMA channel for playback + +flags 0x3 --- DMAN channel for recording + +In the event that you have to configure a GUS PnP manually or a GUS MAX: + + Available IRQs for the GUS are: + 3, 5, 7, 9, 11, 12, 15 + + Available DMA channels for the GUS are: + 1, 3, 5, 6, 7 + + +config <kernel-file> +cd /sys/compile/<kernel-file> +make +make install + +THERE IS NO NEED TO BOOT TO DOS TO CONFIGURE YOUR GUS PNP. +THE DRIVER HAS BUILTIN SUPPORT FOR PNP WHICH I GOT +FROM THE GRAVIS DRIVER DEVELOPMENT KIT + +Many thanks to Brian Litzinger <brian@MediaCity.com> for +porting the sound driver 3.5 to 2.2-current. Well, thats a while +ago hence the reference to 2.2. + + Have fun, + Amancio diff --git a/sys/i386/isa/sound/Readme b/sys/i386/isa/sound/Readme new file mode 100644 index 000000000000..259414357c7b --- /dev/null +++ b/sys/i386/isa/sound/Readme @@ -0,0 +1,248 @@ + +VoxWare v3.5-alpha5 release notes +--------------------------------- + +IMPORTANT! This version of the driver is compatible only with Linux versions + 1.3.33 and later. It may work with earlier ones as a loadable + module but... + + Also this is an ALPHA test version which has not been tested + with all cards. At least AEDSP16 support will not work. PAS16 + and PSS supports have not been tested. /dev/dsp and /dev/audio + playback with standard GUS sounds scrambled. 16 bit mode of + SB16 doesn't work. + +Please read the SOUND-HOWTO (available from sunsite.unc.edu and other Linux ftp +sites). It contains much more information than this file. + +***************************************************************** +* NEW! VoxWare home page is http://personal.eunet.fi/pp/voxware * +* The file Readme.cards contains card specific instructions * +* about configuring various cards. * +***************************************************************** + +There are some programming information (little bit old) in the +Hacker's Guide +(ftp://nic.funet.fi/pub/OS/Linux/ALPHA/sound/snd-sdk-doc-0.1.ps.gz). +Believe me: The file is really there. The directory is just hidden and +you have to cd into it before the file is visible. Note: This directory +was accidently removed some time ago but it's now back. + +I have got many patches from various persons during last year. Some of +them are still on my mailbox and they should be included in versions +after v3.0 (I will not add aditional features before v3.0 is ready). + + ==================================================== +- THIS VERSION ____REQUIRES____ Linux 1.3.33 OR LATER. + ==================================================== + +- THIS VERSION MAY NOT WORK WITH Linux VERSIONS RELEASED + AFTER end of Nov 1995. If this version doesn't compile with + your kernel version, please use the sound driver version + included in your kernel. + +You will need the snd-util-3.0.tar.gz and snd-data-0.1.tar.Z +packages to use this driver. They should be in the same +ftp site or BBS from where you got this driver. For +example at nic.funet.fi:pub/OS/Linux/*. + +If you are looking for the installation instructions, please +look at linux/Readme. + +Supported soundcards +-------------------- + +Gravis Ultrasound (GUS) +GUS MAX +GUS with the 16 bit sampling daughtercard +PAS16 +Windows Sound System compatible soundcards +ECHO-PSS (cards based on the PSS architecture by Analog Devices. + Including Orchid SW32, Cardinal DSP16 among others). + (NOTE! WSS mode may not work (DMA channel setup problem)). +MediaTriX AudioTriX Pro (OPL4 and the optional effect daughtercard + require special initialization. There is a program (setfx) in + the snd-util-3.0.tar.gz package which does it). +Ensoniq SoundScape (works but needs some improvements) +MV Jazz16 based soundcards (ProSonic, 3D etc). +SoundMan Wave (recording may not work, mixer support is limited) +Mozart (OAK OTI-601 interface chip) based soundcards. +MAD16 (an interface chip by OPTi) based soundcards (TB Tropez ???). +(NOTE! The MAD16 looks similar to the Mozart chip. It could be a good +idea to configure MAD16 cards as Mozart ones. The MAD16 driver doesn't set +up MPU401 which the Mozart one does. +CS4232 based cards such as AcerMagic S23. + + +In addition all Sound Blaster models and clones (up to AWE32) work if +you want to use them. + +The Emu synthesizer chip of AWE32 is not and will not be supported. The same is +true with the ASP chip also. Creative Technology will not release detailed +information about them so it's not possible to support them. + +If you want to get support for AWE32 or ASP, please contact Creative Labs. +Ask _politely_ if they are going to support Linux. Maybe they change +their policy if there is enough demand. + +=========================================================================== +If your card is compatible with SB, MPU401 or Windows Sound System, it +may work with the driver even if it's not listed in the above list. In this +case it may require initialization using DOS. Just start DOS and cold +boot to Linux (etc.) by hitting ctrl-alt-del. +=========================================================================== + +Compatibility with the earlier versions +--------------------------------------- + +There have been some changes in soundcard.h after v2.5 of the driver +(v2.90 is compatible with this one). Binaries compiled with this version +of soundcard.h will not work with v2.0 and earlier. + +Contributors +------------ + +This driver contains code by several contributors. In addition several other +persons have given usefull suggestions. The following is a list of major +contributors. (I could have forgotten some names.) + + Craig Metz 1/2 of the PAS16 Mixer and PCM support + Rob Hooft Volume computation algorithm for the FM synth. + Mika Liljeberg uLaw encoding and decoding routines + Andy Fingerhut New ulaw conversion tables (ulaw.h) + Jeff Tranter Linux SOUND HOWTO document + Greg Lee Volume computation algorithm for the GUS and + lot's of valuable suggestions. + Andy Warner ISC port + Jim Lowe, + Amancio Hasty Jr FreeBSD/NetBSD port + Anders Baekgaard Bughunting and valuable suggestions. + Joerg Schubert SB16 DSP support. + Andrew Robinson Improvements to the GUS driver + Megens SA MIDI recording for SB and SB Pro. + Mikael Nordqvist Linear volume support for GUS and + nonblocking /dev/sequencer. + Ian Hartas SVR4.2 port + Markus Aroharju and + Risto Kankkunen Major contributions to the mixer support + of GUS v3.7. + Hunyue Yau Mixer support for SG NX Pro. + Marc Hoffman PSS support. + Rainer Vranken Initialization for Jazz16 (ProSonic, MV3D, SM Wave). + Peter Trattler Initial version of loadable module support for Linux. + JRA Gibson 16 bit mode for Jazz16 + Davor Jadrijevic MAD16 support + Gregor Hoffleit Mozart support + Riccardo Facchetti Audio Excel DSP 16 (aedsp16) support + +There are propably many other names missing. If you have sent me some +patches and your name is not in the above list, please inform me. + +Sponsors etc. +------------- + +The following companies have greatly helped development of this driver +in form of a free copy of their product: + +Novell, Inc. UnixWare personal edition + SDK +The Santa Cruz Operation, Inc. A SCO OpenServer + SDK +Ensoniq Corp, a SoundScape card and extensive amount of assistance +MediaTriX Peripherals Inc, a AudioTriX Pro card + SDK +Acer, Inc. a pair of AcerMagic S23 cards. + +In addition the following companies have provided me sufficial amount +of technical information at least some of their products (free or $$$): + +Advanced Gravis Computer Technology Ltd. +Media Vision Inc. +Analog Devices Inc. +Logitech Inc. +Aztech Labs Inc. +Crystal Semiconductor Corporation, +Integrated Circuit Systems Inc. +OAK Technology +OPTi +Ad Lib Inc. ($$) +Music Quest Inc. ($$) +Creative Labs ($$$) + +If you have some problems +========================= + +Read the sound HOWTO (sunsite.unc.edu:/pub/Linux/docs/...?). +Also look at the home page (http://personal.eunet.fi/pp/voxware). It may +contain info about some recent bug fixes. + +It's likely that you have some problems when trying to use the sound driver +first time. Soundcards don't have standard configuration so there are no +good default configuration to use. Please try to use same I/O, DMA and IRQ +values for the soundcard than with DOS. + +If you get an error message when trying to use the driver, please look +at /var/adm/messages for more verbose error message. + + +In general the easiest way to diagnoze problems is to do "cat /dev/sndstat". + +If you get an error message, there are some problems with the driver setup: + + - "No such file or directory" tells that the device files for + the sound driver are missing. Use the script at the end of + linux/drivers/sound/Readme.linux to create them. + + - "No such device" telss that the sound driver is not in the kernel. + You have to reconfigure and recompile the kernel to have the sound + driver. Compiling the driver doesn't help alone. You have to boot + with the newly compiled one before the driver becomes active. + The Linux-HOWTO should help in this step. + +The following errors are likely with /dev/dsp and /dev/audio. + + - "No such device or address". This error message should not happen + with /dev/sndstat but it's possible with the other sound devices. + This error indicates that there are no suitable hardware for the + device file or the sound driver has been compiled without support for + this particular device. For example /dev/audio and /dev/dsp will not + work if "digitized voice support" was not enabled during "make config". + + - "Device or resource busy". Propably the IRQ (or DMA) channel + required by the soundcard is in use by some other device/driver. + + - "I/O error". Almost certainly (99%) it's an IRQ or DMA conflict. + Look at the kernel messages in /var/adm/notice for more info. + + - "Invalid argument". The application is calling ioctl() + with impossible parameters. Check that the application is + for sound driver version 2.X or later. + +In general the printout of of /dev/sndstat should tell what is the problem. +It's possible that there are bugs in the sound driver but 99% of the problems +reported to me are caused by somehow incorrect setup during "make config". + +For owners of TI TM4000M notebooks +---------------------------------- + +There appears to be some kind of conflict between the sound support +(MV Jazz), mouse port and VoxWare. You could try to configure kernel +with the C&T 82C710 mouse port support disabled. + +Hannu + +Regards, + +Hannu Savolainen +hannu@voxware.pp.fi +(or Hannu.Savolainen@cctap.carel.fi in case the above bounces) + +Snail mail: Hannu Savolainen + Hiekkalaiturintie 3 A 8 + 00980 Helsinki + Finland + +NOTE! I propably don't answer to Snail mail or FAX messages. Sending answer + to each of them is simply too expensive and time consuming. However I + try to reply every email message I get (within a week). If you don't + get response, please check how your address is written in the message + header. I can't answer if I don't have a valid reply address. + +VoxWare home page is http://personal.eunet.fi/pp/voxware diff --git a/sys/i386/isa/sound/Readme.aedsp16 b/sys/i386/isa/sound/Readme.aedsp16 new file mode 100644 index 000000000000..b205a9d0ff56 --- /dev/null +++ b/sys/i386/isa/sound/Readme.aedsp16 @@ -0,0 +1,6 @@ +Informations about Audio Excel DSP 16 can be found in the source +file aedsp16.c +Please, read the head of the source before using it. It contain useful +informations. + + Riccardo diff --git a/sys/i386/isa/sound/Readme.cards b/sys/i386/isa/sound/Readme.cards new file mode 100644 index 000000000000..fe17aa064def --- /dev/null +++ b/sys/i386/isa/sound/Readme.cards @@ -0,0 +1,845 @@ +Configuring VoxWare 3.0 (for Linux) with some most common soundcards +==================================================================== + +NOTE! This document may contain some error. Please inform me + if you find any mistakes. + +Read this before trying to configure the driver +----------------------------------------------- + +There are currently many cards that work with VoxWare. Some of the cards +have native support while the others work since they emulate some other +cards (usually SB, MSS/WSS and/or MPU401). The following cards have native +support in VoxWare. Detailed instructions for configuring these cards +will be given later in this document. + +Pro Audio Spectrum 16 (PAS16) and compatibles: + Pro Audio Spectrum 16 + Pro Audio Studio 16 + Logitech Sound Man 16 + NOTE! The original Pro Audio Spectrum as well as the PAS+ are not + and will not be supported by VoxWare. + +Media Vision Jazz16 based cards + Pro Sonic 16 + Logitech SoundMan Wave + (Other Jazz based cards should work but I don't have any reports + about them). + +Sound Blasters + SB 1.0 to 2.0 + SB Pro + SB 16 + NOTE! The ASP chip and the EMU synth of the AWE32 is not supported + since their manufacturer doesn't release information about + the card. However both the AB16ASP and the AWE32 work with + VoxWare just like a SB16. Also see the comment about some + unsupported cards at the end of this file. + SB16 compatible cards by other manufacturers than Creative. + You have been fooled since there are no SB16 compatible + cards in the market (July95). It's likely that your card + is compatible just with SB Pro but there is also a non SB + compatible 16 bit mode. Usually it's MSS/WSS but could also + be a proprietary one like MV Jazz16. + +Gravis Ultrasound (GUS) + GUS + GUS + the 16 bit option + GUS MAX + GUS ACE (No MIDI port and audio recording) + +MPU-401 and compatibles + The driver works both with the full (intelligent mode) MPU-401 + cards (such as MPU IPC-T and MQX-32M) and with the UART only + dumb MIDI ports. MPU-401 is currently the most common MIDI + interface. Most soundcards are compatible with it. However + don't enable MPU401 mode blindly. Many cards having native support + in VoxWare have their own MPU401 driver. Enabling the standard one + will cause a conflict with these cards. So look if your card is + in the list of supported cards before enabling MPU401. + +Windows Sound System (MSS/WSS) + Even Microsoft has discontinued their own Sound System card, they + managed to make a standard. MSS compatible cards are based on a + codec chip which is easily available from at least two manufacturers + (AD1848 by Analog Devices and CS4231/CS4248 by Crystal Semiconductor). + Currently most soundcards are based on one of the MSS compatible codec + chip. The CS4231 is used in the high quality cards such as GUS MAX, + MediaTriX AudioTriX Pro and TB Tropez (GUS MAX is not MSS compatible). + + Having a AD1848, CS4248 or CS4231 codec chip on the card is a good + sign. Even if the card is not MSS compatible, it could be easy to write + support for it to VoxWare. Note also that most MSS compatible cards + require special boot time initialization which may not be present + in VoxWare. Also some MSS compatible cards have native support in + VoxWare. Enabling the MSS support with these cards is likely to + cause a conflict. So check if your card is listed in this file before + enabling the MSS support. + +6850 UART MIDI + This UART chip is used in the MIDI interface of some (rare) + soundcards. It's supported by VoxWare in case you need it. + +Yamaha FM synthesizers (OPL2, OPL3 and OPL4) + Most soundcards have a FM synthesizer chip. The OPL2 is a 2 + operator chip used in the original AdLib card. Currently it's used + only in the cheapest (8 bit mono) cards. The OPL3 is a 4 operator + FM chip which provides better sound quality and/or more available + voices than the OPL2. The OPL4 is a new chip which has a OPL3 and + a wave table synthesizer packed on the same chip. VoxWare supports + just the OPL3 mode directly. Most cards having a OPL4 (like + SM Wave and AudioTriX Pro) support the OPL4 mode using MPU401 + emulation. Writing a native OPL4 support to VoxWare is difficult + since Yamaha doesn't give information about their sample ROM chip. + + Enable the generic OPL2/OPL3 FM synthesizer support if your + card has a FM chip made by Yamaha. Don't enable it if your card + has a software (TRS) based FM emulator. + +PSS based cards (AD1848 + ADSP-2115 + Echo ESC614 ASIC) + Analog Devices and Echo Speech have together defined a soundcard + architecture based on the above chips. The DSP chip is used + for emulation of SB Pro, FM and General MIDI/MT32. + + There are several cards based on this architecture. The most known + ones are Orchid SW32 and Cardinal DSP16. + + VoxWare supports downloading DSP algorithms to these cards. + +MediaTriX AudioTriX Pro + The ATP card is built around a CS4231 codec and a OPL4 synthesizer + chips. The OPL4 mode is supported by a microcontroller running a + General MIDI emulator. There is also a SB 1.5 compatible playback mode. + +Ensoniq SoundScape and compatibles + Ensoniq has designed a soundcard architecture based on the + OTTO synthesizer chip used in their professional MIDI synthesizers. + Several companies (including Ensoniq, Reveal and Spea) are selling + cards based on this architecture. + +MAD16 and Mozart based cards + The Mozart (OAK OTI-601) and MAD16 Pro (OPTi 82C929) interface + chips are used in many different soundcards, including some + cards by Reveal and Turtle Beach (Tropez). Purpose of these + chips is to connect other audio components to the PC bus. The + interface chip performs address decoding for the other chips. + +Audio Excell DSP16 + Support for this card is made by Riccardo Faccetti + (riccardo@cdc8g5.cdc.polimi.it). See aedsp16.c for more info. + +Crystal CS4232 based cards such as AcerMagic S23 + CS4232 is a PnP multimedia chip which contains a CS3231A codec, + SB and MPU401 emulations. There is support for OPL3 too. + (Unfortunately the MPU401 mode doesn't work). + +Turtle Beach Maui and Tropez + VoxWare supports sample, parch and program loading commands + described in the Maui/Tropez User's manual. There is no initialization + code for Maui so it must be initialized using DOS. Audio side of Tropez + is based on the MAD16 chip (see above). + +Jumpers and software configuration +---------------------------------- + +Some of the earliest soundcards were jumper configurable. You have to +configure VoxWare to configure VoxWare use I/O, IRQ and DMA settings +that match the jumpers. Just few 8 bit cards are fully jumper +configurable (SB 1.x/2.x, SB Pro and clones). +Some cards made by Aztech have an EEPROM which contains the +config info. These cards behave much like hardware jumpered cards. + +Most cards have jumper for the base I/O address but other parameters +are software configurable. Sometimes there are few other jumpers too. + +Latest cards are fully software configurable or they are PnP ISA +compatible. There are no jumpers on the board. + +VoxWare handles software configurable cards automaticly. Just configure +the driver to use I/O, IRQ and DMA settings which are known to work. +You could usually use the same values than with DOS and/or Windows. +Using different settings is possible but not recommended since it may cause +some trouble (for example when warm booting from an OS to another or +when installing new hardware to the machine). + +VoxWare sets the soft configurable parameters of the card automaticly +during boot. Usually you don't need to run any extra initialization +programs when booting Linux but there are some exceptions. See the +card specific instructions (below) for more info. + +The drawback of software configuration is that the driver needs to know +how the card must be initialized. It cannot initialize unknown cards +even if they are otherwise compatible with some other cards (like SB, +MPU401 or Windows Sound System). + +What if your card was not listed above? +--------------------------------------- + +The first thing to do is to look at the major IC chips on the card. +Many of the latest soundcards are based on some standard chips. If you +are lucky, all of them could be supported by VoxWare. The most common ones +are the OPTi MAD16, Mozart, SoundScape (Ensoniq) and the PSS architectures +listed above. Also look at the end of this file for list of unsupported +cards and the ones which could be supported later. + +The last resort is to send _exact_ name and model information of the card +to me together with a list of the major IC chips (manufactured, model) to +me. I could then try to check if your card looks like something familiar. + +There are much more cards in the word than listed above. The first thing to +do with these cards is to check if they emulate some other card/interface +such as SB, MSS and/or MPU401. In this case there is a chance to get the +card to work by booting DOS before starting Linux (boot DOS, hit ctrl-alt-del +and boot Linux without hard resetting the machine). In this method the +DOS based driver initializes the hardware to use a known I/O, IRQ and DMA +settings. If VoxWare is configured to use the same settings, everything should +work OK. + + +Configuring VoxWare (with Linux) +================================ + +VoxWare sound driver is currently a part of Linux kernel distribution. The +driver files are located in directory /usr/src/linux/drivers/sound. + +**************************************************************************** +* VoxWare MUST BE CONFIGURED AND COMPILED WITH THE KERNEL. TRYING * +* TO COMPILE IT ALONE WILL _NOT_ WORK. * +* * +* ALWAYS USE THE SOUND DRIVER VERSION WHICH IS DISTRIBUTED WITH * +* THE KERNEL SOURCE PACKAGE YOU ARE USING. SOME ALPHA AND BETA TEST * +* VERSIONS CAN BE INSTALLED FROM A SEPARATELY DISTRIBUTED PACKAGE * +* BUT CHECK THAT THE PACKAGE IS NOT MUCH OLDER (OR NEWER) THAN THE * +* KERNEL YOU ARE USING. IT'S POSSIBLE THAT THE KERNEL/DRIVER * +* INTERFACE CHANGES BETWEEN KERNEL RELEASES WHICH MAY CAUSE SOME * +* INCOMPATIBILITY PROBLEMS. * +* * +* IN CASE YOU INSTALL A SEPARATELY DISTRIBUTED SOUND DRIVER VERSION, * +* BE SURE TO REMOVE OR RENAME THE OLD SOUND DRIVER DIRECTORY BEFORE * +* INSTALLING THE NEW ONE. LEAVING OLD FILES TO THE SOUND DRIVER * +* DIRECTORY _WILL_ CAUSE PROBLEMS WHEN THE DRIVER IS USED OR * +* COMPILED. * +**************************************************************************** + +To configure the driver, run "make config" in the kernel source directory +(/usr/src/linux). Answer y to the question about Sound card support (after +questions about mouse, CD-ROM, ftape, etc. supports). Sound config options +will then be asked after some additional questions. + +After configuring the kernel and sound driver, run "make dep" and compile +the kernel following instructions in the kernel README. + +The sound driver configuration dialog +------------------------------------- + +All config information of the sound driver is written to file +linux/drivers/sound/local.h. You may save the old version is this file and +use it again in case you want to use the same config later. In this case +just answer n to each question made by the sound config program and put +the original local.h back before running "make dep". +Don't do this if the version number of the sound driver has changed. In this +case you have to enter the configuration information again. + +If you already have the sound driver installed, consult printout of +"cat /dev/sndstat" when configuring the driver again. It gives the I/O, +IRQ and DMA settings you have used earlier. + + +The sound config program (linux/drivers/sound/configure) starts by making +some yes/no questions. Be careful when answering to these questions since +answering y to a question may prevent some later ones from being asked. For +example don't answer y to the first question (PAS16) if you don't really +have a PAS16. Don't enable more cards than you really need since they +just consume memory. Also some drivers (like MPU401) may conflict with your +SCSI controller and prevent kernel from booting. If you card was in the list +of supported cards (above), please look at the card specific config +instructions (later in this file) before starting to configure. Some cards +must be configured in way which is not obvious. + +So here is the beginning of the config dialog. Answer 'y' or 'n' to these +questions. The default answer is shown so that (y/n) means 'y' by default and +(n/y) means 'n'. To use the default value, just hit ENTER. But be careful +since using the default _doesn't_ guarantee anything. + +Note also that all questions may not be asked. The configuration program +may disable some questions dependig on the earlier choices. It may also +select some options automaticly as well. + + "ProAudioSpectrum 16 support", + - Answer 'y'_ONLY_ if you have a Pro Audio Spectrum _16_, + ProAudio Studio 16 or Logitech SoundMan 16 (be sure that + you read the above list correctly). Don't answer 'y' if you + have some other card made by Media Vision or Logitech since they + are not PAS16 compatible. + "SoundBlaster support", + - Answer 'y' if you have an original SB card made by Creative Labs + or a full 100% hardware compatible clone (like Thunderboard or + SM Games). If your card was in the list of supported cards (above), + please look at the card specific instructions later in this file + before answering this question. For an unknown card you may answer + 'y' if the card claims to be SB compatible. + + Don't enable SB if you have a MAD16 or Mozart compatible card. + + "Generic OPL2/OPL3 FM synthesizer support", + - Answer 'y' if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). + Answering 'y' is usually a safe and recommended choice. However some + cards may have software (TSR) FM emulation. Enabling FM support + with these cards may cause trouble. However I don't currently know + such cards. + "Gravis Ultrasound support", + - Answer 'y' if you have GUS or GUS MAX. Answer 'n' if you don't + have GUS since the GUS driver consumes much memory. + Currently I don't have experiences with the GUS ACE so I don't + know what to answer with it. + "MPU-401 support (NOT for SB16)", + - Be careful with this question. The MPU401 interface is supported + by almost any soundcard today. However some natively supported cards + have their own driver for MPU401. Enabling the MPU401 option with + these cards wil cause a conflict. Also enabling MPU401 on a system + that doesn't really have a MPU401 could cause some trouble. If your + card was in the list of supported cards (above), please look at + the card specific instructions later in this file. + It's safe to answer 'y' if you have a true MPU401 MIDI interface + card. + "6850 UART Midi support", + - It's safe to answer 'n' to this question in all cases. The 6850 + UART interface is so rarely used. + "PSS (ECHO-ADI2111) support", + - Answer 'y' only if you have Orchid SW32, Cardinal DSP16 or some + other card based on the PSS chipset (AD1848 codec + ADSP-2115 + DSP chip + Echo ESC614 ASIC CHIP). + "16 bit sampling option of GUS (_NOT_ GUS MAX)", + - Answer 'y' if you have installed the 16 bit sampling daughtercard + to your GUS. Answer 'n' if you have GUS MAX. Enabling this option + disables GUS MAX support. + "GUS MAX support", + - Answer 'y' only if you have a GUS MAX. + "Microsoft Sound System support", + - Again think carefully before answering 'y' to this question. It's + safe to answer 'y' in case you have the original Windows Sound + System card made by Microsoft or Aztech SG 16 Pro (or NX16 Pro). + Also you may answer 'y' in case your card was not listed earlier + in this file. For cards having native support in VoxWare, consult + the card specific instructions later in this file. Some drivers + have their own MSS support and enabling this option wil cause a + conflict. + "Ensoniq Soundscape support", + - Answer 'y' if you have a soundcard based on the Ensoniq SoundScape + chipset. Suach cards are being manufactured at least by Ensoniq, + Spea and Reveal (note that Reveal makes other cards also). + "MediaTriX AudioTriX Pro support", + - Answer 'y' if you have the AudioTriX Pro. + "Support for MAD16 and/or Mozart based cards", + - Answer y if your card has a Mozart (OAK OTI-601) or MAD16 + (OPTi 82C928 or 82C929) audio interface chip. These chips are + currently quite common so it's possible that many no-name cards + have one of them. In addition the MAD16 chip is used in some + cards made by known manufacturers such as Turtle Beach (Tropez), + Reveal (some models) and Diamond (latest ones). + "SoundBlaster Pro support", + - Enable this option if your card is SB Pro or SB16. Enable it + also with any SB Pro clones. Answering 'n' saves some amount of + memory but 'y' is the safe alterative. + "SoundBlaster 16 support", + - Enable if you have a SB16 (including the AWE32). + "Audio Excel DSP 16 initialization support", + - Don't know much about this card. Look at aedsp16.c for more info. + +Then the configuration program asks some y/n questions about the higher +level services. It's recommended to answer 'y' to each of these questions. +Answer 'n' only if you know you will not need the option. + + "/dev/dsp and /dev/audio supports (usually required)", + - Answering 'n' disables /dev/dsp and /dev/audio. Answer 'y'. + "MIDI interface support", + - Answering 'n' disables /dev/midi## devices and access to any + MIDI ports using /dev/sequencer and /dev/music. This option + also affects any MPU401 and/or General MIDI compatible devices. + "FM synthesizer (YM3812/OPL-3) support", + - Answer 'y' here. + "/dev/sequencer support", + - Answering 'n' disables /dev/sequencer and /dev/music. + +Entering the I/O, IRQ and DMA config parameters +----------------------------------------------- + +After the above questions the configuration program prompts for the +card specific configuration information. Usually just a set of +I/O address, IRQ and DMA numbers are asked. With some cards the program +asks for some files to be used during initialization of the card. For example +many cards have a DSP chip or microprocessor which must be initialized by +downloading a program (microcode) file to the card. In some cases this file +is written to a .h file by the config program and then included to the driver +during compile. + +Instructions for answering these questions are given in the next section. + + +Card specific information +========================= + +This section gives additional instructions about configuring some cards. +Please refer manual of your card for valid I/O, IRQ and DMA numbers. Using +the same settings with DOS/Windows and VoxWare is recommended. Using +different values could cause some problems when switching between +different operating systems. + +SoundBlasters (the original ones by Creative) +--------------------------------------------- + +It's possible to configure these cards to use different I/O, IRQ and +DMA settings. Since the available settings have changed between various +models, you have to consult manual of your card for the proper ones. It's +a good idea to use the same values than with DOS/Windows. With SB and SB Pro +it's the only choice. SB16 has software selectable IRQ and DMA channels but +using different values with DOS and Linux is likely to cause troubles. The +DOS driver is not able to reset the card properly after warm boot from Linux +if Linux has used different IRQ or DMA values. + +The original (steam) Sound Blaster (versions 1.x and 2.x) use always +DMA1. There is no way to change it. + +The SB16 needs two DMA channels. A 8 bit one (1 or 3) is required for +8 bit operation and a 16 bit one (5, 6 or 7) for the 16 bit mode. In theory +it's possible to use just one (8 bit) DMA channel by answering the 8 bit +one when the configuration program asks for the 16 bit one. This may work +in some systems but is likely to cause terrible noise on some other systems. + +NOTE! Don't enable the SM Games option (asked by the configuration program) + if you are not 101% sure that your card is a Logitech Soundman Games + (not a SM Wave or SM16). + +SB Clones +--------- + +First of all: There are no SB16 clones. There are SB Pro clones with a +16 bit mode which is not SB16 compatible. The most likely alternative is that +the 16 bit mode means MSS/WSS. + +There are just few fully 100% hardware SB or SB Pro compatible cards. +I know just Thunderboard and SM Games. Other cards require some kind of +hardware initialization before they become SB compatible. Check if your card +was listed in the beginning of this file. In this case you should follow +instructions for your card later in this file. + +For other not fully SB clones yoy may try initialization using DOS in +the following way: + + - Boot DOS so that the card specific driver gets run. + - Hit ctrl-alt-del (or use loadlin) to boot Linux. Don't + switch off power or press the reset button. + - If you use the same I/O, IRQ and DMA settings in Linux, the + card should work. + +If your card is both SB and MSS compatible, I recommend using the MSS mode. +Most cards of this kind are not able to work in the SB and the MSS mode +simultaneously. Using the MSS mode provides 16 bit recording and playback. + +ProAudioSpectrum 16 and compatibles +----------------------------------- + +There are nothing special with these cards. Just don't enable any +other cards in case you don't have them also. The PAS16 has +a SB mode so the driver config program will prompt for the SB settings +do. Use I/O 0x220 and DMA1 for the SB mode. Ensure that you assign different +IRQ numbers for the SB and PAS16 modes. + +With PAS16 you can use two audio device files at the same time. /dev/dsp (and +/dev/audio) is connected to the 8/16 bit native codec and the /dev/dsp1 (and +/dev/audio1) is connected to the SB emulation (8 bit mono only). + +Gravis Ultrasound +----------------- + +There are many different revisions of the Ultrasound card (GUS). The +earliest ones (pre 3.7) don't have a hardware mixer. With these cards +the driver uses a software emulation for synth and pcm playbacks. It's +also possible to switch some of the inputs (line in, mic) off by setting +mixer volume of the channel level below 10%. For recording you have +to select the channel as a recording source and to use volume above 10%. + +GUS 3.7 has a hardware mixer. + +GUS MAX and the 16 bit sampling daughtercard have a CS4231 codec chip which +also contains a mixer. + +Configuring GUS is simple. Just enable the GUS support and GUS MAX or +the 16 bit daughtercard if you have them. Note that enabling the daughter +card disables GUS MAX driver. + +With just the standard GUS enabled the configuration program prompts +for the I/O, IRQ and DMA numbers for the card. Use the same values than +with DOS. + +With the daughter card option enabled you will be prompted for the I/O, +IRQ and DMA numbers for the daughter card. You have to use different I/O +and DMA values than for the standard GUS. The daughter card permits +simultaneous recording and playback. Use /dev/dsp (the daughtercard) for +recording and /dev/dsp1 (GUS GF1) for playback. + +GUS MAX uses the same I/O address and IRQ settings than the original GUS +(GUS MAX = GUS + a CS4231 codec). In addition an extra DMA channel may be used. +Using two DMA channels permits simultaneous playback using two devices +(dev/dsp0 and /dev/dsp1). The second DMA channel is required for +full duplex audio. +To enable the second DMA channels, give a valid DMA channel when the config +program asks for the GUS MAX DMA (entering -1 disables the second DMA). +Using 16 bit DMA channels (5,6 or 7) is recommended. + +If you have problems in recording with GUS MAX, you could try to use +just one 8 bit DMA channel. Recording will not work with one DMA +channel if it's a 16 bit one. + + + +MPU401 and Windows Sound System +------------------------------- + +Again. Don't enable these options in case your card is listed +somewhere else in this file. + +Configuring these cards is obvious (or it should be). With MSS +you should propably enable the OPL3 synth also since +most MSS compatible cards have it. However check that this is true +before enabling OPL3. + +VoxWare supports more than one MPU401 compatible cards at the same time +but the config program asks config info for just the first of them. +Adding the second or third MPU interfaces must be done manually by +editing sound/local.h (after running the config program). Add defines for +MPU2_BASE & MPU2_IRQ (and MPU3_BASE & MPU3_IRQ) to the file. + +CAUTION! + +The default I/O base of Adaptec AHA-1542 SCSI controller is 0x330 which +is also the default of the MPU401 driver. Don't configure the sound driver to +use 0x330 as the MPU401 base if you have a AHA1542. The kernel will not boot +if you make this mistake. + +PSS +--- + +Even the PSS cards are compatible with SB, MSS and MPU401, you must not +enable these options when configuring the driver. The configuration +program handles these options itself. (You may use the SB, MPU and MSS options +together with PSS if you have another card on the system). + +The PSS driver enables MSS and MPU401 modes of the card. SB is not enabled +since it doesn't work concurrently with MSS. The driver loads also a +DSP algorithm which is used to for the general MIDI emulation. The +algorithm file (.ld) is read by the config program and written to a +file included when the pss.c is compiled. For this reason the config +program asks if you want to download the file. Use the genmidi.ld file +distributed with the DOS/Windows drivers of the card (don't use the mt32.ld). +With some cards the file is called 'synth.ld'. You must have access to +the file when configuring the driver. The easiest way is to mount the DOS +partition containing the file with Linux. + +It's possible to load your own DSP algorithms and run them with the card. +Look at the directory sound/pss_test for more info (in the VoxWare-3.0.tar.gz) +package. + +AudioTriX Pro +------------- + +You have to enable the OPL3 and SB (not SB Pro or SB16) drivers in addition +to the native AudioTriX driver. Don't enable MSS or MPU drivers. + +Configuring ATP is little bit tricky since it uses so many I/O, IRQ and +DMA numbers. Using the same values than with DOS/Win is a good idea. Don't +attemp to use the same IRQ or DMA channels twice. + +The SB mode of ATP is implemented so the the ATP driver just enables SB +in the proper address. The SB driver handles the rest. Yoy have to configure +both the SB driver and the SB mode of ATP to use the same IRQ, DMA and I/O +settings. + +Also the ATP has a microcontroller for the General MIDI emulation (OPL4). +For this reason the driver asks for the name of a file containing the +microcode (TRXPRO.HEX). This file is usually located in the directory +where the DOS drivers were installed. You must have access to this file +when configuring the driver. + +If you have the effects daughtercard, it must be initialized by running +the setfx program of snd-util-3.0.tar.gz package. This step is not required +when using the (future) binary distribution version of the driver. + +Ensoniq SoundScape +------------------ + +The SoundScape driver handles initialization of MSS and MPU supports +itself so you don't need to enable other drivers than SoundScape +(enable also the /dev/dsp, /dev/sequencer and MIDI supports). + +SoundScape driver uses the MSS compatible codec of the card. It's important +to note that /dev/dsp0 (/dev/dsp is linked to /dev/dsp0 by default) +doesn't work with SoundScape (yet). The 'ssinit' program needs /dev/dsp0 so +that's the reason why it's there. It's possible that 'primary' pcm channel +becomes supported later. Currently the card's firmware doesn't contain +support for it. + +With 3.0 of VoxWare you have to change your system to use /dev/dsp1 by default +so execute: cd /dev;rm dsp;ln -s dsp1 dsp after you have installed VoxWare +3.0 (first time). + +The configuration program asks two DMA channels and two interrupts. One IRQ +and one DMA is used by the MSS codec. The second IRQ is required for the +MPU401 mode (you have to use different IRQs for both purposes). +The second DMA channel is required for initialization of the microcontroller. +You have to use separate DMA channels. + +The SoundScape card has a Motorola microcontroller which must initialized +_after_ boot (the driver doesn't initialize it during boot). +The initialization is done by running the 'ssinit' program which is +distributed in the snd-util-3.0.tar.gz package. You have to edit two +defines in the ssinit.c and then compile the program. You may run ssinit +manually (after each boot) or add it to /etc/rc.d/rc.local. + +The ssinit program needs the microcode file that comes with the DOS/Windows +driver of the card. You will need to use version 1.30.00 or later +of the microcode file (sndscape.co0 or sndscape.co1 depending on +your card model). THE OLD sndscape.cod WILL NOT WORK. IT WILL HANG YOUR +MACHINE. The only way to get the new microcode file is to download +and install the DOS/Windows driver from ftp://ftp.ensoniq.com/pub. + +Then you have to select the proper microcode file to use: soundscape.co0 +is the right one for most cards and sndscape.co1 is for few (older) cards +made by Reveal and/or Spea. The driver has capability to detect the card +version during boot. Look at the boot log messages in /var/adm/messages +and locate the sound driver initialization message for the SoundScape +card. If the driver displays string <Ensoniq Soundscape (old)>, you have +an old card and you will need to use sndscape.co1. For other cards use +soundscape.co0. + +Check /var/adm/messages after running ssinit. The driver prints +the board version after downloading the microcode file. That version +number must match the number in the name of the microcode file (extension). + +Running ssinit with a wrong version of the sndscape.co? file is not +dangerous as long as you don't try to use a file called sndscape.cod. +If you have initialized the card using a wrong microcode file (sounds +are terrible), just modify ssinit.c to use another microcode file and try +again. It's possible to use an earlier version of sndscape.co[01] but it +may sound wierd. + +Btw, The driver may complain something about "sscapeintr()" after +running ssinit. You should just ignore these messages. + +MAD16 (Pro) and Mozart +---------------------- + +You need to enable just the MAD16 /Mozart support when configuring +the driver. _Don't_ enable SB, MPU401 or MSS. However you will need the +/dev/audio, /dev/sequencer and MIDI supports. + +Mozart and OPTi 82C928 (the original MAD16) chips don't support +MPU401 mode so enter just 0 when the configuration program asks the +MPU/MIDI I/O base. The MAD16 Pro (OPTi 82C929) has MPU401 mode. + +TB Tropez is based on the 82C929 chip. It has two MIDI ports. +The one connected to the MAD16 chip is the second one (there is a second +MIDI connector/pins somewhere??). If you have not connected the second MIDI +port, just disable the MIDI port of MAD16. The 'Maui' compatible synth of +Tropez is jumper configurable and not connected to the MAD16 chip. +It can be used by enabling the stand alone MPU401 support but you have +to initialize it by using the MS-DOS SNDSETUP program. + +There are some other OPTi chips which may be used in soundcards such as +82C930 and MAC32. These chips are not supported by VoxWare yet. Please +contact me if you have a soundcard which uses these chips. + +Some MAD16 based cards may cause feedback, whistle or terrible noise if the +line3 mixer channel is turned too high. + +If you have a MAD16 card which have an OPL4 (FM + Wave table) synthesizer +chip (_not_ an OPL3), you have to apped line containing #define MAD16_OPL4 +to the file linux/dirvers/sound/local.h (after running make config). + +MV Jazz (ProSonic) +------------------ + +The Jazz16 driver is just a hack made to the SB Pro driver. However it works +fairly well. You have to enable SB, SB Pro (_not_ SB16) and MPU401 supports +when configuring the driver. The configuration program asks later if you +want support for MV Jazz16 based cards (after asking SB base address). Answer +'y' here and the driver asks the second (16 bit) DMA channel. + +The Jazz16 driver uses the MPU401 driver in a way which will cause +problems if you have another MPU401 compatible card. In this case you must +give address of the Jazz16 based MPU401 interface when the config +program prompts for the MPU401 information. Then look at the MPU401 +spesific section for instructions about configuring more than one MPU401 cards. + +Logitech Soundman Wave +---------------------- + +Read the above MV Jazz spesific instructions first. + +The Logitech SoundMan Wave (don't confuse with the SM16 or SM Games) is +a MV Jazz based card which has an additional OPL4 based wave table +synthesizer. The OPL4 chip is handled by an on board microcontroller +which must be initialized during boot. The config program asks if +you have a SM Wave immediately after asking the second DMA channel of jazz16. +If you answer 'y', the config program will ask name of the file containing +code to be loaded to the microcontroller. The file is usually called +MIDI0001.BIN and it's located in the DOS/Windows driver directory. The file +may also be called as TSUNAMI.BIN or something else (older cards?). + +The OPL4 synth will be inaccessible without loading the microcontroller code. +Also remember to enable MPU401 support if you want to use the OPL4 mode. + +NOTE! Don't answer 'y' when the driver asks about SM Games support + (the next question after the MIDI0001.BIN name). However + aneswering 'y' is not dangerous. + +Sound Galaxies +-------------- + +There are many different Sound Galaxy cards made by Aztech. The 8 bit +ones are fully SB or SB Pro compatible and there should be no problems +with them. + +The older 16 bit cards (SG Pro16, SG NX Pro16, Nova and Lyra) have +an EEPROM chip for storing the configuration data. There is a microcontroller +which initializes the card to match the EEPROM settigs when the machine +is powered on. These cards actually behave just like they have jumpers +for all of the settings. Configure VoxWare for MSS, MPU, SB/SB Pro and OPL3 +supports with these cards. + +The config program asks if you want support for the mixer of +SG NX Pro. Answer 'y' to these questions if you have one of the above 8 or +16 bit Aztech cards. + +There are some new Sound Galaxies in the market. I have no experience with +them so read the card's manual carefully. + + +Reveal cards +------------ + +There are several different cards made/marketed by Reveal. Some of them +are compatible with SoundScape and some use the MAD16 chip. You may have +to look at the card and try to identify origin of the card. + +Diamond +------- + +The oldest (Sierra Aria based) soundcards made by Diamond are not supported +(they may work if the card is initialized using DOS). The recent (LX?) +models are based on the MAD16 chip which is supported by VoxWare. + +Audio Excel DSP16 +----------------- + +See comments in aedsp16.c. + + +PCMCIA cards +------------ + +Sorry, can't help. Some cards may work and some don't. + +TI TM4000M notebooks +-------------------- + +These computers have a built in sound support based on the Jazz chipset. +Look at the instructions for MV Jazz (above). It's also important to note +that there is something wrong with the mouse port and sound at least on +some TM models. Don't enable the "C&T 82C710 mouse port support" when +configuring Linux. Having it enabled is likely to cause mysterious problems +and kernel failures when sound is used. + +Others? +------- + +Since there are so many different soundcards, it's likely that I have +forgotten to mention many of them. Please inform me if you know yet another +card which works with Linux, please inform me (or is anybody else +willing to maintain a database of supported cards (just like in XF86)?). + +Cards not supported yet +======================= + +First of all. There is an easy way to make most soundcards to work +with Linux. Just use the DOS based driver to initialize the card +to a _known_ state. Then ctrl-alt-del to Linux. If Linux is configured +to use the sama I/O, IRQ and DMA numbers than DOS, the card could work. + +Don't get fooled with SB compatibility. Most cards are compatible with +SB but that may require a TSR which is not possible with Linux. If +the card is compatible with MSS, it's a better choise. Some cards +don't work in the SB and MSS modes at the same time. + +There are some cards which will be supported by VoxWare sooner or later +(currently at least cards based on the ESS chipset). Such cards are +so common that there is some idea in writing the driver. Check the +VoxWare home page (http://personal.eunet.fi/pp/voxware) for latest +information. + +Then there are cards which are no longer manufactured and/or which +are relatively rarely used (such as the 8 bit ProAudioSpectrum +models). It's extremely unlikely that such cards never get supported. +Adding support for a new card requires much work and increases time +required in maintaining the driver (some changes need to be done +to all low level drivers and be tested too, maybe with multiple +operating systems). For this reason I have made a desicion to not support +obsolete cards. It's possible that someone else makes a separately +distributed driver (diffs) for the card. Version v4.0 will be much more +modular so making separately distributed drivers will be easier with it. +(The bad news is that v4.0 will not be available before late -96). + +Writing a driver for a new card is not possible if there are no +programming information available about the card. If you don't +find your new card from this file, look from the home page +(http://personal.eunet.fi/pp/voxware). Then please contact +manufacturer of the card and ask if they have (or are willing to) +released technical details of the card. Do this before contacting me. I +can only answer 'no' if there are no programming information available. + +Some companies don't give low level technical information about their +products to public or at least their require signing a NDA. + +I have also made decicion to not accept code based on reverse engineering +to VoxWare. There are three main reasons: First I don't want to break +relationships to sound card manufacturers. The second reason is that +maintaining and supporting a driver withoun any specs will be a pain. The +third reason is that why shoud we help such companies in selling their +products to Linux users when they don't want to sell to Linux users +at all? + +Unfortunately many of the leading soundcard manufacturers are not willing +to co-operate with Linux/Unix community. For example: Creative Technology +doesn't give information about the ASP chip and the Emu synth chip of AWE32 +and SB32. Turtle Beach don't give information about any of their +products. MediaVision requires NDA before they are willing to +give information about the Jazz16 chip (fortunately Logitech gave +the info about SM Wave). + +So at least the above three companies are out until they are willing to +release documentation about their products (the situation is the +same with many DOS based freeware/shareware games and utilities). If +you want to use Linux/Unix with their cards, please don't try to push +me. It's a better idea to contact the manufacturer and explain that +you want to use your card with Linux/Unix. You could also try to sell +your card to somebody else and then buy a card that is supported by VoxWare. + +However it's possible that things change and a driver gets written +for some of the banned cards. Please, don't send me messages asking if +there is any plans to write a driver for the cards mentioned above. I +will put any news to the VoxWare www home page (see below). + +There are some common audio chipsets that are supported yet. For example +the ESS chips and Sierra Aria. It's likely that these architectures +get some support in future but I can't make any promises. Just look +at the home page for latest info. + +Information about unsupported soundcards and chipsets is welcome as well +as free copies of soundcards, SDKs and operating systems. + +If you have any corrections and/or comments, please contact me. + +Hannu Savolainen +hannu@voxware.pp.fi +VoxWare www home page: http://personal.eunet.fi/pp/voxware + diff --git a/sys/i386/isa/sound/Readme.modules b/sys/i386/isa/sound/Readme.modules new file mode 100644 index 000000000000..315540f510c1 --- /dev/null +++ b/sys/i386/isa/sound/Readme.modules @@ -0,0 +1,87 @@ + Linux sound-driver module + (c) Peter Trattler + License: GPL (Gnu Public License) + + +Idea: + +I've modified the sources for the sound driver to allow simply insert and +remove the sound driver from the kernel by calling (only available for Linux) + + insmod /usr/src/linux/modules/sound.o + +and + + rmmod sound + +This may be useful if you are doing one of the following things: + +1) Debugging the sound driver +2) Creating a new device within the sound-driver +3) You do not the sound driver all the time (as it wastes quite a lot of +memory for its buffers) + + +Compilation: + +Go to /usr/src/linux and make the following steps: + +a) configure the sound driver: To do that call "make config" and enable the +sound-driver -- you will be asked different questions about your +sound-hardware (remember not to use a too big DMA-Buffer size; you +should use 16kB, if you have 16Bit devices, otherwise you can use 32kB) + +b) disable the sound driver in the kernel: call make config again but answer +'N' to "Sound card support" + +c) run "make modules"; the sound-driver sound.o should end up in +/usr/src/linux/modules + + +If memory is tight: + +I've allocated at about 70kB for the sound-drivers internal tables. If this +is too much, 'insmod sound.o' will generate the following warning +... +use 'insmod memsize=xxxx' +... +You can only use this command, if you have (I think) at least +modules-1.1.87 or up. You can also switch debugging on by running the command + +insmod sound.o debugmem=1 + + +Files I changed: + +I've only changed the files soundcard.c(most changes) and some changes within +the Makefile, sound_config.h and the Makefile in /usr/src/linux/drivers + + +Bugs: + +a) As the kmalloc (..., GFP_DMA) caused some unexpected errors (I don't know if +it is my fault), I created some code, which is (by default) enabled by + +#define KMALLOC_DMA_BROKEN 1 (within soundcard.c). + +It trys to allocate a large enough region, so that the complete dma-buffer +can be occupied in this space. If it does not fit within this region it +doubles the size of it. But this can cause problems, if the sound-buffer is +too big (as kmalloc can only handle regions at up to circa 100kB). + +So take care to use for 8Bit devices a sound-DMA-buffer of 32kB (maximum) +and for 16Bit devices a maximum of 16kB. Otherwise the allocation scheme +might fail. + +b) Buffers allocated by the different sound devices via calls to kmalloc are +not freed, if the sound driver is removed again (these buffers tend to be +quite small -- so it does not harm a lot) + +c) If there is not enough (kernel-) memory available, the installation of +the sound-driver fails. (This happens quite often, if you did not install the +driver right after booting -- [PS: I've only got 5MB of Ram, so this might +be the source for this problem]) + + +Author: + Peter Trattler (peter@sbox.tu-graz.ac.at) diff --git a/sys/i386/isa/sound/Readme.v30 b/sys/i386/isa/sound/Readme.v30 new file mode 100644 index 000000000000..cade461d2a6d --- /dev/null +++ b/sys/i386/isa/sound/Readme.v30 @@ -0,0 +1,154 @@ +VoxWare v3.0 +------------ + +This is a PROTOTYPE of the VoxWare v3.0 to be released late 94. + +All features of v2.5 should work as earlier. There could be some +omissions but they are unintentional. I started this version thread +after v2.3 so all features implemented before it are there. + +Even this is a prototype, there should not be any fatal bugs. The +prototype just means that I don't have implemented all features +completely. Mainly in the /dev/sequencer2 driver. +For example recording from /dev/sequencer2 won't work +with other cards than a full features MPU-401 or clones. As well the +way how the MIDI controllers are handled will change. + +IMPORTANT!!!!!!!!!!!!!!!!! + +Don't distribute any binaries compiled with the soundcard.h of this version. +They will not work together with older drivers. + +New features +============ + +There are now two new device interfaces. The /dev/midi## is a raw +tty like interface to MIDI ports. There is a device file for each MIDI +port on your system. They are named (/dev/midi00 to /dev/midiNN). +The second addition is the /dev/sequencer2 which is higher level interface +than the old /dev/sequencer. It's intended for writing device independent +applications like sequencers. + +/dev/midi## +----------- + +This interface should be useful for applications like MIDI sysex librarians. +There are (currently) no timing features so making music could be impossible. + +There are as many /dev/midi## devices as there are MIDI ports in the system. +The /dev/midi00 is connected to the first one, /dev/midi01 to the second etc. + +These devices work like tty devices in raw mode. Everything written to them is +sent out to the MIDI port. There is currently an extra delay of at most +1/100th of sec but it will be removed later. + +The reading algorithm is little bit more complicated. There are two different +cases: + +1) There is at least one byte in the input buffer. + +The read returns as many bytes as it can without waiting for more bytes. +For example when a process reads 100 bytes and there are 10 bytes in the +buffer, the read returns just 10 bytes. + +2) The input buffer is empty when the process calls read. + +The read waits for the first byte and then continues as in case 1. By +default it waits infinitely but there is an ioctl for setting a timeout +for this. The ioctl(fd, SNDCTL_MIDI_PRETIME, &time) changes the timeout. +The time is given in 1/10th of seconds (10 means one second). + +Other ioctl calls: + +ioctl(fd, SNDCTL_MIDI_MPUMODE, &mode) is available for full MPU-401 +compatible devices such as MPU-IPC-T, MQ PC Midi Card or MQX-32. +It's not available for the so called MPU UART ports of some soundcards +(PAS16, SB16 etc). By default the MIDI port is in UART mode after open. +If this ioctl is called with mode=1, the interface is put to the intelligent +(coprocessor) mode. NOTE! The MIDI port will be reset when this ioctl is called. +It could have some strange effects if not called immediately after open. This +call returns EINVAL if the midi port doesn't support the MPU-401 intelligent +mode. + +ioctl(fd, SNDCTL_MIDI_MPUCMD, &cmdstruct) is valid only if the MIDI port +is put to the coprocessor mode using ioctl(SNDCTL_MIDI_MPUMODE). It's used to +send commands to a MPU-401 compatible MIDI cards. Please refer to the +MPU-401 Technical Reference Manual (or Music Quest Technical Reference +Manual) for descriptions of the commands. + +The argument of SNDCTL_MIDI_MPUCOMMAND is of type mpu_command_rec. It +has the following fields: + +typedef struct { + unsigned char cmd; + + char nr_args, nr_returns; + unsigned char data[30]; + } mpu_command_rec; + +where: + cmd Contains the command number. + nr_args Number of arguments of the command. + MUST BE INITIALIZED BEFORE CALL + nr_returns Number of bytes returned by the command. + MUST BE INITIALIZED BEFORE CALL + data Buffer for the command arguments and returned + data. + +Be extremely careful with the nr_args and nr_returns fields. They +must match the command. An incorrect value will put the card and +the driver out of sync. Refer to the MPU-401/MQX-32M documentation for further +details. + + + +/dev/sequencer2 (if you find a better name, please let me know). +--------------- + +This device file works much like the /dev/sequencer which has been present +since the beginning. The main differences are the following: + +- /dev/sequencer makes the MIDI ports to look like the synth devices. In fact +the result is somewhere between the MIDI specification and the synth devices of +/dev/sequencer. Both kind of devices are accessed using the SEQ_START_NOTE() +like macros. The voice number parameters of the API macros have been redefined +to denote MIDI channels. This means that the driver allocates voices for +the channels automatically (this is a responsibility/right of an application +with /dev/sequencer). The result is that a SEQ_START_NOTE() macro has +similar effects for a synth channel than on a MIDI port. This kind of +solution provides better device independence than the /dev/sequencer. The +drawback is that the new interface doesn't permit so low level access to the +device as the /dev/sequencer does. An application developer must choose between +these two interfaces. I think the old /dev/sequencer is better for applications +like module players while the new one is better for making generic sequencer +programs. + +- There are no separate MIDI devices with the /dev/sequencer2. The +ioctl(SNDCTL_SEQ_NRMIDIS) returns always zero. Instead the MIDI ports are +shown as synth devices. ioctl(SNDCTL_SEQ_NRSYNTHS) on /dev/sequencer2 will +return sum of internal synthesizers (GUS, OPL3) and MIDI ports in the systems. + +- The new interface is used much like the ordinary /dev/sequencer. The +event format is new so you have to use the API macros defined in the +sys/soundcard.h. The interface will probably change before the final 3.0 +release but using the API macros should ensure compatibility in source level. +The new event format is not recognized by version 2.X so don't try to +distribute binaries compiled with soundcard.h of v3.X. + +- The basic API usage is similar to the current one. There are some new +macros but the older ones should work as earlier. The most important +incompatibility is that the /dev/sequencer2 driver allocates voices itself. +The other one is that the application must send SEQ_START_TIMER() as it's +first event. Otherwise the timer is not started and the application waits +infinitely. + + +There are several new features but I don't document them here. There are +some info in the soundcard.h (near the end). I have also included some +sample code in the directory v30. Full documentation will +appear in the Hacker's Guide later. + +Don't hesitate to contact me in case you have questions or comments. + +Hannu Savolainen +hannu@voxware.pp.fi diff --git a/sys/i386/isa/sound/ad1848_mixer.h b/sys/i386/isa/sound/ad1848_mixer.h new file mode 100644 index 000000000000..9404047ce77d --- /dev/null +++ b/sys/i386/isa/sound/ad1848_mixer.h @@ -0,0 +1,130 @@ +/* + * sound/ad1848_mixer.h + * + * Definitions for the mixer of AD1848 and compatible codecs. + * + * Copyright by Hannu Savolainen 1994 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * The AD1848 codec has generic input lines called Line, Aux1 and Aux2. + * Soundcard manufacturers have connected actual inputs (CD, synth, line, + * etc) to these inputs in different order. Therefore it's difficult + * to assign mixer channels to to these inputs correctly. The following + * contains two alternative mappings. The first one is for GUS MAX and + * the second is just a generic one (line1, line2 and line3). + * (Actually this is not a mapping but rather some kind of interleaving + * solution). + */ +#ifdef GUSMAX_MIXER +#define MODE1_REC_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \ + SOUND_MASK_CD) + +#define MODE1_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_MIC | \ + SOUND_MASK_CD | \ + SOUND_MASK_IGAIN | \ + SOUND_MASK_PCM|SOUND_MASK_IMIX) + +#define MODE2_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \ + SOUND_MASK_CD | SOUND_MASK_SPEAKER | \ + SOUND_MASK_IGAIN | \ + SOUND_MASK_PCM | SOUND_MASK_IMIX) +#else /* Generic mapping */ +#define MODE1_REC_DEVICES (SOUND_MASK_LINE3 | SOUND_MASK_MIC | \ + SOUND_MASK_LINE1) + +#define MODE1_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_MIC | \ + SOUND_MASK_LINE2 | \ + SOUND_MASK_IGAIN | \ + SOUND_MASK_PCM | SOUND_MASK_IMIX) + +#define MODE2_MIXER_DEVICES (SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | SOUND_MASK_MIC | \ + SOUND_MASK_LINE3 | SOUND_MASK_SPEAKER | \ + SOUND_MASK_IGAIN | \ + SOUND_MASK_PCM | SOUND_MASK_IMIX) +#endif + +struct mixer_def { + unsigned int regno: 7; + unsigned int polarity:1; /* 0=normal, 1=reversed */ + unsigned int bitpos:4; + unsigned int nbits:4; +}; + + +typedef struct mixer_def mixer_ent; + +/* + * Most of the mixer entries work in backwards. Setting the polarity field + * makes them to work correctly. + * + * The channel numbering used by individual soundcards is not fixed. Some + * cards have assigned different meanings for the AUX1, AUX2 and LINE inputs. + * The current version doesn't try to compensate this. + */ + +#define MIX_ENT(name, reg_l, pola_l, pos_l, len_l, reg_r, pola_r, pos_r, len_r) \ + {{reg_l, pola_l, pos_r, len_l}, {reg_r, pola_r, pos_r, len_r}} + +mixer_ent mix_devices[32][2] = { /* As used in GUS MAX */ +MIX_ENT(SOUND_MIXER_VOLUME, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_BASS, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_TREBLE, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_SYNTH, 4, 1, 0, 5, 5, 1, 0, 5), +MIX_ENT(SOUND_MIXER_PCM, 6, 1, 0, 6, 7, 1, 0, 6), +MIX_ENT(SOUND_MIXER_SPEAKER, 26, 1, 0, 4, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_LINE, 18, 1, 0, 5, 19, 1, 0, 5), +MIX_ENT(SOUND_MIXER_MIC, 0, 1, 5, 1, 1, 1, 5, 1), +MIX_ENT(SOUND_MIXER_CD, 2, 1, 0, 5, 3, 1, 0, 5), +MIX_ENT(SOUND_MIXER_IMIX, 13, 1, 2, 6, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_ALTPCM, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_RECLEV, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_IGAIN, 0, 0, 0, 4, 1, 0, 0, 4), +MIX_ENT(SOUND_MIXER_OGAIN, 0, 0, 0, 0, 0, 0, 0, 0), +MIX_ENT(SOUND_MIXER_LINE1, 2, 1, 0, 5, 3, 1, 0, 5), +MIX_ENT(SOUND_MIXER_LINE2, 4, 1, 0, 5, 5, 1, 0, 5), +MIX_ENT(SOUND_MIXER_LINE3, 18, 1, 0, 5, 19, 1, 0, 5) +}; + +static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] = +{ + 0x5a5a, /* Master Volume */ + 0x3232, /* Bass */ + 0x3232, /* Treble */ + 0x4b4b, /* FM */ + 0x6464, /* PCM */ + 0x4b4b, /* PC Speaker */ + 0x4b4b, /* Ext Line */ + 0x1010, /* Mic */ + 0x4b4b, /* CD */ + 0x0000, /* Recording monitor */ + 0x4b4b, /* SB PCM */ + 0x4b4b, /* Recording level */ + 0x4b4b, /* Input gain */ + 0x4b4b, /* Output gain */ + 0x4b4b, /* Line1 */ + 0x4b4b, /* Line2 */ + 0x4b4b /* Line3 */ +}; + +#define LEFT_CHN 0 +#define RIGHT_CHN 1 diff --git a/sys/i386/isa/sound/aedsp16.c b/sys/i386/isa/sound/aedsp16.c new file mode 100644 index 000000000000..b14a24618f0c --- /dev/null +++ b/sys/i386/isa/sound/aedsp16.c @@ -0,0 +1,838 @@ +/* + sound/aedsp16.c + + Audio Excel DSP 16 software configuration routines + + Copyright (C) 1995 Riccardo Facchetti (riccardo@cdc8g5.cdc.polimi.it) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. 2. + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + READ THIS + + This module is intended for Audio Excel DSP 16 Sound Card. + + Audio Excel DSP 16 is an SB pro II, Microsoft Sound System + and MPU-401 compatible card. + It is software-only configurable (no jumpers to hard-set irq/dma/mpu-irq), + so before this module, the only way to configure the DSP under linux was + boot the MS-BAU loading the sound.sys device driver (this driver soft- + configure the sound board hardware by massaging someone of its registers), + and then ctrl-alt-del to boot linux with the DSP configured by the DOG + driver. + + This module works configuring your Audio Excel DSP 16's + irq, dma and mpu-401-irq. The voxware probe routines rely on the + fact that if the hardware is there, they can detect it. The problem + with AEDSP16 is that no hardware can be found by the probe routines + if the sound card is not well configured. Sometimes the kernel probe + routines can find an SBPRO even when the card is not configured (this + is the standard setup of the card), but the SBPRO emulation don't work + well if the card is not properly initialized. For this reason + + InitAEDSP16_...() + + routines are called before the voxware probe routines try to detect the + hardware. + + NOTE (READ THE NOTE TOO, IT CONTAIN USEFUL INFORMATIONS) + + The Audio Excel DSP 16 Sound Card emulates both SBPRO and MSS; + the voxware sound driver can be configured for SBPRO and MSS cards + at the same time, but the aedsp16 can't be two cards!! + When we configure it, we have to choose the SBPRO or the MSS emulation + for AEDSP16. We also can install a *REAL* card of the other type + (see [1], not tested but I can't see any reason for it to fail). + + NOTE: If someone can test the combination AEDSP16+MSS or AEDSP16+SBPRO + please let me know if it works. + + The MPU-401 support can be compiled in together with one of the other + two operating modes. + + The board configuration calls, are in the probe_...() routines because + we have to configure the board before probing it for a particular + hardware. After card configuration, we can probe the hardware. + + NOTE: This is something like plug-and-play: we have only to plug + the AEDSP16 board in the socket, and then configure and compile + a kernel that uses the AEDSP16 software configuration capability. + No jumper setting is needed! + + For example, if you want AEDSP16 to be an SBPro, on irq 10, dma 3 + you have just to make config the voxware package, configuring + the SBPro sound card with that parameters, then when configure + asks if you have an AEDSP16, answer yes. That's it. + Compile the kernel and run it. + + NOTE: This means that you can choose irq and dma, but not the + I/O addresses. To change I/O addresses you have to set them + with jumpers. + + NOTE: InitAEDSP16_...() routines get as parameter the hw_config, + the hardware configuration of the - to be configured - board. + The InitAEDSP16() routine, configure the board following our + wishes, that are in the hw_config structure. + + You can change the irq/dma/mirq settings WITHOUT THE NEED to open + your computer and massage the jumpers (there are no irq/dma/mirq + jumpers to be configured anyway, only I/O port ones have to be + configured with jumpers) + + For some ununderstandable reason, the card default of irq 7, dma 1, + don't work for me. Seems to be an IRQ or DMA conflict. Under heavy + HDD work, the kernel start to erupt out a lot of messages like: + + 'Sound: DMA timed out - IRQ/DRQ config error?' + + For what I can say, I have NOT any conflict at irq 7 (under linux I'm + using the lp polling driver), and dma line 1 is unused as stated by + /proc/dma. I can suppose this is a bug of AEDSP16. I know my hardware so + I'm pretty sure I have not any conflict, but may be I'm wrong. Who knows! + Anyway a setting of irq 10, dma 3 works really fine. + + NOTE: if someone can use AEDSP16 with irq 7, dma 1, please let me know + the emulation mode, all the installed hardware and the hardware + configuration (irq and dma settings of all the hardware). + + This init module should work with SBPRO+MSS, when one of the two is + the AEDSP16 emulation and the other the real card. (see [1]) + For example: + + AEDSP16 (0x220) in SBPRO emu (0x220) + real MSS + other + AEDSP16 (0x220) in MSS emu + real SBPRO (0x240) + other + + MPU401 should work. (see [1]) + + [1] Not tested by me for lack of hardware. + + TODO, WISHES AND TECH + + May be there's lot of redundant delays, but for now I want to leave it + this way. + + Should be interesting eventually write down a new ioctl for the + aedsp16, to let the suser() change the irq/dma/mirq on the fly. + The thing is not trivial. + In the real world, there's no need to have such an ioctl because + when we configure the kernel for compile, we can choose the config + parameters. If we change our mind, we can easily re-config the kernel + and re-compile. + Why let the suser() change the config parameters on the fly ? + If anyone have a reasonable answer to this question, I will write down + the code to do it. + + More integration with voxware, using voxware low level routines to + read-write dsp is not possible because you may want to have MSS + support and in that case we can not rely on the functions included + in sb_dsp.c to control 0x2yy I/O ports. I will continue to use my + own I/O functions. + + - About I/O ports allocation - + + The request_region should be done at device probe in every sound card + module. This module is not the best site for requesting regions. + When the request_region code will be added to the main modules such as + sb, adlib, gus, ad1848, etc, the requesting code in this module should + go away. + + I think the request regions should be done this way: + + if (check_region(...)) + return ERR; // I/O region alredy reserved + device_probe(...); + device_attach(...); + request_region(...); // reserve only when we are sure all is okay + + Request the 2x0h region in any case if we are using this card. + + NOTE: the "(sbpro)" string with which we are requesting the aedsp16 region + (see code) does not mean necessarly that we are emulating sbpro. + It mean that the region is the sbpro I/O ports region. We use this + region to access the control registers of the card, and if emulating + sbpro, I/O sbpro registers too. If we are emulating MSS, the sbpro + registers are not used, in no way, to emulate an sbpro: they are + used only for configuration pourposes. + + Someone pointed out that should be possible use both the SBPRO and MSS + modes because the sound card have all the two chipsets, supposing that + the card is really two cards. I have tried something to have the two + modes work together, but, for some reason unknown to me, without success. + + I think all the soft-config only cards have an init sequence similar to + this. If you have a card that is not an aedsp16, you can try to start + with this module changing it (mainly in the CMD? I think) to fit your + needs. + + Started Fri Mar 17 16:13:18 MET 1995 + + v0.1 (ALPHA, was an user-level program called AudioExcelDSP16.c) + - Initial code. + v0.2 (ALPHA) + - Cleanups. + - Integrated with Linux voxware v 2.90-2 kernel sound driver. + - SoundBlaster Pro mode configuration. + - Microsoft Sound System mode configuration. + - MPU-401 mode configuration. + v0.3 (ALPHA) + - Cleanups. + - Rearranged the code to let InitAEDSP16 be more general. + - Erased the REALLY_SLOW_IO. We don't need it. Erased the linux/io.h + inclusion too. We rely on os.h + - Used the INB and OUTB #defined in os.h instead of inb and outb. + - Corrected the code for GetCardName (DSP Copyright) to get a variable + len string (we are not sure about the len of Copyright string). + This works with any SB and compatible. + - Added the code to request_region at device init (should go in + the main body of voxware). + v0.4 (BETA) + - Better configure.c patch for aedsp16 configuration (better + logic of inclusion of AEDSP16 support) + - Modified the conditional compilation to better support more than + one sound card of the emulated type (read the NOTES above) + - Moved the sb init routine from the attach to the very first + probe in sb_card.c + - Rearrangemens and cleanups + - Wiped out some unnecessary code and variables: this is kernel + code so it is better save some TEXT and DATA + - Fixed the request_region code. We must allocate the aedsp16 (sbpro) + I/O ports in any case because they are used to access the DSP + configuration registers and we can not allow anyone to get them. + v0.5 + - cleanups on comments + - prep for diffs against v3.0-proto-950402 + + */ + +/* + * Include the main voxware header file. It include all the os/voxware/etc + * headers needed by this source. + */ +#include "sound_config.h" +/* + * all but ioport.h :) + */ +#include <linux/ioport.h> + +#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AEDSP16) + +#define VERSION "0.5" /* Version of Audio Excel DSP 16 driver */ + +#undef AEDSP16_DEBUG /* Define this to enable debug code */ +/* Actually no debug code is activated */ + +/* + * Hardware related defaults + */ +#define IRQ 7 /* 5 7(default) 9 10 11 */ +#define MIRQ 0 /* 5 7 9 10 0(default), 0 means disable */ +#define DMA 1 /* 0 1(default) 3 */ + +/* + * Commands of AEDSP16's DSP (SBPRO+special). + * For now they are CMDn, in the future they may change. + */ +#define CMD1 0xe3 /* Get DSP Copyright */ +#define CMD2 0xe1 /* Get DSP Version */ +#define CMD3 0x88 /* */ +#define CMD4 0x5c /* */ +#define CMD5 0x50 /* Set M&I&DRQ mask (the real config) */ +#define CMD6 0x8c /* Enable Microsoft Sound System mode */ + +/* + * Offsets of AEDSP16 DSP I/O ports. The offest is added to portbase + * to have the actual I/O port. + * Register permissions are: + * (wo) == Write Only + * (ro) == Read Only + * (w-) == Write + * (r-) == Read + */ +#define DSP_RESET 0x06 /* offset of DSP RESET (wo) */ +#define DSP_READ 0x0a /* offset of DSP READ (ro) */ +#define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */ +#define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */ +#define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */ +#define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */ + + +#define RETRY 10 /* Various retry values on I/O opera- */ +#define STATUSRETRY 1000 /* tions. Sometimes we have to */ +#define HARDRETRY 500000 /* wait for previous cmd to complete */ + +/* + * Size of character arrays that store name and version of sound card + */ +#define CARDNAMELEN 15 /* Size of the card's name in chars */ +#define CARDVERLEN 2 /* Size of the card's version in chars */ + +/* + * Bit mapped flags for calling InitAEDSP16(), and saving the current + * emulation mode. + */ +#define INIT_NONE (0 ) +#define INIT_SBPRO (1<<0) +#define INIT_MSS (1<<1) +#define INIT_MPU401 (1<<2) +#define RESET_DSP16 (1<<3) + +/* Base HW Port for Audio Card */ +static int portbase = AEDSP16_BASE; +static int irq = IRQ; /* irq for DSP I/O */ +static int mirq = MIRQ; /* irq for MPU-401 I/O */ +static int dma = DMA; /* dma for DSP I/O */ + +/* Init status of the card */ +static int ae_init = INIT_NONE; /* (bitmapped variable) */ +static int oredparams = 0; /* Will contain or'ed values of params */ +static int gc = 0; /* generic counter (utility counter) */ +struct orVals + { /* Contain the values to be or'ed */ + int val; /* irq|mirq|dma */ + int or; /* oredparams |= TheStruct.or */ + }; + +/* + * Magic values that the DSP will eat when configuring irq/mirq/dma + */ +/* DSP IRQ conversion array */ +static struct orVals orIRQ[] = +{ + {0x05, 0x28}, + {0x07, 0x08}, + {0x09, 0x10}, + {0x0a, 0x18}, + {0x0b, 0x20}, + {0x00, 0x00} +}; + +/* MPU-401 IRQ conversion array */ +static struct orVals orMIRQ[] = +{ + {0x05, 0x04}, + {0x07, 0x44}, + {0x09, 0x84}, + {0x0a, 0xc4}, + {0x00, 0x00} +}; + +/* DMA Channels conversion array */ +static struct orVals orDMA[] = +{ + {0x00, 0x01}, + {0x01, 0x02}, + {0x03, 0x03}, + {0x00, 0x00} +}; + +/* + * Buffers to store audio card informations + */ +static char AudioExcelName[CARDNAMELEN + 1]; +static char AudioExcelVersion[CARDVERLEN + 1]; + +static void +tenmillisec (void) +{ + + for (gc = 0; gc < 1000; gc++) + tenmicrosec (); +} + +static int +WaitForDataAvail (int port) +{ + int loop = STATUSRETRY; + unsigned char ret = 0; + + do + { + ret = INB (port + DSP_DATAVAIL); + /* + * Wait for data available (bit 7 of ret == 1) + */ + } + while (!(ret & 0x80) && loop--); + + if (ret & 0x80) + return 0; + + return -1; +} + +static int +ReadData (int port) +{ + if (WaitForDataAvail (port)) + return -1; + return INB (port + DSP_READ); +} + +static int +CheckDSPOkay (int port) +{ + return ((ReadData (port) == 0xaa) ? 0 : -1); +} + +static int +ResetBoard (int port) +{ + /* + * Reset DSP + */ + OUTB (1, (port + DSP_RESET)); + tenmicrosec (); + OUTB (0, (port + DSP_RESET)); + tenmicrosec (); + tenmicrosec (); + return CheckDSPOkay (port); +} + +static int +WriteDSPCommand (int port, int cmd) +{ + unsigned char ret; + int loop = HARDRETRY; + + do + { + ret = INB (port + DSP_STATUS); + /* + * DSP ready to receive data if bit 7 of ret == 0 + */ + if (!(ret & 0x80)) + { + OUTB (cmd, port + DSP_COMMAND); + return 0; + } + } + while (loop--); + + printk ("[aedsp16] DSP Command (0x%x) timeout.\n", cmd); + return -1; +} + +int +InitMSS (int port) +{ + + tenmillisec (); + + if (WriteDSPCommand (port, CMD6)) + { + printk ("[aedsp16] CMD 0x%x: failed!\n", CMD6); + return -1; + } + + tenmillisec (); + + return 0; +} + +static int +SetUpBoard (int port) +{ + int loop = RETRY; + + do + { + if (WriteDSPCommand (portbase, CMD3)) + { + printk ("[aedsp16] CMD 0x%x: failed!\n", CMD3); + return -1; + } + + tenmillisec (); + + } + while (WaitForDataAvail (port) && loop--); + +#if defined(THIS_SHOULD_GO_AWAY) + if (CheckDSPOkay (port)) + { + printk ("[aedsp16] CheckDSPOkay: failed\n"); + return -1; + } +#else + if (ReadData (port) == -1) + { + printk ("[aedsp16] ReadData after CMD 0x%x: failed\n", CMD3); + return -1; + } +#endif + + if (WriteDSPCommand (portbase, CMD4)) + { + printk ("[aedsp16] CMD 0x%x: failed!\n", CMD4); + return -1; + } + + if (WriteDSPCommand (portbase, CMD5)) + { + printk ("[aedsp16] CMD 0x%x: failed!\n", CMD5); + return -1; + } + + if (WriteDSPCommand (portbase, oredparams)) + { + printk ("[aedsp16] Initialization of (M)IRQ and DMA: failed!\n"); + return -1; + } + return 0; +} + +static int +GetCardVersion (int port) +{ + int len = 0; + int ret; + int ver[3]; + + do + { + if ((ret = ReadData (port)) == -1) + return -1; + /* + * We alredy know how many int are stored (2), so we know when the + * string is finished. + */ + ver[len++] = ret; + } + while (len < CARDVERLEN); + sprintf (AudioExcelVersion, "%d.%d", ver[0], ver[1]); + return 0; +} + +static int +GetCardName (int port) +{ + int len = 0; + int ret; + + do + { + if ((ret = ReadData (port)) == -1) + /* + * If no more data availabe, return to the caller, no error if len>0. + * We have no other way to know when the string is finished. + */ + return (len ? 0 : -1); + + AudioExcelName[len++] = ret; + + } + while (len < CARDNAMELEN); + return 0; +} + +static void +InitializeHardParams (void) +{ + + memset (AudioExcelName, 0, CARDNAMELEN + 1); + memset (AudioExcelVersion, 0, CARDVERLEN + 1); + + for (gc = 0; orIRQ[gc].or; gc++) + if (orIRQ[gc].val == irq) + oredparams |= orIRQ[gc].or; + + for (gc = 0; orMIRQ[gc].or; gc++) + if (orMIRQ[gc].or == mirq) + oredparams |= orMIRQ[gc].or; + + for (gc = 0; orDMA[gc].or; gc++) + if (orDMA[gc].val == dma) + oredparams |= orDMA[gc].or; +} + +static int +InitAEDSP16 (int which) +{ + static char *InitName = NULL; + + InitializeHardParams (); + + if (ResetBoard (portbase)) + { + printk ("[aedsp16] ResetBoard: failed!\n"); + return -1; + } + +#if defined(THIS_SHOULD_GO_AWAY) + if (CheckDSPOkay (portbase)) + { + printk ("[aedsp16] CheckDSPOkay: failed!\n"); + return -1; + } +#endif + + if (WriteDSPCommand (portbase, CMD1)) + { + printk ("[aedsp16] CMD 0x%x: failed!\n", CMD1); + return -1; + } + + if (GetCardName (portbase)) + { + printk ("[aedsp16] GetCardName: failed!\n"); + return -1; + } + + /* + * My AEDSP16 card return SC-6000 in AudioExcelName, so + * if we have something different, we have to be warned. + */ + if (strcmp ("SC-6000", AudioExcelName)) + printk ("[aedsp16] Warning: non SC-6000 audio card!\n"); + + if (WriteDSPCommand (portbase, CMD2)) + { + printk ("[aedsp16] CMD 0x%x: failed!\n", CMD2); + return -1; + } + + if (GetCardVersion (portbase)) + { + printk ("[aedsp16] GetCardVersion: failed!\n"); + return -1; + } + + if (SetUpBoard (portbase)) + { + printk ("[aedsp16] SetUpBoard: failed!\n"); + return -1; + } + + if (which == INIT_MSS) + { + if (InitMSS (portbase)) + { + printk ("[aedsp16] Can't initialize Microsoft Sound System mode.\n"); + return -1; + } + } + + /* + * If we are resetting, do not print any message because we may be + * in playing and we do not want lost too much time. + */ + if (!(which & RESET_DSP16)) + { + if (which & INIT_MPU401) + InitName = "MPU401"; + else if (which & INIT_SBPRO) + InitName = "SBPro"; + else if (which & INIT_MSS) + InitName = "MSS"; + else + InitName = "None"; + + printk ("Audio Excel DSP 16 init v%s (%s %s) [%s]\n", + VERSION, AudioExcelName, + AudioExcelVersion, InitName); + } + + tenmillisec (); + + return 0; +} + +#if defined(AEDSP16_SBPRO) + +int +InitAEDSP16_SBPRO (struct address_info *hw_config) +{ + /* + * If the card is alredy init'ed MSS, we can not init it to SBPRO too + * because the board can not emulate simultaneously MSS and SBPRO. + */ + if (ae_init & INIT_MSS) + return -1; + if (ae_init & INIT_SBPRO) + return 0; + + /* + * For now we will leave this + * code included only when INCLUDE_AEDSP16 is configured in, but it should + * be better include it every time. + */ + if (!(ae_init & INIT_MPU401)) + { + if (check_region (hw_config->io_base, 0x0f)) + { + printk ("AEDSP16/SBPRO I/O port region is alredy in use.\n"); + return -1; + } + } + + /* + * Set up the internal hardware parameters, to let the driver reach + * the Sound Card. + */ + portbase = hw_config->io_base; + irq = hw_config->irq; + dma = hw_config->dma; + if (InitAEDSP16 (INIT_SBPRO)) + return -1; + + if (!(ae_init & INIT_MPU401)) + request_region (hw_config->io_base, 0x0f, "aedsp16 (sbpro)"); + + ae_init |= INIT_SBPRO; + return 0; +} + +#endif /* AEDSP16_SBPRO */ + +#if defined(AEDSP16_MSS) + +int +InitAEDSP16_MSS (struct address_info *hw_config) +{ + /* + * If the card is alredy init'ed SBPRO, we can not init it to MSS too + * because the board can not emulate simultaneously MSS and SBPRO. + */ + if (ae_init & INIT_SBPRO) + return -1; + if (ae_init & INIT_MSS) + return 0; + + /* + * For now we will leave this + * code included only when INCLUDE_AEDSP16 is configured in, but it should + * be better include it every time. + */ + if (check_region (hw_config->io_base, 0x08)) + { + printk ("MSS I/O port region is alredy in use.\n"); + return -1; + } + + /* + * We must allocate the AEDSP16 region too because these are the I/O ports + * to access card's control registers. + */ + if (!(ae_init & INIT_MPU401)) + { + if (check_region (AEDSP16_BASE, 0x0f)) + { + printk ("AEDSP16 I/O port region is alredy in use.\n"); + return -1; + } + } + + + /* + * If we are configuring the card for MSS, the portbase for card configuration + * is the default one (0x220 unless you have changed the factory default + * with board switches), so no need to modify the portbase variable. + * The default is AEDSP16_BASE, that is the right value. + */ + irq = hw_config->irq; + dma = hw_config->dma; + if (InitAEDSP16 (INIT_MSS)) + return -1; + + request_region (hw_config->io_base, 0x08, "aedsp16 (mss)"); + + if (!(ae_init & INIT_MPU401)) + request_region (AEDSP16_BASE, 0x0f, "aedsp16 (sbpro)"); + + ae_init |= INIT_MSS; + return 0; +} + +#endif /* AEDSP16_MSS */ + +#if defined(AEDSP16_MPU401) + +int +InitAEDSP16_MPU401 (struct address_info *hw_config) +{ + if (ae_init & INIT_MPU401) + return 0; + + /* + * For now we will leave this + * code included only when INCLUDE_AEDSP16 is configured in, but it should + * be better include it every time. + */ + if (check_region (hw_config->io_base, 0x02)) + { + printk ("SB I/O port region is alredy in use.\n"); + return -1; + } + + /* + * We must allocate the AEDSP16 region too because these are the I/O ports + * to access card's control registers. + */ + if (!(ae_init & (INIT_MSS | INIT_SBPRO))) + { + if (check_region (AEDSP16_BASE, 0x0f)) + { + printk ("AEDSP16 I/O port region is alredy in use.\n"); + return -1; + } + } + + /* + * If mpu401, the irq and dma are not important, do not touch it + * because we may use the default if sbpro is not yet configured, + * we may use the sbpro ones if configured, and nothing wrong + * should happen. + * + * The mirq default is 0, but once set it to non-0 value, we should + * not touch it anymore (unless I write an ioctl to do it, of course). + */ + mirq = hw_config->irq; + if (InitAEDSP16 (INIT_MPU401)) + return -1; + + request_region (hw_config->io_base, 0x02, "aedsp16 (mpu401)"); + + if (!(ae_init & (INIT_MSS | INIT_SBPRO))) + request_region (AEDSP16_BASE, 0x0f, "aedsp16 (sbpro)"); + + ae_init |= INIT_MPU401; + return 0; +} + +#endif /* AEDSP16_MPU401 */ + +#if 0 /* Leave it out for now. We are not using this portion of code. */ + +/* + * Entry point for a reset function. + * May be I will write the infamous ioctl :) + */ +int +ResetAEDSP16 (void) +{ +#if defined(AEDSP16_DEBUG) + printk ("[aedsp16] ResetAEDSP16 called.\n"); +#endif + return InitAEDSP16 (RESET_DSP16); +} + +#endif /* 0 */ + +#endif /* !EXCLUDE_AEDSP16 */ diff --git a/sys/i386/isa/sound/alaw.h b/sys/i386/isa/sound/alaw.h new file mode 100644 index 000000000000..336bf6b2f776 --- /dev/null +++ b/sys/i386/isa/sound/alaw.h @@ -0,0 +1,73 @@ +static unsigned char alaw_linear[] = { + 45, 214, 122, 133, 0, 255, 107, 149, + 86, 171, 126, 129, 0, 255, 117, 138, + 13, 246, 120, 135, 0, 255, 99, 157, + 70, 187, 124, 131, 0, 255, 113, 142, + 61, 198, 123, 132, 0, 255, 111, 145, + 94, 163, 127, 128, 0, 255, 119, 136, + 29, 230, 121, 134, 0, 255, 103, 153, + 78, 179, 125, 130, 0, 255, 115, 140, + 37, 222, 122, 133, 0, 255, 105, 151, + 82, 175, 126, 129, 0, 255, 116, 139, + 5, 254, 120, 135, 0, 255, 97, 159, + 66, 191, 124, 131, 0, 255, 112, 143, + 53, 206, 123, 132, 0, 255, 109, 147, + 90, 167, 127, 128, 0, 255, 118, 137, + 21, 238, 121, 134, 0, 255, 101, 155, + 74, 183, 125, 130, 0, 255, 114, 141, + 49, 210, 123, 133, 0, 255, 108, 148, + 88, 169, 127, 129, 0, 255, 118, 138, + 17, 242, 121, 135, 0, 255, 100, 156, + 72, 185, 125, 131, 0, 255, 114, 142, + 64, 194, 124, 132, 0, 255, 112, 144, + 96, 161, 128, 128, 1, 255, 120, 136, + 33, 226, 122, 134, 0, 255, 104, 152, + 80, 177, 126, 130, 0, 255, 116, 140, + 41, 218, 122, 133, 0, 255, 106, 150, + 84, 173, 126, 129, 0, 255, 117, 139, + 9, 250, 120, 135, 0, 255, 98, 158, + 68, 189, 124, 131, 0, 255, 113, 143, + 57, 202, 123, 132, 0, 255, 110, 146, + 92, 165, 127, 128, 0, 255, 119, 137, + 25, 234, 121, 134, 0, 255, 102, 154, + 76, 181, 125, 130, 0, 255, 115, 141, + +}; + +#ifndef LINEAR_ALAW_NOT_WANTED +static unsigned char linear_alaw[] = { + + 252, 172, 172, 172, 172, 80, 80, 80, + 80, 208, 208, 208, 208, 16, 16, 16, + 16, 144, 144, 144, 144, 112, 112, 112, + 112, 240, 240, 240, 240, 48, 48, 48, + 48, 176, 176, 176, 176, 64, 64, 64, + 64, 192, 192, 192, 192, 0, 0, 0, + 0, 128, 128, 128, 128, 96, 96, 96, + 96, 224, 224, 224, 224, 32, 32, 32, + 160, 160, 88, 88, 216, 216, 24, 24, + 152, 152, 120, 120, 248, 248, 56, 56, + 184, 184, 72, 72, 200, 200, 8, 8, + 136, 136, 104, 104, 232, 232, 40, 40, + 168, 86, 214, 22, 150, 118, 246, 54, + 182, 70, 198, 6, 134, 102, 230, 38, + 166, 222, 158, 254, 190, 206, 142, 238, + 210, 242, 194, 226, 218, 250, 202, 234, + 235, 203, 251, 219, 227, 195, 243, 211, + 175, 239, 143, 207, 191, 255, 159, 223, + 167, 39, 231, 103, 135, 7, 199, 71, + 183, 55, 247, 119, 151, 23, 215, 87, + 87, 169, 169, 41, 41, 233, 233, 105, + 105, 137, 137, 9, 9, 201, 201, 73, + 73, 185, 185, 57, 57, 249, 249, 121, + 121, 153, 153, 25, 25, 217, 217, 89, + 89, 89, 161, 161, 161, 161, 33, 33, + 33, 33, 225, 225, 225, 225, 97, 97, + 97, 97, 129, 129, 129, 129, 1, 1, + 1, 1, 193, 193, 193, 193, 65, 65, + 65, 65, 177, 177, 177, 177, 49, 49, + 49, 49, 241, 241, 241, 241, 113, 113, + 113, 113, 145, 145, 145, 145, 17, 17, + 17, 17, 209, 209, 209, 209, 81, 253, +}; +#endif /* !LINEAR_ALAW_NOT_WANTED */ diff --git a/sys/i386/isa/sound/awe_hw.h b/sys/i386/isa/sound/awe_hw.h new file mode 100644 index 000000000000..8b6be670c4b8 --- /dev/null +++ b/sys/i386/isa/sound/awe_hw.h @@ -0,0 +1,116 @@ +/* + * sound/awe_hw.h + * + * Access routines and definitions for the low level driver for the + * AWE32/Sound Blaster 32 wave table synth. + * version 0.2.0a; Oct. 30, 1996 + * + * (C) 1996 Takashi Iwai + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef AWE_HW_H_DEF +#define AWE_HW_H_DEF + +/* + * user configuration: + * if auto detection can't work properly, define the following values + * for your machine. + */ +/*#define AWE_DEFAULT_BASE_ADDR 0x620*/ /* base port address */ +/*#define AWE_DEFAULT_MEM_SIZE 512*/ /* kbytes */ + + +/* + * maximum size of sample table: + * if your data overflow, increase the following values. + */ +#define AWE_MAX_SAMPLES 400 +#define AWE_MAX_INFOS 900 /* GS presets has 801 infos! */ + + +/* + * Emu-8000 control registers + * name(channel) reg, port + */ + +#define awe_cmd_idx(reg,ch) (((reg)<< 5) | (ch)) + +#define Data0 0x620 /* doubleword r/w */ +#define Data1 0xA20 /* doubleword r/w */ +#define Data2 0xA22 /* word r/w */ +#define Data3 0xE20 /* word r/w */ +#define Pointer 0xE22 /* register pointer r/w */ + +#define AWE_CPF(ch) awe_cmd_idx(0,ch), Data0 /* DW: current pitch and fractional address */ +#define AWE_PTRX(ch) awe_cmd_idx(1,ch), Data0 /* DW: pitch target and reverb send */ +#define AWE_CVCF(ch) awe_cmd_idx(2,ch), Data0 /* DW: current volume and filter cutoff */ +#define AWE_VTFT(ch) awe_cmd_idx(3,ch), Data0 /* DW: volume and filter cutoff targets */ +#define AWE_PSST(ch) awe_cmd_idx(6,ch), Data0 /* DW: pan send and loop start address */ +#define AWE_CSL(ch) awe_cmd_idx(7,ch), Data0 /* DW: chorus send and loop end address */ +#define AWE_CCCA(ch) awe_cmd_idx(0,ch), Data1 /* DW: Q, control bits, and current address */ +#define AWE_HWCF4 awe_cmd_idx(1,9), Data1 /* DW: config dw 4 */ +#define AWE_HWCF5 awe_cmd_idx(1,10), Data1 /* DW: config dw 5 */ +#define AWE_HWCF6 awe_cmd_idx(1,13), Data1 /* DW: config dw 6 */ +#define AWE_SMALR awe_cmd_idx(1,20), Data1 /* DW: sound memory address for left read */ +#define AWE_SMARR awe_cmd_idx(1,21), Data1 /* DW: for right read */ +#define AWE_SMALW awe_cmd_idx(1,22), Data1 /* DW: sound memory address for left write */ +#define AWE_SMARW awe_cmd_idx(1,23), Data1 /* DW: for right write */ +#define AWE_SMLD awe_cmd_idx(1,26), Data1 /* W: sound memory left data */ +#define AWE_SMRD awe_cmd_idx(1,26), Data2 /* W: right data */ +#define AWE_WC awe_cmd_idx(1,27), Data2 /* W: sample counter */ +#define AWE_WC_Cmd awe_cmd_idx(1,27) +#define AWE_WC_Port Data2 +#define AWE_HWCF1 awe_cmd_idx(1,29), Data1 /* W: config w 1 */ +#define AWE_HWCF2 awe_cmd_idx(1,30), Data1 /* W: config w 2 */ +#define AWE_HWCF3 awe_cmd_idx(1,31), Data1 /* W: config w 3 */ +#define AWE_INIT1(ch) awe_cmd_idx(2,ch), Data1 /* W: init array 1 */ +#define AWE_INIT2(ch) awe_cmd_idx(2,ch), Data2 /* W: init array 2 */ +#define AWE_INIT3(ch) awe_cmd_idx(3,ch), Data1 /* W: init array 3 */ +#define AWE_INIT4(ch) awe_cmd_idx(3,ch), Data2 /* W: init array 4 */ +#define AWE_ENVVOL(ch) awe_cmd_idx(4,ch), Data1 /* W: volume envelope delay */ +#define AWE_DCYSUSV(ch) awe_cmd_idx(5,ch), Data1 /* W: volume envelope sustain and decay */ +#define AWE_ENVVAL(ch) awe_cmd_idx(6,ch), Data1 /* W: modulation envelope delay */ +#define AWE_DCYSUS(ch) awe_cmd_idx(7,ch), Data1 /* W: modulation envelope sustain and decay */ +#define AWE_ATKHLDV(ch) awe_cmd_idx(4,ch), Data2 /* W: volume envelope attack and hold */ +#define AWE_LFO1VAL(ch) awe_cmd_idx(5,ch), Data2 /* W: LFO#1 Delay */ +#define AWE_ATKHLD(ch) awe_cmd_idx(6,ch), Data2 /* W: modulation envelope attack and hold */ +#define AWE_LFO2VAL(ch) awe_cmd_idx(7,ch), Data2 /* W: LFO#2 Delay */ +#define AWE_IP(ch) awe_cmd_idx(0,ch), Data3 /* W: initial pitch */ +#define AWE_IFATN(ch) awe_cmd_idx(1,ch), Data3 /* W: initial filter cutoff and attenuation */ +#define AWE_PEFE(ch) awe_cmd_idx(2,ch), Data3 /* W: pitch and filter envelope heights */ +#define AWE_FMMOD(ch) awe_cmd_idx(3,ch), Data3 /* W: vibrato and filter modulation freq */ +#define AWE_TREMFRQ(ch) awe_cmd_idx(4,ch), Data3 /* W: LFO#1 tremolo amount and freq */ +#define AWE_FM2FRQ2(ch) awe_cmd_idx(5,ch), Data3 /* W: LFO#2 vibrato amount and freq */ + +/* used during detection (returns ROM version ?) */ +#define AWE_U1 0xE0, Data3 /* (R)(W) used in initialization */ +#define AWE_U2(ch) 0xC0+(ch), Data3 /* (W)(W) used in init envelope */ + + +#define AWE_MAX_VOICES 32 +#define AWE_NORMAL_VOICES 30 /*30&31 are reserved for DRAM refresh*/ + +#define AWE_DRAM_OFFSET 0x200000 + +#endif diff --git a/sys/i386/isa/sound/awe_voice.h b/sys/i386/isa/sound/awe_voice.h new file mode 100644 index 000000000000..934aaa8eba7e --- /dev/null +++ b/sys/i386/isa/sound/awe_voice.h @@ -0,0 +1,268 @@ +/* + * sound/awe_voice.h + * + * Voice information definitions for the low level driver for the + * AWE32/Sound Blaster 32 wave table synth. + * version 0.2.0a; Oct. 30, 1996 + * + * (C) 1996 Takashi Iwai + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef AWE_VOICE_H +#define AWE_VOICE_H + +#ifndef SAMPLE_TYPE_AWE32 +#define SAMPLE_TYPE_AWE32 0x20 +#endif + +#ifndef _PATCHKEY +#define _PATCHKEY(id) ((id<<8)|0xfd) +#endif + +/*---------------------------------------------------------------- + * patch information record + *----------------------------------------------------------------*/ + +/* patch interface header: 16 bytes */ +typedef struct awe_patch_info { + short key; /* use AWE_PATCH here */ +#define AWE_PATCH _PATCHKEY(0x07) + + short device_no; /* synthesizer number */ + unsigned short sf_id; /* file id (should be zero) */ + short sf_version; /* patch version (not referred) */ + long len; /* data length (without this header) */ + + short type; /* following data type */ +#define AWE_LOAD_INFO 0 +#define AWE_LOAD_DATA 1 + + short reserved; /* word alignment data */ + char data[0]; /* patch data follows here */ +} awe_patch_info; + + +/*---------------------------------------------------------------- + * raw voice information record + *----------------------------------------------------------------*/ + +/* wave table envelope & effect parameters to control EMU8000 */ +typedef struct _awe_voice_parm { + unsigned short moddelay; /* modulation delay (0x8000) */ + unsigned short modatkhld; /* modulation attack & hold time (0x7f7f) */ + unsigned short moddcysus; /* modulation decay & sustain (0x7f7f) */ + unsigned short modrelease; /* modulation release time (0x807f) */ + short modkeyhold, modkeydecay; /* envelope change per key (not used) */ + unsigned short voldelay; /* volume delay (0x8000) */ + unsigned short volatkhld; /* volume attack & hold time (0x7f7f) */ + unsigned short voldcysus; /* volume decay & sustain (0x7f7f) */ + unsigned short volrelease; /* volume release time (0x807f) */ + short volkeyhold, volkeydecay; /* envelope change per key (not used) */ + unsigned short lfo1delay; /* LFO1 delay (0x8000) */ + unsigned short lfo2delay; /* LFO2 delay (0x8000) */ + unsigned short pefe; /* modulation pitch & cutoff (0x0000) */ + unsigned short fmmod; /* LFO1 pitch & cutoff (0x0000) */ + unsigned short tremfrq; /* LFO1 volume & freq (0x0000) */ + unsigned short fm2frq2; /* LFO2 pitch & freq (0x0000) */ + unsigned char cutoff; /* initial cutoff (0xff) */ + unsigned char filterQ; /* initial filter Q [0-15] (0x0) */ + unsigned char chorus; /* chorus send (0x00) */ + unsigned char reverb; /* reverb send (0x00) */ + unsigned short reserved[4]; /* not used */ +} awe_voice_parm; + +/* wave table parameters: 92 bytes */ +typedef struct _awe_voice_info { + unsigned short sf_id; /* file id (should be zero) */ + unsigned short sample; /* sample id */ + long start, end; /* sample offset correction */ + long loopstart, loopend; /* loop offset correction */ + short rate_offset; /* sample rate pitch offset */ + unsigned short mode; /* sample mode */ +#define AWE_MODE_ROMSOUND 0x8000 +#define AWE_MODE_STEREO 1 +#define AWE_MODE_LOOPING 2 +#define AWE_MODE_NORELEASE 4 /* obsolete */ +#define AWE_MODE_INIT_PARM 8 + + short root; /* midi root key */ + short tune; /* pitch tuning (in cents) */ + char low, high; /* key note range */ + char vellow, velhigh; /* velocity range */ + char fixkey, fixvel; /* fixed key, velocity */ + char pan, fixpan; /* panning, fixed panning */ + short exclusiveClass; /* exclusive class (0 = none) */ + unsigned char amplitude; /* sample volume (127 max) */ + unsigned char attenuation; /* attenuation (0.375dB) */ + short scaleTuning; /* pitch scale tuning(%), normally 100 */ + awe_voice_parm parm; /* voice envelope parameters */ + short index; /* internal index (set by driver) */ +} awe_voice_info; + +/* instrument info header: 4 bytes */ +typedef struct _awe_voice_rec { + unsigned char bank; /* midi bank number */ + unsigned char instr; /* midi preset number */ + short nvoices; /* number of voices */ + awe_voice_info info[0]; /* voice information follows here */ +} awe_voice_rec; + + +/*---------------------------------------------------------------- + * sample wave information + *----------------------------------------------------------------*/ + +/* wave table sample header: 32 bytes */ +typedef struct awe_sample_info { + unsigned short sf_id; /* file id (should be zero) */ + unsigned short sample; /* sample id */ + long start, end; /* start & end offset */ + long loopstart, loopend; /* loop start & end offset */ + long size; /* size (0 = ROM) */ + short checksum_flag; /* use check sum = 1 */ + unsigned short mode_flags; /* mode flags */ +#define AWE_SAMPLE_8BITS 1 /* wave data is 8bits */ +#define AWE_SAMPLE_UNSIGNED 2 /* wave data is unsigned */ +#define AWE_SAMPLE_NO_BLANK 4 /* no blank loop is attached */ +#define AWE_SAMPLE_SINGLESHOT 8 /* single-shot w/o loop */ +#define AWE_SAMPLE_BIDIR_LOOP 16 /* bidirectional looping */ +#define AWE_SAMPLE_STEREO_LEFT 32 /* stereo left sound */ +#define AWE_SAMPLE_STEREO_RIGHT 64 /* stereo right sound */ + unsigned long checksum; /* check sum */ + unsigned short data[0]; /* sample data follows here */ +} awe_sample_info; + + +/*---------------------------------------------------------------- + * awe hardware controls + *----------------------------------------------------------------*/ + +#define _AWE_DEBUG_MODE 0x00 +#define _AWE_REVERB_MODE 0x01 +#define _AWE_CHORUS_MODE 0x02 +#define _AWE_REMOVE_LAST_SAMPLES 0x03 +#define _AWE_INITIALIZE_CHIP 0x04 +#define _AWE_SEND_EFFECT 0x05 +#define _AWE_TERMINATE_CHANNEL 0x06 +#define _AWE_TERMINATE_ALL 0x07 +#define _AWE_INITIAL_VOLUME 0x08 +#define _AWE_SET_GUS_BANK 0x09 + +#define _AWE_MODE_FLAG 0x80 +#define _AWE_COOKED_FLAG 0x40 /* not supported */ +#define _AWE_MODE_VALUE_MASK 0x3F + +#define _AWE_CMD(chn, voice, cmd, p1, p2) \ +{_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\ + _seqbuf[_seqbufptr+1] = chn;\ + _seqbuf[_seqbufptr+2] = _AWE_MODE_FLAG|(cmd);\ + _seqbuf[_seqbufptr+3] = voice;\ + *(unsigned short*)&_seqbuf[_seqbufptr+4] = p1;\ + *(unsigned short*)&_seqbuf[_seqbufptr+6] = p2;\ + _SEQ_ADVBUF(8);} + +#define AWE_DEBUG_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_DEBUG_MODE, p1, 0) +#define AWE_REVERB_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_REVERB_MODE, p1, 0) +#define AWE_CHORUS_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_CHORUS_MODE, p1, 0) +#define AWE_REMOVE_LAST_SAMPLES(dev) _AWE_CMD(dev, 0, _AWE_REMOVE_LAST_SAMPLES, 0, 0) +#define AWE_INITIALIZE_CHIP(dev) _AWE_CMD(dev, 0, _AWE_INITIALIZE_CHIP, 0, 0) +#define AWE_SEND_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,type,value) +#define AWE_TERMINATE_CHANNEL(dev,voice) _AWE_CMD(dev,voice,_AWE_TERMINATE_CHANNEL,0,0) +#define AWE_TERMINATE_ALL(dev) _AWE_CMD(dev, 0, _AWE_TERMINATE_ALL, 0, 0) +#define AWE_INITIAL_VOLUME(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 0) +#define AWE_SET_GUS_BANK(dev,bank) _AWE_CMD(dev, 0, _AWE_SET_GUS_BANK, bank, 0) + +/* reverb mode */ +#define AWE_REVERB_ROOM1 0 +#define AWE_REVERB_ROOM2 1 +#define AWE_REVERB_ROOM3 2 +#define AWE_REVERB_HALL1 3 +#define AWE_REVERB_HALL2 4 +#define AWE_REVERB_PLATE 5 +#define AWE_REVERB_DELAY 6 +#define AWE_REVERB_PANNINGDELAY 7 + +/* chorus mode */ +#define AWE_CHORUS_1 0 +#define AWE_CHORUS_2 1 +#define AWE_CHORUS_3 2 +#define AWE_CHORUS_4 3 +#define AWE_CHORUS_FEEDBACK 4 +#define AWE_CHORUS_FLANGER 5 +#define AWE_CHORUS_SHORTDELAY 6 +#define AWE_CHORUS_SHORTDELAY2 7 + +/* effects */ +enum { + +/* modulation envelope parameters */ +/* 0*/ AWE_FX_ENV1_DELAY, /* WORD: ENVVAL */ +/* 1*/ AWE_FX_ENV1_ATTACK, /* BYTE: up ATKHLD */ +/* 2*/ AWE_FX_ENV1_HOLD, /* BYTE: lw ATKHLD */ +/* 3*/ AWE_FX_ENV1_DECAY, /* BYTE: lw DCYSUS */ +/* 4*/ AWE_FX_ENV1_RELEASE, /* BYTE: lw DCYSUS */ +/* 5*/ AWE_FX_ENV1_SUSTAIN, /* BYTE: up DCYSUS */ +/* 6*/ AWE_FX_ENV1_PITCH, /* BYTE: up PEFE */ +/* 7*/ AWE_FX_ENV1_CUTOFF, /* BYTE: lw PEFE */ + +/* volume envelope parameters */ +/* 8*/ AWE_FX_ENV2_DELAY, /* WORD: ENVVOL */ +/* 9*/ AWE_FX_ENV2_ATTACK, /* BYTE: up ATKHLDV */ +/*10*/ AWE_FX_ENV2_HOLD, /* BYTE: lw ATKHLDV */ +/*11*/ AWE_FX_ENV2_DECAY, /* BYTE: lw DCYSUSV */ +/*12*/ AWE_FX_ENV2_RELEASE, /* BYTE: lw DCYSUSV */ +/*13*/ AWE_FX_ENV2_SUSTAIN, /* BYTE: up DCYSUSV */ + +/* LFO1 (tremolo & vibrato) parameters */ +/*14*/ AWE_FX_LFO1_DELAY, /* WORD: LFO1VAL */ +/*15*/ AWE_FX_LFO1_FREQ, /* BYTE: lo TREMFRQ */ +/*16*/ AWE_FX_LFO1_VOLUME, /* BYTE: up TREMFRQ */ +/*17*/ AWE_FX_LFO1_PITCH, /* BYTE: up FMMOD */ +/*18*/ AWE_FX_LFO1_CUTOFF, /* BYTE: lo FMMOD */ + +/* LFO2 (vibrato) parameters */ +/*19*/ AWE_FX_LFO2_DELAY, /* WORD: LFO2VAL */ +/*20*/ AWE_FX_LFO2_FREQ, /* BYTE: lo FM2FRQ2 */ +/*21*/ AWE_FX_LFO2_PITCH, /* BYTE: up FM2FRQ2 */ + +/* Other overall effect parameters */ +/*22*/ AWE_FX_INIT_PITCH, /* SHORT: pitch offset */ +/*23*/ AWE_FX_CHORUS, /* BYTE: chorus effects send (0-255) */ +/*24*/ AWE_FX_REVERB, /* BYTE: reverb effects send (0-255) */ +/*25*/ AWE_FX_CUTOFF, /* BYTE: up IFATN */ +/*26*/ AWE_FX_FILTERQ, /* BYTE: up CCCA */ + +/* Sample / loop offset changes */ +/*27*/ AWE_FX_SAMPLE_START, /* SHORT: offset */ +/*28*/ AWE_FX_LOOP_START, /* SHORT: offset */ +/*29*/ AWE_FX_LOOP_END, /* SHORT: offset */ +/*30*/ AWE_FX_COARSE_SAMPLE_START, /* SHORT: upper word offset */ +/*31*/ AWE_FX_COARSE_LOOP_START, /* SHORT: upper word offset */ +/*32*/ AWE_FX_COARSE_LOOP_END, /* SHORT: upper word offset */ + + AWE_FX_END, +}; + + +#endif /* AWE_VOICE_H */ diff --git a/sys/i386/isa/sound/awe_wave.c b/sys/i386/isa/sound/awe_wave.c new file mode 100644 index 000000000000..47818165a9e4 --- /dev/null +++ b/sys/i386/isa/sound/awe_wave.c @@ -0,0 +1,3367 @@ +/* + * sound/awe_wave.c + * + * The low level driver for the AWE32/Sound Blaster 32 wave table synth. + * version 0.2.0a; Oct. 30, 1996 + * + * (C) 1996 Takashi Iwai + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* if you're using obsolete VoxWare 3.0.x on Linux 1.2.x (or FreeBSD), + * uncomment the following line + */ +#define AWE_OBSOLETE_VOXWARE + + +#ifdef AWE_OBSOLETE_VOXWARE + +#ifdef __FreeBSD__ +# include <i386/isa/sound/sound_config.h> +#else +# include "sound_config.h" +#endif + +#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32) +#define CONFIG_AWE32_SYNTH +#endif + +#else /* AWE_OBSOLETE_VOXWARE */ + +#include "../sound_config.h" + +#endif /* AWE_OBSOLETE_VOXWARE */ + + +/*----------------------------------------------------------------* + * compile condition + *----------------------------------------------------------------*/ + +/* initialize FM passthrough even without extended RAM */ +/*#define AWE_ALWAYS_INIT_FM*/ + +/* debug on */ +#define AWE_DEBUG_ON + +/* verify checksum for uploading samples */ +#define AWE_CHECKSUM_DATA +#define AWE_CHECKSUM_MEMORY + +/* disable interruption during sequencer operation */ +/*#define AWE_NEED_DISABLE_INTR*/ + +/* use buffered access to user wave data */ +#define AWE_USE_BUFFERED_IO + +#ifdef linux +/* i tested this only on my linux */ +#define INLINE __inline__ +#else +#define INLINE /**/ +#endif + +/*----------------------------------------------------------------*/ + +#ifdef CONFIG_AWE32_SYNTH + +#include <i386/isa/sound/awe_hw.h> +#include <i386/isa/sound/awe_voice.h> + +#ifdef AWE_OBSOLETE_VOXWARE +#ifdef __FreeBSD__ +#define SEQUENCER_C +#endif +#include <i386/isa/sound/tuning.h> +#else +#include "../tuning.h" +#endif + +#ifdef linux +# include <linux/ultrasound.h> +#elif defined(__FreeBSD__) +# include <machine/ultrasound.h> +#endif + + +/*---------------------------------------------------------------- + * debug message + *----------------------------------------------------------------*/ + +#ifdef AWE_DEBUG_ON +static int debug_mode = 0; +#define DEBUG(LVL,XXX) {if (debug_mode > LVL) { XXX; }} +#define ERRMSG(XXX) {if (debug_mode) { XXX; }} +#define FATALERR(XXX) XXX +#else +#define DEBUG(LVL,XXX) /**/ +#define ERRMSG(XXX) XXX +#define FATALERR(XXX) XXX +#endif + +/*---------------------------------------------------------------- + * bank and voice record + *----------------------------------------------------------------*/ + +/* bank record */ +typedef struct _awe_voice_list { + unsigned char bank, instr; + awe_voice_info v; + struct _awe_voice_list *next_instr; + struct _awe_voice_list *next_bank; +} awe_voice_list; + +/* sample and information table */ +static awe_sample_info *samples; +static awe_voice_list *infos; + +#define AWE_MAX_PRESETS 256 +#define AWE_DEFAULT_BANK 0 + +/* preset table index */ +static awe_voice_list *preset_table[AWE_MAX_PRESETS]; + +/*---------------------------------------------------------------- + * voice table + *----------------------------------------------------------------*/ + +#define AWE_FX_BYTES ((AWE_FX_END+7)/8) + +typedef struct _voice_info { + int state; /* status (on = 1, off = 0) */ + int note; /* midi key (0-127) */ + int velocity; /* midi velocity (0-127) */ + int bender; /* midi pitchbend (-8192 - 8192) */ + int bender_range; /* midi bender range (x100) */ + int panning; /* panning (0-127) */ + int main_vol; /* channel volume (0-127) */ + int expression_vol; /* midi expression (0-127) */ + + /* EMU8000 parameters */ + int apitch; /* pitch parameter */ + int avol; /* volume parameter */ + + /* instrument parameters */ + int bank; /* current tone bank */ + int instr; /* current program */ + awe_voice_list *vrec; + awe_voice_info *sample; + + /* channel effects */ + unsigned char fx_flags[AWE_FX_BYTES]; + short fx[AWE_FX_END]; +} voice_info; + +static voice_info voices[AWE_MAX_VOICES]; + + +/*---------------------------------------------------------------- + * global variables + *----------------------------------------------------------------*/ + +/* awe32 base address (overwritten at initialization) */ +static int awe_base = 0; +/* memory byte size (overwritten at initialization) */ +static long awe_mem_size = 0; + +/* maximum channels for playing */ +static int awe_max_voices = AWE_MAX_VOICES; + +static long free_mem_ptr = 0; /* free word byte size */ +static int free_info = 0; /* free info tables */ +static int last_info = 0; /* last loaded info index */ +static int free_sample = 0; /* free sample tables */ +static int last_sample = 0; /* last loaded sample index */ +static int loaded_once = 0; /* samples are loaded after init? */ +static unsigned short current_sf_id = 0; /* internal id */ + +static int reverb_mode = 0; /* reverb mode */ +static int chorus_mode = 0; /* chorus mode */ +static unsigned short init_atten = 32; /* 12dB */ + +static int awe_present = 0; /* awe device present? */ +static int awe_busy = 0; /* awe device opened? */ + +static int awe_gus_bank = AWE_DEFAULT_BANK; /* GUS default bank number */ + + +static struct synth_info awe_info = { + "AWE32 Synth", /* name */ + 0, /* device */ + SYNTH_TYPE_SAMPLE, /* synth_type */ + SAMPLE_TYPE_AWE32, /* synth_subtype */ + 0, /* perc_mode (obsolete) */ + AWE_MAX_VOICES, /* nr_voices */ + 0, /* nr_drums (obsolete) */ + AWE_MAX_INFOS /* instr_bank_size */ +}; + + +static struct voice_alloc_info *voice_alloc; /* set at initialization */ + + +/*---------------------------------------------------------------- + * function prototypes + *----------------------------------------------------------------*/ + +#ifndef AWE_OBSOLETE_VOXWARE +static int awe_check_port(void); +static void awe_request_region(void); +static void awe_release_region(void); +#endif + +static void awe_reset_samples(void); +/* emu8000 chip i/o access */ +static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data); +static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned long data); +static unsigned short awe_peek(unsigned short cmd, unsigned short port); +static unsigned long awe_peek_dw(unsigned short cmd, unsigned short port); +static void awe_wait(unsigned short delay); + +/* initialize emu8000 chip */ +static void awe_initialize(void); + +/* set voice parameters */ +static void awe_init_voice_info(awe_voice_info *vp); +static void awe_init_voice_parm(awe_voice_parm *pp); +static int freq_to_note(int freq); +static int calc_rate_offset(int Hz); +/*static int calc_parm_delay(int msec);*/ +static int calc_parm_hold(int msec); +static int calc_parm_attack(int msec); +static int calc_parm_decay(int msec); +static int calc_parm_search(int msec, short *table); + +/* turn on/off note */ +static void awe_note_on(int voice); +static void awe_note_off(int voice); +static void awe_terminate(int voice); +static void awe_exclusive_off(int voice); + +/* calculate voice parameters */ +static void awe_set_pitch(int voice); +static void awe_set_volume(int voice); +static void awe_set_pan(int voice, int forced); +static void awe_fx_fmmod(int voice); +static void awe_fx_tremfrq(int voice); +static void awe_fx_fm2frq2(int voice); +static void awe_fx_cutoff(int voice); +static void awe_fx_initpitch(int voice); +static void awe_calc_pitch(int voice); +static void awe_calc_pitch_from_freq(int voice, int freq); +static void awe_calc_volume(int voice); +static void awe_voice_init(int voice, int inst_only); + +/* sequencer interface */ +static int awe_open(int dev, int mode); +static void awe_close(int dev); +static int awe_ioctl(int dev, unsigned int cmd, caddr_t arg); +static int awe_kill_note(int dev, int voice, int note, int velocity); +static int awe_start_note(int dev, int v, int note_num, int volume); +static int awe_set_instr(int dev, int voice, int instr_no); +static void awe_reset(int dev); +static void awe_hw_control(int dev, unsigned char *event); +static int awe_load_patch(int dev, int format, const char *addr, + int offs, int count, int pmgr_flag); +static void awe_aftertouch(int dev, int voice, int pressure); +static void awe_controller(int dev, int voice, int ctrl_num, int value); +static void awe_panning(int dev, int voice, int value); +static void awe_volume_method(int dev, int mode); +static int awe_patchmgr(int dev, struct patmgr_info *rec); +static void awe_bender(int dev, int voice, int value); +static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc); +static void awe_setup_voice(int dev, int voice, int chn); + +/* hardware controls */ +static void awe_hw_gus_control(int dev, int cmd, unsigned char *event); +static void awe_hw_awe_control(int dev, int cmd, unsigned char *event); + +/* voice search */ +static awe_voice_info *awe_search_voice(int voice, int note); +static awe_voice_list *awe_search_instr(int bank, int preset); + +/* load / remove patches */ +static void awe_check_loaded(void); +static int awe_load_info(awe_patch_info *patch, const char *addr); +static int awe_load_data(awe_patch_info *patch, const char *addr); +static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag); +static int awe_write_wave_data(const char *addr, long offset, int size); +static awe_voice_list *awe_get_removed_list(awe_voice_list *curp); +static void awe_remove_samples(void); +static short awe_set_sample(awe_voice_info *vp); + +/* lowlevel functions */ +static void awe_init_audio(void); +static void awe_init_dma(void); +static void awe_init_array(void); +static void awe_send_array(unsigned short *data); +static void awe_tweak(void); +static void awe_init_fm(void); +static int awe_open_dram_for_write(int offset); +static int awe_open_dram_for_read(int offset); +static void awe_open_dram_for_check(void); +static void awe_close_dram(void); +static void awe_close_dram_for_read(void); +static void awe_write_dram(unsigned short c); +static int awe_detect(void); +static int awe_check_dram(void); +static void awe_set_chorus_mode(int mode); +static void awe_set_reverb_mode(int mode); + +#ifdef AWE_OBSOLETE_VOXWARE + +#define awe_check_port() 0 /* always false */ +#define awe_request_region() /* nothing */ +#define awe_release_region() /* nothing */ + +#else /* AWE_OBSOLETE_VOXWARE */ + +/* the following macros are osbolete */ + +#define PERMANENT_MALLOC(type,var,size,memptr) \ + var = (type)(sound_mem_blocks[sound_nblocks++] = vmalloc(size)) +#define RET_ERROR(err) -err + +#endif /* AWE_OBSOLETE_VOXWARE */ + + +#ifdef AWE_NEED_DISABLE_INTR +#define DECL_INTR_FLAGS(x) unsigned long x +#else +#undef DISABLE_INTR +#undef RESTORE_INTR +#define DECL_INTR_FLAGS(x) /**/ +#define DISABLE_INTR(x) /**/ +#define RESTORE_INTR(x) /**/ +#endif + + +/* macros for Linux and FreeBSD compatibility */ + +#undef OUTW +#undef COPY_FROM_USER +#undef GET_BYTE_FROM_USER +#undef GET_SHORT_FROM_USER +#undef IOCTL_TO_USER + +#ifdef linux +# define NO_DATA_ERR ENODATA +# define OUTW(data, addr) outw(data, addr) +# define COPY_FROM_USER(target, source, offs, count) \ + memcpy_fromfs( ((caddr_t)(target)),(source)+(offs),(count) ) +# define GET_BYTE_FROM_USER(target, addr, offs) \ + *((char *)&(target)) = get_fs_byte( (addr)+(offs) ) +# define GET_SHORT_FROM_USER(target, addr, offs) \ + *((short *)&(target)) = get_fs_word( (addr)+(offs) ) +# define IOCTL_TO_USER(target, offs, source, count) \ + memcpy_tofs ( ((caddr_t)(target)),(source)+(offs),(count) ) +# define BZERO(target,len) \ + memset( (caddr_t)target, '\0', len ) +# define MEMCPY(dst,src,len) \ + memcpy((caddr_t)dst, (caddr_t)src, len) +#elif defined(__FreeBSD__) +# define NO_DATA_ERR EINVAL +# define OUTW(data, addr) outw(addr, data) +# define COPY_FROM_USER(target, source, offs, count) \ + uiomove( ((caddr_t)(target)),(count),((struct uio *)(source)) ) +# define GET_BYTE_FROM_USER(target, addr, offs) \ + uiomove( ((char*)&(target)), 1, ((struct uio *)(addr)) ) +# define GET_SHORT_FROM_USER(target, addr, offs) \ + uiomove( ((char*)&(target)), 2, ((struct uio *)(addr)) ) +# define IOCTL_TO_USER(target, offs, source, count) \ + memcpy( &((target)[offs]), (source), (count) ) +# define BZERO(target,len) \ + bzero( (caddr_t)target, len ) +# define MEMCPY(dst,src,len) \ + bcopy((caddr_t)src, (caddr_t)dst, len) +#endif + + +/*---------------------------------------------------------------- + * synth operation table + *----------------------------------------------------------------*/ + +static struct synth_operations awe_operations = +{ + &awe_info, + 0, + SYNTH_TYPE_SAMPLE, + SAMPLE_TYPE_AWE32, + awe_open, + awe_close, + awe_ioctl, + awe_kill_note, + awe_start_note, + awe_set_instr, + awe_reset, + awe_hw_control, + awe_load_patch, + awe_aftertouch, + awe_controller, + awe_panning, + awe_volume_method, + awe_patchmgr, + awe_bender, + awe_alloc, + awe_setup_voice +}; + + + +/*================================================================ + * attach / unload interface + *================================================================*/ + +#ifdef AWE_OBSOLETE_VOXWARE +long attach_awe_obsolete(long mem_start, struct address_info *hw_config) +#else +int attach_awe(void) +#endif +{ + /* check presence of AWE32 card */ + if (! awe_detect()) { + printk("AWE32: not detected\n"); + return 0; + } + + /* check AWE32 ports are available */ + if (awe_check_port()) { + printk("AWE32: I/O area already used.\n"); + return 0; + } + + /* allocate sample tables */ + PERMANENT_MALLOC(awe_sample_info *, samples, + AWE_MAX_SAMPLES * sizeof(awe_sample_info), mem_start); + PERMANENT_MALLOC(awe_voice_list *, infos, + AWE_MAX_INFOS * sizeof(awe_voice_list), mem_start); + if (samples == NULL || infos == NULL) { + printk("AWE32: can't allocate sample tables\n"); + return 0; + } + + if (num_synths >= MAX_SYNTH_DEV) + printk("AWE32 Error: too many synthesizers\n"); + else { + voice_alloc = &awe_operations.alloc; + voice_alloc->max_voice = awe_max_voices; + synth_devs[num_synths++] = &awe_operations; + } + + /* reserve I/O ports for awedrv */ + awe_request_region(); + + /* clear all samples */ + awe_reset_samples(); + + /* intialize AWE32 hardware */ + awe_initialize(); + +#if 0 /* Drivers shouldn't be this chatty by default */ + printk("<AWE32 SynthCard (%dk)>\n", (int)awe_mem_size/1024); +#endif + sprintf(awe_info.name, "AWE32 Synth (%dk)", (int)awe_mem_size/1024); + + /* set reverb & chorus modes */ + awe_set_reverb_mode(reverb_mode); + awe_set_chorus_mode(chorus_mode); + + awe_present = 1; + +#ifdef AWE_OBSOLETE_VOXWARE + return mem_start; +#else + return 1; +#endif +} + + +void unload_awe(void) +{ + if (awe_present) { + awe_reset_samples(); + awe_release_region(); + } +} + + +#ifdef AWE_OBSOLETE_VOXWARE +int probe_awe_obsolete(struct address_info *hw_config) +{ + return 1; + /*return awe_detect();*/ +} + +#endif + +/*================================================================ + * clear sample tables + *================================================================*/ + +static void +awe_reset_samples(void) +{ + int i; + + /* free all bank tables */ + for (i = 0; i < AWE_MAX_PRESETS; i++) { + preset_table[i] = NULL; + } + + free_mem_ptr = 0; + last_sample = free_sample = 0; + last_info = free_info = 0; + current_sf_id = 0; + loaded_once = 0; +} + + +/*================================================================ + * EMU register access + *================================================================*/ + +/* select a given AWE32 pointer */ +static int awe_cur_cmd = -1; +#define awe_set_cmd(cmd) \ +if (awe_cur_cmd != cmd) { OUTW(cmd, awe_base + 0x802); awe_cur_cmd = cmd; } +#define awe_port(port) (awe_base - 0x620 + port) + +/* write 16bit data */ +INLINE static void +awe_poke(unsigned short cmd, unsigned short port, unsigned short data) +{ + awe_set_cmd(cmd); + OUTW(data, awe_port(port)); +} + +/* write 32bit data */ +INLINE static void +awe_poke_dw(unsigned short cmd, unsigned short port, unsigned long data) +{ + awe_set_cmd(cmd); + OUTW(data, awe_port(port)); /* write lower 16 bits */ + OUTW(data >> 16, awe_port(port)+2); /* write higher 16 bits */ +} + +/* read 16bit data */ +INLINE static unsigned short +awe_peek(unsigned short cmd, unsigned short port) +{ + unsigned short k; + awe_set_cmd(cmd); + k = inw(awe_port(port)); + return k; +} + +/* read 32bit data */ +INLINE static unsigned long +awe_peek_dw(unsigned short cmd, unsigned short port) +{ + unsigned long k1, k2; + awe_set_cmd(cmd); + k1 = inw(awe_port(port)); + k2 = inw(awe_port(port)+2); + k1 |= k2 << 16; + return k1; +} + +/* wait delay number of AWE32 44100Hz clocks */ +static void +awe_wait(unsigned short delay) +{ + unsigned short clock, target; + unsigned short port = awe_port(AWE_WC_Port); + int counter; + + /* sample counter */ + awe_set_cmd(AWE_WC_Cmd); + clock = (unsigned short)inw(port); + target = clock + delay; + counter = 0; + if (target < clock) { + for (; (unsigned short)inw(port) > target; counter++) + if (counter > 65536) + break; + } + for (; (unsigned short)inw(port) < target; counter++) + if (counter > 65536) + break; +} + + +#ifndef AWE_OBSOLETE_VOXWARE + +/*================================================================ + * port check / request + * 0x620-622, 0xA20-A22, 0xE20-E22 + *================================================================*/ + +static int +awe_check_port(void) +{ + return (check_region(awe_port(Data0), 3) || + check_region(awe_port(Data1), 3) || + check_region(awe_port(Data3), 3)); +} + +static void +awe_request_region(void) +{ + request_region(awe_port(Data0), 3, "sound driver (AWE32)"); + request_region(awe_port(Data1), 3, "sound driver (AWE32)"); + request_region(awe_port(Data3), 3, "sound driver (AWE32)"); +} + +static void +awe_release_region(void) +{ + release_region(awe_port(Data0), 3); + release_region(awe_port(Data1), 3); + release_region(awe_port(Data3), 3); +} + +#endif /* !AWE_OBSOLETE_VOXWARE */ + + +/*================================================================ + * AWE32 initialization + *================================================================*/ +static void +awe_initialize(void) +{ + unsigned short data; + DECL_INTR_FLAGS(flags); + + DEBUG(0,printk("AWE32: initializing..\n")); + DISABLE_INTR(flags); + + /* check for an error condition */ + data = awe_peek(AWE_U1); + if (!(data & 0x000F) == 0x000C) { + FATALERR(printk("AWE32: can't initialize AWE32\n")); + } + + /* initialize hardware configuration */ + awe_poke(AWE_HWCF1, 0x0059); + awe_poke(AWE_HWCF2, 0x0020); + + /* disable audio output */ + awe_poke(AWE_HWCF3, 0x0000); + + /* initialize audio channels */ + awe_init_audio(); + + /* initialize init array */ + awe_init_dma(); + awe_init_array(); + + /* check DRAM memory size */ + awe_mem_size = awe_check_dram(); + + /* initialize the FM section of the AWE32 */ + awe_init_fm(); + + /* set up voice envelopes */ + awe_tweak(); + + /* enable audio */ + awe_poke(AWE_HWCF3, 0x0004); + + data = awe_peek(AWE_HWCF2); + if (~data & 0x40) { + FATALERR(printk("AWE32: Unable to initialize AWE32.\n")); + } + + RESTORE_INTR(flags); +} + + +/*================================================================ + * AWE32 voice parameters + *================================================================*/ + +/* initialize voice_info record */ +static void +awe_init_voice_info(awe_voice_info *vp) +{ + vp->sf_id = 0; + vp->sample = 0; + vp->rate_offset = 0; + + vp->start = 0; + vp->end = 0; + vp->loopstart = 0; + vp->loopend = 0; + vp->mode = 0; + vp->root = 60; + vp->tune = 0; + vp->low = 0; + vp->high = 127; + vp->vellow = 0; + vp->velhigh = 127; + + vp->fixkey = -1; + vp->fixvel = -1; + vp->fixpan = -1; + vp->pan = -1; + + vp->exclusiveClass = 0; + vp->amplitude = 127; + vp->attenuation = 0; + vp->scaleTuning = 100; + + awe_init_voice_parm(&vp->parm); +} + +/* initialize voice_parm record: + * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0. + * Vibrato and Tremolo effects are zero. + * Cutoff is maximum. + * Chorus and Reverb effects are zero. + */ +static void +awe_init_voice_parm(awe_voice_parm *pp) +{ + pp->moddelay = 0x8000; + pp->modatkhld = 0x7f7f; + pp->moddcysus = 0x7f7f; + pp->modrelease = 0x807f; + pp->modkeyhold = 0; + pp->modkeydecay = 0; + + pp->voldelay = 0x8000; + pp->volatkhld = 0x7f7f; + pp->voldcysus = 0x7f7f; + pp->volrelease = 0x807f; + pp->volkeyhold = 0; + pp->volkeydecay = 0; + + pp->lfo1delay = 0x8000; + pp->lfo2delay = 0x8000; + pp->pefe = 0; + + pp->fmmod = 0; + pp->tremfrq = 0; + pp->fm2frq2 = 0; + + pp->cutoff = 0xff; + pp->filterQ = 0; + + pp->chorus = 0; + pp->reverb = 0; +} + + +/* convert frequency mHz to abstract cents (= midi key * 100) */ +static int +freq_to_note(int mHz) +{ + /* abscents = log(mHz/8176) / log(2) * 1200 */ + unsigned long max_val = (unsigned long)0xffffffff / 10000; + int i, times; + unsigned long base; + unsigned long freq; + int note, tune; + + if (mHz == 0) + return 0; + if (mHz < 0) + return 12799; /* maximum */ + + freq = mHz; + note = 0; + for (base = 8176 * 2; freq >= base; base *= 2) { + note += 12; + if (note >= 128) /* over maximum */ + return 12799; + } + base /= 2; + + /* to avoid overflow... */ + times = 10000; + while (freq > max_val) { + max_val *= 10; + times /= 10; + base /= 10; + } + + freq = freq * times / base; + for (i = 0; i < 12; i++) { + if (freq < semitone_tuning[i+1]) + break; + note++; + } + + tune = 0; + freq = freq * 10000 / semitone_tuning[i]; + for (i = 0; i < 100; i++) { + if (freq < cent_tuning[i+1]) + break; + tune++; + } + + return note * 100 + tune; +} + + +/* convert Hz to AWE32 rate offset: + * sample pitch offset for the specified sample rate + * rate=44100 is no offset, each 4096 is 1 octave (twice). + * eg, when rate is 22050, this offset becomes -4096. + */ +static int +calc_rate_offset(int Hz) +{ + /* offset = log(Hz / 44100) / log(2) * 4096 */ + int freq, base, i; + + /* maybe smaller than max (44100Hz) */ + if (Hz <= 0 || Hz >= 44100) return 0; + + base = 0; + for (freq = Hz * 2; freq < 44100; freq *= 2) + base++; + base *= 1200; + + freq = 44100 * 10000 / (freq/2); + for (i = 0; i < 12; i++) { + if (freq < semitone_tuning[i+1]) + break; + base += 100; + } + freq = freq * 10000 / semitone_tuning[i]; + for (i = 0; i < 100; i++) { + if (freq < cent_tuning[i+1]) + break; + base++; + } + return -base * 4096 / 1200; +} + + +/*---------------------------------------------------------------- + * convert envelope time parameter to AWE32 raw parameter + *----------------------------------------------------------------*/ + +/* attack & decay/release time table (mHz) */ +static short attack_time_tbl[128] = { +32767, 5939, 3959, 2969, 2375, 1979, 1696, 1484, 1319, 1187, 1079, 989, 913, 848, 791, 742, + 698, 659, 625, 593, 565, 539, 516, 494, 475, 456, 439, 424, 409, 395, 383, 371, + 359, 344, 330, 316, 302, 290, 277, 266, 255, 244, 233, 224, 214, 205, 196, 188, + 180, 173, 165, 158, 152, 145, 139, 133, 127, 122, 117, 112, 107, 103, 98, 94, + 90, 86, 83, 79, 76, 73, 69, 67, 64, 61, 58, 56, 54, 51, 49, 47, + 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 25, 24, 23, + 22, 21, 20, 20, 19, 18, 17, 16, 16, 15, 14, 14, 13, 13, 12, 11, + 11, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 0, +}; + +static short decay_time_tbl[128] = { +32767, 3651, 3508, 3371, 3239, 3113, 2991, 2874, 2761, 2653, 2550, 2450, 2354, 2262, 2174, 2089, + 2007, 1928, 1853, 1781, 1711, 1644, 1580, 1518, 1459, 1401, 1347, 1294, 1243, 1195, 1148, 1103, + 1060, 1018, 979, 940, 904, 868, 834, 802, 770, 740, 711, 683, 657, 631, 606, 582, + 560, 538, 517, 496, 477, 458, 440, 423, 407, 391, 375, 361, 347, 333, 320, 307, + 295, 284, 273, 262, 252, 242, 232, 223, 215, 206, 198, 190, 183, 176, 169, 162, + 156, 150, 144, 138, 133, 128, 123, 118, 113, 109, 104, 100, 96, 93, 89, 85, + 82, 79, 76, 73, 70, 67, 64, 62, 60, 57, 55, 53, 51, 49, 47, 45, + 43, 41, 40, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 0, +}; + +/* +static int +calc_parm_delay(int msec) +{ + return (0x8000 - msec * 1000 / 725); +} +*/ + +static int +calc_parm_hold(int msec) +{ + int val = 0x7f - (unsigned char)(msec / 92); + if (val < 1) val = 1; + if (val > 127) val = 127; + return val; +} + +static int +calc_parm_attack(int msec) +{ + return calc_parm_search(msec, attack_time_tbl); +} + +static int +calc_parm_decay(int msec) +{ + return calc_parm_search(msec, decay_time_tbl); +} + +static int +calc_parm_search(int msec, short *table) +{ + int left = 0, right = 127, mid; + while (left < right) { + mid = (left + right) / 2; + if (msec < (int)table[mid]) + left = mid + 1; + else + right = mid; + } + return left; +} + + +/*================================================================ + * effects table + *================================================================*/ + +/* set an effect value */ +#define FX_SET(v,type,value) \ +(voices[v].fx_flags[(type)/8] |= (1<<((type)%8)),\ + voices[v].fx[type] = (value)) +/* check the effect value is set */ +#define FX_ON(v,type) (voices[v].fx_flags[(type)/8] & (1<<((type)%8))) + +#if 0 +#define FX_BYTE(v,type,value)\ + (FX_ON(v,type) ? (unsigned char)voices[v].fx[type] :\ + (unsigned char)(value)) +#define FX_WORD(v,type,value)\ + (FX_ON(v,type) ? (unsigned short)voices[v].fx[type] :\ + (unsigned short)(value)) + +#else + +/* get byte effect value */ +static unsigned char FX_BYTE(int v, int type, unsigned char value) +{ + unsigned char tmp; + if (FX_ON(v,type)) + tmp = (unsigned char)voices[v].fx[type]; + else + tmp = value; + DEBUG(4,printk("AWE32: [-- byte(%d) = %x]\n", type, tmp)); + return tmp; +} + +/* get word effect value */ +static unsigned short FX_WORD(int v, int type, unsigned short value) +{ + unsigned short tmp; + if (FX_ON(v,type)) + tmp = (unsigned short)voices[v].fx[type]; + else + tmp = value; + DEBUG(4,printk("AWE32: [-- word(%d) = %x]\n", type, tmp)); + return tmp; +} + +#endif + +/* get word (upper=type1/lower=type2) effect value */ +static unsigned short FX_COMB(int v, int type1, int type2, unsigned short value) +{ + unsigned short tmp; + if (FX_ON(v, type1)) + tmp = (unsigned short)(voices[v].fx[type1]) << 8; + else + tmp = value & 0xff00; + if (FX_ON(v, type2)) + tmp |= (unsigned short)(voices[v].fx[type2]) & 0xff; + else + tmp |= value & 0xff; + DEBUG(4,printk("AWE32: [-- comb(%d/%d) = %x]\n", type1, type2, tmp)); + return tmp; +} + +/* address offset */ +static long +FX_OFFSET(int voice, int lo, int hi) +{ + awe_voice_info *vp; + long addr; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return 0; + + addr = 0; + if (FX_ON(voice, hi)) { + addr = (short)voices[voice].fx[hi]; + addr = addr << 15; + } + if (FX_ON(voice, lo)) + addr += (short)voices[voice].fx[lo]; + if (!(vp->mode & (AWE_SAMPLE_8BITS<<6))) + addr /= 2; + return addr; +} + +/* converter function table for realtime paramter change */ + +typedef void (*fx_affect_func)(int voice); +static fx_affect_func fx_realtime[] = { + /* env1: delay, attack, hold, decay, release, sustain, pitch, cutoff*/ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /* env2: delay, attack, hold, decay, release, sustain */ + NULL, NULL, NULL, NULL, NULL, NULL, + /* lfo1: delay, freq, volume, pitch, cutoff */ + NULL, awe_fx_tremfrq, awe_fx_tremfrq, awe_fx_fmmod, awe_fx_fmmod, + /* lfo2: delay, freq, pitch */ + NULL, awe_fx_fm2frq2, awe_fx_fm2frq2, + /* global: initpitch, chorus, reverb, cutoff, filterQ */ + awe_fx_initpitch, NULL, NULL, awe_fx_cutoff, NULL, + /* sample: start, loopstart, loopend */ + NULL, NULL, NULL, +}; + + +/*================================================================ + * turn on/off sample + *================================================================*/ + +static void +awe_note_on(int voice) +{ + unsigned long temp; + long addr; + unsigned short tmp2; + awe_voice_info *vp; + + /* A voice sample must assigned before calling */ + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + + /* channel to be silent and idle */ + awe_poke(AWE_DCYSUSV(voice), 0x0080); + awe_poke(AWE_VTFT(voice), 0); + awe_poke(AWE_CVCF(voice), 0); + awe_poke(AWE_PTRX(voice), 0); + awe_poke(AWE_CPF(voice), 0); + + /* modulation & volume envelope */ + awe_poke(AWE_ENVVAL(voice), + FX_WORD(voice, AWE_FX_ENV1_DELAY, vp->parm.moddelay)); + awe_poke(AWE_ATKHLD(voice), + FX_COMB(voice, AWE_FX_ENV1_ATTACK, AWE_FX_ENV1_HOLD, + vp->parm.modatkhld)); + awe_poke(AWE_DCYSUS(voice), + FX_COMB(voice, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY, + vp->parm.moddcysus)); + awe_poke(AWE_ENVVOL(voice), + FX_WORD(voice, AWE_FX_ENV2_DELAY, vp->parm.voldelay)); + awe_poke(AWE_ATKHLDV(voice), + FX_COMB(voice, AWE_FX_ENV2_ATTACK, AWE_FX_ENV2_HOLD, + vp->parm.volatkhld)); + /* decay/sustain parameter for volume envelope must be set at last */ + + /* pitch offset */ + awe_poke(AWE_IP(voice), voices[voice].apitch); + DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch)); + + /* cutoff and volume */ + tmp2 = FX_BYTE(voice, AWE_FX_CUTOFF, vp->parm.cutoff); + tmp2 = (tmp2 << 8) | voices[voice].avol; + awe_poke(AWE_IFATN(voice), tmp2); + + /* modulation envelope heights */ + awe_poke(AWE_PEFE(voice), + FX_COMB(voice, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF, + vp->parm.pefe)); + + /* lfo1/2 delay */ + awe_poke(AWE_LFO1VAL(voice), + FX_WORD(voice, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay)); + awe_poke(AWE_LFO2VAL(voice), + FX_WORD(voice, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay)); + + /* lfo1 pitch & cutoff shift */ + awe_poke(AWE_FMMOD(voice), + FX_COMB(voice, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF, + vp->parm.fmmod)); + /* lfo1 volume & freq */ + awe_poke(AWE_TREMFRQ(voice), + FX_COMB(voice, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ, + vp->parm.tremfrq)); + /* lfo2 pitch & freq */ + awe_poke(AWE_FM2FRQ2(voice), + FX_COMB(voice, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ, + vp->parm.fm2frq2)); + + /* pan & loop start */ + awe_set_pan(voice, 1); + + /* chorus & loop end (chorus 8bit, MSB) */ + addr = vp->loopend - 1; + addr += FX_OFFSET(voice, AWE_FX_LOOP_END, + AWE_FX_COARSE_LOOP_END); + temp = FX_BYTE(voice, AWE_FX_CHORUS, vp->parm.chorus); + temp = (temp <<24) | (unsigned long)addr; + awe_poke_dw(AWE_CSL(voice), temp); + + /* Q & current address (Q 4bit value, MSB) */ + addr = vp->start - 1; + addr += FX_OFFSET(voice, AWE_FX_SAMPLE_START, + AWE_FX_COARSE_SAMPLE_START); + temp = FX_BYTE(voice, AWE_FX_FILTERQ, vp->parm.filterQ); + temp = (temp<<28) | (unsigned long)addr; + awe_poke_dw(AWE_CCCA(voice), temp); + + /* reset volume */ + awe_poke_dw(AWE_VTFT(voice), 0x0000FFFF); + awe_poke_dw(AWE_CVCF(voice), 0x0000FFFF); + + /* turn on envelope */ + awe_poke(AWE_DCYSUSV(voice), + FX_COMB(voice, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY, + vp->parm.voldcysus)); + /* set chorus */ + temp = FX_BYTE(voice, AWE_FX_REVERB, vp->parm.reverb); + temp = (awe_peek_dw(AWE_PTRX(voice)) & 0xffff0000) | (temp<<8); + awe_poke_dw(AWE_PTRX(voice), temp); + awe_poke_dw(AWE_CPF(voice), 0x40000000); + + DEBUG(3,printk("AWE32: [-- start=%x loop=%x]\n", + (int)vp->start, (int)vp->loopstart)); +} + +/* turn off the voice */ +static void +awe_note_off(int voice) +{ + awe_voice_info *vp; + unsigned short tmp; + if ((vp = voices[voice].sample) == NULL || !voices[voice].state) + return; + if (FX_ON(voice, AWE_FX_ENV1_RELEASE)) + tmp = 0x8000 | voices[voice].fx[AWE_FX_ENV1_RELEASE]; + else + tmp = vp->parm.modrelease; + awe_poke(AWE_DCYSUS(voice), tmp); + if (FX_ON(voice, AWE_FX_ENV2_RELEASE)) + tmp = 0x8000 | voices[voice].fx[AWE_FX_ENV2_RELEASE]; + else + tmp = vp->parm.volrelease; + awe_poke(AWE_DCYSUSV(voice), tmp); +} + +/* force to terminate the voice (no releasing echo) */ +static void +awe_terminate(int voice) +{ + awe_poke(AWE_DCYSUSV(voice), 0x807F); +} + + +/* turn off other voices with the same exclusive class (for drums) */ +static void +awe_exclusive_off(int voice) +{ + int i, excls; + + if (voices[voice].sample == NULL) /* no sample */ + return; + excls = voices[voice].sample->exclusiveClass; + if (excls == 0) /* not exclusive */ + return; + + /* turn off voices with the same class */ + for (i = 0; i < awe_max_voices; i++) { + if (i != voice && voices[voice].state && + voices[i].sample && + voices[i].sample->exclusiveClass == excls) { + DEBUG(4,printk("AWE32: [exoff(%d)]\n", i)); + awe_note_off(i); + awe_voice_init(i, 1); + } + } +} + + +/*================================================================ + * change the parameters of an audible voice + *================================================================*/ + +/* change pitch */ +static void +awe_set_pitch(int voice) +{ + if (!voices[voice].state) return; + awe_poke(AWE_IP(voice), voices[voice].apitch); +} + +/* change volume */ +static void +awe_set_volume(int voice) +{ + awe_voice_info *vp; + unsigned short tmp2; + if (!voices[voice].state) return; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + tmp2 = FX_BYTE(voice, AWE_FX_CUTOFF, vp->parm.cutoff); + tmp2 = (tmp2 << 8) | voices[voice].avol; + awe_poke(AWE_IFATN(voice), tmp2); +} + +/* change pan; this could make a click noise.. */ +static void +awe_set_pan(int voice, int forced) +{ + unsigned long temp; + long addr; + awe_voice_info *vp; + + if (!voices[voice].state && !forced) return; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + + /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */ + if (vp->fixpan > 0) /* 0-127 */ + temp = 255 - (int)vp->fixpan * 2; + else { + int pos = 0; + if (vp->pan >= 0) /* 0-127 */ + pos = (int)vp->pan * 2 - 128; + pos += voices[voice].panning; /* -128 - 127 */ + pos = 127 - pos; + if (pos < 0) + temp = 0; + else if (pos > 255) + temp = 255; + else + temp = pos; + } + addr = vp->loopstart - 1; + addr += FX_OFFSET(voice, AWE_FX_LOOP_START, + AWE_FX_COARSE_LOOP_START); + temp = (temp<<24) | (unsigned long)addr; + awe_poke_dw(AWE_PSST(voice), temp); +} + +/* effects change during playing */ +static void +awe_fx_fmmod(int voice) +{ + awe_voice_info *vp; + if (!voices[voice].state) return; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + awe_poke(AWE_FMMOD(voice), + FX_COMB(voice, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF, + vp->parm.fmmod)); +} + +static void +awe_fx_tremfrq(int voice) +{ + awe_voice_info *vp; + if (!voices[voice].state) return; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + awe_poke(AWE_TREMFRQ(voice), + FX_COMB(voice, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ, + vp->parm.tremfrq)); +} + +static void +awe_fx_fm2frq2(int voice) +{ + awe_voice_info *vp; + if (!voices[voice].state) return; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + awe_poke(AWE_FM2FRQ2(voice), + FX_COMB(voice, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ, + vp->parm.fm2frq2)); +} + +static void +awe_fx_cutoff(int voice) +{ + unsigned short tmp2; + awe_voice_info *vp; + if (!voices[voice].state) return; + if ((vp = voices[voice].sample) == NULL || vp->index < 0) + return; + tmp2 = FX_BYTE(voice, AWE_FX_CUTOFF, vp->parm.cutoff); + tmp2 = (tmp2 << 8) | voices[voice].avol; + awe_poke(AWE_IFATN(voice), tmp2); +} + +static void +awe_fx_initpitch(int voice) +{ + if (!voices[voice].state) return; + if (FX_ON(voice, AWE_FX_INIT_PITCH)) { + DEBUG(3,printk("AWE32: initpitch ok\n")); + } else { + DEBUG(3,printk("AWE32: BAD initpitch %d\n", AWE_FX_INIT_PITCH)); + } + awe_calc_pitch(voice); + awe_poke(AWE_IP(voice), voices[voice].apitch); +} + + +/*================================================================ + * calculate pitch offset + *---------------------------------------------------------------- + * 0xE000 is no pitch offset at 44100Hz sample. + * Every 4096 is one octave. + *================================================================*/ + +static void +awe_calc_pitch(int voice) +{ + voice_info *vp = &voices[voice]; + awe_voice_info *ap; + int offset; + + /* search voice information */ + if ((ap = vp->sample) == NULL) + return; + if (ap->index < 0) { + if (awe_set_sample(ap) < 0) + return; + } + + /* calculate offset */ + if (ap->fixkey >= 0) { + DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune)); + offset = (ap->fixkey - ap->root) * 4096 / 12; + } else { + DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune)); + offset = (vp->note - ap->root) * 4096 / 12; + DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset)); + } + offset += ap->tune * 4096 / 1200; + DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset)); + if (vp->bender != 0) { + DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, vp->bender)); + /* (819200: 1 semitone) ==> (4096: 12 semitones) */ + offset += vp->bender * vp->bender_range / 2400; + } + offset = (offset * ap->scaleTuning) / 100; + DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset)); + + /* add initial pitch correction */ + if (FX_ON(voice, AWE_FX_INIT_PITCH)) { + DEBUG(3,printk("AWE32: fx_pitch(%d) %d\n", voice, vp->fx[AWE_FX_INIT_PITCH])); + offset += vp->fx[AWE_FX_INIT_PITCH]; + } + + /* 0xe000: root pitch */ + vp->apitch = 0xe000 + ap->rate_offset + offset; + DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset)); + if (vp->apitch > 0xffff) + vp->apitch = 0xffff; + if (vp->apitch < 0) + vp->apitch = 0; +} + + +static void +awe_calc_pitch_from_freq(int voice, int freq) +{ + voice_info *vp = &voices[voice]; + awe_voice_info *ap; + int offset; + int note; + + /* search voice information */ + if ((ap = vp->sample) == NULL) + return; + if (ap->index < 0) { + if (awe_set_sample(ap) < 0) + return; + } + note = freq_to_note(freq); + offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200; + offset = (offset * ap->scaleTuning) / 100; + if (FX_ON(voice, AWE_FX_INIT_PITCH)) + offset += vp->fx[AWE_FX_INIT_PITCH]; + vp->apitch = 0xe000 + ap->rate_offset + offset; + if (vp->apitch > 0xffff) + vp->apitch = 0xffff; + if (vp->apitch < 0) + vp->apitch = 0; +} + +/*================================================================ + * calculate volume attenuation + *---------------------------------------------------------------- + * Voice volume is controlled by volume attenuation parameter. + * So volume becomes maximum when avol is 0 (no attenuation), and + * minimum when 255 (-96dB or silence). + *================================================================*/ + +static int vol_table[128] = { + 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49, + 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32, + 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22, + 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16, + 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10, + 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6, + 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3, + 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0, +}; + +static void +awe_calc_volume(int voice) +{ + voice_info *vp = &voices[voice]; + awe_voice_info *ap; + int vol; + + /* search voice information */ + if ((ap = vp->sample) == NULL) + return; + + ap = vp->sample; + if (ap->index < 0) { + if (awe_set_sample(ap) < 0) + return; + } + + if (vp->velocity < ap->vellow) + vp->velocity = ap->vellow; + else if (vp->velocity > ap->velhigh) + vp->velocity = ap->velhigh; + + /* 0 - 127 */ + vol = (vp->velocity * vp->main_vol * vp->expression_vol) / (127*127); + vol = vol * ap->amplitude / 127; + if (vol < 0) vol = 0; + if (vol > 127) vol = 127; + + /* calc to attenuation */ + vol = vol_table[vol]; + vol = vol + (int)ap->attenuation + init_atten; + if (vol > 255) vol = 255; + + vp->avol = vol; + DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol)); +} + + +/*================================================================ + * synth operation routines + *================================================================*/ + +/* initialize the voice */ +static void +awe_voice_init(int voice, int inst_only) +{ + if (! inst_only) { + /* clear voice parameters */ + voices[voice].note = -1; + voices[voice].velocity = 0; + voices[voice].panning = 0; /* zero center */ + voices[voice].bender = 0; /* zero tune skew */ + voices[voice].bender_range = 200; /* sense * 100 */ + voices[voice].main_vol = 127; + voices[voice].expression_vol = 127; + voices[voice].bank = AWE_DEFAULT_BANK; + voices[voice].instr = -1; + voices[voice].vrec = NULL; + voices[voice].sample = NULL; + } + + /* clear voice mapping */ + voices[voice].state = 0; + voice_alloc->map[voice] = 0; + + /* emu8000 parameters */ + voices[voice].apitch = 0; + voices[voice].avol = 255; + + /* clear effects */ + BZERO(voices[voice].fx_flags, sizeof(voices[voice].fx_flags)); +} + + +/*---------------------------------------------------------------- + * device open / close + *----------------------------------------------------------------*/ + +/* open device: + * reset status of all voices, and clear sample position flag + */ +static int +awe_open(int dev, int mode) +{ + if (awe_busy) + return RET_ERROR(EBUSY); + + awe_busy = 1; + awe_reset(dev); + + /* clear sample position flag */ + loaded_once = 0; + + /* set GUS bank to default */ + awe_gus_bank = AWE_DEFAULT_BANK; + return 0; +} + + +/* close device: + * reset all voices again (terminate sounds) + */ +static void +awe_close(int dev) +{ + awe_reset(dev); + awe_busy = 0; +} + + +/* sequencer I/O control: + */ +static int +awe_ioctl(int dev, unsigned int cmd, caddr_t arg) +{ + switch (cmd) { + case SNDCTL_SYNTH_INFO: + awe_info.nr_voices = awe_max_voices; + IOCTL_TO_USER((char*)arg, 0, &awe_info, sizeof(awe_info)); + return 0; + break; + + case SNDCTL_SEQ_RESETSAMPLES: + awe_reset_samples(); + awe_reset(dev); /* better to reset emu8k chip... */ + return 0; + break; + + case SNDCTL_SEQ_PERCMODE: + /* what's this? */ + return 0; + break; + + case SNDCTL_SYNTH_MEMAVL: + DEBUG(0,printk("AWE32: [ioctl memavl = %d]\n", (int)free_mem_ptr)); + return awe_mem_size - free_mem_ptr*2; + + default: + ERRMSG(printk("AWE32: unsupported ioctl %d\n", cmd)); + return RET_ERROR(EINVAL); + } +} + + +/* kill a voice: + * not terminate, just release the voice. + */ +static int +awe_kill_note(int dev, int voice, int note, int velocity) +{ + awe_voice_info *vp; + DECL_INTR_FLAGS(flags); + + DEBUG(2,printk("AWE32: [off(%d)]\n", voice)); + if (voice < 0 || voice >= awe_max_voices) + return RET_ERROR(EINVAL); + if ((vp = voices[voice].sample) == NULL) + return 0; + + if (!(vp->mode & AWE_MODE_NORELEASE)) { + DISABLE_INTR(flags); + awe_note_off(voice); + RESTORE_INTR(flags); + } + awe_voice_init(voice, 1); + return 0; +} + + +/* search the note with the specified key range */ +static awe_voice_info * +awe_search_voice(int voice, int note) +{ + awe_voice_list *rec; + int maxc; + + for (rec = voices[voice].vrec, maxc = AWE_MAX_INFOS; + rec && maxc; rec = rec->next_instr, maxc--) { + if (rec->v.low <= note && note <= rec->v.high) + return &rec->v; + } + return NULL; +} + +/* start a voice: + * if note is 255, identical with aftertouch function. + * Otherwise, start a voice with specified not and volume. + */ +static int +awe_start_note(int dev, int v, int note_num, int volume) +{ + DECL_INTR_FLAGS(flags); + + DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", v, note_num, volume)); + if (v < 0 || v >= awe_max_voices) + return RET_ERROR(EINVAL); + /* an instrument must be set before starting a note */ + if (voices[v].vrec == NULL) { + DEBUG(1,printk("AWE32: [-- vrec is null]\n")); + return 0; + } + + if (note_num == 255) { + /* dynamic volume change; sample is already assigned */ + if (! voices[v].state || voices[v].sample == NULL) + return 0; + /* calculate volume parameter */ + voices[v].velocity = volume; + awe_calc_volume(v); + DISABLE_INTR(flags); + awe_set_volume(v); + RESTORE_INTR(flags); + return 0; + } + /* assign a sample with the corresponding note */ + if ((voices[v].sample = awe_search_voice(v, note_num)) == NULL) { + DEBUG(1,printk("AWE32: [-- sample is null]\n")); + return 0; + } + /* calculate pitch & volume parameters */ + voices[v].note = note_num; + voices[v].velocity = volume; + awe_calc_pitch(v); + awe_calc_volume(v); + + DISABLE_INTR(flags); + /* turn off other voices (for drums) */ + awe_exclusive_off(v); + /* turn on the voice */ + awe_note_on(v); + voices[v].state = 1; /* flag up */ + RESTORE_INTR(flags); + + return 0; +} + + +/* search instrument from preset table with the specified bank */ +static awe_voice_list * +awe_search_instr(int bank, int preset) +{ + awe_voice_list *p; + int maxc; + + for (maxc = AWE_MAX_INFOS, p = preset_table[preset]; + p && maxc; p = p->next_bank, maxc--) { + if (p->bank == bank) + return p; + } + return NULL; +} + + +/* assign the instrument to a voice */ +static int +awe_set_instr(int dev, int voice, int instr_no) +{ + awe_voice_list *rec; + + if (voice < 0 || voice >= awe_max_voices) + return RET_ERROR(EINVAL); + + if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS) + return RET_ERROR(EINVAL); + + if ((rec = awe_search_instr(voices[voice].bank, instr_no)) == NULL) { + /* if bank is not defined, use the default bank 0 */ + if (voices[voice].bank != AWE_DEFAULT_BANK && + (rec = awe_search_instr(AWE_DEFAULT_BANK, instr_no)) == NULL) { + DEBUG(1,printk("AWE32 Warning: can't find instrument %d\n", instr_no)); + return 0; + } + } + + voices[voice].instr = instr_no; + voices[voice].vrec = rec; + voices[voice].sample = NULL; /* not set yet */ + + return 0; +} + + +/* reset all voices; terminate sounds and initialize parameters */ +static void +awe_reset(int dev) +{ + int i; + /* don't turn off voice 31 and 32. they are used also for FM voices */ + for (i = 0; i < AWE_NORMAL_VOICES; i++) { + awe_terminate(i); + awe_voice_init(i, 0); + } + awe_init_fm(); + awe_tweak(); +} + + +/* hardware specific control: + * GUS specific and AWE32 specific controls are available. + */ +static void +awe_hw_control(int dev, unsigned char *event) +{ + int cmd = event[2]; + if (cmd & _AWE_MODE_FLAG) + awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event); + else + awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event); +} + +/* GUS compatible controls */ +static void +awe_hw_gus_control(int dev, int cmd, unsigned char *event) +{ + int voice; + unsigned short p1; + short p2; + int plong; + DECL_INTR_FLAGS(flags); + + voice = event[3]; + p1 = *(unsigned short *) &event[4]; + p2 = *(short *) &event[6]; + plong = *(int*) &event[4]; + + switch (cmd) { + case _GUS_NUMVOICES: + if (p1 >= awe_max_voices) + printk("AWE32: num_voices: voices out of range %d\n", p1); + break; + case _GUS_VOICESAMPLE: + if (voice < awe_max_voices) + awe_set_instr(dev, voice, p1); + break; + + case _GUS_VOICEON: + if (voice < awe_max_voices) { + DISABLE_INTR(flags); + awe_note_on(voice); + RESTORE_INTR(flags); + } + break; + + case _GUS_VOICEOFF: + if (voice < awe_max_voices) { + DISABLE_INTR(flags); + awe_note_off(voice); + RESTORE_INTR(flags); + } + break; + + case _GUS_VOICEMODE: + /* not supported */ + break; + + case _GUS_VOICEBALA: + /* -128 to 127 */ + if (voice < awe_max_voices) + awe_panning(dev, voice, (short)p1); + break; + + case _GUS_VOICEFREQ: + if (voice < awe_max_voices) + awe_calc_pitch_from_freq(voice, plong); + break; + + case _GUS_VOICEVOL: + case _GUS_VOICEVOL2: + /* not supported yet */ + break; + + case _GUS_RAMPRANGE: + case _GUS_RAMPRATE: + case _GUS_RAMPMODE: + case _GUS_RAMPON: + case _GUS_RAMPOFF: + /* volume ramping not supported */ + break; + + case _GUS_VOLUME_SCALE: + break; + + case _GUS_VOICE_POS: + if (voice < awe_max_voices) { + FX_SET(voice, AWE_FX_SAMPLE_START, (short)(plong & 0x7fff)); + FX_SET(voice, AWE_FX_COARSE_SAMPLE_START, (plong >> 15) & 0xffff); + } + break; + } +} + + +/* AWE32 specific controls */ +static void +awe_hw_awe_control(int dev, int cmd, unsigned char *event) +{ + int voice; + unsigned short p1; + short p2; + int chn; + + chn = event[1]; + voice = event[3]; + p1 = *(unsigned short *) &event[4]; + p2 = *(short *) &event[6]; + + +#ifdef AWE_DEBUG_ON + switch (cmd) { + case _AWE_DEBUG_MODE: + debug_mode = p1; + printk("AWE32: debug mode = %d\n", debug_mode); + break; +#endif + case _AWE_REVERB_MODE: + if (p1 <= 7) { + reverb_mode = p1; + DEBUG(0,printk("AWE32: reverb mode %d\n", reverb_mode)); + awe_set_reverb_mode(reverb_mode); + } + break; + + case _AWE_CHORUS_MODE: + if (p1 <= 7) { + chorus_mode = p1; + DEBUG(0,printk("AWE32: chorus mode %d\n", chorus_mode)); + awe_set_chorus_mode(chorus_mode); + } + break; + + case _AWE_REMOVE_LAST_SAMPLES: + DEBUG(0,printk("AWE32: remove last samples\n")); + awe_remove_samples(); + break; + + case _AWE_INITIALIZE_CHIP: + awe_initialize(); + break; + + case _AWE_SEND_EFFECT: + if (voice < awe_max_voices && p1 < AWE_FX_END) { + FX_SET(voice, p1, p2); + DEBUG(0,printk("AWE32: effects (%d) %d %d\n", voice, p1, voices[voice].fx[p1])); + if (fx_realtime[p1]) { + DEBUG(0,printk("AWE32: fx_realtime (%d)\n", voice)); + fx_realtime[p1](voice); + } + } + break; + + case _AWE_TERMINATE_CHANNEL: + if (voice < awe_max_voices) { + DEBUG(0,printk("AWE32: terminate (%d)\n", voice)); + awe_terminate(voice); + awe_voice_init(voice, 1); + } + break; + + case _AWE_TERMINATE_ALL: + DEBUG(0,printk("AWE32: terminate all\n")); + awe_reset(0); + break; + + case _AWE_INITIAL_VOLUME: + DEBUG(0,printk("AWE32: init attenuation %d\n", p1)); + init_atten = p1; + break; + + case _AWE_SET_GUS_BANK: + DEBUG(0,printk("AWE32: set gus bank %d\n", p1)); + awe_gus_bank = p1; + break; + + default: + DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice)); + break; + } +} + + +/*---------------------------------------------------------------- + * load a sound patch: + * three types of patches are accepted: AWE, GUS, and SYSEX. + *----------------------------------------------------------------*/ + +static int +awe_load_patch(int dev, int format, const char *addr, + int offs, int count, int pmgr_flag) +{ + awe_patch_info patch; + int rc = 0; + + if (format == GUS_PATCH) { + return awe_load_guspatch(addr, offs, count, pmgr_flag); + } else if (format == SYSEX_PATCH) { + /* no system exclusive message supported yet */ + return 0; + } else if (format != AWE_PATCH) { + FATALERR(printk("AWE32 Error: Invalid patch format (key) 0x%x\n", format)); + return RET_ERROR(EINVAL); + } + + if (count < sizeof(awe_patch_info)) { + FATALERR(printk("AWE32 Error: Patch header too short\n")); + return RET_ERROR(EINVAL); + } + COPY_FROM_USER(((char*)&patch) + offs, addr, offs, + sizeof(awe_patch_info) - offs); + + count -= sizeof(awe_patch_info); + if (count < patch.len) { + FATALERR(printk("AWE32 Warning: Patch record too short (%d<%d)\n", + count, (int)patch.len)); + patch.len = count; + } + + switch (patch.type) { + case AWE_LOAD_INFO: + rc = awe_load_info(&patch, addr); + break; + + case AWE_LOAD_DATA: + rc = awe_load_data(&patch, addr); + /* + if (!pmgr_flag && rc == 0) + pmgr_inform(dev, PM_E_PATCH_LOADED, instr, free_sample, 0, 0); + */ + break; + + default: + FATALERR(printk("AWE32 Error: unknown patch format type %d\n", + patch.type)); + rc = RET_ERROR(EINVAL); + } + + return rc; +} + + +/* load voice information data */ +static int +awe_load_info(awe_patch_info *patch, const char *addr) +{ + awe_voice_list *rec, *curp; + long offset; + short i, nvoices; + unsigned char bank, instr; + int total_size; + + if (patch->len < sizeof(awe_voice_rec)) { + FATALERR(printk("AWE32 Error: invalid patch info length\n")); + return RET_ERROR(EINVAL); + } + + offset = sizeof(awe_patch_info); + GET_BYTE_FROM_USER(bank, addr, offset); offset++; + GET_BYTE_FROM_USER(instr, addr, offset); offset++; + GET_SHORT_FROM_USER(nvoices, addr, offset); offset+=2; + + if (nvoices <= 0 || nvoices >= 100) { + FATALERR(printk("AWE32 Error: Illegal voice number %d\n", nvoices)); + return RET_ERROR(EINVAL); + } + if (free_info + nvoices > AWE_MAX_INFOS) { + ERRMSG(printk("AWE32 Error: Too many voice informations\n")); + return RET_ERROR(ENOSPC); + } + + total_size = sizeof(awe_voice_rec) + sizeof(awe_voice_info) * nvoices; + if (patch->len < total_size) { + ERRMSG(printk("AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n", + (int)patch->len, nvoices)); + return RET_ERROR(EINVAL); + } + + curp = awe_search_instr(bank, instr); + for (i = 0; i < nvoices; i++) { + rec = &infos[free_info + i]; + + rec->bank = bank; + rec->instr = instr; + if (i < nvoices - 1) + rec->next_instr = rec + 1; + else + rec->next_instr = curp; + rec->next_bank = NULL; + + /* copy awe_voice_info parameters */ + COPY_FROM_USER(&rec->v, addr, offset, sizeof(awe_voice_info)); + offset += sizeof(awe_voice_info); + rec->v.sf_id = current_sf_id; + if (rec->v.mode & AWE_MODE_INIT_PARM) + awe_init_voice_parm(&rec->v.parm); + awe_set_sample(&rec->v); + } + + /* prepend to top of the list */ + infos[free_info].next_bank = preset_table[instr]; + preset_table[instr] = &infos[free_info]; + free_info += nvoices; + + return 0; +} + + +/* load wave sample data */ +static int +awe_load_data(awe_patch_info *patch, const char *addr) +{ + long offset; + int size; + int rc; + + if (free_sample >= AWE_MAX_SAMPLES) { + ERRMSG(printk("AWE32 Error: Sample table full\n")); + return RET_ERROR(ENOSPC); + } + + size = (patch->len - sizeof(awe_sample_info)) / 2; + offset = sizeof(awe_patch_info); + COPY_FROM_USER(&samples[free_sample], addr, offset, + sizeof(awe_sample_info)); + offset += sizeof(awe_sample_info); + if (size != samples[free_sample].size) { + ERRMSG(printk("AWE32 Warning: sample size differed (%d != %d)\n", + (int)samples[free_sample].size, (int)size)); + samples[free_sample].size = size; + } + if (samples[free_sample].size > 0) + if ((rc = awe_write_wave_data(addr, offset, size)) != 0) + return rc; + + awe_check_loaded(); + samples[free_sample].sf_id = current_sf_id; + + free_sample++; + return 0; +} + +/* check the other samples are already loaded */ +static void +awe_check_loaded(void) +{ + if (!loaded_once) { + /* it's the first time */ + last_sample = free_sample; + last_info = free_info; + current_sf_id++; + loaded_once = 1; + } +} + + +/*----------------------------------------------------------------*/ + +static const char *readbuf_addr; +static long readbuf_offs; +static int readbuf_flags; + +#ifdef AWE_USE_BUFFERED_IO + +#define TMP_WAVBUF_SIZE 4096 +static unsigned short readbuf[TMP_WAVBUF_SIZE]; +static int readbuf_size, readbuf_cur, readbuf_left; + +/* read through temporary buffer */ +static unsigned short +awe_readbuf_word(int pos) +{ + if (readbuf_left <= 0) { + int i; + if (readbuf_size - pos < TMP_WAVBUF_SIZE) + readbuf_left = readbuf_size - pos; + else + readbuf_left = TMP_WAVBUF_SIZE; + /* read from user buffer */ + if (readbuf_flags & AWE_SAMPLE_8BITS) { + unsigned char *pbuf = (unsigned char *)readbuf; + COPY_FROM_USER(pbuf, readbuf_addr, + readbuf_offs + pos, readbuf_left); + /* convert 8bit -> 16bit */ + for (i = readbuf_left - 1; i >= 0; i--) + readbuf[i] = pbuf[i] << 8; + } else { + COPY_FROM_USER(readbuf, readbuf_addr, + readbuf_offs + pos * 2, readbuf_left*2); + } + + if (readbuf_flags & AWE_SAMPLE_UNSIGNED) { + /* unsigned -> signed */ + for (i = 0; i < readbuf_left; i++) + readbuf[i] ^= 0x8000; + } + readbuf_cur = 0; + } + + readbuf_left--; + return readbuf[readbuf_cur++]; +} + +#else /* AWE_USE_BUFFERED_IO */ + +#define awe_readbuf_word(pos) awe_read_word(pos) + +#endif /* AWE_USE_BUFFERED_IO */ + + +/* initialize read buffer */ +static void +awe_init_readbuf(const char *addr, long offset, int size, int mode_flags) +{ + readbuf_addr = addr; + readbuf_offs = offset; + readbuf_flags = mode_flags; +#ifdef AWE_USE_BUFFERED_IO + readbuf_size = size; + readbuf_left = 0; + readbuf_cur = 0; +#endif +} + +/* read directly from user buffer */ +static unsigned short +awe_read_word(int pos) +{ + unsigned short c; + /* read from user buffer */ + if (readbuf_flags & AWE_SAMPLE_8BITS) { + unsigned char cc; + GET_BYTE_FROM_USER(cc, readbuf_addr, readbuf_offs + pos); + c = cc << 8; /* convert 8bit -> 16bit */ + } else { + GET_SHORT_FROM_USER(c, readbuf_addr, readbuf_offs + pos * 2); + } + if (readbuf_flags & AWE_SAMPLE_UNSIGNED) + c ^= 0x8000; /* unsigned -> signed */ + return c; +} + + + +#define BLANK_LOOP_START 8 +#define BLANK_LOOP_END 40 +#define BLANK_LOOP_SIZE 48 + +/* loading onto memory */ +static int +awe_write_wave_data(const char *addr, long offset, int size) +{ + awe_sample_info *sp = &samples[free_sample]; + int i, truesize; + int rc; + unsigned long csum1, csum2; + DECL_INTR_FLAGS(flags); + + /* be sure loop points start < end */ + if (sp->loopstart > sp->loopend) { + long tmp = sp->loopstart; + sp->loopstart = sp->loopend; + sp->loopend = tmp; + } + + /* compute true data size to be loaded */ + truesize = size; + if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) + truesize += sp->loopend - sp->loopstart; + if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) + truesize += BLANK_LOOP_SIZE; + if (size > 0 && free_mem_ptr + truesize >= awe_mem_size/2) { + ERRMSG(printk("AWE32 Error: Sample memory full\n")); + return RET_ERROR(ENOSPC); + } + + /* recalculate address offset */ + sp->end -= sp->start; + sp->loopstart -= sp->start; + sp->loopend -= sp->start; + sp->size = truesize; + + sp->start = free_mem_ptr + AWE_DRAM_OFFSET; + sp->end += free_mem_ptr + AWE_DRAM_OFFSET; + sp->loopstart += free_mem_ptr + AWE_DRAM_OFFSET; + sp->loopend += free_mem_ptr + AWE_DRAM_OFFSET; + + DISABLE_INTR(flags); + if ((rc = awe_open_dram_for_write(free_mem_ptr)) != 0) { + RESTORE_INTR(flags); + return rc; + } + + awe_init_readbuf(addr, offset, size, sp->mode_flags); + csum1 = 0; + for (i = 0; i < size; i++) { + unsigned short c; + c = awe_readbuf_word(i); + csum1 += c; + awe_write_dram(c); + if (i == sp->loopend && + (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP)) { + int looplen = sp->loopend - sp->loopstart; + /* copy reverse loop */ + int k; + for (k = 0; k < looplen; k++) { + /* non-buffered data */ + c = awe_read_word(i - k); + awe_write_dram(c); + } + } + } + + /* if no blank loop is attached in the sample, add it */ + if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) { + for (i = 0; i < BLANK_LOOP_SIZE; i++) + awe_write_dram(0); + if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) { + sp->loopstart = sp->end + BLANK_LOOP_START; + sp->loopend = sp->end + BLANK_LOOP_END; + } + sp->size += BLANK_LOOP_SIZE; + } + + awe_close_dram(); + RESTORE_INTR(flags); + if (sp->checksum_flag) { +#ifdef AWE_CHECKSUM_DATA + if (sp->checksum_flag != 2 && csum1 != sp->checksum) { + ERRMSG(printk("AWE32: [%d] checksum mismatch on data %x:%x\n", + free_sample, + (int)samples[free_sample].checksum, + (int)csum1)); + return RET_ERROR(NO_DATA_ERR); + } +#endif /* AWE_CHECKSUM_DATA */ +#ifdef AWE_CHECKSUM_MEMORY + DISABLE_INTR(flags); + if (awe_open_dram_for_read(free_mem_ptr) == 0) { + csum2 = 0; + for (i = 0; i < size; i++) { + unsigned short c; + c = awe_peek(AWE_SMLD); + csum2 += c; + } + awe_close_dram_for_read(); + if (csum2 != samples[free_sample].checksum) { + RESTORE_INTR(flags); + ERRMSG(printk("AWE32: [%d] checksum mismatch on DRAM %x:%x\n", + free_sample, + (int)samples[free_sample].checksum, + (int)csum2)); + return RET_ERROR(NO_DATA_ERR); + } + } + RESTORE_INTR(flags); +#endif /* AWE_CHECKSUM_MEMORY */ + } + free_mem_ptr += sp->size; + + /* re-initialize FM passthrough */ + DISABLE_INTR(flags); + awe_init_fm(); + awe_tweak(); + RESTORE_INTR(flags); + + return 0; +} + + +/* calculate GUS envelope time: + * is this correct? i have no idea.. + */ +static int +calc_gus_envelope_time(int rate, int start, int end) +{ + int r, p, t; + r = (3 - ((rate >> 6) & 3)) * 3; + p = rate & 0x3f; + t = end - start; + if (t < 0) t = -t; + if (13 > r) + t = t << (13 - r); + else + t = t >> (r - 13); + return (t * 10) / (p * 441); +} + +#define calc_gus_sustain(val) (0x7f - vol_table[(val)/2]) +#define calc_gus_attenuation(val) vol_table[(val)/2] + +/* load GUS patch */ +static int +awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag) +{ + struct patch_info patch; + awe_voice_list *rec, *curp; + long sizeof_patch; + int note; + int rc; + + sizeof_patch = (long)&patch.data[0] - (long)&patch; /* header size */ + if (free_sample >= AWE_MAX_SAMPLES) { + ERRMSG(printk("AWE32 Error: Sample table full\n")); + return RET_ERROR(ENOSPC); + } + if (free_info >= AWE_MAX_INFOS) { + ERRMSG(printk("AWE32 Error: Too many voice informations\n")); + return RET_ERROR(ENOSPC); + } + if (size < sizeof_patch) { + ERRMSG(printk("AWE32 Error: Patch header too short\n")); + return RET_ERROR(EINVAL); + } + COPY_FROM_USER(((char*)&patch) + offs, addr, offs, sizeof_patch - offs); + size -= sizeof_patch; + if (size < patch.len) { + FATALERR(printk("AWE32 Warning: Patch record too short (%d<%d)\n", + size, (int)patch.len)); + patch.len = size; + } + + samples[free_sample].sf_id = 0; + samples[free_sample].sample = free_sample; + samples[free_sample].start = 0; + samples[free_sample].end = patch.len; + samples[free_sample].loopstart = patch.loop_start; + samples[free_sample].loopend = patch.loop_end; + samples[free_sample].size = patch.len; + + /* set up mode flags */ + samples[free_sample].mode_flags = 0; + if (!(patch.mode & WAVE_16_BITS)) + samples[free_sample].mode_flags |= AWE_SAMPLE_8BITS; + if (patch.mode & WAVE_UNSIGNED) + samples[free_sample].mode_flags |= AWE_SAMPLE_UNSIGNED; + samples[free_sample].mode_flags |= AWE_SAMPLE_NO_BLANK; + if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP))) + samples[free_sample].mode_flags |= AWE_SAMPLE_SINGLESHOT; + if (patch.mode & WAVE_BIDIR_LOOP) + samples[free_sample].mode_flags |= AWE_SAMPLE_BIDIR_LOOP; + + DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, + samples[free_sample].mode_flags)); + if (patch.mode & WAVE_16_BITS) { + /* convert to word offsets */ + samples[free_sample].size /= 2; + samples[free_sample].end /= 2; + samples[free_sample].loopstart /= 2; + samples[free_sample].loopend /= 2; + } + samples[free_sample].checksum_flag = 0; + samples[free_sample].checksum = 0; + + if ((rc = awe_write_wave_data(addr, sizeof_patch, + samples[free_sample].size)) != 0) + return rc; + + awe_check_loaded(); + samples[free_sample].sf_id = current_sf_id; + free_sample++; + + /* set up voice info */ + rec = &infos[free_info]; + awe_init_voice_info(&rec->v); + rec->v.sf_id = current_sf_id; + rec->v.sample = free_sample - 1; /* the last sample */ + rec->v.rate_offset = calc_rate_offset(patch.base_freq); + note = freq_to_note(patch.base_note); + rec->v.root = note / 100; + rec->v.tune = -(note % 100); + rec->v.low = freq_to_note(patch.low_note) / 100; + rec->v.high = freq_to_note(patch.high_note) / 100; + DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n", + rec->v.rate_offset, note, + rec->v.low, rec->v.high, + patch.low_note, patch.high_note)); + /* panning position; -128 - 127 => 0-127 */ + rec->v.pan = (patch.panning + 128) / 2; + + /* detuning is ignored */ + /* 6points volume envelope */ + if (patch.mode & WAVE_ENVELOPES) { + int attack, hold, decay, release; + attack = calc_gus_envelope_time + (patch.env_rate[0], 0, patch.env_offset[0]); + hold = calc_gus_envelope_time + (patch.env_rate[1], patch.env_offset[0], + patch.env_offset[1]); + decay = calc_gus_envelope_time + (patch.env_rate[2], patch.env_offset[1], + patch.env_offset[2]); + release = calc_gus_envelope_time + (patch.env_rate[3], patch.env_offset[1], + patch.env_offset[4]); + release += calc_gus_envelope_time + (patch.env_rate[4], patch.env_offset[3], + patch.env_offset[4]); + release += calc_gus_envelope_time + (patch.env_rate[5], patch.env_offset[4], + patch.env_offset[5]); + rec->v.parm.volatkhld = (calc_parm_attack(attack) << 8) | + calc_parm_hold(hold); + rec->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) | + calc_parm_decay(decay); + rec->v.parm.volrelease = 0x8000 | calc_parm_decay(release); + DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release)); + rec->v.attenuation = calc_gus_attenuation(patch.env_offset[0]); + } + + /* tremolo effect */ + if (patch.mode & WAVE_TREMOLO) { + int rate = (patch.tremolo_rate * 1000 / 38) / 42; + rec->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate; + DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n", + patch.tremolo_rate, patch.tremolo_depth, + rec->v.parm.tremfrq)); + } + /* vibrato effect */ + if (patch.mode & WAVE_VIBRATO) { + int rate = (patch.vibrato_rate * 1000 / 38) / 42; + rec->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate; + DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n", + patch.tremolo_rate, patch.tremolo_depth, + rec->v.parm.tremfrq)); + } + + /* scale_freq, scale_factor, volume, and fractions not implemented */ + + /* set the voice index */ + awe_set_sample(&rec->v); + + /* prepend to top of the list */ + curp = awe_search_instr(awe_gus_bank, patch.instr_no); + rec->bank = awe_gus_bank; + rec->instr = patch.instr_no; + rec->next_instr = curp; + rec->next_bank = preset_table[rec->instr]; + preset_table[rec->instr] = rec; + free_info++; + + return 0; +} + + +/* remove samples with current sf_id from instrument list */ +static awe_voice_list * +awe_get_removed_list(awe_voice_list *curp) +{ + awe_voice_list *lastp, **prevp; + int maxc; + lastp = curp; + prevp = &lastp; + for (maxc = AWE_MAX_INFOS; + curp && maxc; curp = curp->next_instr, maxc--) { + if (curp->v.sf_id == current_sf_id) + *prevp = curp->next_instr; + else + prevp = &curp->next_instr; + } + return lastp; +} + + +/* remove last loaded samples */ +static void +awe_remove_samples(void) +{ + awe_voice_list **prevp, *p, *nextp; + int maxc; + int i; + + if (last_sample == free_sample && last_info == free_info) + return; + + /* remove the records from preset table */ + for (i = 0; i < AWE_MAX_PRESETS; i++) { + prevp = &preset_table[i]; + for (maxc = AWE_MAX_INFOS, p = preset_table[i]; + p && maxc; p = nextp, maxc--) { + nextp = p->next_bank; + p = awe_get_removed_list(p); + if (p == NULL) + *prevp = nextp; + else { + *prevp = p; + prevp = &p->next_bank; + } + } + } + + for (i = last_sample; i < free_sample; i++) + free_mem_ptr -= samples[i].size; + + free_sample = last_sample; + free_info = last_info; + current_sf_id--; + loaded_once = 0; +} + + +/* search the specified sample */ +static short +awe_set_sample(awe_voice_info *vp) +{ + int i; + for (i = 0; i < free_sample; i++) { + if (samples[i].sf_id == vp->sf_id && + samples[i].sample == vp->sample) { + /* set the actual sample offsets */ + vp->start += samples[i].start; + vp->end += samples[i].end; + vp->loopstart += samples[i].loopstart; + vp->loopend += samples[i].loopend; + /* copy mode flags */ + vp->mode |= (samples[i].mode_flags << 6); + /* set index */ + vp->index = i; + return i; + } + } + return -1; +} + + +/* voice pressure change */ +static void +awe_aftertouch(int dev, int voice, int pressure) +{ + DECL_INTR_FLAGS(flags); + + DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure)); + if (voice < 0 || voice >= awe_max_voices) + return; + voices[voice].velocity = pressure; + awe_calc_volume(voice); + DISABLE_INTR(flags); + awe_set_volume(voice); + RESTORE_INTR(flags); +} + + +/* voice control change */ +static void +awe_controller(int dev, int voice, int ctrl_num, int value) +{ + DECL_INTR_FLAGS(flags); + + if (voice < 0 || voice >= awe_max_voices) + return; + + switch (ctrl_num) { + case CTL_BANK_SELECT: + DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value)); + voices[voice].bank = value; + break; + + case CTRL_PITCH_BENDER: + DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value)); + /* zero centered */ + voices[voice].bender = value; + awe_calc_pitch(voice); + DISABLE_INTR(flags); + awe_set_pitch(voice); + RESTORE_INTR(flags); + break; + + case CTRL_PITCH_BENDER_RANGE: + DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value)); + /* sense x 100 */ + voices[voice].bender_range = value; + /* no audible pitch change yet.. */ + break; + + case CTL_EXPRESSION: + value /= 128; + case CTRL_EXPRESSION: + DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value)); + /* 0 - 127 */ + voices[voice].expression_vol = value; + awe_calc_volume(voice); + DISABLE_INTR(flags); + awe_set_volume(voice); + RESTORE_INTR(flags); + break; + + case CTL_PAN: + DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value)); + /* (0-127) -> signed 8bit */ + voices[voice].panning = value * 2 - 128; + DISABLE_INTR(flags); + awe_set_pan(voice, 0); + RESTORE_INTR(flags); + break; + + case CTL_MAIN_VOLUME: + value = (value * 127) / 16383; + case CTRL_MAIN_VOLUME: + DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value)); + /* 0 - 127 */ + voices[voice].main_vol = value; + awe_calc_volume(voice); + DISABLE_INTR(flags); + awe_set_volume(voice); + RESTORE_INTR(flags); + break; + + case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */ + DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value)); + FX_SET(voice, AWE_FX_REVERB, value * 2); + break; + + case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */ + DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value)); + FX_SET(voice, AWE_FX_CHORUS, value * 2); + break; + + + default: + DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n", + voice, ctrl_num, value)); + break; + } +} + + +/* voice pan change (value = -128 - 127) */ +static void +awe_panning(int dev, int voice, int value) +{ + DECL_INTR_FLAGS(flags); + if (voice >= 0 || voice < awe_max_voices) { + voices[voice].panning = value; + DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, voices[voice].panning)); + DISABLE_INTR(flags); + awe_set_pan(voice, 0); + RESTORE_INTR(flags); + } +} + + +/* volume mode change */ +static void +awe_volume_method(int dev, int mode) +{ + /* not impremented */ + DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode)); +} + + +/* patch manager */ +static int +awe_patchmgr(int dev, struct patmgr_info *rec) +{ + FATALERR(printk("AWE32 Warning: patch manager control not supported\n")); + return 0; +} + + +/* pitch wheel change: 0-16384 */ +static void +awe_bender(int dev, int voice, int value) +{ + DECL_INTR_FLAGS(flags); + + if (voice < 0 || voice >= awe_max_voices) + return; + /* convert to zero centered value */ + voices[voice].bender = value - 8192; + DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, voices[voice].bender)); + awe_calc_pitch(voice); + DISABLE_INTR(flags); + awe_set_pitch(voice); + RESTORE_INTR(flags); +} + + +/* search an empty voice; used by sequencer2 */ +static int +awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc) +{ + int i, p, best = -1, best_time = 0x7fffffff; + + p = alloc->ptr; + /* First look for a completely stopped voice */ + + for (i = 0; i < alloc->max_voice; i++) { + if (alloc->map[p] == 0) { + alloc->ptr = p; + return p; + } + if (alloc->alloc_times[p] < best_time) { + best = p; + best_time = alloc->alloc_times[p]; + } + p = (p + 1) % alloc->max_voice; + } + + /* Then look for a releasing voice */ + for (i = 0; i < alloc->max_voice; i++) { + if (alloc->map[p] == 0xffff) { + alloc->ptr = p; + return p; + } + p = (p + 1) % alloc->max_voice; + } + + if (best >= 0) + p = best; + + /* terminate the voice */ + if (voices[p].state) + awe_terminate(p); + + alloc->ptr = p; + return p; +} + + +/* set up voice; used by sequencer2 */ +static void +awe_setup_voice(int dev, int voice, int chn) +{ + struct channel_info *info; + if (synth_devs[dev] == NULL || + (info = &synth_devs[dev]->chn_info[chn]) == NULL) + return; + if (voice < 0 || voice >= awe_max_voices) + return; + + DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn)); + voices[voice].expression_vol = info->controllers[CTL_EXPRESSION]; + voices[voice].main_vol = + (info->controllers[CTL_MAIN_VOLUME] * 100) / 128; /* 0 - 127 */ + voices[voice].panning = + info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */ + voices[voice].bender = info->bender_value; /* zero center */ + voices[voice].bank = info->controllers[CTL_BANK_SELECT]; + awe_set_instr(dev, voice, info->pgm_num); +} + + +/*================================================================ + * initialization of AWE32 + *================================================================*/ + +/* intiailize audio channels */ +static void +awe_init_audio(void) +{ + int ch; + + /* turn off envelope engines */ + for (ch = 0; ch < AWE_MAX_VOICES; ch++) { + awe_poke(AWE_DCYSUSV(ch), 0x0080); + } + + for (ch = 0; ch < AWE_MAX_VOICES; ch++) { + awe_poke(AWE_ENVVOL(ch), 0); + awe_poke(AWE_ENVVAL(ch), 0); + awe_poke(AWE_DCYSUS(ch), 0); + awe_poke(AWE_ATKHLDV(ch), 0); + awe_poke(AWE_LFO1VAL(ch), 0); + awe_poke(AWE_ATKHLD(ch), 0); + awe_poke(AWE_LFO2VAL(ch), 0); + awe_poke(AWE_IP(ch), 0); + awe_poke(AWE_IFATN(ch), 0); + awe_poke(AWE_PEFE(ch), 0); + awe_poke(AWE_FMMOD(ch), 0); + awe_poke(AWE_TREMFRQ(ch), 0); + awe_poke(AWE_FM2FRQ2(ch), 0); + awe_poke_dw(AWE_PTRX(ch), 0); + awe_poke_dw(AWE_VTFT(ch), 0); + awe_poke_dw(AWE_PSST(ch), 0); + awe_poke_dw(AWE_CSL(ch), 0); + awe_poke_dw(AWE_CCCA(ch), 0); + } + + for (ch = 0; ch < AWE_MAX_VOICES; ch++) { + awe_poke_dw(AWE_CPF(ch), 0); + awe_poke_dw(AWE_CVCF(ch), 0); + } +} + + +/* initialize DMA address */ +static void +awe_init_dma(void) +{ + awe_poke_dw(AWE_SMALR, 0x00000000); + awe_poke_dw(AWE_SMARR, 0x00000000); + awe_poke_dw(AWE_SMALW, 0x00000000); + awe_poke_dw(AWE_SMARW, 0x00000000); +} + + +/* initialization arrays */ + +static unsigned short init1[128] = { + 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330, + 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730, + 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30, + 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30, + + 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330, + 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730, + 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30, + 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30, + + 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330, + 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730, + 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30, + 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30, + + 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330, + 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730, + 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30, + 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30, +}; + +static unsigned short init2[128] = { + 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330, + 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730, + 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30, + 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30, + + 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330, + 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730, + 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30, + 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30, + + 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330, + 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730, + 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30, + 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30, + 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330, + 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730, + 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30, + 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30, +}; + +static unsigned short init3[128] = { + 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5, + 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254, + 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234, + 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224, + + 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254, + 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264, + 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294, + 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3, + + 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287, + 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7, + 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386, + 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55, + + 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308, + 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F, + 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319, + 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570, +}; + +static unsigned short init4[128] = { + 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5, + 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254, + 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234, + 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224, + + 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254, + 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264, + 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294, + 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3, + + 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287, + 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7, + 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386, + 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55, + + 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308, + 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F, + 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319, + 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570, +}; + + +/* send initialization arrays to start up */ +static void +awe_init_array(void) +{ + awe_send_array(init1); + awe_wait(1024); + awe_send_array(init2); + awe_send_array(init3); + awe_poke_dw(AWE_HWCF4, 0); + awe_poke_dw(AWE_HWCF5, 0x83); + awe_poke_dw(AWE_HWCF6, 0x8000); + awe_send_array(init4); +} + +/* send an initialization array */ +static void +awe_send_array(unsigned short *data) +{ + int i; + unsigned short *p; + + p = data; + for (i = 0; i < AWE_MAX_VOICES; i++, p++) + awe_poke(AWE_INIT1(i), *p); + for (i = 0; i < AWE_MAX_VOICES; i++, p++) + awe_poke(AWE_INIT2(i), *p); + for (i = 0; i < AWE_MAX_VOICES; i++, p++) + awe_poke(AWE_INIT3(i), *p); + for (i = 0; i < AWE_MAX_VOICES; i++, p++) + awe_poke(AWE_INIT4(i), *p); +} + + +/* + * set up awe32 channels to some known state. + */ + +static void +awe_tweak(void) +{ + int i; + + /* Set the envelope engine parameters to the "default" values for + simply playing back unarticulated audio at 44.1kHz. Set all + of the channels: */ + + for (i = 0; i < AWE_MAX_VOICES; i++) { + awe_poke(AWE_ENVVOL(i) , 0x8000); + awe_poke(AWE_ENVVAL(i) , 0x8000); + awe_poke(AWE_DCYSUS(i) , 0x7F7F); + awe_poke(AWE_ATKHLDV(i) , 0x7F7F); + awe_poke(AWE_LFO1VAL(i) , 0x8000); + awe_poke(AWE_ATKHLD(i) , 0x7F7F); + awe_poke(AWE_LFO2VAL(i) , 0x8000); + awe_poke(AWE_IP(i) , 0xE000); + awe_poke(AWE_IFATN(i) , 0xFF00); + awe_poke(AWE_PEFE(i) , 0x0000); + awe_poke(AWE_FMMOD(i) , 0x0000); + awe_poke(AWE_TREMFRQ(i) , 0x0010); + awe_poke(AWE_FM2FRQ2(i) , 0x0010); + } +} + + +/* + * initializes the FM section of AWE32 + */ + +static void +awe_init_fm(void) +{ +#ifndef AWE_ALWAYS_INIT_FM + /* if no extended memory is on board.. */ + if (awe_mem_size <= 0) + return; +#endif + DEBUG(0,printk("AWE32: initializing FM\n")); + + /* Initialize the last two channels for DRAM refresh and producing + the reverb and chorus effects for Yamaha OPL-3 synthesizer */ + + awe_poke( AWE_DCYSUSV(30) , 0x0080); + awe_poke_dw(AWE_PSST(30) , 0xFFFFFFE0); + awe_poke_dw(AWE_CSL(30) , 0xFFFFFFE8); + awe_poke_dw(AWE_PTRX(30) , 0x00FFFF00); + awe_poke_dw(AWE_CPF(30) , 0x00000000); + awe_poke_dw(AWE_CCCA(30) , 0x00FFFFE3); + + awe_poke( AWE_DCYSUSV(31) , 0x0080); + awe_poke_dw(AWE_PSST(31) , 0x00FFFFE0); + awe_poke_dw(AWE_CSL(31) , 0xFFFFFFE8); + awe_poke_dw(AWE_PTRX(31) , 0x00FFFF00); + awe_poke_dw(AWE_CPF(31) , 0x00000000); + awe_poke_dw(AWE_CCCA(31) , 0x00FFFFE3); + + /* Timing loop */ + + /* PTRX is 32 bit long but do not write to the MS byte */ + awe_poke(AWE_PTRX(30) , 0x0000); + + while(! (inw(awe_base-0x620+Pointer) & 0x1000)); + while( inw(awe_base-0x620+Pointer) & 0x1000); + + /* now write the MS byte of PTRX */ + OUTW(0x4828, awe_base-0x620+Data0+0x002); + + awe_poke( AWE_IFATN(28) , 0x0000); + awe_poke_dw(AWE_VTFT(30) , 0x8000FFFF); + awe_poke_dw(AWE_VTFT(31) , 0x8000FFFF); + + /* change maximum channels to 30 */ + awe_max_voices = AWE_NORMAL_VOICES; + awe_info.nr_voices = awe_max_voices; + voice_alloc->max_voice = awe_max_voices; +} + +/* + * AWE32 DRAM access routines + */ + +/* open DRAM write accessing mode */ +static int +awe_open_dram_for_write(int offset) +{ + int i; + + /* use all channels for DMA transfer */ + for (i = 0; i < AWE_NORMAL_VOICES; i++) { + awe_poke(AWE_DCYSUSV(i), 0x80); + awe_poke_dw(AWE_VTFT(i), 0); + awe_poke_dw(AWE_CVCF(i), 0); + awe_poke_dw(AWE_PTRX(i), 0x40000000); + awe_poke_dw(AWE_CPF(i), 0x40000000); + awe_poke_dw(AWE_PSST(i), 0); + awe_poke_dw(AWE_CSL(i), 0); + awe_poke_dw(AWE_CCCA(i), 0x06000000); + } + /* point channels 31 & 32 to ROM samples for DRAM refresh */ + awe_poke_dw(AWE_VTFT(30), 0); + awe_poke_dw(AWE_PSST(30), 0x1d8); + awe_poke_dw(AWE_CSL(30), 0x1e0); + awe_poke_dw(AWE_CCCA(30), 0x1d8); + awe_poke_dw(AWE_VTFT(31), 0); + awe_poke_dw(AWE_PSST(31), 0x1d8); + awe_poke_dw(AWE_CSL(31), 0x1e0); + awe_poke_dw(AWE_CCCA(31), 0x1d8); + + /* if full bit is on, not ready to write on */ + if (awe_peek_dw(AWE_SMALW) & 0x80000000) { + for (i = 0; i < AWE_NORMAL_VOICES; i++) + awe_poke_dw(AWE_CCCA(i), 0); + return RET_ERROR(ENOSPC); + } + + /* set address to write */ + awe_poke_dw(AWE_SMALW, offset + AWE_DRAM_OFFSET); + + return 0; +} + +/* open DRAM for RAM size detection */ +static void +awe_open_dram_for_check(void) +{ + int k; + unsigned long scratch; + + awe_poke(AWE_HWCF2 , 0x0020); + + for (k = 0; k < AWE_NORMAL_VOICES; k++) { + awe_poke(AWE_DCYSUSV(k), 0x0080); + awe_poke_dw(AWE_VTFT(k), 0x00000000); + awe_poke_dw(AWE_CVCF(k), 0x00000000); + awe_poke_dw(AWE_PTRX(k), 0x40000000); + awe_poke_dw(AWE_CPF(k), 0x40000000); + awe_poke_dw(AWE_PSST(k), 0x00000000); + awe_poke_dw(AWE_CSL(k), 0x00000000); + scratch = (((k&1) << 9) + 0x400); + scratch = scratch << 16; + awe_poke_dw(AWE_CCCA(k), scratch); + } +} + + +/* close dram access */ +static void +awe_close_dram(void) +{ + int i; + /* wait until FULL bit in SMAxW register be false */ + for (i = 0; i < 10000; i++) { + if (!(awe_peek_dw(AWE_SMALW) & 0x80000000)) + break; + awe_wait(10); + } + + for (i = 0; i < AWE_NORMAL_VOICES; i++) { + awe_poke_dw(AWE_CCCA(i), 0); + awe_poke(AWE_DCYSUSV(i), 0x807F); + } +} + + +#ifdef AWE_CHECKSUM_MEMORY +/* open DRAM read accessing mode */ +static int +awe_open_dram_for_read(int offset) +{ + int i; + + /* use all channels for DMA transfer */ + for (i = 0; i < AWE_NORMAL_VOICES; i++) { + awe_poke(AWE_DCYSUSV(i), 0x80); + awe_poke_dw(AWE_VTFT(i), 0); + awe_poke_dw(AWE_CVCF(i), 0); + awe_poke_dw(AWE_PTRX(i), 0x40000000); + awe_poke_dw(AWE_CPF(i), 0x40000000); + awe_poke_dw(AWE_PSST(i), 0); + awe_poke_dw(AWE_CSL(i), 0); + awe_poke_dw(AWE_CCCA(i), 0x04000000); + } + /* point channels 31 & 32 to ROM samples for DRAM refresh */ + awe_poke_dw(AWE_VTFT(30), 0); + awe_poke_dw(AWE_PSST(30), 0x1d8); + awe_poke_dw(AWE_CSL(30), 0x1e0); + awe_poke_dw(AWE_CCCA(30), 0x1d8); + awe_poke_dw(AWE_VTFT(31), 0); + awe_poke_dw(AWE_PSST(31), 0x1d8); + awe_poke_dw(AWE_CSL(31), 0x1e0); + awe_poke_dw(AWE_CCCA(31), 0x1d8); + + /* if empty flag is on, not ready to read */ + if (awe_peek_dw(AWE_SMALR) & 0x80000000) { + for (i = 0; i < AWE_NORMAL_VOICES; i++) + awe_poke_dw(AWE_CCCA(i), 0); + return RET_ERROR(ENOSPC); + } + + /* set address to read */ + awe_poke_dw(AWE_SMALR, offset + AWE_DRAM_OFFSET); + /* drop stale data */ + awe_peek(AWE_SMLD); + return 0; +} + +/* close dram access for read */ +static void +awe_close_dram_for_read(void) +{ + int i; + /* wait until FULL bit in SMAxW register be false */ + for (i = 0; i < 10000; i++) { + if (!(awe_peek_dw(AWE_SMALR) & 0x80000000)) + break; + awe_wait(10); + } + for (i = 0; i < AWE_NORMAL_VOICES; i++) { + awe_poke_dw(AWE_CCCA(i), 0); + awe_poke(AWE_DCYSUSV(i), 0x807F); + } +} +#endif /* AWE_CHECKSUM_MEMORY */ + + +/* write a word data */ +static void +awe_write_dram(unsigned short c) +{ + int k; + /* wait until FULL bit in SMAxW register be false */ + for (k = 0; k < 10000; k++) { + if (!(awe_peek_dw(AWE_SMALW) & 0x80000000)) + break; + awe_wait(10); + } + awe_poke(AWE_SMLD, c); +} + +/*================================================================ + * detect presence of AWE32 and check memory size + *================================================================*/ + +static int +awe_detect(void) +{ +#ifdef AWE_DEFAULT_BASE_ADDR + awe_base = AWE_DEFAULT_BASE_ADDR; + if (((awe_peek(AWE_U1) & 0x000F) == 0x000C) && + ((awe_peek(AWE_HWCF1) & 0x007E) == 0x0058) && + ((awe_peek(AWE_HWCF2) & 0x0003) == 0x0003)) + return 1; +#endif + if (awe_base == 0) { + for (awe_base = 0x620; awe_base <= 0x680; awe_base += 0x20) { + if ((awe_peek(AWE_U1) & 0x000F) != 0x000C) + continue; + if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058) + continue; + if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003) + continue; + DEBUG(0,printk("AWE32 found at %x\n", awe_base)); + return 1; + } + } + FATALERR(printk("AWE32 not found\n")); + awe_base = 0; + return 0; +} + + +/*================================================================ + * check dram size on AWE board + *================================================================*/ +static int +awe_check_dram(void) +{ + awe_open_dram_for_check(); + + awe_poke_dw(AWE_SMALW , 0x00200000); /* DRAM start address */ + awe_poke( AWE_SMLD , 0x1234); + awe_poke( AWE_SMLD , 0x7777); + + awe_mem_size = 0; + while (awe_mem_size < 28*1024) { /* 28 MB is max onboard memory */ + awe_wait(2); + awe_poke_dw(AWE_SMALR, 0x00200000); /* Address for reading */ + awe_peek(AWE_SMLD); /* Discard stale data */ + if (awe_peek(AWE_SMLD) != 0x1234) + break; + if (awe_peek(AWE_SMLD) != 0x7777) + break; + awe_mem_size += 32; + /* Address for writing */ + awe_poke_dw(AWE_SMALW, 0x00200000+awe_mem_size*512L); + awe_poke(AWE_SMLD, 0xFFFF); + } + awe_close_dram(); + + DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", (int)awe_mem_size)); +#ifdef AWE_DEFAULT_MEM_SIZE + if (awe_mem_size == 0) + awe_mem_size = AWE_DEFAULT_MEM_SIZE; +#endif + /* convert to Kbytes */ + awe_mem_size *= 1024; + return awe_mem_size; +} + + +/*================================================================ + * chorus and reverb controls + *================================================================*/ + +static unsigned short ChorusEffects[24] = +{ + 0xE600,0x03F6,0xBC2C,0xE608,0x031A,0xBC6E,0xE610,0x031A, + 0xBC84,0xE620,0x0269,0xBC6E,0xE680,0x04D3,0xBCA6,0xE6E0, + 0x044E,0xBC37,0xE600,0x0B06,0xBC00,0xE6C0,0x0B06,0xBC00 +}; + +static unsigned long ChorusEffects2[] = +{ + 0x0000 ,0x006D,0x8000,0x0000,0x0000 ,0x017C,0x8000,0x0000, + 0x0000 ,0x0083,0x8000,0x0000,0x0000 ,0x017C,0x8000,0x0000, + 0x0000 ,0x005B,0x8000,0x0000,0x0000 ,0x0026,0x8000,0x0000, + 0x6E000,0x0083,0x8000,0x0000,0x6E000,0x0083,0x8000,0x0000 +}; + +static unsigned short ChorusCommand[14] = +{ + 0x69,0xA20,0x6C,0xA20,0x63,0xA22,0x29, + 0xA20,0x2A,0xA20,0x2D,0xA20,0x2E,0xA20 +}; + +static unsigned short ReverbEffects[224] = +{ + /* Room 1 */ + 0xB488,0xA450,0x9550,0x84B5,0x383A,0x3EB5,0x72F4, + 0x72A4,0x7254,0x7204,0x7204,0x7204,0x4416,0x4516, + 0xA490,0xA590,0x842A,0x852A,0x842A,0x852A,0x8429, + 0x8529,0x8429,0x8529,0x8428,0x8528,0x8428,0x8528, + /* Room 2 */ + 0xB488,0xA458,0x9558,0x84B5,0x383A,0x3EB5,0x7284, + 0x7254,0x7224,0x7224,0x7254,0x7284,0x4448,0x4548, + 0xA440,0xA540,0x842A,0x852A,0x842A,0x852A,0x8429, + 0x8529,0x8429,0x8529,0x8428,0x8528,0x8428,0x8528, + /* Room 3 */ + 0xB488,0xA460,0x9560,0x84B5,0x383A,0x3EB5,0x7284, + 0x7254,0x7224,0x7224,0x7254,0x7284,0x4416,0x4516, + 0xA490,0xA590,0x842C,0x852C,0x842C,0x852C,0x842B, + 0x852B,0x842B,0x852B,0x842A,0x852A,0x842A,0x852A, + /* Hall 1 */ + 0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7284, + 0x7254,0x7224,0x7224,0x7254,0x7284,0x4448,0x4548, + 0xA440,0xA540,0x842B,0x852B,0x842B,0x852B,0x842A, + 0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, + /* Hall 2 */ + 0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7254, + 0x7234,0x7224,0x7254,0x7264,0x7294,0x44C3,0x45C3, + 0xA404,0xA504,0x842A,0x852A,0x842A,0x852A,0x8429, + 0x8529,0x8429,0x8529,0x8428,0x8528,0x8428,0x8528, + /* Plate */ + 0xB4FF,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7234, + 0x7234,0x7234,0x7234,0x7234,0x7234,0x4448,0x4548, + 0xA440,0xA540,0x842A,0x852A,0x842A,0x852A,0x8429, + 0x8529,0x8429,0x8529,0x8428,0x8528,0x8428,0x8528, + /* Delay */ + 0xB4FF,0xA470,0x9500,0x84B5,0x333A,0x39B5,0x7204, + 0x7204,0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500, + 0xA4FF,0xA5FF,0x8420,0x8520,0x8420,0x8520,0x8420, + 0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, + /* Panning Delay */ + 0xB4FF,0xA490,0x9590,0x8474,0x333A,0x39B5,0x7204, + 0x7204,0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500, + 0xA4FF,0xA5FF,0x8420,0x8520,0x8420,0x8520,0x8420, + 0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520 +}; + +static unsigned short ReverbCommand[56] = +{ + 0x43,0xA20,0x45,0xA20,0x7F,0xA22,0x47,0xA20, + 0x54,0xA22,0x56,0xA22,0x4F,0xA20,0x57,0xA20, + 0x5F,0xA20,0x47,0xA22,0x4F,0xA22,0x57,0xA22, + 0x5D,0xA22,0x5F,0xA22,0x61,0xA20,0x63,0xA20, + 0x49,0xA20,0x4B,0xA20,0x51,0xA20,0x53,0xA20, + 0x59,0xA20,0x5B,0xA20,0x41,0xA22,0x43,0xA22, + 0x49,0xA22,0x4B,0xA22,0x51,0xA22,0x53,0xA22 +}; + +static void awe_set_chorus_mode(int effect) +{ + int k; + DECL_INTR_FLAGS(flags); + + DISABLE_INTR(flags); + for (k = 0; k < 3; k++) + awe_poke(ChorusCommand[k*2], + ChorusCommand[k*2+1], + ChorusEffects[k+effect*3]); + for (k = 0; k < 4; k++) + awe_poke_dw(ChorusCommand[6+k*2], + ChorusCommand[6+k*2+1], + ChorusEffects2[k+effect*4]); + RESTORE_INTR(flags); +} + +static void awe_set_reverb_mode(int effect) +{ + int k; + DECL_INTR_FLAGS(flags); + + DISABLE_INTR(flags); + for (k = 0; k < 28; k++) + awe_poke(ReverbCommand[k*2], + ReverbCommand[k*2+1], + ReverbEffects[k+effect*28]); + RESTORE_INTR(flags); +} + +#endif /* CONFIG_AWE32_SYNTH */ diff --git a/sys/i386/isa/sound/coproc.h b/sys/i386/isa/sound/coproc.h new file mode 100644 index 000000000000..f9023821d3f2 --- /dev/null +++ b/sys/i386/isa/sound/coproc.h @@ -0,0 +1,12 @@ +/* + * Definitions for various on board processors on the soundcards. For + * example DSP processors. + */ + +/* + * Coprocessor access types + */ +#define COPR_CUSTOM 0x0001 /* Custom applications */ +#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */ +#define COPR_PCM 0x0004 /* Digitized voice applications */ +#define COPR_SYNTH 0x0008 /* Music synthesis */ diff --git a/sys/i386/isa/sound/cs4232.c b/sys/i386/isa/sound/cs4232.c new file mode 100644 index 000000000000..4b2c38d2e51c --- /dev/null +++ b/sys/i386/isa/sound/cs4232.c @@ -0,0 +1,206 @@ +/* + * sound/cs4232.c + * + * The low level driver for Crystal CS4232 based cards. The CS4232 is a PnP + * compatible chip which contains a CS4231A codec, SB emulation, a MPU401 + * compatible MIDI port, joystick and synthesizer and IDE CD-ROM interfaces. + * This is just a temporary driver until full PnP support gets inplemented. + * Just the WSS codec, FM synth and the MIDI ports are supported. Other + * interfaces are left uninitialized. + * + * Copyright by Hannu Savolainen 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <i386/isa/sound/sound_config.h> + +#if defined(CONFIG_CS4232) + +#define KEY_PORT 0x279 /* Same as LPT1 status port */ +#define CSN_NUM 0x99 /* Just a random number */ + +#define CS_OUT(a) outb( KEY_PORT, a) +#define CS_OUT2(a, b) {CS_OUT(a);CS_OUT(b);} +#define CS_OUT3(a, b, c) {CS_OUT(a);CS_OUT(b);CS_OUT(c);} + +static int mpu_base = 0, mpu_irq = 0; +static int mpu_detected = 0; + +int +probe_cs4232_mpu(struct address_info * hw_config) +{ + /* + * Just write down the config values. + */ + + mpu_base = hw_config->io_base; + mpu_irq = hw_config->irq; + return 0; +} + +void +attach_cs4232_mpu(struct address_info * hw_config) +{ +} + +static unsigned char crystal_key[] = /* A 32 byte magic key sequence */ +{ + 0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc, + 0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2, + 0xf1, 0xf8, 0x7c, 0x3e, 0x9f, 0x4f, 0x27, 0x13, + 0x09, 0x84, 0x42, 0xa1, 0xd0, 0x68, 0x34, 0x1a +}; + +int +probe_cs4232(struct address_info * hw_config) +{ + int i; + int base = hw_config->io_base, irq = hw_config->irq; + int dma1 = hw_config->dma, dma2 = hw_config->dma2; + + /* + * Verify that the I/O port range is free. + */ + + if (0) { + printf("cs4232.c: I/O port 0x%03x not free\n", base); + return 0; + } + /* + * This version of the driver doesn't use the PnP method when + * configuring the card but a simplified method defined by Crystal. + * This means that just one CS4232 compatible device can exist on the + * system. Also this method conflicts with possible PnP support in + * the OS. For this reason driver is just a temporary kludge. + */ + + /* + * Wake up the card by sending a 32 byte Crystal key to the key port. + */ + for (i = 0; i < 32; i++) + CS_OUT(crystal_key[i]); + + /* + * Now set the CSN (Card Select Number). + */ + + CS_OUT2(0x06, CSN_NUM); + + /* + * Ensure that there is no other codec using the same address. + */ + + CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */ + CS_OUT2(0x33, 0x00); /* Inactivate logical dev 0 */ + if (ad1848_detect(hw_config->io_base, NULL, hw_config->osp)) + return 0; + + /* + * Then set some config bytes. First logical device 0 + */ + + CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */ + CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSSbase */ + + if (0) /* Not free */ + CS_OUT3(0x48, 0x00, 0x00) /* FMbase off */ + else + CS_OUT3(0x48, 0x03, 0x88); /* FMbase 0x388 */ + + CS_OUT3(0x42, 0x00, 0x00); /* SBbase off */ + CS_OUT2(0x22, irq); /* SB+WSS IRQ */ + CS_OUT2(0x2a, dma1); /* SB+WSS DMA */ + + if (dma2 != -1) + CS_OUT2(0x25, dma2) /* WSS DMA2 */ + else + CS_OUT2(0x25, 4); /* No WSS DMA2 */ + + CS_OUT2(0x33, 0x01); /* Activate logical dev 0 */ + + /* + * Initialize logical device 3 (MPU) + */ + +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + if (mpu_base != 0 && mpu_irq != 0) { + CS_OUT2(0x15, 0x03); /* Select logical device 3 (MPU) */ + CS_OUT3(0x47, (mpu_base >> 8) & 0xff, mpu_base & 0xff); /* MPUbase */ + CS_OUT2(0x22, mpu_irq); /* MPU IRQ */ + CS_OUT2(0x33, 0x01); /* Activate logical dev 3 */ + } +#endif + + /* + * Finally activate the chip + */ + CS_OUT(0x79); + + /* + * Then try to detect the codec part of the chip + */ + + return ad1848_detect(hw_config->io_base, NULL, hw_config->osp); +} + +void +attach_cs4232(struct address_info * hw_config) +{ + int base = hw_config->io_base, irq = hw_config->irq; + int dma1 = hw_config->dma, dma2 = hw_config->dma2; + + if (dma2 == -1) + dma2 = dma1; + + ad1848_init("CS4232", base, + irq, + dma1, /* Playback DMA */ + dma2, /* Capture DMA */ + 0, + hw_config->osp); + +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + if (mpu_base != 0 && mpu_irq != 0) { + static struct address_info hw_config2 = + {0}; /* Ensure it's initialized */ + + hw_config2.io_base = mpu_base; + hw_config2.irq = mpu_irq; + hw_config2.dma = -1; + hw_config2.dma2 = -1; + hw_config2.always_detect = 0; + hw_config2.name = NULL; + hw_config2.card_subtype = 0; + hw_config2.osp = hw_config->osp; + + if (probe_mpu401(&hw_config2)) { + mpu_detected = 1; + attach_mpu401(&hw_config2); + } else { + mpu_base = mpu_irq = 0; + } + } +#endif +} + +#endif diff --git a/sys/i386/isa/sound/hex2hex.h b/sys/i386/isa/sound/hex2hex.h new file mode 100644 index 000000000000..ecd7b4c4239c --- /dev/null +++ b/sys/i386/isa/sound/hex2hex.h @@ -0,0 +1,97 @@ +/* + * This file is a part of configure.c + * + * hex2hex reads an input file in Intel HEX format and produces + * an (unsigned char) array which contains the bytes and writes it to the + * output file using C syntax + */ + +#define MAX_SIZE (256*1024) +#define ABANDON(why) { \ + fprintf(stderr, "%s: " why "\n", source); \ + fclose(inf);fclose(outf);return 0; \ + } + +int hex2hex(char *source, char *target, char *varline) +{ + FILE *inf, *outf; + + int i,l, c; + unsigned char buf[MAX_SIZE]; + + if ((inf=fopen(source, "r"))==NULL) + { + perror(source); + return 0; + } + + if ((outf=fopen(target, "w"))==NULL) + { + perror(target); + fclose(inf); + return 0; + } + + l=0; + + while ((c=getc(inf))!=EOF) + { + if (c == ':') /* Sync with beginning of line */ + { + int n, check; + unsigned char sum; + int addr; + int linetype; + + if (fscanf(inf, "%02x", &n) != 1) + ABANDON("File format error"); + sum = n; + + if (fscanf(inf, "%04x", &addr) != 1) + ABANDON("File format error"); + sum += addr/256; + sum += addr%256; + + if (fscanf(inf, "%02x", &linetype) != 1) + ABANDON("File format error"); + sum += linetype; + + if (linetype != 0) + continue; + + for (i=0;i<n;i++) + { + if (fscanf(inf, "%02x", &c) != 1) + ABANDON("File format error"); + if (addr >= MAX_SIZE) + ABANDON("File too large"); + buf[addr++] = c; + if (addr > l) + l = addr; + sum += c; + } + + if (fscanf(inf, "%02x", &check) != 1) + ABANDON("File format error"); + + sum = ~sum + 1; + if (check != sum) + ABANDON("Line checksum error"); + } + } + + fprintf(outf, "/*\n *\t Computer generated file. Do not edit.\n */\n"); + fprintf(outf, "%s[] = {\n", varline); + + for (i=0;i<l;i++) + { + if (i) fprintf(outf, ","); + if (i && !(i % 16)) fprintf(outf, "\n"); + fprintf(outf, "0x%02x", buf[i]); + } + + fprintf(outf, "\n};\n\n"); + fclose(inf); + fclose(outf); + return 1; +} diff --git a/sys/i386/isa/sound/iwdefs.h b/sys/i386/isa/sound/iwdefs.h new file mode 100644 index 000000000000..60f50fc50028 --- /dev/null +++ b/sys/i386/isa/sound/iwdefs.h @@ -0,0 +1,712 @@ +/*#######################################################################*/ +/* FILE : iwdefs.h*/ +/**/ +/* REMARKS: This file contains all defines used by DDK functions. It*/ +/* should be included by all applications and should be*/ +/* referenced by programmers to make their code easy to read*/ +/* and understand.*/ +/**/ +/* UPDATE: 3/21/95*/ +/* 7/10/95 --- added #def DRAM_HOLES*/ +/*#######################################################################*/ +#ifndef IWDEFS +#define IWDEFS +/*#######################################################################*/ +/**/ +/* Macros for use in loading Synth Addr Regs*/ +/**/ +/*#######################################################################*/ +#define ADDR_HIGH(x) (short)(x>>7) +#define ADDR_LOW(x) (short)(x<<9) +/*#######################################################################*/ +/**/ +/* Defines for DMA Controllers*/ +/**/ +/*#######################################################################*/ +/* DMA Controler #1 (8-bit controller) */ +#define DMA1_STAT 0x08 /* read status register */ +#define DMA1_WCMD 0x08 /* write command register */ +#define DMA1_WREQ 0x09 /* write request register */ +#define DMA1_SNGL 0x0A /* write single bit register */ +#define DMA1_MODE 0x0B /* write mode register */ +#define DMA1_CLRFF 0x0C /* clear byte ptr flip/flop */ +#define DMA1_MCLR 0x0D /* master clear register */ +#define DMA1_CLRM 0x0E /* clear mask register */ +#define DMA1_WRTALL 0x0F /* write all mask register */ + +/* DMA Controler #2 (16-bit controller) */ +#define DMA2_STAT 0xD0 /* read status register */ +#define DMA2_WCMD 0xD0 /* write command register */ +#define DMA2_WREQ 0xD2 /* write request register */ +#define DMA2_SNGL 0xD4 /* write single bit register */ +#define DMA2_MODE 0xD6 /* write mode register */ +#define DMA2_CLRFF 0xD8 /* clear byte ptr flip/flop */ +#define DMA2_MCLR 0xDA /* master clear register */ +#define DMA2_CLRM 0xDC /* clear mask register */ +#define DMA2_WRTALL 0xDE /* write all mask register */ + +#define DMA0_ADDR 0x00 /* chan 0 base adddress */ +#define DMA0_CNT 0x01 /* chan 0 base count */ +#define DMA1_ADDR 0x02 /* chan 1 base adddress */ +#define DMA1_CNT 0x03 /* chan 1 base count */ +#define DMA2_ADDR 0x04 /* chan 2 base adddress */ +#define DMA2_CNT 0x05 /* chan 2 base count */ +#define DMA3_ADDR 0x06 /* chan 3 base adddress */ +#define DMA3_CNT 0x07 /* chan 3 base count */ +#define DMA4_ADDR 0xC0 /* chan 4 base adddress */ +#define DMA4_CNT 0xC2 /* chan 4 base count */ +#define DMA5_ADDR 0xC4 /* chan 5 base adddress */ +#define DMA5_CNT 0xC6 /* chan 5 base count */ +#define DMA6_ADDR 0xC8 /* chan 6 base adddress */ +#define DMA6_CNT 0xCA /* chan 6 base count */ +#define DMA7_ADDR 0xCC /* chan 7 base adddress */ +#define DMA7_CNT 0xCE /* chan 7 base count */ + +#define DMA0_PAGE 0x87 /* chan 0 page register (refresh)*/ +#define DMA1_PAGE 0x83 /* chan 1 page register */ +#define DMA2_PAGE 0x81 /* chan 2 page register */ +#define DMA3_PAGE 0x82 /* chan 3 page register */ +#define DMA4_PAGE 0x8F /* chan 4 page register (unusable)*/ +#define DMA5_PAGE 0x8B /* chan 5 page register */ +#define DMA6_PAGE 0x89 /* chan 6 page register */ +#define DMA7_PAGE 0x8A /* chan 7 page register */ +/*#######################################################################*/ +/**/ +/* Defines for register UISR (Interrupt Status)*/ +/**/ +/*#######################################################################*/ +#define MIDI_TX_IRQ 0x01 +#define MIDI_RX_IRQ 0x02 +#define ALIB_TIMER1_IRQ 0x04 +#define ALIB_TIMER2_IRQ 0x08 +#define _UASBCI 0x45 /* UASBCI index */ +#define SAMPLE_CONTROL 0x49 /* Not used by IW */ +#define SET_VOICES 0x0E +#define WAVETABLE_IRQ 0x20 +#define ENVELOPE_IRQ 0x40 +#define DMA_TC_IRQ 0x80 +/*#######################################################################*/ +/**/ +/* Synthesizer-related defines*/ +/**/ +/*#######################################################################*/ +#define GEN_INDEX 0x03 /* IGIDX offset into p3xr */ +#define VOICE_SELECT 0x02 /* SVSR offset into p3xr */ +#define VOICE_IRQS 0x8F /* SVII index (read) */ +#define _URSTI 0x4C /* URSTI index */ +#define GF1_SET 0x01 /* URSTI[0] */ +#define GF1_OUT_ENABLE 0x02 /* URSTI[1] */ +#define GF1_IRQ_ENABLE 0x04 /* URSTI[2] */ +#define GF1_RESET 0xFE /* URSTI[0]=0 */ +#define VOICE_VOLUME_IRQ 0x04 /* SVII[2] */ +#define VOICE_WAVE_IRQ 0x08 /* SVII[3] */ +#define VC_IRQ_ENABLE 0x20 /* SACI[5] or SVCI[5]*/ +#define VOICE_NUMBER 0x1F /* Mask for SVII[4:0] */ +#define VC_IRQ_PENDING 0x80 /* SACI[7] or SVCI[7] */ +#define VC_DIRECT 0x40 /* SACI[6] or SVCI[6]*/ +#define VC_DATA_WIDTH 0x04 /* SACI[2] */ +#define VOICE_STOP 0x02 /* SACI[1] */ +#define VOICE_STOPPED 0x01 /* SACI[0] */ +#define VOLUME_STOP 0x02 /* SVCI[1] */ +#define VOLUME_STOPPED 0x01 /* SVCI[0] */ +#define VC_ROLLOVER 0x04 /* SVCI[2] */ +#define VC_LOOP_ENABLE 0x08 /* SVCI[3] or SACI[3]*/ +#define VC_BI_LOOP 0x10 /* SVCI[4] or SACI[4]*/ +#define VOICE_OFFSET 0x20 /* SMSI[5] */ +#define VOLUME_RATE0 0x00 /* SVRI[7:6]=(0,0) */ +#define VOLUME_RATE1 0x40 /* SVRI[7:6]=(0,1) */ +#define VOLUME_RATE2 0x80 /* SVRI[7:6]=(1,0) */ +#define VOLUME_RATE3 0xC0 /* SVRI[7:6]=(1,1) */ +/*#######################################################################*/ +/**/ +/* Power-Mode Control Defines*/ +/**/ +/*#######################################################################*/ +#define SHUT_DOWN 0x7E /* shuts InterWave down */ +#define POWER_UP 0xFE /* enables all modules */ +#define CODEC_PWR_UP 0x81 /* enables Codec Analog Ckts */ +#define CODEC_PWR_DOWN 0x01 /* disables Codec Analog Ckts */ +#define CODEC_REC_UP 0x82 /* Enables Record Path */ +#define CODEC_REC_DOWN 0x02 /* Disables Record Path */ +#define CODEC_PLAY_UP 0x84 /* Enables Playback Path */ +#define CODEC_PLAY_DOWN 0x04 /* Disables Playback Path */ +#define CODEC_IRQ_ENABLE 0x02 /* CEXTI[2] */ +#define CODEC_TIMER_IRQ 0x40 /* CSR3I[6] */ +#define CODEC_REC_IRQ 0x20 /* CSR3I[5] */ +#define CODEC_PLAY_IRQ 0x10 /* CSR3I[4] */ +#define CODEC_INT 0x01 /* CSR1R[0] */ +#define MONO_INPUT 0x80 /* CMONOI[7] */ +#define MONO_OUTPUT 0x40 /* CMONOI[6] */ +#define MIDI_UP 0x88 /* Enables MIDI ports */ +#define MIDI_DOWN 0x08 /* Disables MIDI ports */ +#define SYNTH_UP 0x90 /* Enables Synthesizer */ +#define SYNTH_DOWN 0x10 /* Disables Synthesizer */ +#define LMC_UP 0xA0 /* Enables LM Module */ +#define LMC_DOWN 0x20 /* Disbales LM Module */ +#define XTAL24_UP 0xC0 /* Enables 24MHz Osc */ +#define XTAL24_DOWN 0x40 /* Disables 24MHz Osc */ +#define _PPWRI 0xF2 /* PPWRI index */ +#define PLAY 0x0F +#define REC 0x1F +#define LEFT_AUX1_INPUT 0x02 +#define RIGHT_AUX1_INPUT 0x03 +#define LEFT_AUX2_INPUT 0x04 +#define RIGHT_AUX2_INPUT 0x05 +#define LEFT_LINE_IN 0x12 +#define RIGHT_LINE_IN 0x13 +#define LEFT_LINE_OUT 0x19 +#define RIGHT_LINE_OUT 0x1B +#define LEFT_SOURCE 0x00 +#define RIGHT_SOURCE 0x01 +#define LINE_IN 0x00 +#define AUX1_IN 0x40 +#define MIC_IN 0x80 +#define MIX_IN 0xC0 +#define LEFT_DAC 0x06 +#define RIGHT_DAC 0x07 +#define LEFT_MIC_IN 0x16 +#define RIGHT_MIC_IN 0x17 +#define _CUPCTI 0x0E +#define _CLPCTI 0x0F +#define _CURCTI 0x1E +#define _CLRCTI 0x1F +#define _CLAX1I 0x02 +#define _CRAX1I 0x03 +#define _CLAX2I 0x04 +#define _CRAX2I 0x05 +#define _CLLICI 0x12 +#define _CRLICI 0x13 +#define _CLOAI 0x19 +#define _CROAI 0x1B +#define _CLICI 0x00 +#define _CRICI 0x01 +#define _CLDACI 0x06 +#define _CRDACI 0x07 +#define _CPVFI 0x1D +/*#######################################################################*/ +/**/ +/* Defines for DMA transfer related operations*/ +/**/ +/*#######################################################################*/ +#define MAX_DMA 0x07 +#define DMA_DECREMENT 0x20 +#define AUTO_INIT 0x10 +#define DMA_READ 0x01 +#define DMA_WRITE 0x02 +#define AUTO_READ 0x03 +#define AUTO_WRITE 0x04 +#define IDMA_INV 0x0400 +#define IDMA_WIDTH_16 0x0100 +/*#######################################################################*/ +/**/ +/* Bits for dma flags within a DMA structure.*/ +/**/ +/*#######################################################################*/ +#define DMA_USED 0x0001 + +#define DMA_SPLIT 0x0004 /* DMA Controller Page Crossover*/ +#define CODEC_DMA 0x0008 /* Indicates a Codec DMA*/ +#define DMA_WAIT 0x0020 /* Wait for DMA xfer to complete*/ +#define DMA_DOWN 0x0040 /* DMA xfer from PC to InterWave*/ +#define DRAM_HOLES 0x8000 /* Indicates Non-contiguous RAM configuration*/ +#define DMA_UP 0xFFBF /* DMA xfer from InterWave to PC */ +/*#######################################################################*/ +/**/ +/* Bits for DMA Control Register (LDMACI)*/ +/**/ +/*#######################################################################*/ +#define _LDMACI 0x41 /* Index */ +#define DMA_INV 0x80 +#define DMA_IRQ_ENABLE 0x20 +#define DMA_IRQ_PENDING 0x40 /* on reads of LDMACI[6] */ +#define DMA_DATA_16 0x40 /* on writes to LDMACI[6] */ +#define DMA_WIDTH_16 0x04 /* 1=16-bit, 0=8-bit (DMA channel) */ +#define DMA_RATE 0x18 /* 00=fastest,...,11=slowest */ +#define DMA_UPLOAD 0x02 /* From LM to PC */ +#define DMA_ENABLE 0x01 +/*#######################################################################*/ +/**/ +/* DMA Transfer Rates*/ +/**/ +/*#######################################################################*/ +#define DMA_R0 0xE7 /* Fastest (use ANDing to set) */ +#define DMA_R1 0x08 +#define DMA_R2 0x10 +#define DMA_R3 0x18 /* Slowest */ +/*#######################################################################*/ +/**/ +/* Interrupt Controller Defines*/ +/**/ +/*#######################################################################*/ +#define IW_HANDLERS_ON 0x80 /* Flag for when IVT is modified */ +#define EOI 0x20 +#define OCR1 0x20 /* 8259-1 Operation Control Reg. */ +#define IMR1 0x21 /* 8259-1 Interrupt Mask Reg. */ +#define OCR2 0xA0 /* 8259-2 Operation Control Reg. */ +#define IMR2 0xA1 /* 8259-2 Interrupt Mask Reg. */ +#define IRQ0_UNMASK 0xFE /* Mask to clear bit 0 in IMR */ +#define IRQ1_UNMASK 0xFD +#define IRQ2_UNMASK 0xFB +#define IRQ3_UNMASK 0xF7 +#define IRQ4_UNMASK 0xEF +#define IRQ5_UNMASK 0xDF +#define IRQ6_UNMASK 0xBF +#define IRQ7_UNMASK 0x7F +#define IRQ8_UNMASK 0xFE /* Mask to clear bit 0 in IMR */ +#define IRQ9_UNMASK 0xFD +#define IRQ10_UNMASK 0xFB +#define IRQ11_UNMASK 0xF7 +#define IRQ12_UNMASK 0xEF +#define IRQ13_UNMASK 0xDF +#define IRQ14_UNMASK 0xBF +#define IRQ15_UNMASK 0x7F +#define IRQ0_EOI 0x60 /* Spec EOI for IRQ0 */ +#define IRQ1_EOI 0x61 +#define IRQ2_EOI 0x62 +#define IRQ3_EOI 0x63 +#define IRQ4_EOI 0x64 +#define IRQ5_EOI 0x65 +#define IRQ6_EOI 0x66 +#define IRQ7_EOI 0x67 +#define IRQ8_EOI 0x60 /* Spec EOI for IRQ8 */ +#define IRQ9_EOI 0x61 +#define IRQ10_EOI 0x62 +#define IRQ11_EOI 0x63 +#define IRQ12_EOI 0x64 +#define IRQ13_EOI 0x65 +#define IRQ14_EOI 0x66 +#define IRQ15_EOI 0x67 +/*#######################################################################*/ +/**/ +/* Generic defines*/ +/**/ +/*#######################################################################*/ +/**/ +#define MEMBANK0 0L /* Addr of Memory Bank 0*/ +#define MEMBANK1 4194304L /* Addr of Memory Bank 1*/ +#define MEMBANK2 8388608L /* Addr of Memory Bank 2*/ +#define MEMBANK3 12582912L /* Addr of Memory Bank 3*/ +#define IRQ_UNAVAIL 0x0000 +#define IRQ_AVAIL 0x0001 +#define IRQ_USED 0x0002 +#define MAX_IRQ 16 +#define NEXT_OFFSET 0L +#define PREV_OFFSET 4L +#define SIZE_OFFSET 8L +#define MEM_HEADER_SIZE 12L +#define GF1_POOL (usigned long)(256L*1024L) +#define GUS_MODE 0x00 /* SGMI[0]=0*/ +#define ENH_MODE 0x01 /* SGMI[0]=1*/ +#define ENABLE_LFOS 0x02 /* SGMI[1]*/ +#define NO_WAVETABLE 0x04 /* SGMI[2]*/ +#define RAM_TEST 0x08 /* SGMI[3]*/ +#define TRUE 1 +#define FALSE 0 +#define ON 1 +#define OFF 0 +#define AUDIO 0 +#define EXT 1 +#define GAME 2 +#define EMULATION 3 +#define MPU401 4 +#define AUDIO_EXT 2 +#define ALLOC_FAILURE 0xFFFFFFFFL +#define MEM_EXHAUSTED 0xFFFFFFFFL +#define RAM_MAX 16777216L +#define RAM_STEP 65536L +#define BANK_MAX 4194304L +#define ILLEGAL_SIZE -1 +#define MEM_INIT 1 +#define NO_NEXT 0xFFFFFFFFL +#define NO_PREV NO_NEXT +#define DMA_BAD_ADDR -1 +#define DMA_ON -1 +#define DMA_OK 1 +#define MIDI_TX_IRQ 0x01 +#define MIDI_RX_IRQ 0x02 +#define ALIB_TIMER1_IRQ 0x04 +#define ALIB_TIMER2_IRQ 0x08 +#define WAVETABLE_IRQ 0x20 +#define ENVELOPE_IRQ 0x40 +#define DMA_TC_IRQ 0x80 +#define DMA_SET_MASK 0x04 +#define PNP_DATA_RDY 1 /* PRESSI[0] */ +#define IWAVE_ABSENT 2 +#define IWAVE_OPEN 4 +#define IWAVE_OK 5 +#define BAD_VOICES -1 +#define PNP_ABSENT 0xFF /* No PNP cards in system */ +#define DPMI_INT 0x31 +#define _PCCCI 0x02 +#define _PCSNI 0x06 +#define _PIDXR 0x279 +#define _PNPWRP 0xA79 +#define _LDSALI 0x42 +#define _LDSAHI 0x50 +#define _LMALI 0x43 +#define _LMAHI 0x44 +#define _LMCFI 0x52 +#define _LMCI 0x53 +#define _LDIBI 0x58 +#define _LDICI 0x57 +#define _LMSBAI 0x51 +#define _SVCI_RD 0x8D +#define _SVCI_WR 0x0D +#define _SACI_RD 0x80 +#define _SACI_WR 0x00 +#define _SALI_RD 0x8B +#define _SALI_WR 0x0B +#define _SAHI_RD 0x8A +#define _SAHI_WR 0x0A +#define _SASHI_RD 0x82 +#define _SASHI_WR 0x02 +#define _SASLI_RD 0x83 +#define _SASLI_WR 0x03 +#define _SAEHI_RD 0x84 +#define _SAEHI_WR 0x04 +#define _SAELI_RD 0x85 +#define _SAELI_WR 0x05 +#define _SVRI_RD 0x86 +#define _SVRI_WR 0x06 +#define _SVSI_RD 0x87 +#define _SVSI_WR 0x07 +#define _SVEI_RD 0x88 +#define _SVEI_WR 0x08 +#define _SVLI_RD 0x89 +#define _SVLI_WR 0x09 +#define _SROI_RD 0x8C +#define _SROI_WR 0x0C +#define _SLOI_RD 0x93 +#define _SLOI_WR 0x13 +#define _SMSI_RD 0x95 +#define _SMSI_WR 0x15 +#define _SGMI_RD 0x99 +#define _SGMI_WR 0x19 +#define _SFCI_RD 0x81 +#define _SFCI_WR 0x01 +#define _SUAI_RD 0x90 +#define _SUAI_WR 0x10 +#define _SVII 0x8F +#define _CMODEI 0x0C /* index for CMODEI */ +#define _CFIG3I 0x11 +#define _CFIG2I 0x10 +#define _CLTIMI 0x14 +#define _CUTIMI 0x15 +#define _CSR3I 0x18 /* Index to CSR3I (Interrupt Status) */ +#define _CEXTI 0x0A /* Index to External Control Register */ +#define _CFIG1I 0x09 /* Index to Codec Conf Reg 1 */ +#define _CSR2I 0x0B /* Index to Codec Stat Reg 2 */ +#define _CPDFI 0x08 /* Index to Play Data Format Reg */ +#define _CRDFI 0x1C /* Index to Rec Data Format Reg */ +#define _CLMICI 0x16 /* Index to Left Mic Input Ctrl Register */ +#define _CRMICI 0x17 /* Index to Right Mic Input Ctrl Register */ +#define _CLCI 0x0D /* Index to Loopback Ctrl Register */ +#define _IVERI 0x5B /* Index to register IVERI */ +#define CODEC_MODE1 0x00 +#define CODEC_MODE2 0x40 +#define CODEC_MODE3 0x6C /* Enhanced Mode */ +#define CODEC_STATUS1 0x01 +#define CODEC_STATUS2 0x0B /* Index to CSR2I */ +#define CODEC_STATUS3 0x18 /* Index to CSR3I */ +#define PLAYBACK 0x01 /* Enable playback path CFIG1I[0]=1*/ +#define RECORD 0x02 /* Enable Record path CFIG1I[1]=1*/ +#define TIMER_ENABLE 0x40 /* CFIG2I[6] */ +#define CODEC_MCE 0x40 /* CIDXR[6] */ +#define CALIB_IN_PROGRESS 0x20 /* CSR2I[5] */ +#define CODEC_INIT 0x80 /* CIDXR[7] */ +#define BIT16_BIG 0xC0 /* 16-bit signed, big endian */ +#define IMA_ADPCM 0xA0 /* IMA-compliant ADPCM */ +#define BIT8_ALAW 0x60 /* 8-bit A-law */ +#define BIT16_LITTLE 0x40 /* 16-bit signed, lillte endian */ +#define BIT8_ULAW 0x20 /* 8-bit u-law */ +#define BIT8_LINEAR 0x00 /* 8-bit unsigned */ +#define REC_DFORMAT 0x1C +#define PLAY_DFORMAT 0x08 +#define DMA_ACCESS 0x00 +#define PIO_ACCESS 0xC0 +#define DMA_SIMPLEX 0x04 +#define STEREO 0x10 /* CxDFI[4] */ +#define XTAL1 0x00 /* CxDFI[4]=0 selects 24.5Mhz XTAL */ +#define XTAL2 0x01 /* CxDFI[4]=1 selects 16.9Mhz XTAL */ +#define AUTOCALIB 0x08 /* CFIG1I[3] */ +#define ROM_IO 0x02 /* ROM I/O cycles - LMCI[1]=1 */ +#define DRAM_IO 0x4D /* DRAM I/O cycles - LMCI[1]=0 */ +#define AUTOI 0x01 /* LMCI[0]=1 */ +#define _PLDNI 0x07 +#define ACTIVATE_DEV 0x30 +#define _PWAKEI 0x03 /* Index for PWAKEI */ +#define _PISOCI 0x01 /* Index for PISOCI */ +#define _PSECI 0xF1 /* Index for PSECI */ +#define RANGE_IOCHK 0x31 /* PURCI or PRRCI Index */ +#define MIDI_RESET 0x03 +#define IO_OK 5 /* No IO conflict flag */ +#define IO_CONFLICT 6 /* IO Conflict detected */ +#define IO_0x55 0x01 +#define IO_0xAA 0xFE +/*#######################################################################*/ +/**/ +/* Defines for Sound Handlers in "iw".*/ +/**/ +/*#######################################################################*/ +#define PLAY_DMA_HANDLER 0x01 +#define REC_DMA_HANDLER 0x02 +#define MIDI_TX_HANDLER 0x03 +#define MIDI_RX_HANDLER 0x04 +#define TIMER1_HANDLER 0x05 +#define TIMER2_HANDLER 0x06 +#define WAVE_HANDLER 0x07 +#define VOLUME_HANDLER 0x08 +#define CODEC_TIMER_HANDLER 0x09 +#define CODEC_PLAY_HANDLER 0x0A +#define CODEC_REC_HANDLER 0x0B +#define AUX_HANDLER 0x0C +/*#######################################################################*/ +/**/ +/* Mapping for System Control Regs.*/ +/**/ +/*#######################################################################*/ +#define UMCR 0x00010000 /* Mix Control Reg.*/ +#define UISR 0x00020006 /* IRQ Stat Reg. (read) */ +#define U2X6R 0x00030006 /* SB 2X6 reg */ +#define UACWR 0x00040008 /* AdLib Command Write Reg */ +#define UASRR 0x00050008 /* AdLib Stat Read Reg */ +#define UADR 0x00060009 /* AdLib Data Register */ +#define UACRR 0x0007000A /* AdLib Cmd Read Reg */ +#define UASWR 0x0008000A /* AdLib Stat Write Reg */ +#define UHRDP 0x0009000B /* Hidden Reg Data Port */ +#define UI2XCR 0x000A000C /* SB IRQ 2xC Reg */ +#define U2XCR 0x000B000D /* SB 2xC Reg. (No IRQ) */ +#define U2XER 0x000C000E /* SB 2xE Reg. */ +#define URCR 0x000D000F /* Reg Control Register */ +#define USRR 0x000E000F /* Status Read Register */ +#define UDCI 0x000F000B /* DMA Channel Control Reg */ +#define UICI 0x0010000B /* Interrupt Ctrl Reg */ +#define UGP1I 0x0011010B /* GP Reg 1 (Back Door) */ +#define UGP2I 0x0012020B /* GP Reg 2 (Back Door) */ +#define UGPA1I 0x0013030B /* GP reg 1 Address */ +#define UGPA2I 0x0014040B /* GP reg 2 Address */ +#define UCLRII 0x0015050B /* Clear Interrupt Reg */ +#define UJMPI 0x0016060B /* Jumper Register */ +#define UGP1II 0x0017000B /* Gen. Purp Reg 1(Emulation) */ +#define UGP2II 0x0018000B /* Gen. Purp Reg 2(Emulation) */ +#define GGCR 0x00190201 /* Game Control Register */ +#define GMCR 0x001A0000 /* MIDI Control Register */ +#define GMSR 0x001B0000 /* MIDI Status Reg. */ +#define GMTDR 0x001C0001 /* MIDI xmit data reg */ +#define GMRDR 0x001D0001 /* MIDI rcv data reg */ +#define SVSR 0x001E0002 /* Synth Voice Select Reg */ +#define IGIDXR 0x001F0003 /* General Index Register */ +#define I16DP 0x00200004 /* General 16-bit Data Port */ +#define I8DP 0x00210005 /* General 8-bit Data Port */ +/*#######################################################################*/ +/**/ +/* Synth defines*/ +/**/ +/*#######################################################################*/ +#define SACI 0x00220005 /* Synth Addr Control */ +#define SFCI 0x00230104 /* Synth Freq Control */ +#define SASHI 0x00240204 /* Synth Addr Start High */ +#define SASLI 0x00250304 /* Synth Addr Start Low */ +#define SAEHI 0x00260404 /* Synth Addr End High */ +#define SAELI 0x00270504 /* Synth Addr End Low */ +#define SVRI 0x00280605 /* Synth Volume Rate */ +#define SVSI 0x00290705 /* Synth Volume Start */ +#define SVEI 0x002A0805 /* Synth Volume End */ +#define SVLI 0x002B0904 /* Synth Volume Level */ +#define SAHI 0x002C0A04 /* Synth Address High */ +#define SALI 0x002D0B04 /* Synth Address Low */ +#define SROI 0x002E0C04 /* Synth Right Offset */ +#define SVCI 0x002F0D05 /* Synth Volume Control */ +#define SAVI 0x00300E05 /* Synth Active Voices */ +#define SVII 0x00318F05 /* Synth Voice IRQ */ +#define SUAI 0x00321005 /* Synth Upper Addr */ +#define SEAHI 0x00331104 /* Synth Effect Addr High */ +#define SEALI 0x00341204 /* Synth Effect Addr Low */ +#define SLOI 0x00351304 /* Synth Left Offset */ +#define SEASI 0x00361405 /* Synth Effects Accum Sel */ +#define SMSI 0x00371505 /* Synth Mode Select */ +#define SEVI 0x00381604 /* Synth Effect Volume */ +#define SFLFOI 0x00391705 /* Synth Freq LFO */ +#define SVLFOI 0x003A1805 /* Synth Vol LFO */ +#define SGMI 0x003B1905 /* Synth Global Mode */ +#define SLFOBI 0x003C1A04 /* Synth LFO Base Address */ +#define SROFI 0x003D1B04 +#define SLOFI 0x003E1C04 +#define SEVFI 0x003F1D04 +#define SVIRI 0x00409F05 /* Synth Voice Read IRQ */ +#define LDMACI 0x00414105 /* DMA Control Reg. */ +#define LDSALI 0x00424204 /* LMC DMA Start Addr. Low Reg. */ +#define LMALI 0x00434304 /* LMC Addr Low (I/O) */ +#define LMAHI 0x00444405 /* LMC Addr High (I/O) */ +#define UASBCI 0x00454505 /* Adlib-SB Control */ +#define UAT1I 0x00464605 /* AdLib Timer 1 Count */ +#define UAT2I 0x00474705 /* AdLib Timer 2 Count */ +#define USCI 0x00484905 /* Sample Control Reg */ +#define GJTDI 0x00494B05 +#define URSTI 0x004A4C05 +#define LDSAHI 0x004B5005 +#define LMSBAI 0x004C5104 +#define LMCFI 0x004D5204 +#define LMCI 0x004E5305 +#define LMRFAI 0x004F5404 +#define LMPFAI 0x00505504 +#define LMSFI 0x00515604 +#define LDICI 0x00525704 +#define LDIBI 0x00535804 +#define ICMPTI 0x00545905 +#define IDECI 0x00555A05 +#define IVERI 0x00565B05 +#define IEMUAI 0x00575C05 +#define IEMUBI 0x00585D05 +#define GMRFAI 0x00595E05 +#define ITCI 0x005A5F05 +#define IEIRQI 0x005B6005 +#define LMBDR 0x005C0007 +/*##########################################################*/ +/* Mnemonics for Codec Registers*/ +/*##########################################################*/ +#define CIDXR 0x005D0000 +#define CDATAP 0x005E0001 +#define CSR1R 0x005F0002 +#define CPDR 0x00600003 +#define CRDR 0x00610003 +#define CLICI 0x00620001 +#define CRICI 0x00630101 +#define CLAX1I 0x00640201 +#define CRAX1I 0x00650301 +#define CLAX2I 0x00660401 +#define CRAX2I 0x00670501 +#define CLDACI 0x00680601 +#define CRDACI 0x00690701 +#define CPDFI 0x006A0801 +#define CFIG1I 0x006B0901 +#define CEXTI 0x006C0A01 +#define CSR2I 0x006D0B01 +#define CMODEI 0x006E0C01 +#define CLCI 0x006F0D01 +#define CUPCTI 0x00700E01 +#define CLPCTI 0x00710F01 +#define CFIG2I 0x00721001 +#define CFIG3I 0x00731101 +#define CLLICI 0x00741201 +#define CRLICI 0x00751301 +#define CLTIMI 0x00761401 +#define CUTIMI 0x00771501 +#define CLMICI 0x00781601 +#define CRMICI 0x00791701 +#define CSR3I 0x007A1801 +#define CLOAI 0x007B1901 +#define CMONOI 0x007C1A01 +#define CROAI 0x007D1B01 +#define CRDFI 0x007E1C01 +#define CPVFI 0x007F1D01 +#define CURCTI 0x00801E01 +#define CLRCTI 0x00811F01 +/*##########################################################*/ +/* Mnemonics for PnP Registers*/ +/*##########################################################*/ +#define PCSNBR 0x00820201 +#define PIDXR 0x00830279 +#define PNPWRP 0x00840A79 +#define PNPRDP 0x00850000 +#define PSRPAI 0x00860000 +#define PISOCI 0x00870100 +#define PCCCI 0x00880200 +#define PWAKEI 0x00890300 +#define PRESDI 0x008A0400 +#define PRESSI 0x008B0500 +#define PCSNI 0x008C0600 +#define PLDNI 0x008D0700 +#define PUACTI 0x008E3000 +#define PURCI 0x008F3100 +#define P2X0HI 0x00906000 +#define P2X0LI 0x00916100 +#define P3X0HI 0x00926200 +#define P3X0LI 0x00936300 +#define PHCAI 0x00946400 +#define PLCAI 0x00956500 +#define PUI1SI 0x00967000 +#define PUI1TI 0x00977100 +#define PUI2SI 0x00987200 +#define PUI2TI 0x00997300 +#define PUD1SI 0x009A7400 +#define PUD2SI 0x009B7500 +#define PSEENI 0x009CF000 +#define PSECI 0x009DF100 +#define PPWRI 0x009EF200 +#define PRACTI 0x009F3001 +#define PRRCI 0x00A03101 +#define PRAHI 0x00A16001 +#define PRALI 0x00A26101 +#define PATAHI 0x00A36201 +#define PATALI 0x00A46301 +#define PRISI 0x00A57001 +#define PRITI 0x00A67101 +#define PRDSI 0x00A77401 +#define PGACTI 0x00A83002 +#define PGRCI 0x00A93102 +#define P201HI 0x00AA6002 +#define P201LI 0x00AB6102 +#define PSACTI 0x00AC3003 +#define PSRCI 0x00AD3103 +#define P388HI 0x00AE6003 +#define P388LI 0x00AF6103 +#define PSBISI 0x00B07003 +#define PSBITI 0x00B17103 +#define PMACTI 0x00B23004 +#define PMRCI 0x00B33104 +#define P401HI 0x00B46004 +#define P401LI 0x00B56104 +#define PMISI 0x00B67004 +#define PMITI 0x00B77104 + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned short PORT; +typedef unsigned long DWORD; +typedef unsigned long ADDRESS; +typedef int BOOL; +typedef int FLAG; + +typedef struct + { + short flags; /* InterWave stat flags */ + PORT pcodar; /* Base Port for Codec */ + PORT pcdrar; /* Base Port for Ext Device */ + PORT p2xr; /* Compatibility Base Port */ + PORT p3xr; /* MIDI and Synth Base Port */ + PORT p401ar; /* Gen Purpose Reg. 1 address */ + PORT p201ar; /* Game Ctrl normally at 0x201 */ + PORT pataar; /* Base Address for ATAPI I/O Space */ + PORT p388ar; /* Base Port for AdLib. It should be 388h */ + PORT pnprdp; /* PNP read data port */ + PORT igidxr; /* Gen Index Reg at P3XR+0x03 */ + PORT i16dp; /* 16-bit data port at P3XR+0x04 */ + PORT i8dp; /* 8-bit data port at P3XR+0x05 */ + PORT svsr; /* Synth Voice Select at P3XR+0x02 */ + PORT cdatap; /* Codec Indexed Data Port at PCODAR+0x01 */ + PORT csr1r; /* Codec Stat Reg 1 at PCODAR+0x02 */ + PORT cxdr; /* Play or Record Data Reg at PCODAR+0x03 */ + PORT gmxr; /* GMCR or GMSR at P3XR+0x00 */ + PORT gmxdr; /* GMTDR or GMRDR at P3XR+0x01 */ + PORT lmbdr; /* LMBDR at P3XR+0x07 */ + BYTE csn; /* Card Select Number */ + BYTE cmode; /* Codec Operation Mode */ + int dma1_chan; /* DMA channel 1 (local DMA & codec rec) */ + int dma2_chan; /* DMA channel 2 (codec play) */ + int ext_chan; /* Ext Dev DMA channel */ + BYTE voices; /* Number of active voices */ + DWORD vendor; /* Vendor ID and Product Identifier */ + int synth_irq; /* Synth IRQ number */ + int midi_irq; /* MIDI IRQ number */ + int ext_irq; /* Ext Dev IRQ */ + int mpu_irq; /* MPU401 Dev IRQ */ + int emul_irq; /* Sound Blaster/AdLib Dev IRQ */ + ADDRESS free_mem; /* Address of First Free LM Block */ + DWORD reserved_mem; /* Amount of LM reserved by app. */ + BYTE smode; /* Synth Mode */ + WORD size_mem; /* Total LM in Kbytes */ + + } IWAVE; + +#endif diff --git a/sys/i386/isa/sound/mad16.c b/sys/i386/isa/sound/mad16.c new file mode 100644 index 000000000000..0e2064a97b8a --- /dev/null +++ b/sys/i386/isa/sound/mad16.c @@ -0,0 +1,524 @@ +/* + * sound/mad16.c + * + * Initialization code for OPTi MAD16 compatible audio chips. Including + * + * OPTi 82C928 MAD16 (replaced by C929) OAK OTI-601D Mozart + * OPTi 82C929 MAD16 Pro + * + * These audio interface chips don't prduce sound themselves. They just connect + * some other components (OPL-[234] and a WSS compatible codec) to the PC bus + * and perform I/O, DMA and IRQ address decoding. There is also a UART for + * the MPU-401 mode (not 82C928/Mozart). The Mozart chip appears to be + * compatible with the 82C928 (can anybody confirm this?). + * + * NOTE! If you want to set CD-ROM address and/or joystick enable, define + * MAD16_CONF in local.h as combination of the following bits: + * + * 0x01 - joystick disabled + * + * CD-ROM type selection (select just one): 0x00 - none 0x02 - Sony 31A + * 0x04 - Mitsumi 0x06 - Panasonic (type "LaserMate", not + * "SoundBlaster") 0x08 - Secondary IDE (address 0x170) 0x0a - Primary + * IDE (address 0x1F0) + * + * For example Mitsumi with joystick disabled = 0x04|0x01 = 0x05 For example + * LaserMate (for use with sbpcd) plus joystick = 0x06 + * + * MAD16_CDSEL: This defaults to CD I/O 0x340, no IRQ and DMA3 (DMA5 with + * Mitsumi or IDE). If you like to change these, define MAD16_CDSEL with the + * following bits: + * + * CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320 OPL4 select: 0x20=OPL4, + * 0x00=OPL3 CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0a=IRQ3, + * 0x10=IRQ9, 0x14=IRQ10 and 0x18=IRQ11. + * + * CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or + * 0x03=disabled or CD-ROM DMA (Mitsumi or IDE): 0x00=DMA5, 0x01=DMA6, + * 0x02=DMA7 or 0x03=disabled + * + * For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23. + * + * Copyright by Hannu Savolainen 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <i386/isa/sound/sound_config.h> + +#if defined(CONFIG_MAD16) + +static int already_initialized = 0; + +#define C928 1 +#define MOZART 2 +#define C929 3 + +/* + * Registers + * + * The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations). All ports are + * inactive by default. They can be activated by writing 0xE2 or 0xE3 to the + * password register. The password is valid only until the next I/O read or + * write. + */ + +#define MC1_PORT 0xf8d /* SB address, CDROM interface type, joystick */ +#define MC2_PORT 0xf8e /* CDROM address, IRQ, DMA, plus OPL4 bit */ +#define MC3_PORT 0xf8f +#define PASSWD_REG 0xf8f +#define MC4_PORT 0xf90 +#define MC5_PORT 0xf91 +#define MC6_PORT 0xf92 +#define MC7_PORT 0xf93 + +static int board_type = C928; + +static sound_os_info *mad16_osp; + +#ifndef DDB +#define DDB(x) +#endif + +static unsigned char +mad_read(int port) +{ + unsigned long flags; + unsigned char tmp; + + flags = splhigh(); + + switch (board_type) { /* Output password */ + case C928: + case MOZART: + outb(PASSWD_REG, 0xE2); + break; + + case C929: + outb(PASSWD_REG, 0xE3); + break; + } + + tmp = inb(port); + splx(flags); + + return tmp; +} + +static void +mad_write(int port, int value) +{ + unsigned long flags; + + flags = splhigh(); + + switch (board_type) { /* Output password */ + case C928: + case MOZART: + outb(PASSWD_REG, 0xE2); + break; + + case C929: + outb(PASSWD_REG, 0xE3); + break; + } + + outb(port, (unsigned char) (value & 0xff)); + splx(flags); +} + +static int +detect_mad16(void) +{ + unsigned char tmp, tmp2; + + /* + * Check that reading a register doesn't return bus float (0xff) when + * the card is accessed using password. This may fail in case the + * card is in low power mode. Normally at least the power saving mode + * bit should be 0. + */ + if ((tmp = mad_read(MC1_PORT)) == 0xff) { + DDB(printf("MC1_PORT returned 0xff\n")); + return 0; + } + /* + * Now check that the gate is closed on first I/O after writing the + * password. (This is how a MAD16 compatible card works). + */ + + if ((tmp2 = inb(MC1_PORT)) == tmp) { /* It didn't close */ + DDB(printf("MC1_PORT didn't close after read (0x%02x)\n", tmp2)); + return 0; + } + mad_write(MC1_PORT, tmp ^ 0x80); /* Togge a bit */ + + if ((tmp2 = mad_read(MC1_PORT)) != (tmp ^ 0x80)) { /* Compare the bit */ + mad_write(MC1_PORT, tmp); /* Restore */ + DDB(printf("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2)); + return 0; + } + mad_write(MC1_PORT, tmp); /* Restore */ + return 1; /* Bingo */ + +} + +int +probe_mad16(struct address_info * hw_config) +{ + int i; + static int valid_ports[] = + {0x530, 0xe80, 0xf40, 0x604}; + unsigned char tmp; + unsigned char cs4231_mode = 0; + + int ad_flags = 0; + + if (already_initialized) + return 0; + + mad16_osp = hw_config->osp; + /* + * Check that all ports return 0xff (bus float) when no password is + * written to the password register. + */ + + DDB(printf("--- Detecting MAD16 / Mozart ---\n")); + + + /* + * Then try to detect with the old password + */ + board_type = C928; + + DDB(printf("Detect using password = 0xE2\n")); + + if (!detect_mad16()) { /* No luck. Try different model */ + board_type = C929; + + DDB(printf("Detect using password = 0xE3\n")); + + if (!detect_mad16()) + return 0; + + DDB(printf("mad16.c: 82C929 detected\n")); + } else { + unsigned char model; + + if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) { + DDB(printf("mad16.c: Mozart detected\n")); + board_type = MOZART; + } else { + DDB(printf("mad16.c: 82C928 detected???\n")); + board_type = C928; + } + } + + for (i = 0xf8d; i <= 0xf93; i++) + DDB(printf("port %03x = %03x\n", i, mad_read(i))); + + /* + * Set the WSS address + */ + + tmp = 0x80; /* Enable WSS, Disable SB */ + + for (i = 0; i < 5; i++) { + if (i > 3) { /* Not a valid port */ + printf("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base); + return 0; + } + if (valid_ports[i] == hw_config->io_base) { + tmp |= i << 4; /* WSS port select bits */ + break; + } + } + + /* + * Set optional CD-ROM and joystick settings. + */ + +#ifdef MAD16_CONF + tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */ +#endif + mad_write(MC1_PORT, tmp); + +#if defined(MAD16_CONF) && defined(MAD16_CDSEL) + tmp = MAD16_CDSEL; +#else + tmp = 0x03; +#endif + +#ifdef MAD16_OPL4 + tmp |= 0x20; /* Enable OPL4 access */ +#endif + + mad_write(MC2_PORT, tmp); + mad_write(MC3_PORT, 0xf0); /* Disable SB */ + + if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp)) + return 0; + + if (ad_flags & (AD_F_CS4231 | AD_F_CS4248)) + cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */ + + if (board_type == C929) { + mad_write(MC4_PORT, 0xa2); + mad_write(MC5_PORT, 0xA5 | cs4231_mode); + mad_write(MC6_PORT, 0x03); /* Disable MPU401 */ + } else { + mad_write(MC4_PORT, 0x02); + mad_write(MC5_PORT, 0x30 | cs4231_mode); + } + + for (i = 0xf8d; i <= 0xf93; i++) + DDB(printf("port %03x after init = %03x\n", i, mad_read(i))); + + /* + * Verify the WSS parameters + */ + + if (0) { + printf("MSS: I/O port conflict\n"); + return 0; + } + /* + * Check if the IO port returns valid signature. The original MS + * Sound system returns 0x04 while some cards (AudioTriX Pro for + * example) return 0x00. + */ + + if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 && + (inb(hw_config->io_base + 3) & 0x3f) != 0x00) { + DDB(printf("No MSS signature detected on port 0x%x (0x%x)\n", + hw_config->io_base, inb(hw_config->io_base + 3))); + return 0; + } + if (hw_config->irq > 11) { + printf("MSS: Bad IRQ %d\n", hw_config->irq); + return 0; + } + if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) { + printf("MSS: Bad DMA %d\n", hw_config->dma); + return 0; + } + /* + * Check that DMA0 is not in use with a 8 bit board. + */ + + if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80) { + printf("MSS: Can't use DMA0 with a 8 bit card/slot\n"); + return 0; + } + if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80) { + printf("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); + return 0; + } + return 1; +} + +void +attach_mad16(struct address_info * hw_config) +{ + + static char interrupt_bits[12] = + { + -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20 + }; + char bits; + + static char dma_bits[4] = + { + 1, 2, 0, 3 + }; + + int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3; + int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2; + unsigned char dma2_bit = 0; + + already_initialized = 1; + + if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp)) + return; + + /* + * Set the IRQ and DMA addresses. + */ + + bits = interrupt_bits[hw_config->irq]; + if (bits == -1) + return; + + outb(config_port, bits | 0x40); + if ((inb(version_port) & 0x40) == 0) + printf("[IRQ Conflict?]"); + + /* + * Handle the capture DMA channel + */ + + if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma) { + if ((dma == 0 && dma2 == 1) || + (dma == 1 && dma2 == 0) || + (dma == 3 && dma2 == 0)) { + dma2_bit = 0x04; /* Enable capture DMA */ + } else { + printf("MAD16: Invalid capture DMA\n"); + dma2 = dma; + } + } else + dma2 = dma; + + outb(config_port, bits | dma_bits[dma] | dma2_bit); /* Write IRQ+DMA setup */ + + ad1848_init("MAD16 WSS", hw_config->io_base + 4, + hw_config->irq, + dma, + dma2, 0, + hw_config->osp); +} + +void +attach_mad16_mpu(struct address_info * hw_config) +{ + if (board_type < C929) {/* Early chip. No MPU support. Just SB MIDI */ +#ifdef CONFIG_MIDI + + if (mad_read(MC1_PORT) & 0x20) + hw_config->io_base = 0x240; + else + hw_config->io_base = 0x220; + + return mad16_sb_dsp_init(hw_config); +#else + return 0; +#endif + } +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + if (!already_initialized) + return; + + attach_mpu401(hw_config); +#endif +} + +int +probe_mad16_mpu(struct address_info * hw_config) +{ +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + static int mpu_attached = 0; + static int valid_ports[] = + {0x330, 0x320, 0x310, 0x300}; + static short valid_irqs[] = + {9, 10, 5, 7}; + unsigned char tmp; + + int i; /* A variable with secret power */ + + if (!already_initialized) /* The MSS port must be initialized + * first */ + return 0; + + if (mpu_attached) /* Don't let them call this twice */ + return 0; + mpu_attached = 1; + + if (board_type < C929) {/* Early chip. No MPU support. Just SB MIDI */ + +#ifdef CONFIG_MIDI + unsigned char tmp; + + tmp = mad_read(MC3_PORT); + + /* + * MAD16 SB base is defined by the WSS base. It cannot be + * changed alone. Ignore configured I/O base. Use the active + * setting. + */ + + if (mad_read(MC1_PORT) & 0x20) + hw_config->io_base = 0x240; + else + hw_config->io_base = 0x220; + + switch (hw_config->irq) { + case 5: + tmp = (tmp & 0x3f) | 0x80; + break; + case 7: + tmp = (tmp & 0x3f); + break; + case 11: + tmp = (tmp & 0x3f) | 0x40; + break; + default: + printf("mad16/Mozart: Invalid MIDI IRQ\n"); + return 0; + } + + mad_write(MC3_PORT, tmp | 0x04); + return mad16_sb_dsp_detect(hw_config); +#else + return 0; +#endif + } + tmp = 0x83; /* MPU-401 enable */ + + /* + * Set the MPU base bits + */ + + for (i = 0; i < 5; i++) { + if (i > 3) { /* Out of array bounds */ + printf("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base); + return 0; + } + if (valid_ports[i] == hw_config->io_base) { + tmp |= i << 5; + break; + } + } + + /* + * Set the MPU IRQ bits + */ + + for (i = 0; i < 5; i++) { + if (i > 3) { /* Out of array bounds */ + printf("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq); + return 0; + } + if (valid_irqs[i] == hw_config->irq) { + tmp |= i << 3; + break; + } + } + mad_write(MC6_PORT, tmp); /* Write MPU401 config */ + + return probe_mpu401(hw_config); +#else + return 0; +#endif +} + +/* That's all folks */ +#endif diff --git a/sys/i386/isa/sound/mad16.h b/sys/i386/isa/sound/mad16.h new file mode 100644 index 000000000000..0370973667a4 --- /dev/null +++ b/sys/i386/isa/sound/mad16.h @@ -0,0 +1,91 @@ + +/* + * Initialization code for OPTI MAD16 interface chip by + * Davor Jadrijevic <davor@emard.pub.hr> + * (Included by ad1848.c when MAD16 support is enabled) + * + * It looks like MAD16 is similar than the Mozart chip (OAK OTI-601). + * It could be even possible that these chips are exactly the same. Can + * anybody confirm this? + */ + +static void wr_a_mad16(int base, int v, int a) +{ + OUTB(a, base + 0xf); + OUTB(v, base + 0x11); +} + +static void wr_b_mad16(int base, int v, int a) +{ + OUTB(a, base + 0xf); + OUTB(v, base + 0xd); +} + +/* +static int rd_a_mad16(int base, int a) +{ + OUTB(a, base + 0xf); + return INB(base + 0x11); +} +*/ + +static int rd_b_mad16(int base, int a) +{ + OUTB(a, base + 0xf); + return INB(base + 0xd); +} + +/* +static int rd_0_mad16(int base, int a) +{ + OUTB(a, base + 0xf); + return INB(base + 0xf); +} + +static void wr_ad(int base, int v, int a) +{ + OUTB(a, base + 4); + OUTB(v, base + 5); +} + +static int rd_ad(int base, int a) +{ + OUTB(a, base + 4); + return INB(base + 5); +} +*/ + +static int mad16init(int adr) +{ + int j; + long i; + + static int ad1848_bases[] = +{ 0x220, -1, -1, 0x240, -1, -1, -1, -1, 0x530, 0xE80, 0xF40, 0x604, 0 }; + + int mad16_base = 0xf80, ad1848_base; + + + for(j = 0; (j < 16) && (ad1848_bases[j] != 0); j++) + if(adr == ad1848_bases[j]) + break; + + if( (ad1848_base = ad1848_bases[j]) < 0x530) + { + printk("Unknown MAD16 setting 0x%3X\n", adr); + return -1; + } + + /* printk("OPTi MAD16 WSS at 0x%3X\n", ad1848_base); */ + + rd_b_mad16(mad16_base, 0xe2); + wr_a_mad16(mad16_base, 0x1a, 0xe2); + wr_b_mad16(mad16_base, j * 16 + 1, 0xe2); + wr_a_mad16(mad16_base, 0x1a, 0xe2); + for( i = 0; i < 10000; i++) + if( (INB(ad1848_base+4) & 0x80) == 0 ) + break; + + return 0; +}; + diff --git a/sys/i386/isa/sound/mad16_sb_midi.c b/sys/i386/isa/sound/mad16_sb_midi.c new file mode 100644 index 000000000000..d1b3ad0167cc --- /dev/null +++ b/sys/i386/isa/sound/mad16_sb_midi.c @@ -0,0 +1,285 @@ +/* + * sound/mad16_sb_midi.c + * + * The low level driver for MAD16 SoundBlaster-DS-chip-based MIDI. + * + * Copyright by Hannu Savolainen 1993, Aaron Ucko 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <i386/isa/sound/sound_config.h> + +#if defined(CONFIG_MAD16) && defined(CONFIG_MIDI) + +#define sbc_base mad16_sb_base +#include <i386/isa/sound/sb_card.h> + +static int input_opened = 0; +static int my_dev; +static int mad16_sb_base = 0x220; +static int mad16_sb_irq = 0; +static int mad16_sb_dsp_ok = 0; +static sound_os_info *midi_osp; + +int mad16_sb_midi_mode = NORMAL_MIDI; +int mad16_sb_midi_busy = 0; + +int mad16_sb_duplex_midi = 0; +volatile int mad16_sb_intr_active = 0; + +void (*midi_input_intr) (int dev, unsigned char data); + +static void mad16_sb_midi_init(int model); + +static int +mad16_sb_dsp_command(unsigned char val) +{ + int i; + unsigned long limit; + + limit = get_time() + hz / 10; /* The timeout is 0.1 secods */ + + /* + * Note! the i<500000 is an emergency exit. The + * mad16_sb_dsp_command() is sometimes called while interrupts are + * disabled. This means that the timer is disabled also. However the + * timeout situation is a abnormal condition. Normally the DSP should + * be ready to accept commands after just couple of loops. + */ + + for (i = 0; i < 500000 && get_time() < limit; i++) { + if ((inb(DSP_STATUS) & 0x80) == 0) { + outb(DSP_COMMAND, val); + return 1; + } + } + + printf("MAD16 (SBP mode): DSP Command(%x) Timeout.\n", val); + printf("IRQ conflict???\n"); + return 0; +} + +void +mad16_sbintr(int irq) +{ + int status; + + unsigned long flags; + unsigned char data; + + status = inb(DSP_DATA_AVAIL); /* Clear interrupt */ + + flags = splhigh(); + + data = inb(DSP_READ); + if (input_opened) + midi_input_intr(my_dev, data); + + splx(flags); +} + +static int +mad16_sb_reset_dsp(void) +{ + int loopc; + + outb(DSP_RESET, 1); + DELAY(10); + outb(DSP_RESET, 0); + DELAY(30); + + for (loopc = 0; loopc < 100 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++) + DELAY(10); + /* Wait for data available status */ + + if (inb(DSP_READ) != 0xAA) + return 0; /* Sorry */ + + return 1; +} + +int +mad16_sb_dsp_detect(struct address_info * hw_config) +{ + mad16_sb_base = hw_config->io_base; + mad16_sb_irq = hw_config->irq; + midi_osp = hw_config->osp; + + if (mad16_sb_dsp_ok) + return 0; /* Already initialized */ + if (!mad16_sb_reset_dsp()) + return 0; + + return 1; /* Detected */ +} + +void +mad16_sb_dsp_init(struct address_info * hw_config) +/* + * this function now just verifies the reported version and calls + * mad16_sb_midi_init -- everything else is done elsewhere + */ +{ + + midi_osp = hw_config->osp; + if (snd_set_irq_handler(mad16_sb_irq, mad16_sbintr, midi_osp) < 0) { + printf("MAD16 SB MIDI: IRQ not free\n"); + return; + } + + conf_printf("MAD16 MIDI (SB mode)", hw_config); + mad16_sb_midi_init(2); + + mad16_sb_dsp_ok = 1; + return; +} + +static int +mad16_sb_midi_open(int dev, int mode, + void (*input) (int dev, unsigned char data), + void (*output) (int dev) +) +{ + + if (!mad16_sb_dsp_ok) { + printf("MAD16_SB Error: MIDI hardware not installed\n"); + return -(ENXIO); + } + if (mad16_sb_midi_busy) + return -(EBUSY); + + if (mode != OPEN_WRITE && !mad16_sb_duplex_midi) { + if (num_midis == 1) + printf("MAD16 (SBP mode): Midi input not currently supported\n"); + return -(EPERM); + } + mad16_sb_midi_mode = NORMAL_MIDI; + if (mode != OPEN_WRITE) { + if (mad16_sb_intr_active) + return -(EBUSY); + mad16_sb_midi_mode = UART_MIDI; + } + if (mad16_sb_midi_mode == UART_MIDI) { + mad16_sb_reset_dsp(); + + if (!mad16_sb_dsp_command(0x35)) + return -(EIO); /* Enter the UART mode */ + mad16_sb_intr_active = 1; + + input_opened = 1; + midi_input_intr = input; + } + mad16_sb_midi_busy = 1; + + return 0; +} + +static void +mad16_sb_midi_close(int dev) +{ + if (mad16_sb_midi_mode == UART_MIDI) { + mad16_sb_reset_dsp(); /* The only way to kill the UART mode */ + } + mad16_sb_intr_active = 0; + mad16_sb_midi_busy = 0; + input_opened = 0; +} + +static int +mad16_sb_midi_out(int dev, unsigned char midi_byte) +{ + unsigned long flags; + + if (mad16_sb_midi_mode == NORMAL_MIDI) { + flags = splhigh(); + if (mad16_sb_dsp_command(0x38)) + mad16_sb_dsp_command(midi_byte); + else + printf("MAD16_SB Error: Unable to send a MIDI byte\n"); + splx(flags); + } else + mad16_sb_dsp_command(midi_byte); /* UART write */ + + return 1; +} + +static int +mad16_sb_midi_start_read(int dev) +{ + if (mad16_sb_midi_mode != UART_MIDI) { + printf("MAD16 (SBP mode): MIDI input not implemented.\n"); + return -(EPERM); + } + return 0; +} + +static int +mad16_sb_midi_end_read(int dev) +{ + if (mad16_sb_midi_mode == UART_MIDI) { + mad16_sb_reset_dsp(); + mad16_sb_intr_active = 0; + } + return 0; +} + +static int +mad16_sb_midi_ioctl(int dev, unsigned cmd, ioctl_arg arg) +{ + return -(EPERM); +} + +#define MIDI_SYNTH_NAME "pseudo-SoundBlaster Midi" +#define MIDI_SYNTH_CAPS 0 +#include <i386/isa/sound/midi_synth.h> + +static struct midi_operations mad16_sb_midi_operations = +{ + {"MAD16 (SBP mode)", 0, 0, SNDCARD_MAD16}, + &std_midi_synth, + {0}, + mad16_sb_midi_open, + mad16_sb_midi_close, + mad16_sb_midi_ioctl, + mad16_sb_midi_out, + mad16_sb_midi_start_read, + mad16_sb_midi_end_read, + NULL, /* Kick */ + NULL, /* command */ + NULL, /* buffer_status */ + NULL +}; + +static void +mad16_sb_midi_init(int model) +{ + if (num_midis >= MAX_MIDI_DEV) { + printf("Sound: Too many midi devices detected\n"); + return; + } + std_midi_synth.midi_dev = num_midis; + my_dev = num_midis; + midi_devs[num_midis++] = &mad16_sb_midi_operations; +} + +#endif diff --git a/sys/i386/isa/sound/maui.c b/sys/i386/isa/sound/maui.c new file mode 100644 index 000000000000..e92b48a4bff2 --- /dev/null +++ b/sys/i386/isa/sound/maui.c @@ -0,0 +1,225 @@ +/* + * sound/maui.c + * + * The low level driver for Turtle Beach Maui and Tropez. + * + * Copyright by Hannu Savolainen 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#define USE_SEQ_MACROS +#define USE_SIMPLE_MACROS + +#include <i386/isa/sound/sound_config.h> + + +#if defined(CONFIG_MAUI) + +static int maui_base = 0x330; + +static volatile int irq_ok = 0; +static sound_os_info *maui_osp; + +#define HOST_DATA_PORT (maui_base + 2) +#define HOST_STAT_PORT (maui_base + 3) +#define HOST_CTRL_PORT (maui_base + 3) + +#define STAT_TX_INTR 0x40 +#define STAT_TX_AVAIL 0x20 +#define STAT_TX_IENA 0x10 +#define STAT_RX_INTR 0x04 +#define STAT_RX_AVAIL 0x02 +#define STAT_RX_IENA 0x01 + +static int (*orig_load_patch) (int dev, int format, snd_rw_buf * addr, + int offs, int count, int pmgr_flag) = NULL; + +static int +maui_read(void) +{ + int timeout; + + for (timeout = 0; timeout < 1000000; timeout++) + if (inb(HOST_STAT_PORT) & STAT_RX_AVAIL) + return inb(HOST_DATA_PORT); + + printf("Maui: Receive timeout\n"); + + return -1; +} + +static int +maui_write(u_char data) +{ + int timeout; + + for (timeout = 0; timeout < 10000000; timeout++) { + if (inb(HOST_STAT_PORT) & STAT_TX_AVAIL) { + outb(HOST_DATA_PORT, data); + return 1; + } + } + + printf("Maui: Write timeout\n"); + + return 0; +} + +void +mauiintr(int irq) +{ + irq_ok = 1; +} + + +int +maui_load_patch(int dev, int format, snd_rw_buf * addr, + int offs, int count, int pmgr_flag) +{ + + struct sysex_info header; + u_long left, src_offs; + int hdr_size = (u_long) &header.data[0] - (u_long) &header; + int i; + + if (format == SYSEX_PATCH) /* Handled by midi_synth.c */ + return orig_load_patch(dev, format, addr, offs, count, pmgr_flag); + + if (format != MAUI_PATCH) { + printf("Maui: Unknown patch format\n"); + } + if (count < hdr_size) { + printf("Maui error: Patch header too short\n"); + return -(EINVAL); + } + count -= hdr_size; + + /* + * Copy the header from user space but ignore the first bytes which + * have been transferred already. + */ + + if (uiomove(&((char *) &header)[offs], hdr_size - offs, addr)) { + printf("sb: Bad copyin()!\n"); + }; + + if (count < header.len) { + printf("Maui warning: Host command record too short (%d<%d)\n", + count, (int) header.len); + header.len = count; + } + left = header.len; + src_offs = 0; + + for (i = 0; i < left; i++) { + u_char data; + uiomove((char *) &(data), 1, addr); + if (i == 0 && !(data & 0x80)) + return -(EINVAL); + + if (maui_write(data) == -1) + return -(EIO); + } + + if ((i = maui_read()) != 0x80) { + if (i != -1) + printf("Maui: Error status %02x\n", i); + + return -(EIO); + } + return 0; +} + +int +probe_maui(struct address_info * hw_config) +{ + int i; + int tmp1, tmp2; + + maui_base = hw_config->io_base; + maui_osp = hw_config->osp; + + if (snd_set_irq_handler(hw_config->irq, mauiintr, maui_osp) < 0) + return 0; + + if (!maui_write(0xCF)) {/* Report hardware version */ + /* snd_release_irq(hw_config->irq); */ + return 0; + } + if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) { + /* snd_release_irq(hw_config->irq); */ + return 0; + } + printf("WaveFront hardware version %d.%d\n", tmp1, tmp2); + + if (!maui_write(0x9F)) /* Report firmware version */ + return 0; + if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) + return 0; + printf("WaveFront firmware version %d.%d\n", tmp1, tmp2); + + if (!maui_write(0x85)) /* Report free DRAM */ + return 0; + tmp1 = 0; + for (i = 0; i < 4; i++) { + tmp1 |= maui_read() << (7 * i); + } + printf("Available DRAM %dk\n", tmp1 / 1024); + + for (i = 0; i < 1000; i++) + if (probe_mpu401(hw_config)) + break; + + return probe_mpu401(hw_config); +} + +void +attach_maui(struct address_info * hw_config) +{ + int this_dev = num_midis; + + conf_printf("Maui", hw_config); + + hw_config->irq *= -1; + attach_mpu401(hw_config); + + if (num_midis > this_dev) { /* The MPU401 driver installed itself */ + struct synth_operations *synth; + + /* + * Intercept patch loading calls so that they canbe handled + * by the Maui driver. + */ + + synth = midi_devs[this_dev]->converter; + + if (synth != NULL) { + orig_load_patch = synth->load_patch; + synth->load_patch = &maui_load_patch; + } else + printf("Maui: Can't install patch loader\n"); + } + return; +} + +#endif diff --git a/sys/i386/isa/sound/mmap_test.c b/sys/i386/isa/sound/mmap_test.c new file mode 100644 index 000000000000..229144939301 --- /dev/null +++ b/sys/i386/isa/sound/mmap_test.c @@ -0,0 +1,274 @@ +/* + * This is a simple program which demonstrates use of mmapped DMA buffer + * of the sound driver directly from application program. + * + * This sample program works (currently) only with Linux, FreeBSD and BSD/OS + * (FreeBSD and BSD/OS require OSS version 3.8-beta16 or later. + * + * Note! Don't use mmapped DMA buffers (direct audio) unless you have + * very good reasons to do it. Programs using this feature will not + * work with all soundcards. GUS (GF1) is one of them (GUS MAX works). + * + * This program requires version 3.5-beta7 or later of OSS + * (3.8-beta16 or later in FreeBSD and BSD/OS). + */ + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <machine/soundcard.h> +#include <sys/time.h> + +main() +{ + int fd, sz, fsz, i, tmp, n, l, have_data=0, nfrag; + int caps; + + int sd, sl=0, sp; + + unsigned char data[500000], *dp = data; + + struct buffmem_desc imemd, omemd; + caddr_t buf; + struct timeval tim; + + unsigned char *op; + + struct audio_buf_info info; + + int frag = 0xffff000c; /* Max # fragments of 2^13=8k bytes */ + + fd_set writeset; + + close(0); + if ((fd=open("/dev/dsp", O_RDWR, 0))==-1) + { + perror("/dev/dsp"); + exit(-1); + } +/* + * Then setup sampling parameters. Just sampling rate in this case. + */ + + tmp = 8000; + ioctl(fd, SNDCTL_DSP_SPEED, &tmp); + +/* + * Load some test data. + */ + + sl = sp = 0; + if ((sd=open("smpl", O_RDONLY, 0))!=-1) + { + sl = read(sd, data, sizeof(data)); + printf("%d bytes read from file.\n", sl); + close(sd); + } + else perror("smpl"); + + if (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps)==-1) + { + perror("/dev/dsp"); + fprintf(stderr, "Sorry but your sound driver is too old\n"); + exit(-1); + } + +/* + * Check that the device has capability to do this. Currently just + * CS4231 based cards will work. + * + * The application should also check for DSP_CAP_MMAP bit but this + * version of driver doesn't have it yet. + */ +/* ioctl(fd, SNDCTL_DSP_SETSYNCRO, 0); */ + +/* + * You need version 3.5-beta7 or later of the sound driver before next + * two lines compile. There is no point to modify this program to + * compile with older driver versions since they don't have working + * mmap() support. + */ + if (!(caps & DSP_CAP_TRIGGER) || + !(caps & DSP_CAP_MMAP)) + { + fprintf(stderr, "Sorry but your soundcard can't do this\n"); + exit(-1); + } + +/* + * Select the fragment size. This is propably important only when + * the program uses select(). Fragment size defines how often + * select call returns. + */ + + ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag); + +/* + * Compute total size of the buffer. It's important to use this value + * in mmap() call. + */ + + if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)==-1) + { + perror("GETOSPACE"); + exit(-1); + } + + sz = info.fragstotal * info.fragsize; + fsz = info.fragsize; +/* + * Call mmap(). + * + * IMPORTANT NOTE!!!!!!!!!!! + * + * Full duplex audio devices have separate input and output buffers. + * It is not possible to map both of them at the same mmap() call. The buffer + * is selected based on the prot argument in the following way: + * + * - PROT_READ (alone) selects the input buffer. + * - PROT_WRITE (alone) selects the output buffer. + * - PROT_WRITE|PROT_READ together select the output buffer. This combination + * is required in BSD to make the buffer accessible. With just PROT_WRITE + * every attempt to access the returned buffer will result in segmentation/bus + * error. PROT_READ|PROT_WRITE is also permitted in Linux with OSS version + * 3.8-beta16 and later (earlier versions don't accept it). + * + * Non duplex devices have just one buffer. When an application wants to do both + * input and output it's recommended that the device is closed and re-opened when + * switching between modes. PROT_READ|PROT_WRITE can be used to open the buffer + * for both input and output (with OSS 3.8-beta16 and later) but the result may be + * unpredictable. + */ + + if ((buf=mmap(NULL, sz, PROT_WRITE | PROT_READ, MAP_FILE|MAP_SHARED, fd, 0))==(caddr_t)-1) + { + perror("mmap (write)"); + exit(-1); + } + printf("mmap (out) returned %08x\n", buf); + op=buf; + +/* + * op contains now a pointer to the DMA buffer + */ + +/* + * Then it's time to start the engine. The driver doesn't allow read() and/or + * write() when the buffer is mapped. So the only way to start operation is + * to togle device's enable bits. First set them off. Setting them on enables + * recording and/or playback. + */ + + tmp = 0; + ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp); + +/* + * It might be usefull to write some data to the buffer before starting. + */ + + tmp = PCM_ENABLE_OUTPUT; + ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp); + +/* + * The machine is up and running now. Use SNDCTL_DSP_GETOPTR to get the + * buffer status. + * + * NOTE! The driver empties each buffer fragmen after they have been + * played. This prevents looping sound if there are some performance problems + * in the application side. For similar reasons it recommended that the + * application uses some amout of play ahead. It can rewrite the unplayed + * data later if necessary. + */ + + nfrag = 0; + while (1) + { + struct count_info count; + int p, l, extra; + + FD_ZERO(&writeset); + FD_SET(fd, &writeset); + + tim.tv_sec = 10; + tim.tv_usec= 0; + + select(fd+1, &writeset, &writeset, NULL, NULL); +/* + * SNDCTL_DSP_GETOPTR (and GETIPTR as well) return three items. The + * bytes field returns number of bytes played since start. It can be used + * as a real time clock. + * + * The blocks field returns number of fragment transitions (interrupts) since + * previous GETOPTR call. It can be used as a method to detect underrun + * situations. + * + * The ptr field is the DMA pointer inside the buffer area (in bytes from + * the beginning of total buffer area). + */ + + if (ioctl(fd, SNDCTL_DSP_GETOPTR, &count)==-1) + { + perror("GETOPTR"); + exit(-1); + } + if (count.ptr < 0 ) count.ptr = 0; + nfrag += count.blocks; + + +#ifdef VERBOSE + + printf("\rTotal: %09d, Fragment: %03d, Ptr: %06d", + count.bytes, nfrag, count.ptr); + fflush(stdout); +#endif + +/* + * Caution! This version doesn't check for bounds of the DMA + * memory area. It's possible that the returned pointer value is not aligned + * to fragment boundaries. It may be several samples behind the boundary + * in case there was extra delay between the actual hardware interrupt and + * the time when DSP_GETOPTR was called. + * + * Don't just call memcpy() with length set to 'fragment_size' without + * first checking that the transfer really fits to the buffer area. + * A mistake of just one byte causes seg fault. It may be easiest just + * to align the returned pointer value to fragment boundary before using it. + * + * It would be very good idea to write few extra samples to next fragment + * too. Otherwise several (uninitialized) samples from next fragment + * will get played before your program gets chance to initialize them. + * Take in count the fact thaat there are other processes batling about + * the same CPU. This effect is likely to be very annoying if fragment + * size is decreased too much. + */ + +/* + * Just a minor clarification to the above. The following line alings + * the pointer to fragment boundaries. Note! Don't trust that fragment + * size is always a power of 2. It may not be so in future. + */ + count.ptr = ((count.ptr+16)/fsz )*fsz; +#ifdef VERBOSE + printf(" memcpy(%6d, %4d)", (dp-data), fsz); + fflush(stdout); +#endif + +/* + * Set few bytes in the beginning of next fragment too. + */ + + if ((count.ptr+fsz+16) < sz) /* Last fragment? */ + extra = 16; + else + extra = 0; + memcpy(op+count.ptr, dp, (fsz+extra)); + dp += fsz; + if (dp > (data+sl-fsz)) + dp = data; + + } + + exit(0); +} diff --git a/sys/i386/isa/sound/pas_defs.h b/sys/i386/isa/sound/pas_defs.h new file mode 100644 index 000000000000..c4af2d499db4 --- /dev/null +++ b/sys/i386/isa/sound/pas_defs.h @@ -0,0 +1,250 @@ +/* */ +/* Port addresses and bit fields for the Media Vision Pro AudioSpectrum second generation sound cards. */ +/* */ +/* Feel free to use this header file in any application you create that has support for the Media Vision */ +/* Pro AudioSpectrum second generation sound cards. Other uses prohibited without prior permission. */ +/* */ +/* - cmetz@thor.tjhsst.edu */ +/* */ +/* Notes: */ +/* */ +/* * All of these ports go into the MVD101 multimedia controller chip, which then signals the other chips to do */ +/* the actual work. Many ports like the FM ones functionally attach directly to the destination chip though */ +/* they don't actually have a direct connection. */ +/* */ +/* * The PAS2 series cards have an MVD101 multimedia controller chip, the original PAS cards don't. The original */ +/* PAS cards are pretty defunct now, so no attempt is made here to support them. */ +/* */ +/* * The PAS2 series cards are all really different at the hardware level, though the MVD101 hides some of the */ +/* incompatibilities, there still are differences that need to be accounted for. */ +/* */ +/* Card CD-ROM interface PCM chip Mixer chip FM chip */ +/* PAS Plus Sony proprietary (Crystal?) 8-bit DAC National OPL3 */ +/* PAS 16 Zilog SCSI MVA416 16-bit Codec MVA508 OPL3 */ +/* CDPC Sony proprietary Sony 16-bit Codec National OPL3 */ +/* Fusion CD 16 Sony proprietary MVA416 16-bit Codec MVA508 OPL3 */ +/* Fusion CD Sony proprietary (Crystal?) 8-bit DAC National OPL3 */ +/* */ +#define PAS_DEFAULT_BASE 0x388 + +/* Symbolic Name Value R W Subsystem Description */ +#define SPEAKER_CONTROL 0x61 /* W PC speaker Control register */ +#define SPEAKER_CONTROL_GHOST 0x738B /* R W PC speaker Control ghost register */ +#define SPEAKER_TIMER_CONTROL 0x43 /* W PC speaker Timer control register */ +#define SPEAKER_TIMER_CONTROL_GHOST 0x778B /* R W PC speaker Timer control register ghost */ +#define SPEAKER_TIMER_DATA 0x42 /* W PC speaker Timer data register */ +#define SPEAKER_TIMER_DATA_GHOST 0x138A /* R W PC speaker Timer data register ghost */ + +#define WARM_BOOT 0x41 /* W Control Used to detect system warm boot */ +#define WARM_BOOT_GHOST 0x7789 /* ? W Control Use to get the card to fake warm boot */ +#define MASTER_DECODE 0x9A01 /* W Control Address >> 2 of card base address */ +#define PRESCALE_DIVIDER 0xBF8A /* R W PCM Ration between Codec clock and master clock */ +#define WAIT_STATE 0xBF88 /* R W Control Four-bit bus wait-state count (~140ns ea.) */ +#define BOARD_REV_ID 0x2789 /* R Control Extended Board Revision ID */ + +#define CHIP_REV 0xFF88 /* R 0=PAS, 1=PAS+, 2=CDPC, 3=PAS16C, 4=PAS16D */ + +#define SYSTEM_CONFIGURATION_1 0x8388 /* R W Control */ + #define S_C_1_PCS_ENABLE 0x01 /* R W PC speaker 1=enable, 0=disable PC speaker emulation */ + #define S_C_1_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=14.31818Mhz/12, 0=28.224Mhz master clock */ + #define S_C_1_FM_EMULATE_CLOCK 0x04 /* R W FM 1=use 28.224Mhz/2, 0=use 14.31818Mhz clock */ + #define S_C_1_PCS_STEREO 0x10 /* R W PC speaker 1=enable PC speaker stereo effect, 0=disable */ + #define S_C_1_PCS_REALSOUND 0x20 /* R W PC speaker 1=enable RealSound enhancement, 0=disable */ + #define S_C_1_FORCE_EXT_RESET 0x40 /* R W Control Force external reset */ + #define S_C_1_FORCE_INT_RESET 0x80 /* R W Control Force internal reset */ +#define SYSTEM_CONFIGURATION_2 0x8389 /* R W Control */ + #define S_C_2_PCM_OVERSAMPLING 0x03 /* R W PCM 00=0x, 01=2x, 10=4x, 11=reserved */ + #define S_C_2_PCM_16_BIT 0x04 /* R W PCM 1=16-bit, 0=8-bit samples */ +#define SYSTEM_CONFIGURATION_3 0x838A /* R W Control */ + #define S_C_3_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=use 1.008Mhz clock for PCM, 0=don't */ +#define SYSTEM_CONFIGURATION_4 0x838B /* R W Control CD-ROM interface controls */ + +#define IO_CONFIGURATION_1 0xF388 /* R W Control */ + #define I_C_1_BOOT_RESET_ENABLE 0x80 /* R W Control 1=reset board on warm boot, 0=don't */ + #define I_C_1_JOYSTICK_ENABLE 0x40 /* R W Control 1=enable joystick port, 0=don't */ +#define IO_CONFIGURATION_2 0xF389 /* R W Control */ + #define I_C_2_PCM_DMA_DISABLED 0x00 /* R W PCM PCM DMA disabled */ +#define IO_CONFIGURATION_3 0xF38A /* R W Control */ + #define I_C_3_PCM_IRQ_DISABLED 0x00 /* R W PCM PCM IRQ disabled */ + +#define COMPATIBILITY_ENABLE 0xF788 /* R W Control */ + #define C_E_MPU401_ENABLE 0x01 /* R W MIDI 1=enable, 0=disable MPU401 MIDI emulation */ + #define C_E_SB_ENABLE 0x02 /* R W PCM 1=enable, 0=disable Sound Blaster emulation */ + #define C_E_SB_ACTIVE 0x04 /* R PCM "Sound Blaster Interrupt active" */ + #define C_E_MPU401_ACTIVE 0x08 /* R MIDI "MPU UART mode active" */ + #define C_E_PCM_COMPRESSION 0x10 /* R W PCM 1=enable, 0=disabled compression */ +#define EMULATION_ADDRESS 0xF789 /* R W Control */ + #define E_A_SB_BASE 0x0f /* R W PCM bits A4-A7 for SB base port */ + #define E_A_MPU401_BASE 0xf0 /* R W MIDI bits A4-A7 for MPU401 base port */ +#define EMULATION_CONFIGURATION 0xFB8A /* R W ***** Only valid on newer PAS2 cards (?) ***** */ + #define E_C_MPU401_IRQ 0x07 /* R W MIDI MPU401 emulation IRQ */ + #define E_C_SB_IRQ 0x38 /* R W PCM SB emulation IRQ */ + #define E_C_SB_DMA 0xC0 /* R W PCM SB emulation DMA */ + +#define OPERATION_MODE_1 0xEF8B /* R Control */ + #define O_M_1_CDROM_TYPE 0x03 /* R CD-ROM 3=SCSI, 2=Sony, 0=no CD-ROM interface */ + #define O_M_1_FM_TYPE 0x04 /* R FM 1=sterero, 0=mono FM chip */ + #define O_M_1_PCM_TYPE 0x08 /* R PCM 1=16-bit Codec, 0=8-bit DAC */ +#define OPERATION_MODE_2 0xFF8B /* R Control */ + #define O_M_2_PCS_ENABLED 0x02 /* R PC speaker PC speaker emulation 1=enabled, 0=disabled */ + #define O_M_2_BUS_TIMING 0x10 /* R Control 1=AT bus timing, 0=XT bus timing */ + #define O_M_2_BOARD_REVISION 0xe0 /* R Control Board revision */ + +#define INTERRUPT_MASK 0x0B8B /* R W Control */ + #define I_M_FM_LEFT_IRQ_ENABLE 0x01 /* R W FM Enable FM left interrupt */ + #define I_M_FM_RIGHT_IRQ_ENABLE 0x02 /* R W FM Enable FM right interrupt */ + #define I_M_PCM_RATE_IRQ_ENABLE 0x04 /* R W PCM Enable Sample Rate interrupt */ + #define I_M_PCM_BUFFER_IRQ_ENABLE 0x08 /* R W PCM Enable Sample Buffer interrupt */ + #define I_M_MIDI_IRQ_ENABLE 0x10 /* R W MIDI Enable MIDI interrupt */ + #define I_M_BOARD_REV 0xE0 /* R Control Board revision */ + +#define INTERRUPT_STATUS 0x0B89 /* R W Control */ + #define I_S_FM_LEFT_IRQ 0x01 /* R W FM Left FM Interrupt Pending */ + #define I_S_FM_RIGHT_IRQ 0x02 /* R W FM Right FM Interrupt Pending */ + #define I_S_PCM_SAMPLE_RATE_IRQ 0x04 /* R W PCM Sample Rate Interrupt Pending */ + #define I_S_PCM_SAMPLE_BUFFER_IRQ 0x08 /* R W PCM Sample Buffer Interrupt Pending */ + #define I_S_MIDI_IRQ 0x10 /* R W MIDI MIDI Interrupt Pending */ + #define I_S_PCM_CHANNEL 0x20 /* R W PCM 1=right, 0=left */ + #define I_S_RESET_ACTIVE 0x40 /* R W Control Reset is active (Timed pulse not finished) */ + #define I_S_PCM_CLIPPING 0x80 /* R W PCM Clipping has occurred */ + +#define FILTER_FREQUENCY 0x0B8A /* R W Control */ + #define F_F_FILTER_DISABLED 0x00 /* R W Mixer No filter */ +#if 0 + struct { /* R W Mixer Filter translation */ + unsigned int freq:24; + unsigned int value:8; + } F_F_FILTER_translate[] = + { { 73500, 0x01 }, /* 73500Hz - divide by 16 */ + { 65333, 0x02 }, /* 65333Hz - divide by 18 */ + { 49000, 0x09 }, /* 49000Hz - divide by 24 */ + { 36750, 0x11 }, /* 36750Hz - divide by 32 */ + { 24500, 0x19 }, /* 24500Hz - divide by 48 */ + { 18375, 0x07 }, /* 18375Hz - divide by 64 */ + { 12783, 0x0f }, /* 12783Hz - divide by 92 */ + { 12250, 0x04 }, /* 12250Hz - divide by 96 */ + { 9188, 0x17 }, /* 9188Hz - divide by 128 */ + { 6125, 0x1f }, /* 6125Hz - divide by 192 */ + }; +#endif + #define F_F_MIXER_UNMUTE 0x20 /* R W Mixer 1=disable, 0=enable board mute */ + #define F_F_PCM_RATE_COUNTER 0x40 /* R W PCM 1=enable, 0=disable sample rate counter */ + #define F_F_PCM_BUFFER_COUNTER 0x80 /* R W PCM 1=enable, 0=disable sample buffer counter */ + +#define PAS_NONE 0 +#define PAS_PLUS 1 +#define PAS_CDPC 2 +#define PAS_16 3 +#define PAS_16D 4 + +#ifdef DEFINE_TRANSLATIONS +static unsigned char I_C_2_PCM_DMA_translate[] = /* R W PCM PCM DMA channel value translations */ + { 4, 1, 2, 3, 0, 5, 6, 7 }; +static unsigned char I_C_3_PCM_IRQ_translate[] = /* R W PCM PCM IRQ level value translation */ + { 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11 }; +#ifdef unused +static unsigned char E_C_MPU401_IRQ_translate[] = /* R W MIDI MPU401 emulation IRQ value translation */ + { 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x05, 0x06, 0x07 }; +#endif +static unsigned char E_C_SB_IRQ_translate[] = /* R W PCM SB emulation IRQ translate */ + { 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0 }; +static unsigned char E_C_SB_DMA_translate[] = /* R W PCM SB emulation DMA translate */ + { 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0 }; +#ifdef unused +static unsigned char O_M_1_to_card[] = /* R W Control Translate (OM1 & 0x0f) to card type */ + { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 2, 3 }; +#endif +#endif + +#define PARALLEL_MIXER 0x078B /* W Mixer Documented for MVD101 as FM Mono Right decode?? */ + #define P_M_MV508_ADDRESS 0x80 /* W Mixer MVD508 Address/mixer select */ + #define P_M_MV508_DATA 0x00 + #define P_M_MV508_LEFT 0x20 /* W Mixer MVD508 Left channel select */ + #define P_M_MV508_RIGHT 0x40 /* W Mixer MVD508 Right channel select */ + #define P_M_MV508_BOTH 0x00 /* W Mixer MVD508 Both channel select */ + #define P_M_MV508_MIXER 0x10 /* W Mixer MVD508 Select a mixer (rather than a volume) */ + #define P_M_MV508_VOLUME 0x00 + + #define P_M_MV508_INPUTMIX 0x20 /* W Mixer MVD508 Select mixer A */ + #define P_M_MV508_OUTPUTMIX 0x00 /* W Mixer MVD508 Select mixer B */ + + #define P_M_MV508_MASTER_A 0x01 /* W Mixer MVD508 Master volume control A (output) */ + #define P_M_MV508_MASTER_B 0x02 /* W Mixer MVD508 Master volume control B (DSP input) */ + #define P_M_MV508_BASS 0x03 /* W Mixer MVD508 Bass control */ + #define P_M_MV508_TREBLE 0x04 /* W Mixer MVD508 Treble control */ + #define P_M_MV508_MODE 0x05 /* W Mixer MVD508 Master mode control */ + + #define P_M_MV508_LOUDNESS 0x04 /* W Mixer MVD508 Mode control - Loudness filter */ + #define P_M_MV508_ENHANCE_BITS 0x03 + #define P_M_MV508_ENHANCE_NONE 0x00 /* W Mixer MVD508 Mode control - No stereo enhancement */ + #define P_M_MV508_ENHANCE_40 0x01 /* W Mixer MVD508 Mode control - 40% stereo enhancement */ + #define P_M_MV508_ENHANCE_60 0x02 /* W Mixer MVD508 Mode control - 60% stereo enhancement */ + #define P_M_MV508_ENHANCE_80 0x03 /* W Mixer MVD508 Mode control - 80% stereo enhancement */ + + #define P_M_MV508_FM 0x00 /* W Mixer MVD508 Channel 0 - FM */ + #define P_M_MV508_IMIXER 0x01 /* W Mixer MVD508 Channel 1 - Input mixer (rec monitor) */ + #define P_M_MV508_LINE 0x02 /* W Mixer MVD508 Channel 2 - Line in */ + #define P_M_MV508_CDROM 0x03 /* W Mixer MVD508 Channel 3 - CD-ROM */ + #define P_M_MV508_MIC 0x04 /* W Mixer MVD508 Channel 4 - Microphone */ + #define P_M_MV508_PCM 0x05 /* W Mixer MVD508 Channel 5 - PCM */ + #define P_M_MV508_SPEAKER 0x06 /* W Mixer MVD508 Channel 6 - PC Speaker */ + #define P_M_MV508_SB 0x07 /* W Mixer MVD508 Channel 7 - SB DSP */ + +#define SERIAL_MIXER 0xB88 /* R W Control Serial mixer control (used other ways) */ + #define S_M_PCM_RESET 0x01 /* R W PCM Codec/DSP reset */ + #define S_M_FM_RESET 0x02 /* R W FM FM chip reset */ + #define S_M_SB_RESET 0x04 /* R W PCM SB emulation chip reset */ + #define S_M_MIXER_RESET 0x10 /* R W Mixer Mixer chip reset */ + #define S_M_INTEGRATOR_ENABLE 0x40 /* R W Speaker Enable PC speaker integrator (FORCE RealSound) */ + #define S_M_OPL3_DUAL_MONO 0x80 /* R W FM Set the OPL-3 to dual mono mode */ + +#define PCM_CONTROL 0xF8A /* R W PCM PCM Control Register */ + #define P_C_MIXER_CROSS_FIELD 0x0f + #define P_C_MIXER_CROSS_R_TO_R 0x01 /* R W Mixer Connect Right to Right */ + #define P_C_MIXER_CROSS_L_TO_R 0x02 /* R W Mixer Connect Left to Right */ + #define P_C_MIXER_CROSS_R_TO_L 0x04 /* R W Mixer Connect Right to Left */ + #define P_C_MIXER_CROSS_L_TO_L 0x08 /* R W Mixer Connect Left to Left */ + #define P_C_PCM_DAC_MODE 0x10 /* R W PCM Playback (DAC) mode */ + #define P_C_PCM_ADC_MODE 0x00 /* R W PCM Record (ADC) mode */ + #define P_C_PCM_MONO 0x20 /* R W PCM Mono mode */ + #define P_C_PCM_STEREO 0x00 /* R W PCM Stereo mode */ + #define P_C_PCM_ENABLE 0x40 /* R W PCM Enable PCM engine */ + #define P_C_PCM_DMA_ENABLE 0x80 /* R W PCM Enable DRQ */ + +#define SAMPLE_COUNTER_CONTROL 0x138B /* R W PCM Sample counter control register */ + #define S_C_C_SQUARE_WAVE 0x04 /* R W PCM Square wave generator (use for sample rate) */ + #define S_C_C_RATE 0x06 /* R W PCM Rate generator (use for sample buffer count) */ + #define S_C_C_LSB_THEN_MSB 0x30 /* R W PCM Change all 16 bits, LSB first, then MSB */ + + /* MVD101 and SDK documentations have S_C_C_SAMPLE_RATE and S_C_C_SAMPLE_BUFFER transposed. Only one works :-) */ + #define S_C_C_SAMPLE_RATE 0x00 /* R W PCM Select sample rate timer */ + #define S_C_C_SAMPLE_BUFFER 0x40 /* R W PCM Select sample buffer counter */ + + #define S_C_C_PC_SPEAKER 0x80 /* R W PCM Select PC speaker counter */ + +#define SAMPLE_RATE_TIMER 0x1388 /* W PCM Sample rate timer register (PCM wait interval) */ +#define SAMPLE_BUFFER_COUNTER 0x1389 /* R W PCM Sample buffer counter (DMA buffer size) */ + +#define MIDI_CONTROL 0x178b /* R W MIDI Midi control register */ + #define M_C_ENA_TSTAMP_IRQ 0x01 /* R W MIDI Enable Time Stamp Interrupts */ + #define M_C_ENA_TME_COMP_IRQ 0x02 /* R W MIDI Enable time compare interrupts */ + #define M_C_ENA_INPUT_IRQ 0x04 /* R W MIDI Enable input FIFO interrupts */ + #define M_C_ENA_OUTPUT_IRQ 0x08 /* R W MIDI Enable output FIFO interrupts */ + #define M_C_ENA_OUTPUT_HALF_IRQ 0x10 /* R W MIDI Enable output FIFO half full interrupts */ + #define M_C_RESET_INPUT_FIFO 0x20 /* R W MIDI Reset input FIFO pointer */ + #define M_C_RESET_OUTPUT_FIFO 0x40 /* R W MIDI Reset output FIFO pointer */ + #define M_C_ENA_THRU_MODE 0x80 /* R W MIDI Echo input to output (THRU) */ + +#define MIDI_STATUS 0x1B88 /* R W MIDI Midi (interrupt) status register */ + #define M_S_TIMESTAMP 0x01 /* R W MIDI Midi time stamp interrupt occurred */ + #define M_S_COMPARE 0x02 /* R W MIDI Midi compare time interrupt occurred */ + #define M_S_INPUT_AVAIL 0x04 /* R W MIDI Midi input data available interrupt occurred */ + #define M_S_OUTPUT_EMPTY 0x08 /* R W MIDI Midi output FIFO empty interrupt occurred */ + #define M_S_OUTPUT_HALF_EMPTY 0x10 /* R W MIDI Midi output FIFO half empty interrupt occurred */ + #define M_S_INPUT_OVERRUN 0x20 /* R W MIDI Midi input overrun error occurred */ + #define M_S_OUTPUT_OVERRUN 0x40 /* R W MIDI Midi output overrun error occurred */ + #define M_S_FRAMING_ERROR 0x80 /* R W MIDI Midi input framing error occurred */ + +#define MIDI_FIFO_STATUS 0x1B89 /* R W MIDI Midi fifo status */ +#define MIDI_DATA 0x178A /* R W MIDI Midi data register */ +#define MIDI_INPUT_AVAILABLE 0x0f /* RW MIDI */ diff --git a/sys/i386/isa/sound/pas_hw.h b/sys/i386/isa/sound/pas_hw.h new file mode 100644 index 000000000000..5f823287fa90 --- /dev/null +++ b/sys/i386/isa/sound/pas_hw.h @@ -0,0 +1,236 @@ +/* */ +/* Port addresses and bit fields for the Media Vision Pro AudioSpectrum second generation sound cards. */ +/* */ +/* Feel free to use this header file in any application you create that has support for the Media Vision */ +/* Pro AudioSpectrum second generation sound cards. Other uses prohibited without prior permission. */ +/* */ +/* - cmetz@thor.tjhsst.edu */ +/* */ +/* Notes: */ +/* */ +/* * All of these ports go into the MVD101 multimedia controller chip, which then signals the other chips to do */ +/* the actual work. Many ports like the FM ones functionally attach directly to the destination chip though */ +/* they don't actually have a direct connection. */ +/* */ +/* * The PAS2 series cards have an MVD101 multimedia controller chip, the original PAS cards don't. The original */ +/* PAS cards are pretty defunct now, so no attempt is made here to support them. */ +/* */ +/* * The PAS2 series cards are all really different at the hardware level, though the MVD101 hides some of the */ +/* incompatibilities, there still are differences that need to be accounted for. */ +/* */ +/* Card CD-ROM interface PCM chip Mixer chip FM chip */ +/* PAS Plus Sony proprietary (Crystal?) 8-bit DAC National OPL3 */ +/* PAS 16 Zilog SCSI MVA416 16-bit Codec MVA508 OPL3 */ +/* CDPC Sony proprietary Sony 16-bit Codec National OPL3 */ +/* Fusion CD 16 Sony proprietary MVA416 16-bit Codec MVA508 OPL3 */ +/* Fusion CD Sony proprietary (Crystal?) 8-bit DAC National OPL3 */ +/* */ +#define PAS_DEFAULT_BASE 0x388 + +/* Symbolic Name Value R W Subsystem Description */ +#define SPEAKER_CONTROL 0x61 /* W PC speaker Control register */ +#define SPEAKER_CONTROL_GHOST 0x738B /* R W PC speaker Control ghost register */ +#define SPEAKER_TIMER_CONTROL 0x43 /* W PC speaker Timer control register */ +#define SPEAKER_TIMER_CONTROL_GHOST 0x778B /* R W PC speaker Timer control register ghost */ +#define SPEAKER_TIMER_DATA 0x42 /* W PC speaker Timer data register */ +#define SPEAKER_TIMER_DATA_GHOST 0x138A /* R W PC speaker Timer data register ghost */ + +#define WARM_BOOT 0x41 /* W Control Used to detect system warm boot */ +#define WARM_BOOT_GHOST 0x7789 /* ? W Control Use to get the card to fake warm boot */ +#define MASTER_DECODE 0x9A01 /* W Control Address >> 2 of card base address */ +#define PRESCALE_DIVIDER 0xBF8A /* R W PCM Ration between Codec clock and master clock */ +#define WAIT_STATE 0xBF88 /* R W Control Four-bit bus wait-state count (~140ns ea.) */ +#define BOARD_REV_ID 0x2789 /* R Control Extended Board Revision ID */ + +#define CHIP_REV 0xFF88 /* R 0=PAS, 1=PAS+, 2=CDPC, 3=PAS16C, 4=PAS16D */ + +#define SYSTEM_CONFIGURATION_1 0x8388 /* R W Control */ +# define S_C_1_PCS_ENABLE 0x01 /* R W PC speaker 1=enable, 0=disable PC speaker emulation */ +# define S_C_1_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=14.31818Mhz/12, 0=28.224Mhz master clock */ +# define S_C_1_FM_EMULATE_CLOCK 0x04 /* R W FM 1=use 28.224Mhz/2, 0=use 14.31818Mhz clock */ +# define S_C_1_PCS_STEREO 0x10 /* R W PC speaker 1=enable PC speaker stereo effect, 0=disable */ +# define S_C_1_PCS_REALSOUND 0x20 /* R W PC speaker 1=enable RealSound enhancement, 0=disable */ +# define S_C_1_FORCE_EXT_RESET 0x40 /* R W Control Force external reset */ +# define S_C_1_FORCE_INT_RESET 0x80 /* R W Control Force internal reset */ +#define SYSTEM_CONFIGURATION_2 0x8389 /* R W Control */ +# define S_C_2_PCM_OVERSAMPLING 0x03 /* R W PCM 00=0x, 01=2x, 10=4x, 11=reserved */ +# define S_C_2_PCM_16_BIT 0x04 /* R W PCM 1=16-bit, 0=8-bit samples */ +#define SYSTEM_CONFIGURATION_3 0x838A /* R W Control */ +# define S_C_3_PCM_CLOCK_SELECT 0x02 /* R W PCM 1=use 1.008Mhz clock for PCM, 0=don't */ +#define SYSTEM_CONFIGURATION_4 0x838B /* R W Control CD-ROM interface controls */ + +#define IO_CONFIGURATION_1 0xF388 /* R W Control */ +# define I_C_1_BOOT_RESET_ENABLE 0x80 /* R W Control 1=reset board on warm boot, 0=don't */ +# define I_C_1_JOYSTICK_ENABLE 0x40 /* R W Control 1=enable joystick port, 0=don't */ +#define IO_CONFIGURATION_2 0xF389 /* R W Control */ +# define I_C_2_PCM_DMA_DISABLED 0x00 /* R W PCM PCM DMA disabled */ +#define IO_CONFIGURATION_3 0xF38A /* R W Control */ +# define I_C_3_PCM_IRQ_DISABLED 0x00 /* R W PCM PCM IRQ disabled */ + +#define COMPATIBILITY_ENABLE 0xF788 /* R W Control */ +# define C_E_MPU401_ENABLE 0x01 /* R W MIDI 1=enable, 0=disable MPU401 MIDI emulation */ +# define C_E_SB_ENABLE 0x02 /* R W PCM 1=enable, 0=disable Sound Blaster emulation */ +# define C_E_SB_ACTIVE 0x04 /* R PCM "Sound Blaster Interrupt active" */ +# define C_E_MPU401_ACTIVE 0x08 /* R MIDI "MPU UART mode active" */ +# define C_E_PCM_COMPRESSION 0x10 /* R W PCM 1=enable, 0=disabled compression */ +#define EMULATION_ADDRESS 0xF789 /* R W Control */ +# define E_A_SB_BASE 0x0f /* R W PCM bits A4-A7 for SB base port */ +# define E_A_MPU401_BASE 0xf0 /* R W MIDI bits A4-A7 for MPU401 base port */ +#define EMULATION_CONFIGURATION 0xFB8A /* R W ***** Only valid on newer PAS2 cards (?) ***** */ +# define E_C_MPU401_IRQ 0x07 /* R W MIDI MPU401 emulation IRQ */ +# define E_C_SB_IRQ 0x38 /* R W PCM SB emulation IRQ */ +# define E_C_SB_DMA 0xC0 /* R W PCM SB emulation DMA */ + +#define OPERATION_MODE_1 0xEF8B /* R Control */ +# define O_M_1_CDROM_TYPE 0x03 /* R CD-ROM 3=SCSI, 2=Sony, 0=no CD-ROM interface */ +# define O_M_1_FM_TYPE 0x04 /* R FM 1=sterero, 0=mono FM chip */ +# define O_M_1_PCM_TYPE 0x08 /* R PCM 1=16-bit Codec, 0=8-bit DAC */ +#define OPERATION_MODE_2 0xFF8B /* R Control */ +# define O_M_2_PCS_ENABLED 0x02 /* R PC speaker PC speaker emulation 1=enabled, 0=disabled */ +# define O_M_2_BUS_TIMING 0x10 /* R Control 1=AT bus timing, 0=XT bus timing */ +# define O_M_2_BOARD_REVISION 0xe0 /* R Control Board revision */ + +#define INTERRUPT_MASK 0x0B8B /* R W Control */ +# define I_M_FM_LEFT_IRQ_ENABLE 0x01 /* R W FM Enable FM left interrupt */ +# define I_M_FM_RIGHT_IRQ_ENABLE 0x02 /* R W FM Enable FM right interrupt */ +# define I_M_PCM_RATE_IRQ_ENABLE 0x04 /* R W PCM Enable Sample Rate interrupt */ +# define I_M_PCM_BUFFER_IRQ_ENABLE 0x08 /* R W PCM Enable Sample Buffer interrupt */ +# define I_M_MIDI_IRQ_ENABLE 0x10 /* R W MIDI Enable MIDI interrupt */ +# define I_M_BOARD_REV 0xE0 /* R Control Board revision */ + +#define INTERRUPT_STATUS 0x0B89 /* R W Control */ +# define I_S_FM_LEFT_IRQ 0x01 /* R W FM Left FM Interrupt Pending */ +# define I_S_FM_RIGHT_IRQ 0x02 /* R W FM Right FM Interrupt Pending */ +# define I_S_PCM_SAMPLE_RATE_IRQ 0x04 /* R W PCM Sample Rate Interrupt Pending */ +# define I_S_PCM_SAMPLE_BUFFER_IRQ 0x08 /* R W PCM Sample Buffer Interrupt Pending */ +# define I_S_MIDI_IRQ 0x10 /* R W MIDI MIDI Interrupt Pending */ +# define I_S_PCM_CHANNEL 0x20 /* R W PCM 1=right, 0=left */ +# define I_S_RESET_ACTIVE 0x40 /* R W Control Reset is active (Timed pulse not finished) */ +# define I_S_PCM_CLIPPING 0x80 /* R W PCM Clipping has occurred */ + +#define FILTER_FREQUENCY 0x0B8A /* R W Control */ +# define F_F_FILTER_DISABLED 0x00 /* R W Mixer No filter */ +# define F_F_MIXER_UNMUTE 0x20 /* R W Mixer 1=disable, 0=enable board mute */ +# define F_F_PCM_RATE_COUNTER 0x40 /* R W PCM 1=enable, 0=disable sample rate counter */ +# define F_F_PCM_BUFFER_COUNTER 0x80 /* R W PCM 1=enable, 0=disable sample buffer counter */ + +#define PAS_NONE 0 +#define PAS_PLUS 1 +#define PAS_CDPC 2 +#define PAS_16 3 +#define PAS_16D 4 + +#ifdef DEFINE_TRANSLATIONS + unsigned char I_C_2_PCM_DMA_translate[] = /* R W PCM PCM DMA channel value translations */ + { 4, 1, 2, 3, 0, 5, 6, 7 }; + unsigned char I_C_3_PCM_IRQ_translate[] = /* R W PCM PCM IRQ level value translation */ + { 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11 }; + unsigned char E_C_MPU401_IRQ_translate[] = /* R W MIDI MPU401 emulation IRQ value translation */ + { 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x05, 0x06, 0x07 }; + unsigned char E_C_SB_IRQ_translate[] = /* R W PCM SB emulation IRQ translate */ + { 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0 }; + unsigned char E_C_SB_DMA_translate[] = /* R W PCM SB emulation DMA translate */ + { 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0 }; + unsigned char O_M_1_to_card[] = /* R W Control Translate (OM1 & 0x0f) to card type */ + { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 2, 3 }; +#else + extern unsigned char I_C_2_PCM_DMA_translate[]; /* R W PCM PCM DMA channel value translations */ + extern unsigned char I_C_3_PCM_IRQ_translate[]; /* R W PCM PCM IRQ level value translation */ + extern unsigned char E_C_MPU401_IRQ_translate[]; /* R W MIDI MPU401 emulation IRQ value translation */ + extern unsigned char E_C_SB_IRQ_translate[]; /* R W PCM SB emulation IRQ translate */ + extern unsigned char E_C_SB_DMA_translate[]; /* R W PCM SB emulation DMA translate */ + extern unsigned char O_M_1_to_card[]; /* R W Control Translate (OM1 & 0x0f) to card type */ +#endif + +#define PARALLEL_MIXER 0x078B /* W Mixer Documented for MVD101 as FM Mono Right decode?? */ +# define P_M_MV508_ADDRESS 0x80 /* W Mixer MVD508 Address/mixer select */ +# define P_M_MV508_DATA 0x00 +# define P_M_MV508_LEFT 0x20 /* W Mixer MVD508 Left channel select */ +# define P_M_MV508_RIGHT 0x40 /* W Mixer MVD508 Right channel select */ +# define P_M_MV508_BOTH 0x00 /* W Mixer MVD508 Both channel select */ +# define P_M_MV508_MIXER 0x10 /* W Mixer MVD508 Select a mixer (rather than a volume) */ +# define P_M_MV508_VOLUME 0x00 + +# define P_M_MV508_INPUTMIX 0x20 /* W Mixer MVD508 Select mixer A */ +# define P_M_MV508_OUTPUTMIX 0x00 /* W Mixer MVD508 Select mixer B */ + +# define P_M_MV508_MASTER_A 0x01 /* W Mixer MVD508 Master volume control A (output) */ +# define P_M_MV508_MASTER_B 0x02 /* W Mixer MVD508 Master volume control B (DSP input) */ +# define P_M_MV508_BASS 0x03 /* W Mixer MVD508 Bass control */ +# define P_M_MV508_TREBLE 0x04 /* W Mixer MVD508 Treble control */ +# define P_M_MV508_MODE 0x05 /* W Mixer MVD508 Master mode control */ + +# define P_M_MV508_LOUDNESS 0x04 /* W Mixer MVD508 Mode control - Loudness filter */ +# define P_M_MV508_ENHANCE_BITS 0x03 +# define P_M_MV508_ENHANCE_NONE 0x00 /* W Mixer MVD508 Mode control - No stereo enhancement */ +# define P_M_MV508_ENHANCE_40 0x01 /* W Mixer MVD508 Mode control - 40% stereo enhancement */ +# define P_M_MV508_ENHANCE_60 0x02 /* W Mixer MVD508 Mode control - 60% stereo enhancement */ +# define P_M_MV508_ENHANCE_80 0x03 /* W Mixer MVD508 Mode control - 80% stereo enhancement */ + +# define P_M_MV508_FM 0x00 /* W Mixer MVD508 Channel 0 - FM */ +# define P_M_MV508_IMIXER 0x01 /* W Mixer MVD508 Channel 1 - Input mixer (rec monitor) */ +# define P_M_MV508_LINE 0x02 /* W Mixer MVD508 Channel 2 - Line in */ +# define P_M_MV508_CDROM 0x03 /* W Mixer MVD508 Channel 3 - CD-ROM */ +# define P_M_MV508_MIC 0x04 /* W Mixer MVD508 Channel 4 - Microphone */ +# define P_M_MV508_PCM 0x05 /* W Mixer MVD508 Channel 5 - PCM */ +# define P_M_MV508_SPEAKER 0x06 /* W Mixer MVD508 Channel 6 - PC Speaker */ +# define P_M_MV508_SB 0x07 /* W Mixer MVD508 Channel 7 - SB DSP */ + +#define SERIAL_MIXER 0xB88 /* R W Control Serial mixer control (used other ways) */ +# define S_M_PCM_RESET 0x01 /* R W PCM Codec/DSP reset */ +# define S_M_FM_RESET 0x02 /* R W FM FM chip reset */ +# define S_M_SB_RESET 0x04 /* R W PCM SB emulation chip reset */ +# define S_M_MIXER_RESET 0x10 /* R W Mixer Mixer chip reset */ +# define S_M_INTEGRATOR_ENABLE 0x40 /* R W Speaker Enable PC speaker integrator (FORCE RealSound) */ +# define S_M_OPL3_DUAL_MONO 0x80 /* R W FM Set the OPL-3 to dual mono mode */ + +#define PCM_CONTROL 0xF8A /* R W PCM PCM Control Register */ +# define P_C_MIXER_CROSS_FIELD 0x0f +# define P_C_MIXER_CROSS_R_TO_R 0x01 /* R W Mixer Connect Right to Right */ +# define P_C_MIXER_CROSS_L_TO_R 0x02 /* R W Mixer Connect Left to Right */ +# define P_C_MIXER_CROSS_R_TO_L 0x04 /* R W Mixer Connect Right to Left */ +# define P_C_MIXER_CROSS_L_TO_L 0x08 /* R W Mixer Connect Left to Left */ +# define P_C_PCM_DAC_MODE 0x10 /* R W PCM Playback (DAC) mode */ +# define P_C_PCM_ADC_MODE 0x00 /* R W PCM Record (ADC) mode */ +# define P_C_PCM_MONO 0x20 /* R W PCM Mono mode */ +# define P_C_PCM_STEREO 0x00 /* R W PCM Stereo mode */ +# define P_C_PCM_ENABLE 0x40 /* R W PCM Enable PCM engine */ +# define P_C_PCM_DMA_ENABLE 0x80 /* R W PCM Enable DRQ */ + +#define SAMPLE_COUNTER_CONTROL 0x138B /* R W PCM Sample counter control register */ +# define S_C_C_SQUARE_WAVE 0x04 /* R W PCM Square wave generator (use for sample rate) */ +# define S_C_C_RATE 0x06 /* R W PCM Rate generator (use for sample buffer count) */ +# define S_C_C_LSB_THEN_MSB 0x30 /* R W PCM Change all 16 bits, LSB first, then MSB */ + + /* MVD101 and SDK documentations have S_C_C_SAMPLE_RATE and S_C_C_SAMPLE_BUFFER transposed. Only one works :-) */ +# define S_C_C_SAMPLE_RATE 0x00 /* R W PCM Select sample rate timer */ +# define S_C_C_SAMPLE_BUFFER 0x40 /* R W PCM Select sample buffer counter */ + +# define S_C_C_PC_SPEAKER 0x80 /* R W PCM Select PC speaker counter */ + +#define SAMPLE_RATE_TIMER 0x1388 /* W PCM Sample rate timer register (PCM wait interval) */ +#define SAMPLE_BUFFER_COUNTER 0x1389 /* R W PCM Sample buffer counter (DMA buffer size) */ + +#define MIDI_CONTROL 0x178b /* R W MIDI Midi control register */ +# define M_C_ENA_TSTAMP_IRQ 0x01 /* R W MIDI Enable Time Stamp Interrupts */ +# define M_C_ENA_TME_COMP_IRQ 0x02 /* R W MIDI Enable time compare interrupts */ +# define M_C_ENA_INPUT_IRQ 0x04 /* R W MIDI Enable input FIFO interrupts */ +# define M_C_ENA_OUTPUT_IRQ 0x08 /* R W MIDI Enable output FIFO interrupts */ +# define M_C_ENA_OUTPUT_HALF_IRQ 0x10 /* R W MIDI Enable output FIFO half full interrupts */ +# define M_C_RESET_INPUT_FIFO 0x20 /* R W MIDI Reset input FIFO pointer */ +# define M_C_RESET_OUTPUT_FIFO 0x40 /* R W MIDI Reset output FIFO pointer */ +# define M_C_ENA_THRU_MODE 0x80 /* R W MIDI Echo input to output (THRU) */ + +#define MIDI_STATUS 0x1B88 /* R W MIDI Midi (interrupt) status register */ +# define M_S_TIMESTAMP 0x01 /* R W MIDI Midi time stamp interrupt occurred */ +# define M_S_COMPARE 0x02 /* R W MIDI Midi compare time interrupt occurred */ +# define M_S_INPUT_AVAIL 0x04 /* R W MIDI Midi input data available interrupt occurred */ +# define M_S_OUTPUT_EMPTY 0x08 /* R W MIDI Midi output FIFO empty interrupt occurred */ +# define M_S_OUTPUT_HALF_EMPTY 0x10 /* R W MIDI Midi output FIFO half empty interrupt occurred */ +# define M_S_INPUT_OVERRUN 0x20 /* R W MIDI Midi input overrun error occurred */ +# define M_S_OUTPUT_OVERRUN 0x40 /* R W MIDI Midi output overrun error occurred */ +# define M_S_FRAMING_ERROR 0x80 /* R W MIDI Midi input framing error occurred */ + +#define MIDI_FIFO_STATUS 0x1B89 /* R W MIDI Midi fifo status */ +#define MIDI_DATA 0x178A /* R W MIDI Midi data register */ +#define MIDI_INPUT_AVAILABLE 0x0f /* RW MIDI */ diff --git a/sys/i386/isa/sound/pcm86.c b/sys/i386/isa/sound/pcm86.c new file mode 100644 index 000000000000..aa7e3d77ef21 --- /dev/null +++ b/sys/i386/isa/sound/pcm86.c @@ -0,0 +1,2189 @@ +/* + * PC-9801-86 PCM driver for FreeBSD(98). + * + * Copyright (c) 1995 NAGAO Tadaaki (ABTK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: pcm86.c,v 2.4 1996/01/24 19:53:34 abtk Exp $ + */ + +/* + * !! NOTE !! : + * This file DOES NOT belong to the VoxWare distribution though it works + * as part of the VoxWare drivers. It is FreeBSD(98) original. + * -- Nagao (nagao@cs.titech.ac.jp) + */ + + +#include <i386/isa/sound/sound_config.h> + +#ifdef CONFIGURE_SOUNDCARD + +#if !defined(EXCLUDE_PCM86) && !defined(EXCLUDE_AUDIO) + + +/* + * Constants + */ + +#define YES 1 +#define NO 0 + +#define IMODE_NONE 0 +#define IMODE_INPUT 1 +#define IMODE_OUTPUT 2 + +/* PC-9801-86 specific constants */ +#define PCM86_IOBASE 0xa460 /* PCM I/O ports */ +#define PCM86_FIFOSIZE 32768 /* There is a 32kB FIFO buffer on 86-board */ + +/* XXX -- These values should be chosen appropriately. */ +#define PCM86_INTRSIZE_OUT 1024 +#define PCM86_INTRSIZE_IN (PCM86_FIFOSIZE / 2 - 128) +#define DEFAULT_VOLUME 15 /* 0(min) - 15(max) */ + + +/* + * Switches for debugging and experiments + */ + +/* #define PCM86_DEBUG */ + +#ifdef PCM86_DEBUG +# ifdef DEB +# undef DEB +# endif +# define DEB(x) x +#endif + + +/* + * Private variables and types + */ + +typedef unsigned char pcm_data; + +enum board_type { + NO_SUPPORTED_BOARD = 0, + PC980186_FAMILY = 1, + PC980173_FAMILY = 2 +}; + +static char *board_name[] = { + /* Each must be of the length less than 32 bytes. */ + "No supported board", + "PC-9801-86 soundboard", + "PC-9801-73 soundboard" +}; + +/* Current status of the driver */ +static struct { + int iobase; + int irq; + enum board_type board_type; + int opened; + int format; + int bytes; + int chipspeedno; + int chipspeed; + int speed; + int stereo; + int volume; + int intr_busy; + int intr_size; + int intr_mode; + int intr_last; + int intr_trailer; + pcm_data * pdma_buf; + int pdma_count; + int pdma_chunkcount; + int acc; + int last_l; + int last_r; +} pcm_s; + +static struct { + pcm_data buff[4]; + int size; +} tmpbuf; + +static int my_dev = 0; +static char pcm_initialized = NO; + +/* 86-board supports only the following rates. */ +static int rates_tbl[8] = { +#ifndef WAVEMASTER_FREQ + 44100, 33075, 22050, 16538, 11025, 8269, 5513, 4134 +#else + /* + * It is said that Q-Vision's WaveMaster of some earlier lot(s?) has + * sampling rates incompatible with PC-9801-86. + * But I'm not sure whether the following rates are correct, especially + * 4000Hz. + */ + 44100, 33075, 22050, 16000, 11025, 8000, 5510, 4000 +#endif +}; + +/* u-law to linear translation table */ +static pcm_data ulaw2linear[256] = { + 130, 134, 138, 142, 146, 150, 154, 158, + 162, 166, 170, 174, 178, 182, 186, 190, + 193, 195, 197, 199, 201, 203, 205, 207, + 209, 211, 213, 215, 217, 219, 221, 223, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, + 240, 241, 241, 242, 242, 243, 243, 244, + 244, 245, 245, 246, 246, 247, 247, 248, + 248, 248, 249, 249, 249, 249, 250, 250, + 250, 250, 251, 251, 251, 251, 252, 252, + 252, 252, 252, 252, 253, 253, 253, 253, + 253, 253, 253, 253, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 125, 121, 117, 113, 109, 105, 101, 97, + 93, 89, 85, 81, 77, 73, 69, 65, + 62, 60, 58, 56, 54, 52, 50, 48, + 46, 44, 42, 40, 38, 36, 34, 32, + 30, 29, 28, 27, 26, 25, 24, 23, + 22, 21, 20, 19, 18, 17, 16, 15, + 15, 14, 14, 13, 13, 12, 12, 11, + 11, 10, 10, 9, 9, 8, 8, 7, + 7, 7, 6, 6, 6, 6, 5, 5, + 5, 5, 4, 4, 4, 4, 3, 3, + 3, 3, 3, 3, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* linear to u-law translation table */ +static pcm_data linear2ulaw[256] = { + 255, 231, 219, 211, 205, 201, 197, 193, + 190, 188, 186, 184, 182, 180, 178, 176, + 175, 174, 173, 172, 171, 170, 169, 168, + 167, 166, 165, 164, 163, 162, 161, 160, + 159, 159, 158, 158, 157, 157, 156, 156, + 155, 155, 154, 154, 153, 153, 152, 152, + 151, 151, 150, 150, 149, 149, 148, 148, + 147, 147, 146, 146, 145, 145, 144, 144, + 143, 143, 143, 143, 142, 142, 142, 142, + 141, 141, 141, 141, 140, 140, 140, 140, + 139, 139, 139, 139, 138, 138, 138, 138, + 137, 137, 137, 137, 136, 136, 136, 136, + 135, 135, 135, 135, 134, 134, 134, 134, + 133, 133, 133, 133, 132, 132, 132, 132, + 131, 131, 131, 131, 130, 130, 130, 130, + 129, 129, 129, 129, 128, 128, 128, 128, + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, + 3, 4, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 13, 13, 13, + 13, 14, 14, 14, 14, 15, 15, 15, + 15, 16, 16, 17, 17, 18, 18, 19, + 19, 20, 20, 21, 21, 22, 22, 23, + 23, 24, 24, 25, 25, 26, 26, 27, + 27, 28, 28, 29, 29, 30, 30, 31, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 50, 52, 54, 56, 58, 60, + 62, 65, 69, 73, 77, 83, 91, 103 +}; + + +/* + * Prototypes + */ + +static int pcm86_detect(struct address_info *); + +static int pcm86_open(int, int); +static void pcm86_close(int); +static void pcm86_output_block(int, unsigned long, int, int, int); +static void pcm86_start_input(int, unsigned long, int, int, int); +static int pcm86_ioctl(int, unsigned int, unsigned int, int); +static int pcm86_prepare_for_input(int, int, int); +static int pcm86_prepare_for_output(int, int, int); +static void pcm86_reset(int); +static void pcm86_halt_xfer(int); + +static void dsp73_send_command(unsigned char); +static void dsp73_send_data(unsigned char); +static void dsp73_init(void); +static int set_format(int); +static int set_speed(int); +static int set_stereo(int); +static void set_volume(int); +static void fifo_start(int); +static void fifo_stop(void); +static void fifo_reset(void); +static void fifo_output_block(void); +static int fifo_send(pcm_data *, int); +static void fifo_sendtrailer(int); +static void fifo_send_stereo(pcm_data *, int); +static void fifo_send_monoral(pcm_data *, int); +static void fifo_send_stereo_ulaw(pcm_data *, int); +static void fifo_send_stereo_8(pcm_data *, int, int); +static void fifo_send_stereo_16le(pcm_data *, int, int); +static void fifo_send_stereo_16be(pcm_data *, int, int); +static void fifo_send_mono_ulaw(pcm_data *, int); +static void fifo_send_mono_8(pcm_data *, int, int); +static void fifo_send_mono_16le(pcm_data *, int, int); +static void fifo_send_mono_16be(pcm_data *, int, int); +static void fifo_input_block(void); +static void fifo_recv(pcm_data *, int); +static void fifo_recv_stereo(pcm_data *, int); +static void fifo_recv_monoral(pcm_data *, int); +static void fifo_recv_stereo_ulaw(pcm_data *, int); +static void fifo_recv_stereo_8(pcm_data *, int, int); +static void fifo_recv_stereo_16le(pcm_data *, int, int); +static void fifo_recv_stereo_16be(pcm_data *, int, int); +static void fifo_recv_mono_ulaw(pcm_data *, int); +static void fifo_recv_mono_8(pcm_data *, int, int); +static void fifo_recv_mono_16le(pcm_data *, int, int); +static void fifo_recv_mono_16be(pcm_data *, int, int); +static void pcm_stop(void); +static void pcm_init(void); + + +/* + * Identity + */ + +static struct audio_operations pcm86_operations = +{ + "PC-9801-86 SoundBoard", /* filled in properly by auto configuration */ + NOTHING_SPECIAL, + ( AFMT_MU_LAW | + AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | + AFMT_S8 | AFMT_U16_LE | AFMT_U16_BE ), + NULL, + pcm86_open, + pcm86_close, + pcm86_output_block, + pcm86_start_input, + pcm86_ioctl, + pcm86_prepare_for_input, + pcm86_prepare_for_output, + pcm86_reset, + pcm86_halt_xfer, + NULL, + NULL +}; + + +/* + * Codes for internal use + */ + +static void +dsp73_send_command(unsigned char command) +{ + /* wait for RDY */ + while ((inb(pcm_s.iobase + 2) & 0x48) != 8); + + /* command mode */ + outb(pcm_s.iobase + 2, (inb(pcm_s.iobase + 2) & 0x20) | 3); + + /* wait for RDY */ + while ((inb(pcm_s.iobase + 2) & 0x48) != 8); + + /* send command */ + outb(pcm_s.iobase + 4, command); +} + + +static void +dsp73_send_data(unsigned char data) +{ + /* wait for RDY */ + while ((inb(pcm_s.iobase + 2) & 0x48) != 8); + + /* data mode */ + outb(pcm_s.iobase + 2, (inb(pcm_s.iobase + 2) & 0x20) | 0x83); + + /* wait for RDY */ + while ((inb(pcm_s.iobase + 2) & 0x48) != 8); + + /* send command */ + outb(pcm_s.iobase + 4, data); +} + + +static void +dsp73_init(void) +{ + const unsigned char dspinst[15] = { + 0x00, 0x00, 0x27, + 0x3f, 0xe0, 0x01, + 0x00, 0x00, 0x27, + 0x36, 0x5a, 0x0d, + 0x3e, 0x60, 0x04 + }; + unsigned char t; + int i; + + /* reset DSP */ + t = inb(pcm_s.iobase + 2); + outb(pcm_s.iobase + 2, (t & 0x80) | 0x23); + + /* mute on */ + dsp73_send_command(0x04); + dsp73_send_data(0x6f); + dsp73_send_data(0x3c); + + /* write DSP instructions */ + dsp73_send_command(0x01); + dsp73_send_data(0x00); + for (i = 0; i < 16; i++) + dsp73_send_data(dspinst[i]); + + /* mute off */ + dsp73_send_command(0x04); + dsp73_send_data(0x6f); + dsp73_send_data(0x30); + + /* wait for RDY */ + while ((inb(pcm_s.iobase + 2) & 0x48) != 8); + + outb(pcm_s.iobase + 2, 3); +} + + +static int +set_format(int format) +{ + switch (format) { + case AFMT_MU_LAW: + case AFMT_S8: + case AFMT_U8: + pcm_s.format = format; + pcm_s.bytes = 1; /* 8bit */ + break; + case AFMT_S16_LE: + case AFMT_U16_LE: + case AFMT_S16_BE: + case AFMT_U16_BE: + pcm_s.format = format; + pcm_s.bytes = 2; /* 16bit */ + break; + case AFMT_QUERY: + break; + default: + return -1; + } + + return pcm_s.format; +} + + +static int +set_speed(int speed) +{ + int i; + + if (speed < 4000) /* Minimum 4000Hz */ + speed = 4000; + if (speed > 44100) /* Maximum 44100Hz */ + speed = 44100; + for (i = 7; i >= 0; i--) { + if (speed <= rates_tbl[i]) { + pcm_s.chipspeedno = i; + pcm_s.chipspeed = rates_tbl[i]; + break; + } + } + pcm_s.speed = speed; + + return speed; +} + + +static int +set_stereo(int stereo) +{ + pcm_s.stereo = stereo ? YES : NO; + + return pcm_s.stereo; +} + + +static void +set_volume(int volume) +{ + if (volume < 0) + volume = 0; + if (volume > 15) + volume = 15; + pcm_s.volume = volume; + + outb(pcm_s.iobase + 6, 0xaf - volume); /* D/A -> LINE OUT */ + outb(0x5f,0); + outb(0x5f,0); + outb(0x5f,0); + outb(0x5f,0); + outb(pcm_s.iobase + 6, 0x20); /* FM -> A/D */ + outb(0x5f,0); + outb(0x5f,0); + outb(0x5f,0); + outb(0x5f,0); + outb(pcm_s.iobase + 6, 0x60); /* LINE IN -> A/D */ + outb(0x5f,0); + outb(0x5f,0); + outb(0x5f,0); + outb(0x5f,0); +} + + +static void +fifo_start(int mode) +{ + unsigned char tmp; + + /* Set frame length & panpot(LR). */ + tmp = inb(pcm_s.iobase + 10) & 0x88; + outb(pcm_s.iobase + 10, tmp | ((pcm_s.bytes == 1) ? 0x72 : 0x32)); + + tmp = pcm_s.chipspeedno; + if (mode == IMODE_INPUT) + tmp |= 0x40; + + /* Reset intr. flag. */ + outb(pcm_s.iobase + 8, tmp); + outb(pcm_s.iobase + 8, tmp | 0x10); + + /* Enable FIFO intr. */ + outb(pcm_s.iobase + 8, tmp | 0x30); + + /* Set intr. interval. */ + outb(pcm_s.iobase + 10, pcm_s.intr_size / 128 - 1); + + /* Start intr. */ + outb(pcm_s.iobase + 8, tmp | 0xb0); +} + + +static void +fifo_stop(void) +{ + unsigned char tmp; + + /* Reset intr. flag, and disable FIFO intr. */ + tmp = inb(pcm_s.iobase + 8) & 0x0f; + outb(pcm_s.iobase + 8, tmp); +} + + +static void +fifo_reset(void) +{ + unsigned char tmp; + + /* Reset FIFO. */ + tmp = inb(pcm_s.iobase + 8) & 0x77; + outb(pcm_s.iobase + 8, tmp | 0x8); + outb(pcm_s.iobase + 8, tmp); +} + + +static void +fifo_output_block(void) +{ + int chunksize, count; + + if (pcm_s.pdma_chunkcount) { + /* Update chunksize and then send the next chunk to FIFO. */ + chunksize = pcm_s.pdma_count / pcm_s.pdma_chunkcount--; + count = fifo_send(pcm_s.pdma_buf, chunksize); + } else { + /* ??? something wrong... */ + printk("pcm0: chunkcount overrun\n"); + chunksize = count = 0; + } + + if (((audio_devs[my_dev]->dmap->qlen < 2) && (pcm_s.pdma_chunkcount == 0)) + || (count < pcm_s.intr_size)) { + /* The sent chunk seems to be the last one. */ + fifo_sendtrailer(pcm_s.intr_size); + pcm_s.intr_last = YES; + } + + pcm_s.pdma_buf += chunksize; + pcm_s.pdma_count -= chunksize; +} + + +static int +fifo_send(pcm_data *buf, int count) +{ + int i, length, r, cnt, rslt; + pcm_data *p; + + /* Calculate the length of PCM frames. */ + cnt = count + tmpbuf.size; + length = pcm_s.bytes << pcm_s.stereo; + r = cnt % length; + cnt -= r; + + if (cnt > 0) { + if (pcm_s.stereo) + fifo_send_stereo(buf, cnt); + else + fifo_send_monoral(buf, cnt); + /* Carry over extra data which doesn't seem to be a full PCM frame. */ + p = (pcm_data *)buf + count - r; + for (i = 0; i < r; i++) + tmpbuf.buff[i] = *p++; + } else { + /* Carry over extra data which doesn't seem to be a full PCM frame. */ + p = (pcm_data *)buf; + for (i = tmpbuf.size; i < r; i++) + tmpbuf.buff[i] = *p++; + } + tmpbuf.size = r; + + rslt = ((cnt / length) * pcm_s.chipspeed / pcm_s.speed) * pcm_s.bytes * 2; +#ifdef PCM86_DEBUG + printk("fifo_send(): %d bytes sent\n", rslt); +#endif + return rslt; +} + + +static void +fifo_sendtrailer(int count) +{ + /* Send trailing zeros to the FIFO buffer. */ + int i; + + for (i = 0; i < count; i++) + outb(pcm_s.iobase + 12, 0); + pcm_s.intr_trailer = YES; + +#ifdef PCM86_DEBUG + printk("fifo_sendtrailer(): %d bytes sent\n", count); +#endif +} + + +static void +fifo_send_stereo(pcm_data *buf, int count) +{ + /* Convert format and sampling speed. */ + switch (pcm_s.format) { + case AFMT_MU_LAW: + fifo_send_stereo_ulaw(buf, count); + break; + case AFMT_S8: + fifo_send_stereo_8(buf, count, NO); + break; + case AFMT_U8: + fifo_send_stereo_8(buf, count, YES); + break; + case AFMT_S16_LE: + fifo_send_stereo_16le(buf, count, NO); + break; + case AFMT_U16_LE: + fifo_send_stereo_16le(buf, count, YES); + break; + case AFMT_S16_BE: + fifo_send_stereo_16be(buf, count, NO); + break; + case AFMT_U16_BE: + fifo_send_stereo_16be(buf, count, YES); + break; + } +} + + +static void +fifo_send_monoral(pcm_data *buf, int count) +{ + /* Convert format and sampling speed. */ + switch (pcm_s.format) { + case AFMT_MU_LAW: + fifo_send_mono_ulaw(buf, count); + break; + case AFMT_S8: + fifo_send_mono_8(buf, count, NO); + break; + case AFMT_U8: + fifo_send_mono_8(buf, count, YES); + break; + case AFMT_S16_LE: + fifo_send_mono_16le(buf, count, NO); + break; + case AFMT_U16_LE: + fifo_send_mono_16le(buf, count, YES); + break; + case AFMT_S16_BE: + fifo_send_mono_16be(buf, count, NO); + break; + case AFMT_U16_BE: + fifo_send_mono_16be(buf, count, YES); + break; + } +} + + +static void +fifo_send_stereo_ulaw(pcm_data *buf, int count) +{ + int i; + signed char dl, dl0, dl1, dr, dr0, dr1; + pcm_data t[2]; + + if (tmpbuf.size > 0) + t[0] = ulaw2linear[tmpbuf.buff[0]]; + else + t[0] = ulaw2linear[*buf++]; + t[1] = ulaw2linear[*buf++]; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + outb(pcm_s.iobase + 12, t[0]); + outb(pcm_s.iobase + 12, t[1]); + count -= 2; + for (i = 0; i < count; i++) + outb(pcm_s.iobase + 12, ulaw2linear[*buf++]); + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = t[0]; + dr1 = t[1]; + i = 0; + count /= 2; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + dl0 = dl1; + dr0 = dr1; + if (i < count) { + dl1 = ulaw2linear[*buf++]; + dr1 = ulaw2linear[*buf++]; + } else + dl1 = dr1 = 0; + } + dl = ((dl0 * (pcm_s.chipspeed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.chipspeed; + dr = ((dr0 * (pcm_s.chipspeed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, dl); + outb(pcm_s.iobase + 12, dr); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_send_stereo_8(pcm_data *buf, int count, int uflag) +{ + int i; + signed char dl, dl0, dl1, dr, dr0, dr1, zlev; + pcm_data t[2]; + + zlev = uflag ? -128 : 0; + + if (tmpbuf.size > 0) + t[0] = tmpbuf.buff[0] + zlev; + else + t[0] = *buf++ + zlev; + t[1] = *buf++ + zlev; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + outb(pcm_s.iobase + 12, t[0]); + outb(pcm_s.iobase + 12, t[1]); + count -= 2; + for (i = 0; i < count; i++) + outb(pcm_s.iobase + 12, *buf++ + zlev); + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = t[0]; + dr1 = t[1]; + i = 0; + count /= 2; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + dl0 = dl1; + dr0 = dr1; + if (i < count) { + dl1 = *buf++ + zlev; + dr1 = *buf++ + zlev; + } else + dl1 = dr1 = 0; + } + dl = ((dl0 * (pcm_s.chipspeed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.chipspeed; + dr = ((dr0 * (pcm_s.chipspeed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, dl); + outb(pcm_s.iobase + 12, dr); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_send_stereo_16le(pcm_data *buf, int count, int uflag) +{ + int i; + short dl, dl0, dl1, dr, dr0, dr1, zlev; + pcm_data t[4]; + + zlev = uflag ? -128 : 0; + + for (i = 0; i < 4; i++) + t[i] = (tmpbuf.size > i) ? tmpbuf.buff[i] : *buf++; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + outb(pcm_s.iobase + 12, t[1] + zlev); + outb(pcm_s.iobase + 12, t[0]); + outb(pcm_s.iobase + 12, t[3] + zlev); + outb(pcm_s.iobase + 12, t[2]); + count = count / 2 - 2; + for (i = 0; i < count; i++) { + outb(pcm_s.iobase + 12, *(buf + 1) + zlev); + outb(pcm_s.iobase + 12, *buf); + buf += 2; + } + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = t[0] + ((t[1] + zlev) << 8); + dr1 = t[2] + ((t[3] + zlev) << 8); + i = 0; + count /= 4; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + dl0 = dl1; + dr0 = dr1; + if (i < count) { + dl1 = *buf + ((*(buf + 1) + zlev) << 8); + buf += 2; + dr1 = *buf + ((*(buf + 1) + zlev) << 8); + buf += 2; + } else + dl1 = dr1 = 0; + } + dl = ((dl0 * (pcm_s.chipspeed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.chipspeed; + dr = ((dr0 * (pcm_s.chipspeed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, (dl >> 8) & 0xff); + outb(pcm_s.iobase + 12, dl & 0xff); + outb(pcm_s.iobase + 12, (dr >> 8) & 0xff); + outb(pcm_s.iobase + 12, dr & 0xff); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_send_stereo_16be(pcm_data *buf, int count, int uflag) +{ + int i; + short dl, dl0, dl1, dr, dr0, dr1, zlev; + pcm_data t[4]; + + zlev = uflag ? -128 : 0; + + for (i = 0; i < 4; i++) + t[i] = (tmpbuf.size > i) ? tmpbuf.buff[i] : *buf++; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + outb(pcm_s.iobase + 12, t[0] + zlev); + outb(pcm_s.iobase + 12, t[1]); + outb(pcm_s.iobase + 12, t[2] + zlev); + outb(pcm_s.iobase + 12, t[3]); + count = count / 2 - 2; + for (i = 0; i < count; i++) { + outb(pcm_s.iobase + 12, *buf + zlev); + outb(pcm_s.iobase + 12, *(buf + 1)); + buf += 2; + } + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = ((t[0] + zlev) << 8) + t[1]; + dr1 = ((t[2] + zlev) << 8) + t[3]; + i = 0; + count /= 4; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + dl0 = dl1; + dr0 = dr1; + if (i < count) { + dl1 = ((*buf + zlev) << 8) + *(buf + 1); + buf += 2; + dr1 = ((*buf + zlev) << 8) + *(buf + 1); + buf += 2; + } else + dl1 = dr1 = 0; + } + dl = ((dl0 * (pcm_s.chipspeed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.chipspeed; + dr = ((dr0 * (pcm_s.chipspeed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, (dl >> 8) & 0xff); + outb(pcm_s.iobase + 12, dl & 0xff); + outb(pcm_s.iobase + 12, (dr >> 8) & 0xff); + outb(pcm_s.iobase + 12, dr & 0xff); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_send_mono_ulaw(pcm_data *buf, int count) +{ + int i; + signed char d, d0, d1; + + if (pcm_s.speed == pcm_s.chipspeed) + /* No reason to convert the pcm speed. */ + for (i = 0; i < count; i++) { + d = ulaw2linear[*buf++]; + outb(pcm_s.iobase + 12, d); + outb(pcm_s.iobase + 12, d); + } + else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + d1 = ulaw2linear[*buf++]; + i = 0; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + d0 = d1; + d1 = (i < count) ? ulaw2linear[*buf++] : 0; + } + d = ((d0 * (pcm_s.chipspeed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, d); + outb(pcm_s.iobase + 12, d); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_send_mono_8(pcm_data *buf, int count, int uflag) +{ + int i; + signed char d, d0, d1, zlev; + + zlev = uflag ? -128 : 0; + + if (pcm_s.speed == pcm_s.chipspeed) + /* No reason to convert the pcm speed. */ + for (i = 0; i < count; i++) { + d = *buf++ + zlev; + outb(pcm_s.iobase + 12, d); + outb(pcm_s.iobase + 12, d); + } + else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + d1 = *buf++ + zlev; + i = 0; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + d0 = d1; + d1 = (i < count) ? *buf++ + zlev : 0; + } + d = ((d0 * (pcm_s.chipspeed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, d); + outb(pcm_s.iobase + 12, d); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_send_mono_16le(pcm_data *buf, int count, int uflag) +{ + int i; + short d, d0, d1, zlev; + pcm_data t[2]; + + zlev = uflag ? -128 : 0; + + for (i = 0; i < 2; i++) + t[i] = (tmpbuf.size > i) ? tmpbuf.buff[i] : *buf++; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + outb(pcm_s.iobase + 12, t[1] + zlev); + outb(pcm_s.iobase + 12, t[0]); + outb(pcm_s.iobase + 12, t[1] + zlev); + outb(pcm_s.iobase + 12, t[0]); + count = count / 2 - 1; + for (i = 0; i < count; i++) { + outb(pcm_s.iobase + 12, *(buf + 1) + zlev); + outb(pcm_s.iobase + 12, *buf); + outb(pcm_s.iobase + 12, *(buf + 1) + zlev); + outb(pcm_s.iobase + 12, *buf); + buf += 2; + } + } else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + d1 = t[0] + ((t[1] + zlev) << 8); + i = 0; + count /= 2; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + d0 = d1; + if (i < count) { + d1 = *buf + ((*(buf + 1) + zlev) << 8); + buf += 2; + } else + d1 = 0; + } + d = ((d0 * (pcm_s.chipspeed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, (d >> 8) & 0xff); + outb(pcm_s.iobase + 12, d & 0xff); + outb(pcm_s.iobase + 12, (d >> 8) & 0xff); + outb(pcm_s.iobase + 12, d & 0xff); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_send_mono_16be(pcm_data *buf, int count, int uflag) +{ + int i; + short d, d0, d1, zlev; + pcm_data t[2]; + + zlev = uflag ? -128 : 0; + + for (i = 0; i < 2; i++) + t[i] = (tmpbuf.size > i) ? tmpbuf.buff[i] : *buf++; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + outb(pcm_s.iobase + 12, t[0] + zlev); + outb(pcm_s.iobase + 12, t[1]); + outb(pcm_s.iobase + 12, t[0] + zlev); + outb(pcm_s.iobase + 12, t[1]); + count = count / 2 - 1; + for (i = 0; i < count; i++) { + outb(pcm_s.iobase + 12, *buf + zlev); + outb(pcm_s.iobase + 12, *(buf + 1)); + outb(pcm_s.iobase + 12, *buf + zlev); + outb(pcm_s.iobase + 12, *(buf + 1)); + buf += 2; + } + } else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + d1 = ((t[0] + zlev) << 8) + t[1]; + i = 0; + count /= 2; + while (i < count) { + while (pcm_s.acc >= pcm_s.chipspeed) { + pcm_s.acc -= pcm_s.chipspeed; + i++; + d0 = d1; + if (i < count) { + d1 = ((*buf + zlev) << 8) + *(buf + 1); + buf += 2; + } else + d1 = 0; + } + d = ((d0 * (pcm_s.chipspeed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.chipspeed; + outb(pcm_s.iobase + 12, d & 0xff); + outb(pcm_s.iobase + 12, (d >> 8) & 0xff); + outb(pcm_s.iobase + 12, d & 0xff); + outb(pcm_s.iobase + 12, (d >> 8) & 0xff); + pcm_s.acc += pcm_s.speed; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_input_block(void) +{ + int chunksize; + + if (pcm_s.pdma_chunkcount) { + /* Update chunksize and then receive the next chunk from FIFO. */ + chunksize = pcm_s.pdma_count / pcm_s.pdma_chunkcount--; + fifo_recv(pcm_s.pdma_buf, chunksize); + pcm_s.pdma_buf += chunksize; + pcm_s.pdma_count -= chunksize; + } else + /* ??? something wrong... */ + printk("pcm0: chunkcount overrun\n"); +} + + +static void +fifo_recv(pcm_data *buf, int count) +{ + int i; + + if (count > tmpbuf.size) { + for (i = 0; i < tmpbuf.size; i++) + *buf++ = tmpbuf.buff[i]; + count -= tmpbuf.size; + tmpbuf.size = 0; + if (pcm_s.stereo) + fifo_recv_stereo(buf, count); + else + fifo_recv_monoral(buf, count); + } else { + for (i = 0; i < count; i++) + *buf++ = tmpbuf.buff[i]; + for (i = 0; i < tmpbuf.size - count; i++) + tmpbuf.buff[i] = tmpbuf.buff[i + count]; + tmpbuf.size -= count; + } + +#ifdef PCM86_DEBUG + printk("fifo_recv(): %d bytes received\n", + ((count / (pcm_s.bytes << pcm_s.stereo)) * pcm_s.chipspeed + / pcm_s.speed) * pcm_s.bytes * 2); +#endif +} + + +static void +fifo_recv_stereo(pcm_data *buf, int count) +{ + /* Convert format and sampling speed. */ + switch (pcm_s.format) { + case AFMT_MU_LAW: + fifo_recv_stereo_ulaw(buf, count); + break; + case AFMT_S8: + fifo_recv_stereo_8(buf, count, NO); + break; + case AFMT_U8: + fifo_recv_stereo_8(buf, count, YES); + break; + case AFMT_S16_LE: + fifo_recv_stereo_16le(buf, count, NO); + break; + case AFMT_U16_LE: + fifo_recv_stereo_16le(buf, count, YES); + break; + case AFMT_S16_BE: + fifo_recv_stereo_16be(buf, count, NO); + break; + case AFMT_U16_BE: + fifo_recv_stereo_16be(buf, count, YES); + break; + } +} + + +static void +fifo_recv_monoral(pcm_data *buf, int count) +{ + /* Convert format and sampling speed. */ + switch (pcm_s.format) { + case AFMT_MU_LAW: + fifo_recv_mono_ulaw(buf, count); + break; + case AFMT_S8: + fifo_recv_mono_8(buf, count, NO); + break; + case AFMT_U8: + fifo_recv_mono_8(buf, count, YES); + break; + case AFMT_S16_LE: + fifo_recv_mono_16le(buf, count, NO); + break; + case AFMT_U16_LE: + fifo_recv_mono_16le(buf, count, YES); + break; + case AFMT_S16_BE: + fifo_recv_mono_16be(buf, count, NO); + break; + case AFMT_U16_BE: + fifo_recv_mono_16be(buf, count, YES); + break; + } +} + + +static void +fifo_recv_stereo_ulaw(pcm_data *buf, int count) +{ + int i, cnt; + signed char dl, dl0, dl1, dr, dr0, dr1; + + cnt = count / 2; + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < cnt; i++) { + *buf++ = linear2ulaw[inb(pcm_s.iobase + 12)]; + *buf++ = linear2ulaw[inb(pcm_s.iobase + 12)]; + } + if (count % 2) { + *buf++ = linear2ulaw[inb(pcm_s.iobase + 12)]; + tmpbuf.buff[0] = linear2ulaw[inb(pcm_s.iobase + 12)]; + tmpbuf.size = 1; + } + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12); + for (i = 0; i < cnt; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = linear2ulaw[dl & 0xff]; + *buf++ = linear2ulaw[dr & 0xff]; + pcm_s.acc += pcm_s.chipspeed; + } + if (count % 2) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = linear2ulaw[dl & 0xff]; + tmpbuf.buff[0] = linear2ulaw[dr & 0xff]; + tmpbuf.size = 1; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_recv_stereo_8(pcm_data *buf, int count, int uflag) +{ + int i, cnt; + signed char dl, dl0, dl1, dr, dr0, dr1, zlev; + + zlev = uflag ? -128 : 0; + + cnt = count / 2; + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < cnt; i++) { + *buf++ = inb(pcm_s.iobase + 12) + zlev; + *buf++ = inb(pcm_s.iobase + 12) + zlev; + } + if (count % 2) { + *buf++ = inb(pcm_s.iobase + 12) + zlev; + tmpbuf.buff[0] = inb(pcm_s.iobase + 12) + zlev; + tmpbuf.size = 1; + } + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12); + for (i = 0; i < cnt; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = dl + zlev; + *buf++ = dr + zlev; + pcm_s.acc += pcm_s.chipspeed; + } + if (count % 2) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = dl + zlev; + tmpbuf.buff[0] = dr + zlev; + tmpbuf.size = 1; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_recv_stereo_16le(pcm_data *buf, int count, int uflag) +{ + int i, cnt; + short dl, dl0, dl1, dr, dr0, dr1, zlev; + pcm_data t[4]; + + zlev = uflag ? -128 : 0; + + cnt = count / 4; + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < cnt; i++) { + *(buf + 1) = inb(pcm_s.iobase + 12) + zlev; + *buf = inb(pcm_s.iobase + 12); + *(buf + 3) = inb(pcm_s.iobase + 12) + zlev; + *(buf + 2) = inb(pcm_s.iobase + 12); + buf += 4; + } + if (count % 4) { + t[1] = inb(pcm_s.iobase + 12) + zlev; + t[0] = inb(pcm_s.iobase + 12); + t[3] = inb(pcm_s.iobase + 12) + zlev; + t[2] = inb(pcm_s.iobase + 12); + tmpbuf.size = 0; + for (i = 0; i < count % 4; i++) + *buf++ = t[i]; + for (i = count % 4; i < 4; i++) + tmpbuf.buff[tmpbuf.size++] = t[i]; + } + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = inb(pcm_s.iobase + 12) << 8; + dl1 |= inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12) << 8; + dr1 |= inb(pcm_s.iobase + 12); + for (i = 0; i < cnt; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12) << 8; + dl1 |= inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12) << 8; + dr1 |= inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = dl & 0xff; + *buf++ = ((dl >> 8) & 0xff) + zlev; + *buf++ = dr & 0xff; + *buf++ = ((dr >> 8) & 0xff) + zlev; + pcm_s.acc += pcm_s.chipspeed; + } + if (count % 4) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12) << 8; + dl1 |= inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12) << 8; + dr1 |= inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + t[0] = dl & 0xff; + t[1] = ((dl >> 8) & 0xff) + zlev; + t[2] = dr & 0xff; + t[3] = ((dr >> 8) & 0xff) + zlev; + tmpbuf.size = 0; + for (i = 0; i < count % 4; i++) + *buf++ = t[i]; + for (i = count % 4; i < 4; i++) + tmpbuf.buff[tmpbuf.size++] = t[i]; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_recv_stereo_16be(pcm_data *buf, int count, int uflag) +{ + int i, cnt; + short dl, dl0, dl1, dr, dr0, dr1, zlev; + pcm_data t[4]; + + zlev = uflag ? -128 : 0; + + cnt = count / 4; + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < cnt; i++) { + *buf++ = inb(pcm_s.iobase + 12) + zlev; + *buf++ = inb(pcm_s.iobase + 12); + *buf++ = inb(pcm_s.iobase + 12) + zlev; + *buf++ = inb(pcm_s.iobase + 12); + } + if (count % 4) { + t[0] = inb(pcm_s.iobase + 12) + zlev; + t[1] = inb(pcm_s.iobase + 12); + t[2] = inb(pcm_s.iobase + 12) + zlev; + t[3] = inb(pcm_s.iobase + 12); + tmpbuf.size = 0; + for (i = 0; i < count % 4; i++) + *buf++ = t[i]; + for (i = count % 4; i < 4; i++) + tmpbuf.buff[tmpbuf.size++] = t[i]; + } + } else { + /* Speed conversion with linear interpolation method. */ + dl0 = pcm_s.last_l; + dr0 = pcm_s.last_r; + dl1 = inb(pcm_s.iobase + 12) << 8; + dl1 |= inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12) << 8; + dr1 |= inb(pcm_s.iobase + 12); + for (i = 0; i < cnt; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12) << 8; + dl1 |= inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12) << 8; + dr1 |= inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = ((dl >> 8) & 0xff) + zlev; + *buf++ = dl & 0xff; + *buf++ = ((dr >> 8) & 0xff) + zlev; + *buf++ = dr & 0xff; + pcm_s.acc += pcm_s.chipspeed; + } + if (count % 4) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + dl0 = dl1; + dr0 = dr1; + dl1 = inb(pcm_s.iobase + 12) << 8; + dl1 |= inb(pcm_s.iobase + 12); + dr1 = inb(pcm_s.iobase + 12) << 8; + dr1 |= inb(pcm_s.iobase + 12); + } + dl = ((dl0 * (pcm_s.speed - pcm_s.acc)) + (dl1 * pcm_s.acc)) + / pcm_s.speed; + dr = ((dr0 * (pcm_s.speed - pcm_s.acc)) + (dr1 * pcm_s.acc)) + / pcm_s.speed; + t[0] = ((dl >> 8) & 0xff) + zlev; + t[1] = dl & 0xff; + t[2] = ((dr >> 8) & 0xff) + zlev; + t[3] = dr & 0xff; + tmpbuf.size = 0; + for (i = 0; i < count % 4; i++) + *buf++ = t[i]; + for (i = count % 4; i < 4; i++) + tmpbuf.buff[tmpbuf.size++] = t[i]; + } + + pcm_s.last_l = dl0; + pcm_s.last_r = dr0; + } +} + + +static void +fifo_recv_mono_ulaw(pcm_data *buf, int count) +{ + int i; + signed char d, d0, d1; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < count; i++) { + d = ((signed char)inb(pcm_s.iobase + 12) + + (signed char)inb(pcm_s.iobase + 12)) >> 1; + *buf++ = linear2ulaw[d & 0xff]; + } + } else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + d1 = ((signed char)inb(pcm_s.iobase + 12) + + (signed char)inb(pcm_s.iobase + 12)) >> 1; + for (i = 0; i < count; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + d0 = d1; + d1 = ((signed char)inb(pcm_s.iobase + 12) + + (signed char)inb(pcm_s.iobase + 12)) >> 1; + } + d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = linear2ulaw[d & 0xff]; + pcm_s.acc += pcm_s.chipspeed; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_recv_mono_8(pcm_data *buf, int count, int uflag) +{ + int i; + signed char d, d0, d1, zlev; + + zlev = uflag ? -128 : 0; + + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < count; i++) { + d = ((signed char)inb(pcm_s.iobase + 12) + + (signed char)inb(pcm_s.iobase + 12)) >> 1; + *buf++ = d + zlev; + } + } else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + d1 = ((signed char)inb(pcm_s.iobase + 12) + + (signed char)inb(pcm_s.iobase + 12)) >> 1; + for (i = 0; i < count; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + d0 = d1; + d1 = ((signed char)inb(pcm_s.iobase + 12) + + (signed char)inb(pcm_s.iobase + 12)) >> 1; + } + d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = d + zlev; + pcm_s.acc += pcm_s.chipspeed; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_recv_mono_16le(pcm_data *buf, int count, int uflag) +{ + int i, cnt; + short d, d0, d1, el, er, zlev; + + zlev = uflag ? -128 : 0; + + cnt = count / 2; + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < cnt; i++) { + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d = (el + er) >> 1; + *buf++ = d & 0xff; + *buf++ = ((d >> 8) & 0xff) + zlev; + } + if (count % 2) { + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d = (el + er) >> 1; + *buf++ = d & 0xff; + tmpbuf.buff[0] = ((d >> 8) & 0xff) + zlev; + tmpbuf.size = 1; + } + } else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d1 = (el + er) >> 1; + for (i = 0; i < cnt; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + d0 = d1; + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d1 = (el + er) >> 1; + } + d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = d & 0xff; + *buf++ = ((d >> 8) & 0xff) + zlev; + pcm_s.acc += pcm_s.chipspeed; + } + if (count % 2) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + d0 = d1; + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d1 = (el + er) >> 1; + } + d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = d & 0xff; + tmpbuf.buff[0] = ((d >> 8) & 0xff) + zlev; + tmpbuf.size = 1; + } + + pcm_s.last_l = d0; + } +} + + +static void +fifo_recv_mono_16be(pcm_data *buf, int count, int uflag) +{ + int i, cnt; + short d, d0, d1, el, er, zlev; + + zlev = uflag ? -128 : 0; + + cnt = count / 2; + if (pcm_s.speed == pcm_s.chipspeed) { + /* No reason to convert the pcm speed. */ + for (i = 0; i < cnt; i++) { + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d = (el + er) >> 1; + *buf++ = ((d >> 8) & 0xff) + zlev; + *buf++ = d & 0xff; + } + if (count % 2) { + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d = (el + er) >> 1; + *buf++ = ((d >> 8) & 0xff) + zlev; + tmpbuf.buff[0] = d & 0xff; + tmpbuf.size = 1; + } + } else { + /* Speed conversion with linear interpolation method. */ + d0 = pcm_s.last_l; + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d1 = (el + er) >> 1; + for (i = 0; i < cnt; i++) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + d0 = d1; + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d1 = (el + er) >> 1; + } + d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = ((d >> 8) & 0xff) + zlev; + *buf++ = d & 0xff; + pcm_s.acc += pcm_s.chipspeed; + } + if (count % 2) { + while (pcm_s.acc >= pcm_s.speed) { + pcm_s.acc -= pcm_s.speed; + d0 = d1; + el = inb(pcm_s.iobase + 12) << 8; + el |= inb(pcm_s.iobase + 12); + er = inb(pcm_s.iobase + 12) << 8; + er |= inb(pcm_s.iobase + 12); + d1 = (el + er) >> 1; + } + d = ((d0 * (pcm_s.speed - pcm_s.acc)) + (d1 * pcm_s.acc)) + / pcm_s.speed; + *buf++ = ((d >> 8) & 0xff) + zlev; + tmpbuf.buff[0] = d & 0xff; + tmpbuf.size = 1; + } + + pcm_s.last_l = d0; + } +} + + +static void +pcm_stop(void) +{ + fifo_stop(); /* stop FIFO */ + fifo_reset(); /* reset FIFO buffer */ + + /* Reset driver's status. */ + pcm_s.intr_busy = NO; + pcm_s.intr_last = NO; + pcm_s.intr_trailer = NO; + pcm_s.acc = 0; + pcm_s.last_l = 0; + pcm_s.last_r = 0; + + DEB(printk("pcm_stop\n")); +} + + +static void +pcm_init(void) +{ + /* Initialize registers on the board. */ + pcm_stop(); + if (pcm_s.board_type == PC980173_FAMILY) + dsp73_init(); + + /* Set default volume. */ + set_volume(DEFAULT_VOLUME); + + /* Initialize driver's status. */ + pcm_s.opened = NO; + pcm_initialized = YES; +} + + +/* + * Codes for global use + */ + +int +probe_pcm86(struct address_info *hw_config) +{ + return pcm86_detect(hw_config); +} + + +long +attach_pcm86(long mem_start, struct address_info *hw_config) +{ + if (pcm_s.board_type == NO_SUPPORTED_BOARD) + return mem_start; + + /* Initialize the board. */ + pcm_init(); + + printk("pcm0: <%s>", pcm86_operations.name); + + if (num_audiodevs < MAX_AUDIO_DEV) { + my_dev = num_audiodevs++; + audio_devs[my_dev] = &pcm86_operations; + audio_devs[my_dev]->buffcount = DSP_BUFFCOUNT; + audio_devs[my_dev]->buffsize = DSP_BUFFSIZE; +#ifdef PCM86_DEBUG + printk("\nbuffsize = %d", DSP_BUFFSIZE); +#endif + } else + printk("pcm0: Too many PCM devices available"); + + return mem_start; +} + + +static int +pcm86_detect(struct address_info *hw_config) +{ + int opna_iobase = 0x188, irq = 12, i; + unsigned char tmp; + + if (hw_config->io_base == -1) { + printf("pcm0: iobase not specified. Assume default port(0x%x)\n", + PCM86_IOBASE); + hw_config->io_base = PCM86_IOBASE; + } + pcm_s.iobase = hw_config->io_base; + + /* auto configuration */ + tmp = inb(pcm_s.iobase) & 0xfc; + switch ((tmp & 0xf0) >> 4) { + case 2: + opna_iobase = 0x188; + pcm_s.board_type = PC980173_FAMILY; + break; + case 3: + opna_iobase = 0x288; + pcm_s.board_type = PC980173_FAMILY; + break; + case 4: + opna_iobase = 0x188; + pcm_s.board_type = PC980186_FAMILY; + break; + case 5: + opna_iobase = 0x288; + pcm_s.board_type = PC980186_FAMILY; + break; + default: + pcm_s.board_type = NO_SUPPORTED_BOARD; + return NO; + } + + /* Enable OPNA(YM2608) facilities. */ + outb(pcm_s.iobase, tmp | 0x01); + + /* Wait for OPNA to be ready. */ + i = 100000; /* Some large value */ + while((inb(opna_iobase) & 0x80) && (i-- > 0)); + + /* Make IOA/IOB port ready (IOA:input, IOB:output) */ + outb(opna_iobase, 0x07); + outb(0x5f, 0); /* Because OPNA ports are comparatively slow(?), */ + outb(0x5f, 0); /* we'd better wait a moment. */ + outb(0x5f, 0); + outb(0x5f, 0); + tmp = inb(opna_iobase + 2) & 0x3f; + outb(opna_iobase + 2, tmp | 0x80); + + /* Wait for OPNA to be ready. */ + i = 100000; /* Some large value */ + while((inb(opna_iobase) & 0x80) && (i-- > 0)); + + /* Get irq number from IOA port. */ + outb(opna_iobase, 0x0e); + outb(0x5f, 0); + outb(0x5f, 0); + outb(0x5f, 0); + outb(0x5f, 0); + tmp = inb(opna_iobase + 2) & 0xc0; + switch (tmp >> 6) { + case 0: /* INT0 (IRQ3)*/ + irq = 3; + break; + case 1: /* INT6 (IRQ13)*/ + irq = 13; + break; + case 2: /* INT4 (IRQ10)*/ + irq = 10; + break; + case 3: /* INT5 (IRQ12)*/ + irq = 12; + break; + default: /* error */ + return NO; + } + + /* Wait for OPNA to be ready. */ + i = 100000; /* Some large value */ + while((inb(opna_iobase) & 0x80) && (i-- > 0)); + + /* Reset OPNA timer register. */ + outb(opna_iobase, 0x27); + outb(0x5f, 0); + outb(0x5f, 0); + outb(0x5f, 0); + outb(0x5f, 0); + outb(opna_iobase + 2, 0x30); + + /* Ok. Detection finished. */ + sprintf(pcm86_operations.name, board_name[pcm_s.board_type]); + pcm_initialized = NO; + pcm_s.irq = irq; + + if ((hw_config->irq > 0) && (hw_config->irq != irq)) + printf("pcm0: change irq %d -> %d\n", hw_config->irq, irq); + hw_config->irq = irq; + + return YES; +} + + +static int +pcm86_open(int dev, int mode) +{ + int err; + + if (!pcm_initialized) + return RET_ERROR(ENXIO); + + if (pcm_s.intr_busy || pcm_s.opened) + return RET_ERROR(EBUSY); + + if ((err = snd_set_irq_handler(pcm_s.irq, pcmintr, "PC-9801-73/86")) < 0) + return err; + + pcm_stop(); + + tmpbuf.size = 0; + pcm_s.intr_mode = IMODE_NONE; + pcm_s.opened = YES; + + return 0; +} + + +static void +pcm86_close(int dev) +{ + snd_release_irq(pcm_s.irq); + + pcm_s.opened = NO; +} + + +static void +pcm86_output_block(int dev, unsigned long buf, int count, int intrflag, + int dma_restart) +{ + unsigned long flags, cnt; + int maxchunksize; + +#ifdef PCM86_DEBUG + printk("pcm86_output_block():"); + if (audio_devs[dev]->dmap->flags & DMA_BUSY) + printk(" DMA_BUSY"); + if (audio_devs[dev]->dmap->flags & DMA_RESTART) + printk(" DMA_RESTART"); + if (audio_devs[dev]->dmap->flags & DMA_ACTIVE) + printk(" DMA_ACTIVE"); + if (audio_devs[dev]->dmap->flags & DMA_STARTED) + printk(" DMA_STARTED"); + if (audio_devs[dev]->dmap->flags & DMA_ALLOC_DONE) + printk(" DMA_ALLOC_DONE"); + printk("\n"); +#endif + +#if 0 + DISABLE_INTR(flags); +#endif + +#ifdef PCM86_DEBUG + printk("pcm86_output_block(): count = %d, intrsize= %d\n", + count, pcm_s.intr_size); +#endif + + pcm_s.pdma_buf = (pcm_data *)buf; + pcm_s.pdma_count = count; + pcm_s.pdma_chunkcount = 1; + maxchunksize = (((PCM86_FIFOSIZE - pcm_s.intr_size * 2) + / (pcm_s.bytes * 2)) * pcm_s.speed + / pcm_s.chipspeed) * (pcm_s.bytes << pcm_s.stereo); + if (count > maxchunksize) + pcm_s.pdma_chunkcount = 2 * count / maxchunksize; + /* + * Let chunksize = (float)count / (float)pcm_s.pdma_chunkcount. + * Data of size chunksize is sent to the FIFO buffer on the 86-board + * on every occuring of interrupt. + * By assuming that pcm_s.intr_size < PCM86_FIFOSIZE / 2, we can conclude + * that the FIFO buffer never overflows from the following lemma. + * + * Lemma: + * maxchunksize / 2 <= chunksize <= maxchunksize. + * (Though pcm_s.pdma_chunkcount is obtained through the flooring + * function, this inequality holds.) + * Proof) Omitted. + */ + + fifo_output_block(); + + pcm_s.intr_last = NO; + pcm_s.intr_mode = IMODE_OUTPUT; + if (!pcm_s.intr_busy) + fifo_start(IMODE_OUTPUT); + pcm_s.intr_busy = YES; + +#if 0 + RESTORE_INTR(flags); +#endif +} + + +static void +pcm86_start_input(int dev, unsigned long buf, int count, int intrflag, + int dma_restart) +{ + unsigned long flags, cnt; + int maxchunksize; + +#ifdef PCM86_DEBUG + printk("pcm86_start_input():"); + if (audio_devs[dev]->dmap->flags & DMA_BUSY) + printk(" DMA_BUSY"); + if (audio_devs[dev]->dmap->flags & DMA_RESTART) + printk(" DMA_RESTART"); + if (audio_devs[dev]->dmap->flags & DMA_ACTIVE) + printk(" DMA_ACTIVE"); + if (audio_devs[dev]->dmap->flags & DMA_STARTED) + printk(" DMA_STARTED"); + if (audio_devs[dev]->dmap->flags & DMA_ALLOC_DONE) + printk(" DMA_ALLOC_DONE"); + printk("\n"); +#endif + +#if 0 + DISABLE_INTR(flags); +#endif + + pcm_s.intr_size = PCM86_INTRSIZE_IN; + +#ifdef PCM86_DEBUG + printk("pcm86_start_input(): count = %d, intrsize= %d\n", + count, pcm_s.intr_size); +#endif + + pcm_s.pdma_buf = (pcm_data *)buf; + pcm_s.pdma_count = count; + pcm_s.pdma_chunkcount = 1; + maxchunksize = ((pcm_s.intr_size / (pcm_s.bytes * 2)) * pcm_s.speed + / pcm_s.chipspeed) * (pcm_s.bytes << pcm_s.stereo); + if (count > maxchunksize) + pcm_s.pdma_chunkcount = 2 * count / maxchunksize; + + pcm_s.intr_mode = IMODE_INPUT; + if (!pcm_s.intr_busy) + fifo_start(IMODE_INPUT); + pcm_s.intr_busy = YES; + +#if 0 + RESTORE_INTR(flags); +#endif +} + + +static int +pcm86_ioctl(int dev, unsigned int cmd, unsigned int arg, int local) +{ + switch (cmd) { + case SOUND_PCM_WRITE_RATE: + if (local) + return set_speed(arg); + return IOCTL_OUT(arg, set_speed(IOCTL_IN(arg))); + + case SOUND_PCM_READ_RATE: + if (local) + return pcm_s.speed; + return IOCTL_OUT(arg, pcm_s.speed); + + case SNDCTL_DSP_STEREO: + if (local) + return set_stereo(arg); + return IOCTL_OUT(arg, set_stereo(IOCTL_IN(arg))); + + case SOUND_PCM_WRITE_CHANNELS: + if (local) + return set_stereo(arg - 1) + 1; + return IOCTL_OUT(arg, set_stereo(IOCTL_IN(arg) - 1) + 1); + + case SOUND_PCM_READ_CHANNELS: + if (local) + return pcm_s.stereo + 1; + return IOCTL_OUT(arg, pcm_s.stereo + 1); + + case SNDCTL_DSP_SETFMT: + if (local) + return set_format(arg); + return IOCTL_OUT(arg, set_format(IOCTL_IN(arg))); + + case SOUND_PCM_READ_BITS: + if (local) + return pcm_s.bytes * 8; + return IOCTL_OUT(arg, pcm_s.bytes * 8); + } + + /* Invalid ioctl request */ + return RET_ERROR(EINVAL); +} + + +static int +pcm86_prepare_for_input(int dev, int bufsize, int nbufs) +{ + pcm_s.intr_size = PCM86_INTRSIZE_IN; + pcm_s.intr_mode = IMODE_NONE; + pcm_s.acc = 0; + pcm_s.last_l = 0; + pcm_s.last_r = 0; + + DEB(printk("pcm86_prepare_for_input\n")); + + return 0; +} + + +static int +pcm86_prepare_for_output(int dev, int bufsize, int nbufs) +{ + pcm_s.intr_size = PCM86_INTRSIZE_OUT; + pcm_s.intr_mode = IMODE_NONE; + pcm_s.acc = 0; + pcm_s.last_l = 0; + pcm_s.last_r = 0; + + DEB(printk("pcm86_prepare_for_output\n")); + + return 0; +} + + +static void +pcm86_reset(int dev) +{ + pcm_stop(); +} + + +static void +pcm86_halt_xfer(int dev) +{ + pcm_stop(); + + DEB(printk("pcm86_halt_xfer\n")); +} + + +void +pcmintr(int unit) +{ + unsigned char tmp; + + if ((inb(pcm_s.iobase + 8) & 0x10) == 0) + return; /* not FIFO intr. */ + + switch(pcm_s.intr_mode) { + case IMODE_OUTPUT: + if (pcm_s.intr_trailer) { + DEB(printk("pcmintr(): fifo_reset\n")); + fifo_reset(); + pcm_s.intr_trailer = NO; + pcm_s.intr_busy = NO; + } + if (pcm_s.pdma_count > 0) + fifo_output_block(); + else + DMAbuf_outputintr(my_dev, 1); + /* Reset intr. flag. */ + tmp = inb(pcm_s.iobase + 8); + outb(pcm_s.iobase + 8, tmp & ~0x10); + outb(pcm_s.iobase + 8, tmp | 0x10); + break; + + case IMODE_INPUT: + fifo_input_block(); + if (pcm_s.pdma_count == 0) + DMAbuf_inputintr(my_dev); + /* Reset intr. flag. */ + tmp = inb(pcm_s.iobase + 8); + outb(pcm_s.iobase + 8, tmp & ~0x10); + outb(pcm_s.iobase + 8, tmp | 0x10); + break; + + default: + pcm_stop(); + printk("pcm0: unexpected interrupt\n"); + } +} + + +#endif /* EXCLUDE_PCM86, EXCLUDE_AUDIO */ + +#endif /* CONFIGURE_SOUNDCARD */ diff --git a/sys/i386/isa/sound/sb_defs.h b/sys/i386/isa/sound/sb_defs.h new file mode 100644 index 000000000000..e21c7c86e9ee --- /dev/null +++ b/sys/i386/isa/sound/sb_defs.h @@ -0,0 +1,43 @@ +#ifdef PC98 +#define DSP_RESET (sbc_base + 0x600) +#define DSP_READ (sbc_base + 0xA00) +#define DSP_WRITE (sbc_base + 0xC00) +#define DSP_COMMAND (sbc_base + 0xC00) +#define DSP_STATUS (sbc_base + 0xC00) +#define DSP_DATA_AVAIL (sbc_base + 0xE00) +#define DSP_DATA_AVL16 (sbc_base + 0xF00) +#define MIXER_ADDR (sbc_base + 0x400) +#define MIXER_DATA (sbc_base + 0x500) +#define OPL3_LEFT (sbc_base + 0x000) +#define OPL3_RIGHT (sbc_base + 0x200) +#define OPL3_BOTH (sbc_base + 0x800) +#else +#define DSP_RESET (sbc_base + 0x6) +#define DSP_READ (sbc_base + 0xA) +#define DSP_WRITE (sbc_base + 0xC) +#define DSP_COMMAND (sbc_base + 0xC) +#define DSP_STATUS (sbc_base + 0xC) +#define DSP_DATA_AVAIL (sbc_base + 0xE) +#define DSP_DATA_AVL16 (sbc_base + 0xF) +#define MIXER_ADDR (sbc_base + 0x4) +#define MIXER_DATA (sbc_base + 0x5) +#define OPL3_LEFT (sbc_base + 0x0) +#define OPL3_RIGHT (sbc_base + 0x2) +#define OPL3_BOTH (sbc_base + 0x8) +#endif +/* DSP Commands */ + +#define DSP_CMD_SPKON 0xD1 +#define DSP_CMD_SPKOFF 0xD3 +#define DSP_CMD_DMAON 0xD0 +#define DSP_CMD_DMAOFF 0xD4 + +#define IMODE_NONE 0 +#define IMODE_OUTPUT 1 +#define IMODE_INPUT 2 +#define IMODE_INIT 3 +#define IMODE_MIDI 4 + +#define NORMAL_MIDI 0 +#define UART_MIDI 1 + diff --git a/sys/i386/isa/sound/sbcard.h b/sys/i386/isa/sound/sbcard.h new file mode 100644 index 000000000000..464128ccf46c --- /dev/null +++ b/sys/i386/isa/sound/sbcard.h @@ -0,0 +1,54 @@ +/* + * file: sbcard.h + */ + +extern int sbc_major, sbc_minor ; +/* + * sound blaster registers + */ + +#define DSP_RESET (sbc_base + 0x6) +#define DSP_READ (sbc_base + 0xA) +#define DSP_WRITE (sbc_base + 0xC) +#define DSP_COMMAND (sbc_base + 0xC) +#define DSP_STATUS (sbc_base + 0xC) +#define DSP_DATA_AVAIL (sbc_base + 0xE) +#define DSP_DATA_AVL16 (sbc_base + 0xF) +#define MIXER_ADDR (sbc_base + 0x4) +#define MIXER_DATA (sbc_base + 0x5) +#define OPL3_LEFT (sbc_base + 0x0) +#define OPL3_RIGHT (sbc_base + 0x2) +#define OPL3_BOTH (sbc_base + 0x8) + +/* + * DSP Commands. There are many, and in many cases they are used explicitly + */ + +#define DSP_CMD_SPKON 0xD1 +#define DSP_CMD_SPKOFF 0xD3 +#define DSP_CMD_DMAON 0xD0 /* ??? the comment says Halt DMA */ +#define DSP_CMD_DMAOFF 0xD4 /* ??? comment says continue dma */ + +#define DSP_CMD_DMAHALT 0xD0 +#define DSP_CMD_TCONST 0x40 /* set time constant */ +#define DSP_CMD_HSSIZE 0x48 /* high speed dma count */ +#define DSP_CMD_HSDAC 0x91 /* high speed dac */ +#define DSP_CMD_HSADC 0x99 /* high speed adc */ +#define DSP_CMD_DAC8 0x14 /* 8-bit dac (dma count) */ +#define DSP_CMD_ADC8 0x24 /* 8-bit adc (dma count) */ + +#define DSP_CMD_GETVER 0xE1 +#define DSP_CMD_GETID 0xE7 /* return id bytes */ + +#if 0 /*** unknown ***/ + +#endif + +#define IMODE_NONE 0 +#define IMODE_OUTPUT PCM_ENABLE_OUTPUT +#define IMODE_INPUT PCM_ENABLE_INPUT +#define IMODE_INIT 3 +#define IMODE_MIDI 4 + +#define NORMAL_MIDI 0 +#define UART_MIDI 1 diff --git a/sys/i386/isa/sound/sound.doc b/sys/i386/isa/sound/sound.doc new file mode 100644 index 000000000000..f6db243c407b --- /dev/null +++ b/sys/i386/isa/sound/sound.doc @@ -0,0 +1,87 @@ +Instructions on using audio on a FreeBSD 2.1 (or 2.0-current) system. +See also /sys/i386/conf/LINT. + +You may add one or more of the following depending on what you do and don't +want compiled into your kernel. Note: Excluding things with EXCLUDE_... +is NOT recommended unless you really know what you're doing. + + options "AUDIO_MPU401" # INCLUDE MPU401 support + options AUDIO_GUS # INCLUDE GUS support + options AUDIO_SBPRO # INCLUDE SB Pro support + options "AUDIO_SB16" # INCLUDE SB 16 support + options "AUDIO_YM3812" # INCLUDE AdLib support + options AUDIO_PAS # INCLUDE Pro Audio Studio support + options AUDIO_SB # INCLUDE SB support + options AUDIO_MSS # INCLUDE MSS support + options EXCLUDE_AUDIO # NO digital audio support + options EXCLUDE_SEQUENCER # NO sequencer support + options EXCLUDE_GUS_IODETECT # NO GUS io detection + options EXCLUDE_SB_EMULATION # NO PAS SB emulation support + options "EXCLUDE_OPL3" # NO OPL3 chip support + options EXCLUDE_PRO_MIDI # NO PAS MIDI support + options EXCLUDE_CHIP_MIDI # NO MIDI chip support + options EXCLUDE_MIDI # NO MIDI support whatsoever + +To enable sound card support, you need to uncomment and add one or more of +the following lines to your kernel configuration file according to the +directions below: + +#device snd5 at isa? port 0x330 irq 6 vector mpuintr +#device snd4 at isa? port 0x220 irq 15 drq 6 vector gusintr +#device snd3 at isa? port 0x388 irq 10 drq 6 vector pasintr +#device snd2 at isa? port 0x220 irq 7 drq 1 vector sbintr +#device snd6 at isa? port 0x220 irq 7 drq 5 vector sbintr +#device snd10 at isa? port 0x530 irq 10 drq 1 vector adintr +#device snd7 at isa? port 0x300 +#device snd1 at isa? port 0x388 + +Note for PAS user: you should change snd1 line to +#device snd1 at isa? port 0x38a +(next stereo port) to avoid conflict with snd3 + + Unit numbers are: + 1 for Yamaha FM synth + 2 for SB/SB Pro DSP + 3 for PAS PCM and Midi + 4 for GUS + 5 for MPU-401 (there is separate driver for the SB16) + 6 for SB16 (DSP) + 7 for SB16 Midi (MPU-401 emulation) + 10 for Microsoft Windows Sound System (AD1846) + + If you have ProAudioSpectrum, uncomment units 3, 2 and 1 + If you have SoundBlaster 1.0 to 2.0 or SB Pro, uncomment 2 and 1. + If you have SoundBlaster 16, uncomment 2, 1, 6 and 7. + (use the same IRQ for the cards 2, 6 and 7. The DMA of the + card 2 is the 8 bit one and the DMA of the card 6 is the 16 bit one. + the port address of the card 7 is the Midi I/O address of the SB16. + If you have GravisUltrasound, uncomment 4 + If you have MPU-401, uncomment 5 + +NOTE: The MPU-401 driver may or may not work, and is unfortunately +unverifiable since no one I know has one. If you can test this, +please let me know! Also note that you will have to change these +settings if your soundcard is set for a non-standard address or IRQ. +Please check your documentation (or verify with any provided DOS utilities +that may have come with your card) and set the IRQ or address fields +accordingly. + +Also: Some systems with the OPTI chipset will require you to #define +BROKEN_BUS_CLOCK in /sys/i386/sound/pas2_card.c. Symptoms are that +you will hear a lot of clicking and popping sounds, like a geiger counter, +coming out of the PAS even when is not playing anything. + +Also: You can configure more then one card on a single DMA using +ALLOW_CONFLICT_DMA. + +Probing problems: Since the SB16 uses the same IRQ and addresses for +the different drivers, some of the snd dirvers will not be probed because +the kernel thinks there is a conflict. This can be worked-around by +setting the ALLOW_CONFLICT_IOADDR or ALLOW_CONFLICT_IRQ options. + +Warning: Setting the ALLOW_* options will will bypass checks for ALL drivers, +so be careful when you use them! + + - Jordan Hubbard (jkh@freefall.cdrom.com) + - Steven Wallace (swallace@freefall.cdrom.com) + - Sujal Patel (smpatel@wam.umd.edu) diff --git a/sys/i386/isa/sound/sound_pnp.c b/sys/i386/isa/sound/sound_pnp.c new file mode 100644 index 000000000000..d3d278b9cc10 --- /dev/null +++ b/sys/i386/isa/sound/sound_pnp.c @@ -0,0 +1,186 @@ +/* + * sound/sound_pnp.c + * + * PnP soundcard support (Linux spesific) + * + * Copyright by Hannu Savolainen 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include <i386/isa/sound/sound_config.h> + +/* + * XXX check what to use in place of CONFIG_PNP + */ +#if (NSND > 0) && defined(CONFIG_PNP) + +#include <linux/pnp.h> + +static struct pnp_sounddev *pnp_devs[20] = { NULL }; + +static int max_pnpdevs = 20; +static int nr_pnpdevs = 0; +static int pnp_sig = 0; + +void +install_pnp_sounddrv(struct pnp_sounddev * drv) +{ + if (nr_pnpdevs < max_pnpdevs) { + pnp_devs[nr_pnpdevs++] = drv; + } else + printf("Sound: More than 20 PnP drivers defined\n"); +} + +void +cs4232_pnp(void *parm) +{ + struct pnp_dev *dev = (struct pnp_dev *) parm; + char *name; + + int portmask = 0x00, irqmask = 0x01, dmamask = 0x03; + int opl3_driver, wss_driver; + + printf("CS4232 driver waking up\n"); + + if (dev->card && dev->card->name) + name = dev->card->name; + else + name = "PnP WSS"; + + if ((wss_driver = sndtable_identify_card("AD1848"))) + portmask |= 0x01; /* MSS */ + else + printf("Sound: MSS/WSS device detected but no driver enabled\n"); + + if ((opl3_driver = sndtable_identify_card("OPL3"))) + portmask |= 0x02; /* OPL3 */ + else + printf("Sound: OPL3/4 device detected but no driver enabled\n"); + + printf("WSS driver %d, OPL3 driver %d\n", wss_driver, opl3_driver); + + if (!portmask) /* No drivers available */ + return; + + if (!pnp_allocate_device(pnp_sig, dev, portmask, irqmask, dmamask, 0x00)) + printf("Device activation failed\n"); + else { + struct address_info hw_config; + int wss_base, opl3_base; + int irq; + int dma1, dma2; + + printf("Device activation OK\n"); + wss_base = pnp_get_port(dev, 0); + opl3_base = pnp_get_port(dev, 1); + irq = pnp_get_irq(dev, 0); + dma1 = pnp_get_dma(dev, 0); + dma2 = pnp_get_dma(dev, 1); + + printf("I/O0 %03x\n", wss_base); + printf("I/O1 %03x\n", opl3_base); + printf("IRQ %d\n", irq); + printf("DMA0 %d\n", dma1); + printf("DMA1 %d\n", dma2); + + if (opl3_base && opl3_driver) { + hw_config.io_base = opl3_base; + hw_config.irq = 0; + hw_config.dma = -1; + hw_config.dma2 = -1; + hw_config.always_detect = 0; + hw_config.name = ""; + hw_config.osp = NULL; + hw_config.card_subtype = 0; + + if (sndtable_probe(opl3_driver, &hw_config)) + sndtable_init_card(opl3_driver, &hw_config); + + } + if (wss_base && wss_driver) { + hw_config.io_base = wss_base; + hw_config.irq = irq; + hw_config.dma = dma1; + hw_config.dma2 = (dma2 == NO_DMA) ? dma1 : dma2; + hw_config.always_detect = 0; + hw_config.name = name; + hw_config.osp = NULL; + hw_config.card_subtype = 0; + + if (sndtable_probe(wss_driver, &hw_config)) + sndtable_init_card(wss_driver, &hw_config); + + } + } +} + +static int +pnp_activate(int id, struct pnp_dev * dev) +{ + int i; + + for (i = 0; i < nr_pnpdevs; i++) + if (pnp_devs[i]->id == id) { + + printf("PnP dev: %08x, %s\n", id, pnp_devid2asc(id)); + + pnp_devs[i]->setup((void *) dev); + return 1; + } + return 0; +} + +void +sound_pnp_init(void) +{ + static struct pnp_sounddev cs4232_dev = + {PNP_DEVID('C', 'S', 'C', 0x0000), cs4232_pnp, "CS4232"}; + + struct pnp_dev *dev; + + install_pnp_sounddrv(&cs4232_dev); + + dev = NULL; + + if ((pnp_sig = pnp_connect("sound")) == -1) { + printf("Sound: Can't connect to kernel PnP services.\n"); + return; + } + while ((dev = pnp_get_next_device(pnp_sig, dev)) != NULL) { + if (!pnp_activate(dev->key, dev)) { + /* Scan all compatible devices */ + + int i; + + for (i = 0; i < dev->ncompat; i++) + if (pnp_activate(dev->compat_keys[i], dev)) + break; + } + } +} + +void +sound_pnp_disconnect(void) +{ + pnp_disconnect(pnp_sig); +} +#endif diff --git a/sys/i386/isa/sound/soundvers.h b/sys/i386/isa/sound/soundvers.h new file mode 100644 index 000000000000..ca892e8259da --- /dev/null +++ b/sys/i386/isa/sound/soundvers.h @@ -0,0 +1 @@ +#define SOUND_VERSION_STRING "3.0-beta-950506" diff --git a/sys/i386/isa/sound/sscape.c b/sys/i386/isa/sound/sscape.c new file mode 100644 index 000000000000..9204b188aab8 --- /dev/null +++ b/sys/i386/isa/sound/sscape.c @@ -0,0 +1,1120 @@ +/* + * sound/sscape.c + * + * Low level driver for Ensoniq Soundscape + * + * Copyright by Hannu Savolainen 1994 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sound_config.h" + +#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SSCAPE) + +#include "coproc.h" + +/* + * I/O ports + */ +#define MIDI_DATA 0 +#define MIDI_CTRL 1 +#define HOST_CTRL 2 +#define TX_READY 0x02 +#define RX_READY 0x01 +#define HOST_DATA 3 +#define ODIE_ADDR 4 +#define ODIE_DATA 5 + +/* + * Indirect registers + */ +#define GA_INTSTAT_REG 0 +#define GA_INTENA_REG 1 +#define GA_DMAA_REG 2 +#define GA_DMAB_REG 3 +#define GA_INTCFG_REG 4 +#define GA_DMACFG_REG 5 +#define GA_CDCFG_REG 6 +#define GA_SMCFGA_REG 7 +#define GA_SMCFGB_REG 8 +#define GA_HMCTL_REG 9 + +/* + * DMA channel identifiers (A and B) + */ +#define SSCAPE_DMA_A 0 +#define SSCAPE_DMA_B 1 + +#define PORT(name) (devc->base+name) + +/* + * Host commands recognized by the OBP microcode + */ +#define CMD_GEN_HOST_ACK 0x80 +#define CMD_GEN_MPU_ACK 0x81 +#define CMD_GET_BOARD_TYPE 0x82 +#define CMD_SET_CONTROL 0x88 +#define CMD_GET_CONTROL 0x89 +#define CMD_SET_MT32 0x96 +#define CMD_GET_MT32 0x97 +#define CMD_SET_EXTMIDI 0x9b +#define CMD_GET_EXTMIDI 0x9c + +#define CMD_ACK 0x80 + +typedef struct sscape_info + { + int base, irq, dma; + int ok; /* Properly detected */ + int dma_allocated; + int my_audiodev; + int opened; + } + +sscape_info; +static struct sscape_info dev_info = +{0}; +static struct sscape_info *devc = &dev_info; + +DEFINE_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag); + +#ifdef REVEAL_SPEA +/* Spea and Reveal have assigned interrupt bits differently than Ensoniq */ +static char valid_interrupts[] = +{9, 7, 5, 15}; + +#else +static char valid_interrupts[] = +{9, 5, 7, 10}; + +#endif + +static unsigned char +sscape_read (struct sscape_info *devc, int reg) +{ + unsigned long flags; + unsigned char val; + + DISABLE_INTR (flags); + OUTB (reg, PORT (ODIE_ADDR)); + val = INB (PORT (ODIE_DATA)); + RESTORE_INTR (flags); + return val; +} + +static void +sscape_write (struct sscape_info *devc, int reg, int data) +{ + unsigned long flags; + + DISABLE_INTR (flags); + OUTB (reg, PORT (ODIE_ADDR)); + OUTB (data, PORT (ODIE_DATA)); + RESTORE_INTR (flags); +} + +static void +host_open (struct sscape_info *devc) +{ + OUTB (0x00, PORT (HOST_CTRL)); /* Put the board to the host mode */ +} + +static void +host_close (struct sscape_info *devc) +{ + OUTB (0x03, PORT (HOST_CTRL)); /* Put the board to the MIDI mode */ +} + +static int +host_write (struct sscape_info *devc, unsigned char *data, int count) +{ + unsigned long flags; + int i, timeout; + + DISABLE_INTR (flags); + + /* + * Send the command and data bytes + */ + + for (i = 0; i < count; i++) + { + for (timeout = 10000; timeout > 0; timeout--) + if (INB (PORT (HOST_CTRL)) & TX_READY) + break; + + if (timeout <= 0) + { + RESTORE_INTR (flags); + return 0; + } + + OUTB (data[i], PORT (HOST_DATA)); + } + + + RESTORE_INTR (flags); + + return 1; +} + +static int +host_read (struct sscape_info *devc) +{ + unsigned long flags; + int timeout; + unsigned char data; + + DISABLE_INTR (flags); + + /* + * Read a byte + */ + + for (timeout = 10000; timeout > 0; timeout--) + if (INB (PORT (HOST_CTRL)) & RX_READY) + break; + + if (timeout <= 0) + { + RESTORE_INTR (flags); + return -1; + } + + data = INB (PORT (HOST_DATA)); + + RESTORE_INTR (flags); + + return data; +} + +static int +host_command1 (struct sscape_info *devc, int cmd) +{ + unsigned char buf[10]; + + buf[0] = (unsigned char) (cmd & 0xff); + + return host_write (devc, buf, 1); +} + +static int +host_command2 (struct sscape_info *devc, int cmd, int parm1) +{ + unsigned char buf[10]; + + buf[0] = (unsigned char) (cmd & 0xff); + buf[1] = (unsigned char) (parm1 & 0xff); + + return host_write (devc, buf, 2); +} + +static int +host_command3 (struct sscape_info *devc, int cmd, int parm1, int parm2) +{ + unsigned char buf[10]; + + buf[0] = (unsigned char) (cmd & 0xff); + buf[1] = (unsigned char) (parm1 & 0xff); + buf[2] = (unsigned char) (parm2 & 0xff); + + return host_write (devc, buf, 3); +} + +static void +set_mt32 (struct sscape_info *devc, int value) +{ + host_open (devc); + host_command2 (devc, CMD_SET_MT32, + value ? 1 : 0); + if (host_read (devc) != CMD_ACK) + { + printk ("SNDSCAPE: Setting MT32 mode failed\n"); + } + host_close (devc); +} + +static int +get_board_type (struct sscape_info *devc) +{ + int tmp; + + host_open (devc); + if (!host_command1 (devc, CMD_GET_BOARD_TYPE)) + tmp = -1; + else + tmp = host_read (devc); + host_close (devc); + return tmp; +} + +void +sscapeintr (INT_HANDLER_PARMS (irq, dummy)) +{ + unsigned char bits, tmp; + static int debug = 0; + + printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG))); + if (SOMEONE_WAITING (sscape_sleeper, sscape_sleep_flag)) + { + WAKE_UP (sscape_sleeper, sscape_sleep_flag); + } + + if (bits & 0x02) /* Host interface interrupt */ + { + printk ("SSCAPE: Host interrupt, data=%02x\n", host_read (devc)); + } + +#if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI) + if (bits & 0x01) + { + mpuintr (INT_HANDLER_CALL (irq)); + if (debug++ > 10) /* Temporary debugging hack */ + { + sscape_write (devc, GA_INTENA_REG, 0x00); /* Disable all interrupts */ + } + } +#endif + + /* + * Acknowledge interrupts (toggle the interrupt bits) + */ + + tmp = sscape_read (devc, GA_INTENA_REG); + sscape_write (devc, GA_INTENA_REG, (~bits & 0x0e) | (tmp & 0xf1)); + +} + +static void +sscape_enable_intr (struct sscape_info *devc, unsigned intr_bits) +{ + unsigned char temp, orig; + + temp = orig = sscape_read (devc, GA_INTENA_REG); + temp |= intr_bits; + temp |= 0x80; /* Master IRQ enable */ + + if (temp == orig) + return; /* No change */ + + sscape_write (devc, GA_INTENA_REG, temp); +} + +static void +sscape_disable_intr (struct sscape_info *devc, unsigned intr_bits) +{ + unsigned char temp, orig; + + temp = orig = sscape_read (devc, GA_INTENA_REG); + temp &= ~intr_bits; + if ((temp & ~0x80) == 0x00) + temp = 0x00; /* Master IRQ disable */ + if (temp == orig) + return; /* No change */ + + sscape_write (devc, GA_INTENA_REG, temp); +} + +static void +do_dma (struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode) +{ + unsigned char temp; + + if (dma_chan != SSCAPE_DMA_A) + { + printk ("SSCAPE: Tried to use DMA channel != A. Why?\n"); + return; + } + + DMAbuf_start_dma (devc->my_audiodev, + buf, + blk_size, mode); + + temp = devc->dma << 4; /* Setup DMA channel select bits */ + if (devc->dma <= 3) + temp |= 0x80; /* 8 bit DMA channel */ + + temp |= 1; /* Trigger DMA */ + sscape_write (devc, GA_DMAA_REG, temp); + temp &= 0xfe; /* Clear DMA trigger */ + sscape_write (devc, GA_DMAA_REG, temp); +} + +static int +verify_mpu (struct sscape_info *devc) +{ + /* + * The SoundScape board could be in three modes (MPU, 8250 and host). + * If the card is not in the MPU mode, enabling the MPU driver will + * cause infinite loop (the driver believes that there is always some + * received data in the buffer. + * + * Detect this by looking if there are more than 10 received MIDI bytes + * (0x00) in the buffer. + */ + + int i; + + for (i = 0; i < 10; i++) + { + if (INB (devc->base + HOST_CTRL) & 0x80) + return 1; + + if (INB (devc->base) != 0x00) + return 1; + } + + printk ("SoundScape: The device is not in the MPU-401 mode\n"); + return 0; +} + +static int +sscape_coproc_open (void *dev_info, int sub_device) +{ + if (sub_device == COPR_MIDI) + { + set_mt32 (devc, 0); + if (!verify_mpu (devc)) + return RET_ERROR (EIO); + } + + return 0; +} + +static void +sscape_coproc_close (void *dev_info, int sub_device) +{ + struct sscape_info *devc = dev_info; + unsigned long flags; + + DISABLE_INTR (flags); + if (devc->dma_allocated) + { + sscape_write (devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */ +#ifndef EXCLUDE_NATIVE_PCM + DMAbuf_close_dma (devc->my_audiodev); +#endif + devc->dma_allocated = 0; + } + RESET_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag); + RESTORE_INTR (flags); + + return; +} + +static void +sscape_coproc_reset (void *dev_info) +{ +} + +static int +sscape_download_boot (struct sscape_info *devc, unsigned char *block, int size, int flag) +{ + unsigned long flags; + unsigned char temp; + int done, timeout; + + if (flag & CPF_FIRST) + { + /* + * First block. Have to allocate DMA and to reset the board + * before continuing. + */ + + DISABLE_INTR (flags); + if (devc->dma_allocated == 0) + { +#ifndef EXCLUDE_NATIVE_PCM + if (DMAbuf_open_dma (devc->my_audiodev) < 0) + { + RESTORE_INTR (flags); + return 0; + } +#endif + + devc->dma_allocated = 1; + } + RESTORE_INTR (flags); + + sscape_write (devc, GA_HMCTL_REG, + (temp = sscape_read (devc, GA_HMCTL_REG)) & 0x3f); /*Reset */ + + for (timeout = 10000; timeout > 0; timeout--) + sscape_read (devc, GA_HMCTL_REG); /* Delay */ + + /* Take board out of reset */ + sscape_write (devc, GA_HMCTL_REG, + (temp = sscape_read (devc, GA_HMCTL_REG)) | 0x80); + } + + /* + * Transfer one code block using DMA + */ + memcpy (audio_devs[devc->my_audiodev]->dmap->raw_buf[0], block, size); + + DISABLE_INTR (flags); +/******** INTERRUPTS DISABLED NOW ********/ + do_dma (devc, SSCAPE_DMA_A, + audio_devs[devc->my_audiodev]->dmap->raw_buf_phys[0], + size, DMA_MODE_WRITE); + + /* + * Wait until transfer completes. + */ + RESET_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag); + done = 0; + timeout = 100; + while (!done && timeout-- > 0) + { + int resid; + + DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1); + clear_dma_ff (devc->dma); + if ((resid = get_dma_residue (devc->dma)) == 0) + done = 1; + } + + RESTORE_INTR (flags); + if (!done) + return 0; + + if (flag & CPF_LAST) + { + /* + * Take the board out of reset + */ + OUTB (0x00, PORT (HOST_CTRL)); + OUTB (0x00, PORT (MIDI_CTRL)); + + temp = sscape_read (devc, GA_HMCTL_REG); + temp |= 0x40; + sscape_write (devc, GA_HMCTL_REG, temp); /* Kickstart the board */ + + /* + * Wait until the ODB wakes up + */ + + DISABLE_INTR (flags); + done = 0; + timeout = 5 * HZ; + while (!done && timeout-- > 0) + { + DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1); + if (INB (PORT (HOST_DATA)) == 0xff) /* OBP startup acknowledge */ + done = 1; + } + RESTORE_INTR (flags); + if (!done) + { + printk ("SoundScape: The OBP didn't respond after code download\n"); + return 0; + } + + DISABLE_INTR (flags); + done = 0; + timeout = 5 * HZ; + while (!done && timeout-- > 0) + { + DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1); + if (INB (PORT (HOST_DATA)) == 0xfe) /* Host startup acknowledge */ + done = 1; + } + RESTORE_INTR (flags); + if (!done) + { + printk ("SoundScape: OBP Initialization failed.\n"); + return 0; + } + + printk ("SoundScape board of type %d initialized OK\n", + get_board_type (devc)); + +#ifdef SSCAPE_DEBUG3 + /* + * Temporary debugging aid. Print contents of the registers after + * downloading the code. + */ + { + int i; + + for (i = 0; i < 13; i++) + printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i)); + } +#endif + + } + + return 1; +} + +static int +download_boot_block (void *dev_info, copr_buffer * buf) +{ + if (buf->len <= 0 || buf->len > sizeof (buf->data)) + return RET_ERROR (EINVAL); + + if (!sscape_download_boot (devc, buf->data, buf->len, buf->flags)) + { + printk ("SSCAPE: Unable to load microcode block to the OBP.\n"); + return RET_ERROR (EIO); + } + + return 0; +} + +static int +sscape_coproc_ioctl (void *dev_info, unsigned int cmd, unsigned int arg, int local) +{ + + switch (cmd) + { + case SNDCTL_COPR_RESET: + sscape_coproc_reset (dev_info); + return 0; + break; + + case SNDCTL_COPR_LOAD: + { + copr_buffer *buf; + int err; + + buf = (copr_buffer *) KERNEL_MALLOC (sizeof (copr_buffer)); + IOCTL_FROM_USER ((char *) buf, (char *) arg, 0, sizeof (*buf)); + err = download_boot_block (dev_info, buf); + KERNEL_FREE (buf); + return err; + } + break; + + default: + return RET_ERROR (EINVAL); + } + + return RET_ERROR (EINVAL); +} + +static coproc_operations sscape_coproc_operations = +{ + "SoundScape M68K", + sscape_coproc_open, + sscape_coproc_close, + sscape_coproc_ioctl, + sscape_coproc_reset, + &dev_info +}; + +static int +sscape_audio_open (int dev, int mode) +{ + unsigned long flags; + sscape_info *devc = (sscape_info *) audio_devs[dev]->devc; + + DISABLE_INTR (flags); + if (devc->opened) + { + RESTORE_INTR (flags); + return RET_ERROR (EBUSY); + } + + if (devc->dma_allocated == 0) + { + int err; + + if ((err = DMAbuf_open_dma (devc->my_audiodev)) < 0) + { + RESTORE_INTR (flags); + return err; + } + + devc->dma_allocated = 1; + } + + devc->opened = 1; + RESTORE_INTR (flags); +#ifdef SSCAPE_DEBUG4 + /* + * Temporary debugging aid. Print contents of the registers + * when the device is opened. + */ + { + int i; + + for (i = 0; i < 13; i++) + printk ("I%d = %02x\n", i, sscape_read (devc, i)); + } +#endif + + return 0; +} + +static void +sscape_audio_close (int dev) +{ + unsigned long flags; + sscape_info *devc = (sscape_info *) audio_devs[dev]->devc; + + DEB (printk ("sscape_audio_close(void)\n")); + + DISABLE_INTR (flags); + + if (devc->dma_allocated) + { + sscape_write (devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */ + DMAbuf_close_dma (dev); + devc->dma_allocated = 0; + } + devc->opened = 0; + + RESTORE_INTR (flags); +} + +static int +set_speed (sscape_info * devc, int arg) +{ + return 8000; +} + +static int +set_channels (sscape_info * devc, int arg) +{ + return 1; +} + +static int +set_format (sscape_info * devc, int arg) +{ + return AFMT_U8; +} + +static int +sscape_audio_ioctl (int dev, unsigned int cmd, unsigned int arg, int local) +{ + sscape_info *devc = (sscape_info *) audio_devs[dev]->devc; + + switch (cmd) + { + case SOUND_PCM_WRITE_RATE: + if (local) + return set_speed (devc, arg); + return IOCTL_OUT (arg, set_speed (devc, IOCTL_IN (arg))); + + case SOUND_PCM_READ_RATE: + if (local) + return 8000; + return IOCTL_OUT (arg, 8000); + + case SNDCTL_DSP_STEREO: + if (local) + return set_channels (devc, arg + 1) - 1; + return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg) + 1) - 1); + + case SOUND_PCM_WRITE_CHANNELS: + if (local) + return set_channels (devc, arg); + return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg))); + + case SOUND_PCM_READ_CHANNELS: + if (local) + return 1; + return IOCTL_OUT (arg, 1); + + case SNDCTL_DSP_SAMPLESIZE: + if (local) + return set_format (devc, arg); + return IOCTL_OUT (arg, set_format (devc, IOCTL_IN (arg))); + + case SOUND_PCM_READ_BITS: + if (local) + return 8; + return IOCTL_OUT (arg, 8); + + default:; + } + return RET_ERROR (EINVAL); +} + +static void +sscape_audio_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart) +{ +} + +static void +sscape_audio_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart) +{ +} + +static int +sscape_audio_prepare_for_input (int dev, int bsize, int bcount) +{ + return 0; +} + +static int +sscape_audio_prepare_for_output (int dev, int bsize, int bcount) +{ + return 0; +} + +static void +sscape_audio_halt (int dev) +{ +} + +static void +sscape_audio_reset (int dev) +{ + sscape_audio_halt (dev); +} + +static struct audio_operations sscape_audio_operations = +{ + "Ensoniq SoundScape channel A", + 0, + AFMT_U8 | AFMT_S16_LE, + NULL, + sscape_audio_open, + sscape_audio_close, + sscape_audio_output_block, + sscape_audio_start_input, + sscape_audio_ioctl, + sscape_audio_prepare_for_input, + sscape_audio_prepare_for_output, + sscape_audio_reset, + sscape_audio_halt, + NULL, + NULL +}; + +long +attach_sscape (long mem_start, struct address_info *hw_config) +{ + int my_dev; + +#ifndef SSCAPE_REGS + /* + * Config register values for Spea/V7 Media FX and Ensoniq S-2000. + * These values are card + * dependent. If you have another SoundScape based card, you have to + * find the correct values. Do the following: + * - Compile this driver with SSCAPE_DEBUG1 defined. + * - Shut down and power off your machine. + * - Boot with DOS so that the SSINIT.EXE program is run. + * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed + * when detecting the SoundScape. + * - Modify the following list to use the values printed during boot. + * Undefine the SSCAPE_DEBUG1 + */ +#define SSCAPE_REGS { \ +/* I0 */ 0x00, \ + 0xf0, /* Note! Ignored. Set always to 0xf0 */ \ + 0x20, /* Note! Ignored. Set always to 0x20 */ \ + 0x20, /* Note! Ignored. Set always to 0x20 */ \ + 0xf5, /* Ignored */ \ + 0x10, \ + 0x00, \ + 0x2e, /* I7 MEM config A. Likely to vary between models */ \ + 0x00, /* I8 MEM config A. Likely to vary between models */ \ +/* I9 */ 0x40 /* Ignored */ \ + } +#endif + + unsigned long flags; + static unsigned char regs[10] = SSCAPE_REGS; + + int i, irq_bits = 0xff; + + if (!probe_sscape (hw_config)) + return mem_start; + + printk (" <Ensoniq Soundscape>"); + + for (i = 0; i < sizeof (valid_interrupts); i++) + if (hw_config->irq == valid_interrupts[i]) + { + irq_bits = i; + break; + } + + if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff)) + { + printk ("Invalid IRQ%d\n", hw_config->irq); + return mem_start; + } + + DISABLE_INTR (flags); + + for (i = 1; i < 10; i++) + switch (i) + { + case 1: /* Host interrupt enable */ + sscape_write (devc, i, 0xf0); /* All interrupts enabled */ + break; + + case 2: /* DMA A status/trigger register */ + case 3: /* DMA B status/trigger register */ + sscape_write (devc, i, 0x20); /* DMA channel disabled */ + break; + + case 4: /* Host interrupt config reg */ + sscape_write (devc, i, 0xf0 | (irq_bits << 2) | irq_bits); + break; + + case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */ + sscape_write (devc, i, (regs[i] & 0x3f) | + (sscape_read (devc, i) & 0x0c)); + break; + + case 6: /* CD-ROM config. Don't touch. */ + break; + + case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */ + sscape_write (devc, i, + (sscape_read (devc, i) & 0xf0) | 0x00); + break; + + default: + sscape_write (devc, i, regs[i]); + } + + RESTORE_INTR (flags); + +#ifdef SSCAPE_DEBUG2 + /* + * Temporary debugging aid. Print contents of the registers after + * changing them. + */ + { + int i; + + for (i = 0; i < 13; i++) + printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i)); + } +#endif + +#if !defined(EXCLUDE_MIDI) && !defined(EXCLUDE_MPU_EMU) + hw_config->always_detect = 1; + if (probe_mpu401 (hw_config)) + { + int prev_devs; + + prev_devs = num_midis; + mem_start = attach_mpu401 (mem_start, hw_config); + + if (num_midis == (prev_devs + 1)) /* The MPU driver installed itself */ + midi_devs[prev_devs]->coproc = &sscape_coproc_operations; + } +#endif + +#ifndef EXCLUDE_NATIVE_PCM + /* Not supported yet */ + +#ifndef EXCLUDE_AUDIO + if (num_audiodevs < MAX_AUDIO_DEV) + { + audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations; + audio_devs[my_dev]->dmachan = hw_config->dma; + audio_devs[my_dev]->buffcount = 1; + audio_devs[my_dev]->buffsize = DSP_BUFFSIZE; + audio_devs[my_dev]->devc = devc; + devc->my_audiodev = my_dev; + devc->opened = 0; + audio_devs[my_dev]->coproc = &sscape_coproc_operations; + if (snd_set_irq_handler (hw_config->irq, sscapeintr, "SoundScape") < 0) + printk ("Error: Can't allocate IRQ for SoundScape\n"); + + sscape_write (devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */ + } + else + printk ("SoundScape: More than enough audio devices detected\n"); +#endif +#endif + devc->ok = 1; + return mem_start; +} + +int +probe_sscape (struct address_info *hw_config) +{ + unsigned char save; + + devc->base = hw_config->io_base; + devc->irq = hw_config->irq; + devc->dma = hw_config->dma; + + /* + * First check that the address register of "ODIE" is + * there and that it has exactly 4 writeable bits. + * First 4 bits + */ + if ((save = INB (PORT (ODIE_ADDR))) & 0xf0) + return 0; + + OUTB (0x00, PORT (ODIE_ADDR)); + if (INB (PORT (ODIE_ADDR)) != 0x00) + return 0; + + OUTB (0xff, PORT (ODIE_ADDR)); + if (INB (PORT (ODIE_ADDR)) != 0x0f) + return 0; + + OUTB (save, PORT (ODIE_ADDR)); + + /* + * Now verify that some indirect registers return zero on some bits. + * This may break the driver with some future revisions of "ODIE" but... + */ + + if (sscape_read (devc, 0) & 0x0c) + return 0; + + if (sscape_read (devc, 1) & 0x0f) + return 0; + + if (sscape_read (devc, 5) & 0x0f) + return 0; + +#ifdef SSCAPE_DEBUG1 + /* + * Temporary debugging aid. Print contents of the registers before + * changing them. + */ + { + int i; + + for (i = 0; i < 13; i++) + printk ("I%d = %02x (old value)\n", i, sscape_read (devc, i)); + } +#endif + + return 1; +} + +int +probe_ss_ms_sound (struct address_info *hw_config) +{ + int i, irq_bits = 0xff; + + if (devc->ok == 0) + { + printk ("SoundScape: Invalid initialization order.\n"); + return 0; + } + + for (i = 0; i < sizeof (valid_interrupts); i++) + if (hw_config->irq == valid_interrupts[i]) + { + irq_bits = i; + break; + } +#ifdef REVEAL_SPEA + { + int tmp, status = 0; + int cc; + + if (!((tmp = sscape_read (devc, GA_HMCTL_REG)) & 0xc0)) + { + sscape_write (devc, GA_HMCTL_REG, tmp | 0x80); + for (cc = 0; cc < 200000; ++cc) + INB (devc->base + ODIE_ADDR); + } + } +#endif + + if (hw_config->irq > 15 || irq_bits == 0xff) + { + printk ("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq); + return 0; + } + + return ad1848_detect (hw_config->io_base); +} + +long +attach_ss_ms_sound (long mem_start, struct address_info *hw_config) +{ + /* + * This routine configures the SoundScape card for use with the + * Win Sound System driver. The AD1848 codec interface uses the CD-ROM + * config registers of the "ODIE". + */ + + int i, irq_bits = 0xff; + +#ifdef EXCLUDE_NATIVE_PCM + int prev_devs = num_audiodevs; + +#endif + + /* + * Setup the DMA polarity. + */ + sscape_write (devc, GA_DMACFG_REG, 0x50); + + /* + * Take the gate-arry off of the DMA channel. + */ + sscape_write (devc, GA_DMAB_REG, 0x20); + + /* + * Init the AD1848 (CD-ROM) config reg. + */ + + for (i = 0; i < sizeof (valid_interrupts); i++) + if (hw_config->irq == valid_interrupts[i]) + { + irq_bits = i; + break; + } + + sscape_write (devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | + (irq_bits << 1)); + + if (hw_config->irq == devc->irq) + printk ("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n"); + + ad1848_init ("SoundScape", hw_config->io_base, + hw_config->irq, + hw_config->dma, + hw_config->dma); + +#ifdef EXCLUDE_NATIVE_PCM + if (num_audiodevs == (prev_devs + 1)) /* The AD1848 driver installed itself */ + audio_devs[prev_devs]->coproc = &sscape_coproc_operations; +#endif +#ifdef SSCAPE_DEBUG5 + /* + * Temporary debugging aid. Print contents of the registers + * after the AD1848 device has been initialized. + */ + { + int i; + + for (i = 0; i < 13; i++) + printk ("I%d = %02x\n", i, sscape_read (devc, i)); + } +#endif + + return mem_start; +} + +#endif diff --git a/sys/i386/isa/sound/trix.c b/sys/i386/isa/sound/trix.c new file mode 100644 index 000000000000..6e3db0fa7c90 --- /dev/null +++ b/sys/i386/isa/sound/trix.c @@ -0,0 +1,323 @@ +/* + * sound/trix.c + * + * Low level driver for the MediaTriX AudioTriX Pro + * (MT-0002-PC Control Chip) + * + * Copyright by Hannu Savolainen 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. 2. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "sound_config.h" + +#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_TRIX) + +#ifdef INCLUDE_TRIX_BOOT +#include "trix_boot.h" +#endif + +static int kilroy_was_here = 0; /* Don't detect twice */ +static int sb_initialized = 0; +static int mpu_initialized = 0; + +static unsigned char +trix_read (int addr) +{ + OUTB ((unsigned char) addr, 0x390); /* MT-0002-PC ASIC address */ + return INB (0x391); /* MT-0002-PC ASIC data */ +} + +static void +trix_write (int addr, int data) +{ + OUTB ((unsigned char) addr, 0x390); /* MT-0002-PC ASIC address */ + OUTB ((unsigned char) data, 0x391); /* MT-0002-PC ASIC data */ +} + +static void +download_boot (int base) +{ + int i = 0, n = sizeof (trix_boot); + + trix_write (0xf8, 0x00); /* ??????? */ + OUTB (0x01, base + 6); /* Clear the internal data pointer */ + OUTB (0x00, base + 6); /* Restart */ + + /* + * Write the boot code to the RAM upload/download register. + * Each write increments the internal data pointer. + */ + OUTB (0x01, base + 6); /* Clear the internal data pointer */ + OUTB (0x1A, 0x390); /* Select RAM download/upload port */ + + for (i = 0; i < n; i++) + OUTB (trix_boot[i], 0x391); + for (i = n; i < 10016; i++) /* Clear up to first 16 bytes of data RAM */ + OUTB (0x00, 0x391); + OUTB (0x00, base + 6); /* Reset */ + OUTB (0x50, 0x390); /* ?????? */ +} + +static int +trix_set_wss_port (struct address_info *hw_config) +{ + unsigned char addr_bits; + + if (kilroy_was_here) /* Already initialized */ + return 0; + + kilroy_was_here = 1; + + if (trix_read (0x15) != 0x71) /* No asic signature */ + return 0; + + /* + * Disable separate wave playback and recording DMA channels since + * the driver doesn't support duplex mode yet. + */ + + trix_write (0x13, trix_read (0x13) & ~0x80); + trix_write (0x14, trix_read (0x14) & ~0x80); + + /* + * Configure the ASIC to place the codec to the proper I/O location + */ + + switch (hw_config->io_base) + { + case 0x530: + addr_bits = 0; + break; + case 0x604: + addr_bits = 1; + break; + case 0xE80: + addr_bits = 2; + break; + case 0xF40: + addr_bits = 3; + break; + default: + return 0; + } + + trix_write (0x19, (trix_read (0x19) & 0x03) | addr_bits); + return 1; +} + +/* + * Probe and attach routines for the Windows Sound System mode of + * AudioTriX Pro + */ + +int +probe_trix_wss (struct address_info *hw_config) +{ + /* + * Check if the IO port returns valid signature. The original MS Sound + * system returns 0x04 while some cards (AudioTriX Pro for example) + * return 0x00. + */ + if (!trix_set_wss_port (hw_config)) + return 0; + + if ((INB (hw_config->io_base + 3) & 0x3f) != 0x00) + { + DDB (printk ("No MSS signature detected on port 0x%x\n", hw_config->io_base)); + return 0; + } + + if (hw_config->irq > 11) + { + printk ("AudioTriX: Bad WSS IRQ %d\n", hw_config->irq); + return 0; + } + + if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3) + { + printk ("AudioTriX: Bad WSS DMA %d\n", hw_config->dma); + return 0; + } + + /* + * Check that DMA0 is not in use with a 8 bit board. + */ + + if (hw_config->dma == 0 && INB (hw_config->io_base + 3) & 0x80) + { + printk ("AudioTriX: Can't use DMA0 with a 8 bit card\n"); + return 0; + } + + if (hw_config->irq > 7 && hw_config->irq != 9 && INB (hw_config->io_base + 3) & 0x80) + { + printk ("AudioTriX: Can't use IRQ%d with a 8 bit card\n", hw_config->irq); + return 0; + } + + return ad1848_detect (hw_config->io_base + 4); +} + +long +attach_trix_wss (long mem_start, struct address_info *hw_config) +{ + static unsigned char interrupt_bits[12] = + {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20}; + char bits; + + static unsigned char dma_bits[4] = + {1, 2, 0, 3}; + + int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3; + + if (!kilroy_was_here) + return mem_start; + + /* + * Set the IRQ and DMA addresses. + */ + + bits = interrupt_bits[hw_config->irq]; + if (bits == -1) + return mem_start; + + OUTB (bits | 0x40, config_port); + if ((INB (version_port) & 0x40) == 0) + printk ("[IRQ Conflict?]"); + + OUTB (bits | dma_bits[hw_config->dma], config_port); /* Write IRQ+DMA setup */ + + ad1848_init ("AudioTriX Pro", hw_config->io_base + 4, + hw_config->irq, + hw_config->dma, + hw_config->dma); + return mem_start; +} + +int +probe_trix_sb (struct address_info *hw_config) +{ + + int tmp; + unsigned char conf; + static char irq_translate[] = + {-1, -1, -1, 0, 1, 2, -1, 3}; + +#ifndef INCLUDE_TRIX_BOOT + return 0; /* No boot code -> no fun */ +#endif + if (!kilroy_was_here) + return 0; /* AudioTriX Pro has not been detected earlier */ + + if (sb_initialized) + return 0; + + if (hw_config->io_base & 0xffffff8f != 0x200) + return 0; + + tmp = hw_config->irq; + if (tmp > 7) + return 0; + if (irq_translate[tmp] == -1) + return 0; + + tmp = hw_config->dma; + if (tmp != 1 && tmp != 3) + return 0; + + conf = 0x84; /* DMA and IRQ enable */ + conf |= hw_config->io_base & 0x70; /* I/O address bits */ + conf |= irq_translate[hw_config->irq]; + if (hw_config->dma == 3) + conf |= 0x08; + trix_write (0x1b, conf); + + download_boot (hw_config->io_base); + sb_initialized = 1; + + return 1; +} + +long +attach_trix_sb (long mem_start, struct address_info *hw_config) +{ + printk (" <AudioTriX>"); + return mem_start; +} + +long +attach_trix_mpu (long mem_start, struct address_info *hw_config) +{ + return attach_mpu401 (mem_start, hw_config); +} + +int +probe_trix_mpu (struct address_info *hw_config) +{ + unsigned char conf; + static char irq_bits[] = + {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5}; + + if (!kilroy_was_here) + return 0; /* AudioTriX Pro has not been detected earlier */ + + if (!sb_initialized) + return 0; + + if (mpu_initialized) + return 0; + + if (hw_config->irq > 9) + return 0; + + if (irq_bits[hw_config->irq] == -1) + return 0; + + switch (hw_config->io_base) + { + case 0x330: + conf = 0x00; + break; + case 0x370: + conf = 0x04; + break; + case 0x3b0: + conf = 0x08; + break; + case 0x3f0: + conf = 0x0c; + break; + default: + return 0; /* Invalid port */ + } + + conf |= irq_bits[hw_config->irq] << 4; + + trix_write (0x19, (trix_read (0x19) & 0x83) | conf); + + mpu_initialized = 1; + + return probe_mpu401 (hw_config); +} + +#endif diff --git a/sys/i386/isa/sound/trix_boot.h b/sys/i386/isa/sound/trix_boot.h new file mode 100644 index 000000000000..d6bd16aff382 --- /dev/null +++ b/sys/i386/isa/sound/trix_boot.h @@ -0,0 +1,2488 @@ +/* + * Computer generated file. Do not edit. + */ +static unsigned char trix_boot[] = { +0x80,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0xe1,0x00,0x00, +0x00,0x00,0x00,0x02,0x44,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x02,0x44,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x74,0x00,0xa2,0xe3,0x92,0xd3,0xa2,0xe4,0x92,0xd4,0x75,0x81,0x45,0x12,0x3d,0x2e, +0xd2,0xaa,0xd2,0xaf,0x12,0x04,0xb9,0x7e,0x97,0x7f,0x54,0x90,0x00,0x00,0x02,0x0e, +0x14,0x80,0xfe,0x12,0x00,0x5c,0x12,0x03,0xc7,0x02,0x00,0x74,0xd0,0x00,0xd0,0x01, +0xc0,0x02,0xc0,0x03,0xc0,0x01,0xc0,0x00,0x8b,0x82,0x8a,0x83,0xe0,0xcc,0xfa,0xa3, +0xe0,0xcd,0xfb,0x22,0xd0,0x82,0xd0,0x83,0xf5,0xf0,0xea,0xf0,0xa3,0xeb,0xf0,0xe5, +0xf0,0x22,0xeb,0x33,0xe4,0x95,0xe0,0xfa,0xed,0x33,0xe4,0x95,0xe0,0xfc,0xec,0x33, +0xea,0x6c,0x13,0xc0,0xe0,0x12,0x03,0xcf,0xd0,0xf0,0x60,0x0c,0x30,0xf6,0x02,0xaa, +0xf0,0xea,0x33,0xb3,0xe4,0xfa,0x33,0xfb,0x22,0x7a,0x00,0x7c,0x00,0x12,0x03,0xcf, +0x60,0x05,0xb3,0xe4,0xfa,0x33,0xfb,0x22,0xeb,0x33,0xe4,0x95,0xe0,0xfa,0xed,0x33, +0xe4,0x95,0xe0,0xfc,0xec,0x33,0xea,0x6c,0x13,0xc0,0xe0,0x12,0x03,0xcf,0xd0,0xe0, +0x30,0xe6,0x01,0xfa,0xe4,0xca,0x23,0x54,0x01,0xfb,0x22,0x7a,0x00,0x7c,0x00,0x12, +0x03,0xcf,0xe4,0xfa,0x33,0xfb,0x22,0xeb,0x33,0xe4,0x95,0xe0,0xfa,0xed,0x33,0xe4, +0x95,0xe0,0xfc,0xec,0x33,0xea,0x6c,0x13,0xc0,0xe0,0x12,0x03,0xcf,0xd0,0xe0,0x30, +0xe6,0x01,0xfa,0xe4,0xca,0xf4,0x23,0x54,0x01,0xfb,0x22,0x7a,0x00,0x7c,0x00,0x12, +0x03,0xcf,0xe4,0xfa,0xb3,0x33,0xfb,0x22,0x7a,0x00,0x7c,0x00,0x12,0x03,0xcf,0x0b, +0x60,0x04,0xe4,0xfa,0x33,0xfb,0xeb,0x22,0x7a,0x00,0x7c,0x00,0x12,0x03,0xcf,0x0b, +0x60,0x03,0xe4,0xfa,0xfb,0xeb,0x22,0x7a,0x00,0x7c,0x00,0x12,0x03,0xcf,0x60,0x04, +0xe4,0xfa,0x04,0xfb,0xeb,0x22,0xd0,0x83,0xd0,0x82,0xe4,0x93,0xf5,0xf0,0xa3,0xe4, +0x93,0xa3,0xc0,0x82,0xc0,0x83,0xb8,0x03,0x0a,0xc0,0x04,0xc0,0x05,0xc0,0x00,0x78, +0x04,0x80,0x08,0xc0,0x02,0xc0,0x03,0xc0,0x00,0x78,0x02,0xa6,0xf0,0x08,0xf6,0x12, +0x03,0xd8,0xd0,0x00,0xb8,0x03,0x05,0xd0,0x05,0xd0,0x04,0x22,0x8b,0x05,0x8a,0x04, +0xd0,0x03,0xd0,0x02,0x22,0xd0,0x83,0xd0,0x82,0x12,0x02,0x14,0x80,0x0e,0xd0,0x83, +0xd0,0x82,0x12,0x02,0x14,0xc3,0xe4,0x99,0xf9,0xe4,0x98,0xf8,0xc0,0x82,0xc0,0x83, +0x8a,0x83,0x8b,0x82,0xc0,0x82,0xc0,0x83,0x80,0x28,0x78,0x00,0x79,0x01,0x80,0x04, +0x78,0xff,0x79,0xff,0xd0,0x83,0xd0,0x82,0xe4,0x93,0xa3,0xc0,0x82,0xc0,0x83,0x8a, +0x83,0x8b,0x82,0xb4,0x01,0x05,0xe0,0x29,0xfb,0xf0,0x22,0xc0,0x82,0xc0,0x83,0xb4, +0x02,0x13,0xe0,0xfa,0xa3,0xe0,0x29,0xfb,0xea,0x38,0xfa,0xd0,0x83,0xd0,0x82,0xf0, +0xa3,0xeb,0xf0,0x4a,0x22,0x75,0xf0,0x04,0xc0,0x00,0x78,0x02,0xe0,0xf6,0x08,0xa3, +0xd5,0xf0,0xf9,0x29,0xfd,0xd0,0x00,0xec,0x38,0xfc,0xeb,0x38,0xfb,0xea,0x38,0xfa, +0xd0,0x83,0xd0,0x82,0x75,0xf0,0x04,0x78,0x02,0xe6,0xf0,0xa3,0x08,0xd5,0xf0,0xf9, +0x4c,0x4b,0x4a,0x22,0xe4,0x93,0xf8,0xa3,0xe4,0x93,0xf9,0xa3,0x22,0xd0,0x83,0xd0, +0x82,0x12,0x02,0x14,0x80,0x0e,0xd0,0x83,0xd0,0x82,0x12,0x02,0x14,0xc3,0xe4,0x99, +0xf9,0xe4,0x98,0xf8,0xc0,0x82,0xc0,0x83,0x8a,0x83,0x8b,0x82,0xc0,0x82,0xc0,0x83, +0x80,0x2a,0x78,0x00,0x79,0x01,0x80,0x04,0x78,0xff,0x79,0xff,0xd0,0x83,0xd0,0x82, +0xe4,0x93,0xa3,0xc0,0x82,0xc0,0x83,0x8a,0x83,0x8b,0x82,0xb4,0x01,0x07,0xe0,0x29, +0xf0,0xc3,0x99,0xfb,0x22,0xc0,0x82,0xc0,0x83,0xb4,0x02,0x19,0xe0,0xfa,0xa3,0xe0, +0x29,0xfb,0xea,0x38,0xfa,0xd0,0x83,0xd0,0x82,0xf0,0xa3,0xeb,0xf0,0xc3,0x99,0xfb, +0xea,0x98,0xfa,0x4b,0x22,0x75,0xf0,0x04,0xc0,0x00,0x78,0x02,0xe0,0xf6,0x08,0xa3, +0xd5,0xf0,0xf9,0x29,0xfd,0xd0,0x00,0xec,0x38,0xfc,0xeb,0x38,0xfb,0xea,0x38,0xfa, +0xd0,0x83,0xd0,0x82,0x75,0xf0,0x04,0xc0,0x00,0x78,0x02,0xe6,0xf0,0xa3,0x08,0xd5, +0xf0,0xf9,0xd0,0x00,0xc3,0x99,0xfd,0xec,0x98,0xfc,0xeb,0x98,0xfb,0xea,0x98,0xfa, +0x4b,0x4c,0x4d,0x22,0xeb,0x60,0x11,0x24,0xf0,0x50,0x04,0xe4,0xfa,0xfb,0x22,0xec, +0xc3,0x13,0xfc,0xed,0x13,0xfd,0xdb,0xf7,0x8c,0x02,0x8d,0x03,0xea,0x4b,0x22,0xeb, +0x60,0x11,0x24,0xf0,0x50,0x04,0xe4,0xfa,0xfb,0x22,0xed,0xc3,0x33,0xfd,0xec,0x33, +0xfc,0xdb,0xf7,0x8c,0x02,0x8d,0x03,0xea,0x4b,0x22,0xea,0x5c,0xfa,0xeb,0x5d,0xfb, +0x4a,0x22,0xea,0x4c,0xfa,0xeb,0x4d,0xfb,0x4a,0x22,0x8a,0x83,0x8b,0x82,0xed,0xf0, +0xfb,0x22,0x8a,0x83,0x8b,0x82,0xec,0xf0,0xfa,0xa3,0xed,0xf0,0xfb,0x4a,0x22,0xc0, +0x03,0xc0,0x02,0x12,0x05,0xf9,0xd0,0x83,0xd0,0x82,0x78,0x04,0x79,0x02,0xe7,0xf0, +0x09,0xa3,0xd8,0xfa,0x4c,0x4b,0x4a,0x22,0x78,0x03,0x79,0x01,0x80,0x08,0x79,0x02, +0x80,0x02,0x79,0x04,0x78,0x02,0xd0,0x83,0xd0,0x82,0xe4,0x93,0x2b,0xf5,0xf0,0xa3, +0xe4,0x93,0x3a,0x80,0x27,0x78,0x03,0x79,0x01,0x80,0x14,0x78,0x05,0x79,0x01,0x80, +0x0e,0x79,0x02,0x80,0x08,0x78,0x04,0x79,0x02,0x80,0x04,0x79,0x04,0x78,0x02,0xd0, +0x83,0xd0,0x82,0xe4,0x93,0x2f,0xf5,0xf0,0xa3,0xe4,0x93,0x3e,0xa3,0xc0,0x82,0xc0, +0x83,0xf5,0x83,0x85,0xf0,0x82,0x75,0xf0,0x00,0xe0,0xf6,0x42,0xf0,0x08,0xa3,0xd9, +0xf8,0xe5,0xf0,0x22,0x78,0x03,0x79,0x01,0x80,0x08,0x79,0x02,0x80,0x02,0x79,0x04, +0x78,0x02,0xd0,0x83,0xd0,0x82,0xe4,0x93,0x2f,0xf5,0xf0,0xa3,0xe4,0x93,0x3e,0xa3, +0xc0,0x82,0xc0,0x83,0xf5,0x83,0x85,0xf0,0x82,0x75,0xf0,0x00,0xe6,0xf0,0xa3,0x08, +0x42,0xf0,0xd9,0xf8,0xe5,0xf0,0x22,0xeb,0x2d,0xfb,0xea,0x3c,0xfa,0x4b,0x22,0xed, +0xc3,0x9b,0xfb,0xec,0x9a,0xfa,0x4b,0x22,0xeb,0x8c,0xf0,0xa4,0xca,0x8d,0xf0,0xa4, +0x2a,0xfa,0xeb,0x8d,0xf0,0xa4,0xfb,0xe5,0xf0,0x2a,0xfa,0x4b,0x22,0x79,0x00,0xea, +0x30,0xe7,0x07,0x79,0x01,0x78,0x03,0x12,0x04,0x5f,0xec,0x30,0xe7,0x08,0x63,0x01, +0x01,0x78,0x05,0x12,0x04,0x5f,0xc0,0x01,0x12,0x04,0x25,0xd0,0x01,0xb9,0x01,0x05, +0x78,0x05,0x12,0x04,0x5f,0x8c,0x02,0x8d,0x03,0xea,0x4b,0x22,0xe4,0xc3,0x9b,0xfb, +0xe4,0x9a,0xfa,0x4b,0x22,0xbb,0x00,0x04,0xba,0x00,0x01,0x22,0x78,0x00,0x79,0x00, +0x74,0x10,0xc0,0xe0,0xc3,0xed,0x33,0xfd,0xec,0x33,0xfc,0xe9,0x33,0xf9,0xe8,0x33, +0xf8,0xc3,0xe9,0x9b,0xf5,0xf0,0xe8,0x9a,0x40,0x0b,0xf8,0xa9,0xf0,0xed,0x24,0x01, +0xfd,0xec,0x34,0x00,0xfc,0xd0,0xe0,0x14,0xc0,0xe0,0x70,0xd8,0xd0,0xe0,0x22,0xe4, +0xc3,0x96,0xf6,0x18,0xe4,0x96,0xf6,0x22,0xd0,0x83,0xd0,0x82,0xe4,0x93,0xf8,0xa3, +0xe4,0x93,0xf9,0xa3,0xe4,0x93,0xfc,0xa3,0xe4,0x93,0xfd,0xa3,0xc3,0xeb,0x99,0xf9, +0xea,0x98,0xf8,0x20,0xe7,0x08,0xc3,0xed,0x9b,0xec,0x9a,0x30,0xe7,0x0d,0xe4,0x93, +0xf5,0xf0,0xa3,0xe4,0x93,0xa3,0xc0,0xe0,0xc0,0xf0,0x22,0xa3,0xa3,0xe9,0x29,0x50, +0x02,0x05,0x83,0x25,0x82,0xf5,0x82,0xe5,0x83,0x38,0x28,0xf5,0x83,0xe4,0x93,0xf5, +0xf0,0xa3,0xe4,0x93,0xc0,0xe0,0xc0,0xf0,0x22,0x90,0x46,0xc2,0xaa,0x83,0xab,0x82, +0x90,0x42,0x80,0x12,0x05,0x14,0x90,0x9b,0x15,0xaa,0x83,0xab,0x82,0x90,0x9b,0x15, +0x12,0x05,0x1f,0x60,0x2c,0xc0,0x02,0xc0,0x03,0xc0,0x82,0xc0,0x83,0x78,0x02,0x79, +0x04,0xe4,0x93,0xf6,0xa3,0x08,0xd9,0xf9,0x8b,0x82,0x8a,0x83,0x8c,0x02,0x8d,0x03, +0x12,0x05,0x14,0xd0,0x83,0xd0,0x82,0xd0,0x03,0xd0,0x02,0xa3,0xa3,0xa3,0xa3,0x80, +0xcf,0x12,0x05,0x28,0x9b,0x15,0x4c,0x83,0x46,0xc2,0x12,0x05,0x28,0x9b,0x15,0x9b, +0x15,0x95,0x54,0x22,0x12,0x05,0x1f,0x70,0x01,0x22,0xe4,0xf0,0xa3,0x80,0xf5,0xeb, +0x65,0x82,0x70,0x03,0xea,0x65,0x83,0x22,0xd0,0x83,0xd0,0x82,0x78,0x02,0x79,0x06, +0xe4,0x93,0xf6,0xa3,0x08,0xd9,0xf9,0xc0,0x82,0xc0,0x83,0x8d,0x82,0x8c,0x83,0x12, +0x05,0x1f,0x60,0x13,0xe4,0x93,0xa3,0xad,0x82,0xac,0x83,0x8f,0x82,0x8e,0x83,0xf0, +0xa3,0xaf,0x82,0xae,0x83,0x80,0xe4,0x22,0x60,0x19,0xc0,0x00,0xc0,0x01,0xc0,0x83, +0xc0,0x82,0xf8,0x54,0x01,0x24,0x02,0xf9,0x12,0x06,0x00,0xd0,0x82,0xd0,0x83,0xd0, +0x01,0xd0,0x00,0xef,0x25,0x82,0xfd,0xee,0x35,0x83,0xfc,0xc3,0xef,0x99,0xf5,0x82, +0xff,0xee,0x98,0xfe,0xf5,0x83,0xd0,0x02,0xd0,0x03,0xd0,0xe0,0xf0,0xa3,0xd0,0xe0, +0xf0,0xa3,0xec,0xf0,0xa3,0xed,0xf0,0xc0,0x03,0xc0,0x02,0x22,0x8e,0x83,0x8f,0x82, +0xe0,0xf5,0xf0,0xa3,0xe0,0xc0,0xe0,0xc0,0xf0,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22, +0xd0,0x01,0xd0,0x00,0xd0,0xe0,0xd0,0xf0,0xc0,0x00,0xc0,0x01,0xc0,0xf0,0xc0,0xe0, +0x22,0x78,0x01,0x79,0x03,0x02,0x06,0x00,0x78,0x01,0x79,0x05,0x02,0x06,0x00,0x78, +0x02,0x79,0x02,0x02,0x06,0x00,0x78,0x02,0x79,0x04,0x02,0x06,0x00,0x78,0x01,0x79, +0x03,0x02,0x06,0x13,0x78,0x01,0x79,0x05,0x02,0x06,0x13,0x78,0x02,0x79,0x02,0x02, +0x06,0x13,0x78,0x02,0x79,0x04,0x02,0x06,0x13,0x78,0x04,0x79,0x02,0x02,0x06,0x13, +0xef,0xc3,0x98,0xff,0xee,0x94,0x00,0xfe,0x8f,0x82,0x8e,0x83,0xe7,0xf0,0xa3,0x09, +0xd8,0xfa,0x22,0xc0,0xe0,0x8f,0x82,0x8e,0x83,0xe0,0xf7,0xa3,0x09,0xd8,0xfa,0xae, +0x83,0xaf,0x82,0xd0,0xe0,0x22,0x74,0x02,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12, +0x03,0x61,0x04,0x00,0x90,0x42,0x80,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x00,0x12,0x05, +0xc1,0x7b,0x05,0x12,0x05,0xc1,0x7b,0x01,0x90,0x00,0x03,0x12,0x0d,0x73,0x7b,0x02, +0x12,0x05,0xc1,0x7b,0x05,0x12,0x05,0xc1,0x7b,0x01,0x90,0x00,0x03,0x12,0x0d,0x73, +0x90,0x00,0x00,0x12,0x0d,0xed,0x7b,0xf9,0x90,0x42,0x0c,0xeb,0xf0,0x90,0x42,0x0c, +0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60, +0x1a,0x7b,0x00,0x12,0x05,0xc1,0x90,0x42,0x0c,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c, +0xe7,0x7b,0x0c,0x7a,0x42,0x12,0x02,0x48,0x01,0x80,0xd2,0x7b,0x1b,0x12,0x05,0xc1, +0x7b,0xf8,0x90,0x00,0x02,0x12,0x0c,0xe7,0x7b,0x01,0x7a,0x00,0x02,0x05,0x9c,0xe4, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x20,0xeb,0x2d,0xfb,0x90, +0x42,0x0d,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90,0x42,0x0d,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b,0xfe, +0xeb,0x5d,0xfb,0x8b,0x05,0x12,0x03,0x55,0x05,0x00,0xeb,0x4d,0xfb,0x12,0x05,0xc1, +0x90,0x42,0x0d,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x7b,0xe8,0x8b,0x05,0x7b, +0x0d,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x2d,0xf0,0xfb,0x12,0x03,0x55,0x06,0x00, +0x12,0x05,0xc1,0x90,0x42,0x0d,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05, +0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x7b,0x00,0x7a,0x00,0x90,0x42, +0x0f,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x0f,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05, +0x8a,0x04,0x7b,0xe8,0x7a,0x03,0x12,0x00,0xc4,0x60,0x1a,0x90,0x00,0x00,0x12,0x0d, +0xed,0x8b,0x05,0x7b,0x02,0xeb,0x5d,0x70,0x02,0x80,0x0a,0x7b,0x0f,0x7a,0x42,0x12, +0x02,0x42,0x02,0x80,0xd1,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04, +0x7b,0x80,0x7a,0x00,0x12,0x03,0xc7,0x90,0x42,0x0e,0xeb,0xf0,0x74,0x05,0x2f,0xfb, +0xe4,0x3e,0xfa,0x12,0x02,0x42,0x02,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b, +0x3f,0xeb,0x5d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x0e,0xe0,0xfb,0x90,0x00,0x02,0x12, +0x0c,0xe7,0x7b,0x18,0x8b,0x05,0x7b,0x0e,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x2d, +0xf0,0xfb,0x74,0x05,0x2f,0xfb,0xe4,0x3e,0xfa,0x12,0x02,0x42,0x02,0x8a,0x83,0x8b, +0x82,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x0e,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c, +0xe7,0x7b,0x18,0x8b,0x05,0x7b,0x0e,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x2d,0xf0, +0xfb,0x74,0x05,0x2f,0xfb,0xe4,0x3e,0xfa,0x12,0x02,0x42,0x02,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x0e,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7, +0x7b,0x18,0x8b,0x05,0x7b,0x0e,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x2d,0xf0,0xfb, +0x74,0x05,0x2f,0xfb,0xe4,0x3e,0xfa,0x12,0x02,0x42,0x02,0x8a,0x83,0x8b,0x82,0xe0, +0xfb,0x12,0x05,0xc1,0x90,0x42,0x0e,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x7b, +0x18,0x8b,0x05,0x7b,0x0e,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x2d,0xf0,0xfb,0x74, +0x05,0x2f,0xfb,0xe4,0x3e,0xfa,0x12,0x02,0x42,0x02,0x8a,0x83,0x8b,0x82,0xe0,0xfb, +0x8b,0x05,0x7b,0x07,0xeb,0x5d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x0e,0xe0,0xfb,0x90, +0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05, +0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x50,0xeb,0x2d,0xfb,0x90,0x42,0x11, +0xeb,0xf0,0x12,0x03,0x55,0x05,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x12, +0x02,0xdf,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x06,0x00,0x12,0x05,0xd6,0x8b,0x05, +0x7b,0x01,0xeb,0x5d,0xfb,0x12,0x05,0xf2,0x7a,0x00,0x12,0x03,0x02,0x12,0x05,0xc1, +0x90,0x42,0x11,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x68, +0xeb,0x2d,0xfb,0x90,0x42,0x12,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x12,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb, +0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x30,0x7a,0xff,0x12,0x02,0xfa,0x8b,0x05,0x8a, +0x04,0x12,0x03,0x55,0x05,0x00,0x12,0x05,0xd6,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb, +0x12,0x05,0xf2,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x80,0x7a,0x00, +0x12,0x03,0x02,0x12,0x05,0xf2,0x12,0x03,0x02,0x12,0x05,0xc1,0x90,0x42,0x12,0xe0, +0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x68,0xeb,0x2d,0xfb,0x90, +0x42,0x13,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90,0x42,0x13,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05, +0x8a,0x04,0x7b,0x7f,0x7a,0xff,0x12,0x02,0xfa,0x12,0x05,0xc1,0x90,0x42,0x13,0xe0, +0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x38,0xeb,0x2d,0xfb,0x90, +0x42,0x14,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90,0x42,0x14,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05, +0x8a,0x04,0x7b,0x08,0x7a,0xff,0x12,0x02,0xfa,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55, +0x05,0x00,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x12,0x02,0xdf, +0x12,0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0xf0,0x7a,0x00,0x12,0x02, +0xfa,0x12,0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61,0x08,0x00, +0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x07,0x12,0x02,0xc4,0x12,0x05,0xf2,0x12, +0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x07,0x7a,0x00,0x12,0x02,0xfa,0x12,0x05,0xf2, +0x12,0x03,0x02,0x12,0x05,0xf2,0x12,0x03,0x02,0x12,0x05,0xc1,0x90,0x42,0x14,0xe0, +0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x7b,0xe8,0x8b,0x05,0x7b,0x14,0x7a,0x42,0x8a, +0x83,0x8b,0x82,0xe0,0x2d,0xf0,0xfb,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x14,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a, +0x00,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0xff,0x12,0x02,0xfa,0x8b,0x05,0x8a,0x04, +0x12,0x03,0x61,0x06,0x00,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x01, +0x12,0x02,0xdf,0x12,0x05,0xf2,0x12,0x03,0x02,0x12,0x05,0xc1,0x90,0x42,0x14,0xe0, +0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x68,0xeb,0x2d,0xfb,0x90, +0x42,0x15,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90,0x42,0x15,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b,0xf0, +0xeb,0x5d,0xfb,0x8b,0x05,0x12,0x03,0x55,0x05,0x00,0x12,0x05,0xc8,0x8b,0x05,0x7b, +0x0f,0xeb,0x5d,0xfb,0x12,0x05,0xe4,0xeb,0x4d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x15, +0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79, +0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x68,0xeb,0x2d,0xfb, +0x90,0x42,0x16,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90,0x42,0x16, +0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b, +0xbf,0xeb,0x5d,0xfb,0x8b,0x05,0x12,0x03,0x55,0x05,0x00,0x8d,0x03,0x60,0x0d,0x8b, +0x05,0x7b,0x40,0x90,0x42,0x17,0xeb,0xf0,0x8d,0x03,0x80,0x0b,0x8b,0x05,0x7b,0x00, +0x90,0x42,0x17,0xeb,0xf0,0x8d,0x03,0x8b,0x05,0x90,0x42,0x17,0xe0,0xfb,0xeb,0x4d, +0xfb,0x12,0x05,0xc1,0x90,0x42,0x16,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02, +0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00, +0x8b,0x05,0x7b,0x68,0xeb,0x2d,0xfb,0x90,0x42,0x18,0xeb,0xf0,0x7b,0x82,0x7a,0x42, +0x8b,0x05,0x8a,0x04,0x90,0x42,0x18,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83, +0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b,0xdf,0xeb,0x5d,0xfb,0x8b,0x05,0x12,0x03,0x55, +0x05,0x00,0x8d,0x03,0x60,0x0d,0x8b,0x05,0x7b,0x20,0x90,0x42,0x19,0xeb,0xf0,0x8d, +0x03,0x80,0x0b,0x8b,0x05,0x7b,0x00,0x90,0x42,0x19,0xeb,0xf0,0x8d,0x03,0x8b,0x05, +0x90,0x42,0x19,0xe0,0xfb,0xeb,0x4d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x18,0xe0,0xfb, +0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12, +0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x68,0xeb,0x2d,0xfb,0x90,0x42, +0x1a,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05,0x8a,0x04,0x90,0x42,0x1a,0xe0,0xfb, +0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b,0xef,0xeb, +0x5d,0xfb,0x8b,0x05,0x12,0x03,0x55,0x05,0x00,0x8d,0x03,0x60,0x0d,0x8b,0x05,0x7b, +0x10,0x90,0x42,0x1b,0xeb,0xf0,0x8d,0x03,0x80,0x0b,0x8b,0x05,0x7b,0x00,0x90,0x42, +0x1b,0xeb,0xf0,0x8d,0x03,0x8b,0x05,0x90,0x42,0x1b,0xe0,0xfb,0xeb,0x4d,0xfb,0x12, +0x05,0xc1,0x90,0x42,0x1a,0xe0,0xfb,0x90,0x00,0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c, +0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x8b,0x05, +0x7b,0x38,0xeb,0x2d,0xfb,0x90,0x42,0x1c,0xeb,0xf0,0x7b,0x82,0x7a,0x42,0x8b,0x05, +0x8a,0x04,0x90,0x42,0x1c,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x8b,0x05,0x7b,0xf7,0xeb,0x5d,0xfb,0x8b,0x05,0x12,0x03,0x55,0x05,0x00, +0x8d,0x03,0x60,0x0d,0x8b,0x05,0x7b,0x08,0x90,0x42,0x1d,0xeb,0xf0,0x8d,0x03,0x80, +0x0b,0x8b,0x05,0x7b,0x00,0x90,0x42,0x1d,0xeb,0xf0,0x8d,0x03,0x8b,0x05,0x90,0x42, +0x1d,0xe0,0xfb,0xeb,0x4d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x1c,0xe0,0xfb,0x90,0x00, +0x02,0x12,0x0c,0xe7,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58, +0xc2,0xb4,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x90,0x46,0xc2,0xe0,0xfa,0xa3,0xe0, +0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x12, +0x05,0xe4,0x12,0x03,0x0a,0x12,0x03,0x55,0x05,0x00,0x8b,0x05,0x90,0x46,0xc2,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x05,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x8b, +0x05,0x8a,0x04,0x7b,0x00,0x7a,0x01,0x12,0x00,0xc4,0x60,0x22,0x12,0x03,0x55,0x05, +0x00,0x8b,0x05,0x7b,0x82,0x7a,0x42,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x12,0x03, +0x55,0x05,0x00,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0xd2,0xb4, +0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0xc2,0xb4,0x12,0x03, +0x55,0x04,0x00,0x60,0x09,0x7b,0x02,0x90,0x42,0x20,0xeb,0xf0,0x80,0x07,0x7b,0x00, +0x90,0x42,0x20,0xeb,0xf0,0x90,0x42,0x20,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04, +0x90,0x46,0xc2,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x90,0x42,0x1e,0xea,0xf0, +0xeb,0xa3,0xf0,0x12,0x03,0x55,0x05,0x00,0x8b,0x05,0x90,0x42,0x1e,0xe0,0xfa,0xa3, +0xe0,0xfb,0x12,0x03,0x0a,0x12,0x03,0x55,0x06,0x00,0x8b,0x05,0x90,0x42,0x1e,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0xd2,0xb4,0x02,0x05,0x9c,0xe4,0x78,0x00, +0x79,0x04,0x12,0x05,0x58,0xc2,0xb4,0x90,0x46,0xc2,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a, +0x83,0x8b,0x82,0xe0,0xfb,0x90,0x42,0x21,0xeb,0xf0,0xd2,0xb4,0x90,0x42,0x21,0xe0, +0xfb,0x02,0x05,0x9c,0xe4,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90,0x00,0x00,0x12, +0x0e,0x2f,0x90,0x00,0x00,0x12,0x42,0x7e,0x7b,0x00,0x7a,0x00,0x02,0x05,0x9c,0xe4, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90,0x00,0x00,0x12,0x1a,0xf2,0x02,0x05,0x9c, +0xe4,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0xab,0x87,0x90,0x42,0x22,0xeb,0xf0,0x7b, +0x7f,0x8b,0x05,0x7b,0x22,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x5d,0xf0,0xfb,0x90, +0x42,0x22,0xe0,0xfb,0x8b,0x87,0xab,0x89,0x90,0x42,0x22,0xeb,0xf0,0x90,0x42,0x22, +0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x8b,0x05,0x7b,0x20,0xeb,0x4d,0xfb, +0x90,0x42,0x22,0xeb,0xf0,0x90,0x42,0x22,0xe0,0xfb,0x8b,0x89,0x7b,0xfe,0x8b,0x8d, +0x7b,0x00,0x8b,0x8b,0xd2,0x8e,0xc2,0x9f,0xd2,0x9e,0xc2,0x9d,0xd2,0x9c,0xd2,0xac, +0x7b,0x00,0x7a,0x00,0x02,0x05,0x9c,0xe4,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90, +0x43,0x84,0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x90,0x42,0x27,0xeb,0xf0, +0x90,0x43,0x85,0xe0,0xfb,0x90,0x42,0x28,0xeb,0xf0,0x90,0x43,0x86,0xe0,0xfb,0x90, +0x42,0x29,0xeb,0xf0,0x7b,0x87,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05, +0x8a,0x04,0x7b,0x07,0x12,0x02,0xdf,0x8b,0x05,0x8a,0x04,0x7b,0x97,0x7a,0x43,0x12, +0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7, +0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x90,0x42, +0x23,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0xa7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42, +0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00, +0x8b,0x05,0x8a,0x04,0x7b,0x07,0x12,0x02,0xdf,0x8b,0x05,0x8a,0x04,0x7b,0xb7,0x7a, +0x43,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7, +0x90,0x42,0x25,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x28,0xe0,0xfb,0x7a,0x00,0x12, +0x04,0x68,0x00,0x06,0x00,0x7f,0x15,0x60,0x10,0x7c,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x11,0x72,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x12,0x68,0x13,0x4e, +0x14,0x34,0x14,0x78,0x14,0xbc,0x15,0x00,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60, +0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x60,0x15,0x44, +0x15,0x60,0x15,0x52,0x15,0x52,0x15,0x52,0x15,0x52,0x15,0x52,0x7b,0xc7,0x7a,0x43, +0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83, +0x8b,0x82,0xe0,0x60,0x6e,0x7b,0x87,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27, +0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b, +0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x45,0x7b,0x97,0x7a,0x43, +0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83, +0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01, +0x3b,0x60,0x1e,0x90,0x42,0x29,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x23,0xe0,0xfa, +0xa3,0xe0,0xfb,0x12,0x05,0xcf,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x04,0x12,0x28, +0xf4,0x80,0x6c,0x7b,0xa7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb, +0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a, +0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x45,0x7b,0xb7,0x7a,0x43,0x8b,0x05, +0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60, +0x1e,0x90,0x42,0x29,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x25,0xe0,0xfa,0xa3,0xe0, +0xfb,0x12,0x05,0xc1,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x03,0x12,0x33,0xda,0x02, +0x16,0x7b,0x7b,0xc7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a, +0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0x60,0x6e,0x7b,0x87,0x7a,0x43,0x8b, +0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b, +0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b, +0x60,0x45,0x7b,0x97,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a, +0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04, +0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x1e,0x90,0x42,0x29,0xe0,0xfb,0x12,0x05, +0xc1,0x90,0x42,0x23,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x27,0xe0, +0xfb,0x90,0x00,0x03,0x12,0x33,0xb6,0x80,0x6c,0x7b,0xa7,0x7a,0x43,0x8b,0x05,0x8a, +0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0, +0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x45, +0x7b,0xb7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12, +0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff, +0x7a,0x00,0x12,0x01,0x3b,0x60,0x1e,0x90,0x42,0x29,0xe0,0xfb,0x12,0x05,0xc1,0x90, +0x42,0x25,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x27,0xe0,0xfb,0x90, +0x00,0x03,0x12,0x33,0xe6,0x02,0x16,0x7b,0x7b,0xc7,0x7a,0x43,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0x60, +0x66,0x7b,0x87,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00, +0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b, +0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x3d,0x7b,0x97,0x7a,0x43,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb, +0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x16,0x90, +0x42,0x23,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x27,0xe0,0xfb,0x90, +0x00,0x02,0x12,0x33,0xc2,0x80,0x64,0x7b,0xa7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a, +0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x3d,0x7b,0xb7, +0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7, +0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00, +0x12,0x01,0x3b,0x60,0x16,0x90,0x42,0x25,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc1, +0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x02,0x12,0x33,0xf2,0x02,0x16,0x7b,0x7b,0xc7, +0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7, +0x8a,0x83,0x8b,0x82,0xe0,0x60,0x66,0x7b,0x87,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a, +0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x3d,0x7b,0x97, +0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7, +0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00, +0x12,0x01,0x3b,0x60,0x16,0x90,0x42,0x23,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc1, +0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x02,0x12,0x33,0xce,0x80,0x64,0x7b,0xa7,0x7a, +0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a, +0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12, +0x01,0x3b,0x60,0x3d,0x7b,0xb7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05, +0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x3b,0x60,0x16,0x90,0x42,0x25,0xe0,0xfa, +0xa3,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x02,0x12,0x33, +0xfe,0x02,0x16,0x7b,0x90,0x42,0x29,0xe0,0xfb,0x8b,0x05,0x7b,0xb7,0x7a,0x43,0x12, +0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7, +0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x8b,0x05,0x7b,0xc7,0x7a,0x43,0x12,0x05, +0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x12, +0x05,0xe4,0x12,0x03,0x0a,0x02,0x16,0x7b,0x90,0x42,0x29,0xe0,0xfb,0x8b,0x05,0x7b, +0xa7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a, +0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x8b,0x05,0x7b,0xc7, +0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00, +0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x02,0x16,0x7b,0x90,0x42,0x29,0xe0, +0xfb,0x8b,0x05,0x7b,0x97,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42, +0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x01, +0x8b,0x05,0x7b,0xc7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27, +0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x02,0x16,0x7b, +0x90,0x42,0x29,0xe0,0xfb,0x8b,0x05,0x7b,0x87,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05, +0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12, +0x03,0x0a,0x7b,0x01,0x8b,0x05,0x7b,0xc7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a, +0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03, +0x0a,0x02,0x16,0x7b,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x01,0x12,0x32,0x3e,0x02, +0x16,0x7b,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x01,0x12,0x31,0x8a,0x02,0x16,0x7b, +0x90,0x42,0x28,0xe0,0xfb,0x8b,0x05,0x7b,0x20,0x12,0x00,0xdb,0x60,0x66,0x90,0x42, +0x29,0xe0,0xfb,0x8b,0x05,0x7b,0xd7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x27,0xe0,0xfb,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x20,0x12,0x03, +0xc7,0x12,0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x28,0xe0,0xfb, +0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x42,0x29,0xe0,0xfb, +0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x07,0x12,0x02,0xdf,0x12,0x05,0xcf,0x90,0x42, +0x28,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x04,0x12,0x34, +0xed,0x02,0x16,0x7b,0x90,0x42,0x28,0xe0,0xfb,0x8b,0x05,0x7b,0x40,0x12,0x00,0xdb, +0x60,0x6e,0x7b,0xe0,0x8b,0x05,0x7b,0x28,0x7a,0x42,0x8a,0x83,0x8b,0x82,0xe0,0x2d, +0xf0,0xfb,0x7b,0xd7,0x7a,0x43,0x8b,0x05,0x8a,0x04,0x90,0x42,0x27,0xe0,0xfb,0x7a, +0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x20,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x28,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a, +0x00,0x8b,0x05,0x8a,0x04,0x7b,0x07,0x12,0x02,0xdf,0x8b,0x05,0x8a,0x04,0x90,0x42, +0x29,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xcf,0x90,0x42,0x28,0xe0,0xfb, +0x12,0x05,0xc1,0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x04,0x12,0x34,0xed,0x80,0x2b, +0x90,0x43,0x85,0xe0,0xfb,0x8b,0x05,0x7b,0x60,0x12,0x00,0xdb,0x60,0x1d,0x90,0x42, +0x29,0xe0,0xfb,0x7a,0x00,0x12,0x05,0xcf,0x90,0x42,0x28,0xe0,0xfb,0x12,0x05,0xc1, +0x90,0x42,0x27,0xe0,0xfb,0x90,0x00,0x04,0x12,0x34,0xed,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90,0x43,0x83,0xe0,0xfb,0x8b,0x05,0x7b,0x00, +0x12,0x01,0x28,0x60,0x03,0x02,0x05,0x9c,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b, +0x85,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x82,0x7a,0x43,0x12,0x02, +0x42,0x01,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x43,0x83, +0xe0,0xfb,0x8b,0x05,0x90,0x43,0x82,0xe0,0xfb,0x12,0x01,0x37,0x60,0x03,0x02,0x05, +0x9c,0x7b,0x00,0x90,0x43,0x82,0xeb,0xf0,0x90,0x43,0x84,0xe0,0xfb,0x7a,0x00,0x8b, +0x05,0x8a,0x04,0x7b,0xf0,0x7a,0x00,0x12,0x02,0xfa,0x12,0x04,0x68,0x00,0x80,0x00, +0xe0,0x18,0xae,0x17,0xb5,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x17,0xda,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0x2e,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0x52,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0x5a,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0x76,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18,0xae,0x18, +0xae,0x18,0xae,0x18,0x92,0x90,0x43,0x86,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43,0x85, +0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43,0x84,0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d, +0xfb,0x90,0x00,0x03,0x12,0x26,0xe4,0x02,0x18,0xae,0x90,0x43,0x86,0xe0,0xfb,0x8b, +0x05,0x7b,0x00,0x12,0x01,0x28,0x60,0x21,0x7b,0x40,0x12,0x05,0xc1,0x90,0x43,0x85, +0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43,0x84,0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d, +0xfb,0x90,0x00,0x03,0x12,0x26,0xe4,0x80,0x22,0x90,0x43,0x86,0xe0,0xfb,0x12,0x05, +0xc1,0x90,0x43,0x85,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43,0x84,0xe0,0xfb,0x8b,0x05, +0x7b,0x0f,0xeb,0x5d,0xfb,0x90,0x00,0x03,0x12,0x21,0x57,0x02,0x18,0xae,0x90,0x43, +0x86,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43,0x85,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43, +0x84,0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x90,0x00,0x03,0x12,0x27,0xd2, +0x80,0x5c,0x90,0x00,0x00,0x12,0x0e,0xa7,0x80,0x54,0x90,0x43,0x85,0xe0,0xfb,0x12, +0x05,0xc1,0x90,0x43,0x84,0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x90,0x00, +0x02,0x12,0x27,0xea,0x80,0x38,0x90,0x43,0x85,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43, +0x84,0xe0,0xfb,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x90,0x00,0x02,0x12,0x27,0xde, +0x80,0x1c,0x90,0x43,0x86,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x43,0x84,0xe0,0xfb,0x8b, +0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x90,0x00,0x02,0x12,0x3b,0xc3,0x80,0x00,0x02,0x05, +0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x7a, +0x00,0x12,0x04,0x68,0x00,0xf0,0x00,0xff,0x19,0x56,0x18,0xea,0x19,0x1a,0x19,0x31, +0x19,0x1a,0x19,0x03,0x19,0x03,0x19,0x03,0x18,0xfb,0x19,0x56,0x19,0x56,0x19,0x56, +0x19,0x56,0x19,0x56,0x19,0x56,0x19,0x56,0x19,0x48,0x7b,0x01,0x90,0x45,0xd7,0xeb, +0xf0,0x7b,0xf0,0x90,0x00,0x01,0x12,0x2a,0x68,0x80,0x5b,0x7b,0xf7,0x90,0x00,0x01, +0x12,0x2a,0x68,0x7b,0x00,0x90,0x43,0x84,0xeb,0xf0,0x7b,0x00,0x90,0x43,0x83,0xeb, +0xf0,0x7b,0x00,0x90,0x43,0x82,0xeb,0xf0,0x80,0x3c,0x7b,0x00,0x90,0x43,0x84,0xeb, +0xf0,0x7b,0x01,0x90,0x43,0x83,0xeb,0xf0,0x7b,0x00,0x90,0x43,0x82,0xeb,0xf0,0x80, +0x25,0x7b,0x00,0x90,0x43,0x84,0xeb,0xf0,0x7b,0x02,0x90,0x43,0x83,0xeb,0xf0,0x7b, +0x00,0x90,0x43,0x82,0xeb,0xf0,0x80,0x0e,0x90,0x46,0xc4,0xe0,0x60,0x06,0x90,0x00, +0x00,0x12,0x1a,0xf2,0x80,0x00,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12, +0x05,0x58,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x80,0x7a, +0x00,0x12,0x00,0xf3,0x60,0x1b,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x8b,0x05,0x8a, +0x04,0x7b,0xf8,0x7a,0x00,0x12,0x00,0xc4,0x60,0x07,0x7b,0x00,0x90,0x45,0xd7,0xeb, +0xf0,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xf0,0x7a,0x00, +0x12,0x02,0xfa,0x12,0x04,0x68,0x00,0x80,0x00,0xf0,0x1a,0xcf,0x1a,0x8e,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0x8e,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0x8e,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0x8e,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xa8,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xa8,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0x8e,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf, +0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xcf,0x1a,0xc2,0x12,0x03, +0x55,0x04,0x00,0x90,0x43,0x84,0xeb,0xf0,0x7b,0x00,0x90,0x43,0x82,0xeb,0xf0,0x7b, +0x02,0x90,0x43,0x83,0xeb,0xf0,0x80,0x47,0x12,0x03,0x55,0x04,0x00,0x90,0x43,0x84, +0xeb,0xf0,0x7b,0x00,0x90,0x43,0x82,0xeb,0xf0,0x7b,0x01,0x90,0x43,0x83,0xeb,0xf0, +0x80,0x2d,0x12,0x03,0x55,0x04,0x00,0x90,0x00,0x01,0x12,0x18,0xb1,0x80,0x20,0x90, +0x45,0xd7,0xe0,0x60,0x0d,0x12,0x03,0x55,0x04,0x00,0x90,0x00,0x01,0x12,0x2a,0x68, +0x80,0x0b,0x12,0x03,0x55,0x04,0x00,0x90,0x00,0x01,0x12,0x16,0x7e,0x80,0x00,0x02, +0x05,0x9c,0xe4,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90,0x00,0x00,0x12,0x2a,0x57, +0x7b,0x00,0x90,0x43,0x82,0xeb,0xf0,0x7b,0x00,0x90,0x43,0x83,0xeb,0xf0,0x7b,0x00, +0x90,0x43,0x84,0xeb,0xf0,0x7b,0x00,0x90,0x45,0xd7,0xeb,0xf0,0x7b,0x00,0x7a,0x00, +0x90,0x42,0x2a,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb, +0x8b,0x05,0x8a,0x04,0x7b,0x10,0x7a,0x00,0x12,0x00,0xc4,0x70,0x03,0x02,0x1c,0x52, +0x7b,0xff,0x8b,0x05,0x7b,0x87,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a, +0x7b,0xff,0x8b,0x05,0x7b,0x97,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a, +0x7b,0xff,0x8b,0x05,0x7b,0xa7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a, +0x7b,0xff,0x8b,0x05,0x7b,0xb7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a, +0x7b,0x00,0x8b,0x05,0x7b,0xc7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90, +0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a, +0x7b,0x00,0x7a,0x00,0x90,0x42,0x2c,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x2c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x20,0x7a,0x00,0x12,0x00,0xc4,0x60, +0x46,0x7b,0x00,0x8b,0x05,0x7b,0xd7,0x7a,0x43,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x2a,0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x20,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x2c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x2c,0x7a, +0x42,0x12,0x02,0x42,0x02,0x80,0xa5,0x7b,0x2a,0x7a,0x42,0x12,0x02,0x42,0x02,0x02, +0x1b,0x28,0x02,0x05,0x9c,0x74,0x02,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03, +0x61,0x04,0x00,0x12,0x03,0x38,0x04,0x00,0x8b,0x05,0x7b,0x04,0x7c,0x00,0x12,0x02, +0xc4,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xf8,0x7a,0xff,0x12,0x03,0xc7,0x90,0x42, +0x2e,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x2e,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05, +0x8a,0x04,0x7b,0x0c,0x7a,0x00,0x12,0x03,0xd8,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61, +0x04,0x00,0x12,0x03,0x38,0x05,0x00,0x12,0x05,0xd6,0x8b,0x05,0x7b,0x7f,0xeb,0x5d, +0xfb,0x12,0x05,0xf2,0x7a,0x00,0x12,0x03,0xcf,0x90,0x42,0x2e,0xea,0xf0,0xeb,0xa3, +0xf0,0x90,0x42,0x2e,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x80,0x7a, +0x00,0x12,0x03,0xd8,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61,0x04,0x00,0x12,0x03,0x38, +0x07,0x00,0x12,0x05,0xd6,0x8b,0x05,0x7b,0x7f,0xeb,0x5d,0xfb,0x12,0x05,0xf2,0x7a, +0x00,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x7b,0xc0,0x7a,0xff,0x12,0x03,0xc7,0x90, +0x42,0x2e,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x00,0x7a,0x36,0x8b,0x05,0x8a,0x04,0x7b, +0x2e,0x7a,0x42,0x12,0x00,0x53,0x90,0x42,0x2e,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05, +0x8a,0x04,0x12,0x03,0x61,0x04,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x08, +0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0x12,0x02,0x05,0x9c,0xe4,0x78, +0x00,0x79,0x04,0x12,0x05,0x58,0x7b,0x14,0x7a,0x00,0x90,0x00,0x02,0x12,0x06,0x26, +0x90,0x88,0x43,0xe0,0x70,0x03,0x02,0x1e,0x84,0x7b,0x00,0x90,0x88,0x43,0xeb,0xf0, +0x7b,0x00,0x7a,0x00,0x90,0x42,0x34,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x34,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x80,0x7a,0x00,0x12,0x00,0xc4,0x70, +0x03,0x02,0x1e,0x84,0x7b,0xc1,0x7a,0x4a,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34,0xe0, +0xfa,0xa3,0xe0,0xfb,0xeb,0x2b,0xfb,0xea,0x3a,0xfa,0x12,0x03,0xc7,0x8a,0x83,0x8b, +0x82,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x3e,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42, +0x3e,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x01, +0x3b,0x60,0x0e,0x90,0x42,0x3e,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x1c, +0x55,0x7b,0xb3,0x7a,0x7f,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0, +0xfb,0xeb,0x2b,0xfb,0xea,0x3a,0xfa,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfa, +0xa3,0xe0,0xfb,0x90,0x42,0x3c,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x3c,0xe0,0xfa, +0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x90,0x42, +0x3a,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x3c,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83, +0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x90,0x42,0x36,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42, +0x36,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x00, +0x8e,0x60,0x36,0x90,0x42,0x3a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x3e,0x02,0x00, +0x90,0x42,0x3e,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x3e,0xe0,0xfa,0xa3,0xe0,0xfb, +0x90,0x00,0x02,0x12,0x1c,0x55,0x7b,0x36,0x7a,0x42,0x12,0x02,0x48,0x02,0x7b,0x3a, +0x7a,0x42,0x12,0x02,0x1d,0x00,0x04,0x80,0xb5,0x7b,0x34,0x7a,0x42,0x12,0x02,0x42, +0x02,0x02,0x1d,0x6c,0x7b,0x00,0x7a,0x00,0x90,0x42,0x34,0xea,0xf0,0xeb,0xa3,0xf0, +0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x10,0x7a,0x00, +0x12,0x00,0xc4,0x70,0x03,0x02,0x1f,0x26,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb, +0x8b,0x05,0x7b,0xe0,0x7a,0x45,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34, +0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x12, +0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x8b,0x05,0x7b,0xe0,0x7a,0x45,0x12,0x05,0xc8, +0x8b,0x05,0x8a,0x04,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01, +0x46,0x00,0x0e,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04, +0x7b,0x01,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x42,0x34, +0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x01,0x12,0x32,0x3e,0x7b,0x34,0x7a,0x42,0x12, +0x02,0x42,0x02,0x02,0x1e,0x90,0x7b,0x00,0x7a,0x00,0x90,0x42,0x34,0xea,0xf0,0xeb, +0xa3,0xf0,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x18, +0x7a,0x00,0x12,0x00,0xc4,0x70,0x03,0x02,0x20,0xf4,0x7b,0xff,0x8b,0x05,0x7b,0x02, +0x7a,0x00,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0, +0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x05, +0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12, +0x03,0x0a,0x7b,0x80,0x8b,0x05,0x7b,0x02,0x7a,0x00,0x12,0x05,0xc8,0x8b,0x05,0x8a, +0x04,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0a, +0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x02,0x7a, +0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x7a,0x00,0x8b,0x05, +0x8a,0x04,0x7b,0x02,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34, +0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12,0x03,0xc7,0x12, +0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7, +0x12,0x05,0xf2,0x12,0x03,0x12,0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05, +0x7b,0x02,0x7a,0x00,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34,0xe0,0xfa, +0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12,0x03,0xc7,0x12,0x05,0xe4, +0x12,0x03,0x0a,0x7b,0x02,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34,0xe0,0xfa, +0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0xff,0x12,0x03, +0xc7,0x12,0x05,0xf2,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12,0x03,0xc7,0x8b,0x05, +0x8a,0x04,0x7b,0x02,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x34, +0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12,0x03,0xc7,0x12, +0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x06,0x7a,0x00,0x12,0x03,0xc7, +0x12,0x05,0xf2,0x12,0x03,0x12,0x7b,0x02,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x90,0x42, +0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a, +0x00,0x12,0x03,0xc7,0x12,0x05,0xf2,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12,0x03, +0xc7,0x8b,0x05,0x8a,0x04,0x7b,0x02,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x34,0xe0,0xfa,0xa3,0xe0,0xfb,0x78,0x03,0x12,0x01,0x46,0x00,0x0a,0x12, +0x03,0xc7,0x12,0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x08,0x7a,0x00, +0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0x12,0x7b,0x34,0x7a,0x42,0x12,0x02,0x42, +0x02,0x02,0x1f,0x32,0x7b,0x00,0x7a,0x00,0x90,0x00,0x08,0xea,0xf0,0xeb,0xa3,0xf0, +0x7b,0x00,0x7a,0x00,0x90,0x00,0xf0,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x02,0x7a,0x00, +0x90,0x45,0xd8,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0xe8,0x7a,0x00,0x90,0x45,0xda,0xea, +0xf0,0xeb,0xa3,0xf0,0x7b,0x00,0x7a,0x00,0x90,0x45,0xde,0xea,0xf0,0xeb,0xa3,0xf0, +0x90,0x45,0xdc,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x12,0x90,0x46,0xc0,0xeb,0xf0,0x7b, +0x01,0x7a,0x00,0x02,0x05,0x9c,0xe4,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90,0x00, +0x00,0x12,0x06,0xaf,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58, +0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x09,0x12,0x01,0x28,0x60,0x16,0x12,0x03, +0x55,0x06,0x00,0x12,0x05,0xc1,0x12,0x03,0x55,0x06,0x00,0x90,0x00,0x02,0x12,0x24, +0x93,0x02,0x05,0x9c,0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04, +0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x90,0x42,0x42, +0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x42,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38, +0x01,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xff,0x7a,0x00,0x12,0x01,0x2c,0x60, +0x03,0x02,0x05,0x9c,0x7b,0xb3,0x7a,0x7f,0x8b,0x05,0x8a,0x04,0x90,0x42,0x42,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x7a,0x00,0xeb,0x2b,0xfb,0xea,0x3a, +0xfa,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x48, +0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x48,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a, +0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x90,0x42,0x46,0xea,0xf0,0xeb,0xa3,0xf0, +0x90,0x42,0x48,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x42, +0x44,0xeb,0xf0,0x90,0x42,0x44,0xe0,0xfb,0x8b,0x05,0x7b,0x00,0x12,0x00,0x82,0x70, +0x03,0x02,0x24,0x90,0x90,0x42,0x46,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x8b,0x05,0x12,0x03,0x55,0x05,0x00,0x12,0x00,0xa9,0x70,0x19,0x90,0x42, +0x46,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x8b,0x05,0x12,0x03,0x55, +0x05,0x00,0x12,0x00,0xdb,0x60,0x03,0x02,0x24,0x7c,0x90,0x42,0x46,0xe0,0xfa,0xa3, +0xe0,0xfb,0x12,0x03,0x3e,0x02,0x00,0x90,0x42,0x4a,0xea,0xf0,0xeb,0xa3,0xf0,0x90, +0x00,0x00,0x12,0x3a,0xeb,0x90,0x42,0x40,0xea,0xf0,0xeb,0xa3,0xf0,0x8b,0x05,0x8a, +0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x2c,0x60,0x03,0x02,0x05,0x9c,0x90,0x42,0x40, +0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x02,0x00,0x8b,0x05,0x7b,0x80,0x12,0x01, +0x37,0x60,0x14,0x90,0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0, +0xfb,0x90,0x00,0x01,0x12,0x39,0xf6,0x90,0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x12, +0x03,0x3e,0x04,0x00,0x8b,0x05,0x8a,0x04,0x90,0x42,0x4a,0xe0,0xfa,0xa3,0xe0,0xfb, +0x12,0x01,0x3b,0x60,0x63,0x90,0x42,0x4a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38, +0x03,0x00,0x12,0x05,0xc1,0x90,0x42,0x4a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38, +0x04,0x00,0x8b,0x05,0x7b,0x01,0xeb,0x5d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x40,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x03,0x12,0x39,0x8b, +0x90,0x42,0x4a,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x90,0x42,0x40,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0x12,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x90, +0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x01, +0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x12,0x03,0x55,0x05,0x00, +0x8b,0x05,0x90,0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a, +0x04,0x7b,0x02,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x12,0x03, +0x55,0x06,0x00,0x8b,0x05,0x90,0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8, +0x8b,0x05,0x8a,0x04,0x7b,0x03,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03, +0x0a,0x90,0x42,0x42,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x0d,0x00,0x8b,0x05, +0x7b,0x01,0xeb,0x5d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb, +0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x02,0x12,0x3a,0x0d,0x90,0x42,0x40,0xe0, +0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x3b,0x2b,0x90,0x42,0x40,0xe0,0xfa,0xa3, +0xe0,0xfb,0x90,0x00,0x02,0x12,0x2d,0x5b,0x90,0x42,0x4a,0xe0,0xfa,0xa3,0xe0,0xfb, +0x8b,0x05,0x8a,0x04,0x7b,0x0b,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xcf,0x90,0x42, +0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x03,0x12, +0x38,0xd9,0x90,0x42,0x4a,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb, +0x8b,0x05,0x7b,0x04,0x7c,0x00,0x12,0x02,0xc4,0x90,0x42,0x45,0xeb,0xf0,0x90,0x42, +0x45,0xe0,0xfb,0x8b,0x05,0x7b,0x00,0x12,0x01,0x28,0x60,0x12,0x90,0x42,0x42,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x09,0x00,0x90,0x42,0x45,0xeb,0xf0,0x90,0x42, +0x45,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x40,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83, +0x8b,0x82,0xe0,0xfb,0x90,0x00,0x02,0x12,0x39,0xd9,0x80,0x14,0x7b,0x44,0x7a,0x42, +0x12,0x02,0x48,0x01,0x7b,0x46,0x7a,0x42,0x12,0x02,0x1d,0x00,0x04,0x02,0x22,0x23, +0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x7b,0xc1,0x7a,0x4a, +0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0xeb,0x2b,0xfb,0xea,0x3a, +0xfa,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x51, +0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x51,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a, +0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x2c,0x60,0x03,0x02,0x05,0x9c,0x7b,0x5e,0x7a, +0x46,0x90,0x42,0x4e,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x00,0x00,0x12,0x3a,0xeb,0x90, +0x42,0x4c,0xea,0xf0,0xeb,0xa3,0xf0,0x8b,0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12, +0x01,0x2c,0x60,0x03,0x02,0x05,0x9c,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12, +0x03,0x38,0x02,0x00,0x8b,0x05,0x7b,0x80,0x12,0x01,0x37,0x60,0x14,0x90,0x42,0x4c, +0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x01,0x12,0x39, +0xf6,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x3e,0x04,0x00,0x8b,0x05, +0x8a,0x04,0x90,0x42,0x51,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x01,0x3b,0x60,0x63,0x90, +0x42,0x51,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x03,0x00,0x12,0x05,0xc1,0x90, +0x42,0x51,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x04,0x00,0x8b,0x05,0x7b,0x01, +0xeb,0x5d,0xfb,0x12,0x05,0xc1,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83, +0x8b,0x82,0xe0,0xfb,0x90,0x00,0x03,0x12,0x39,0x8b,0x90,0x42,0x51,0xe0,0xfa,0xa3, +0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05, +0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xf2,0x12, +0x03,0x12,0x7b,0x09,0x8b,0x05,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05, +0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12, +0x03,0x0a,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0, +0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x02,0x7a,0x00,0x12,0x03,0xc7,0x12, +0x05,0xe4,0x12,0x03,0x0a,0x12,0x03,0x55,0x05,0x00,0x8b,0x05,0x90,0x42,0x4c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x03,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x42,0x4e,0xe0,0xfa,0xa3,0xe0,0xfb, +0x12,0x03,0x38,0x0d,0x00,0x8b,0x05,0x7b,0x01,0xeb,0x5d,0xfb,0x12,0x05,0xc1,0x90, +0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x02, +0x12,0x3a,0x0d,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x3b, +0x2b,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x2d,0x5b,0x90, +0x42,0x51,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x0b,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xcf,0x90,0x42,0x4c,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b, +0x82,0xe0,0xfb,0x90,0x00,0x03,0x12,0x38,0xd9,0x90,0x42,0x51,0xe0,0xfa,0xa3,0xe0, +0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b,0x04,0x7c,0x00,0x12,0x02,0xc4, +0x90,0x42,0x50,0xeb,0xf0,0x90,0x42,0x50,0xe0,0xfb,0x8b,0x05,0x7b,0x00,0x12,0x01, +0x28,0x60,0x12,0x90,0x42,0x4e,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x09,0x00, +0x90,0x42,0x50,0xeb,0xf0,0x90,0x42,0x50,0xe0,0xfb,0x12,0x05,0xc1,0x90,0x42,0x4c, +0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x02,0x12,0x39, +0xd9,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x7b,0xe0,0x7a, +0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x78,0x03,0x12,0x01, +0x46,0x00,0x0e,0x12,0x03,0xc7,0x12,0x03,0x38,0x0d,0x00,0x8b,0x05,0x7b,0x00,0xeb, +0x5d,0xfb,0x90,0x42,0x57,0xeb,0xf0,0x90,0x45,0xdc,0xe0,0xfa,0xa3,0xe0,0xfb,0x90, +0x42,0x53,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x53,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b, +0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x3b,0x70,0x03,0x02,0x27,0xcf,0x90, +0x42,0x53,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x3e,0x08,0x00,0x90,0x42,0x55,0xea, +0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x53,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01, +0x00,0x8b,0x05,0x12,0x03,0x55,0x04,0x00,0x12,0x01,0x28,0x60,0x4f,0x90,0x42,0x53, +0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x02,0x00,0x8b,0x05,0x12,0x03,0x55,0x05, +0x00,0x12,0x01,0x28,0x60,0x36,0x90,0x42,0x57,0xe0,0x60,0x22,0x7b,0x81,0x8b,0x05, +0x90,0x42,0x53,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b, +0x02,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x80,0x0e,0x90,0x42, +0x53,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x31,0x2c,0x90,0x42,0x55,0xe0, +0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x53,0xea,0xf0,0xeb,0xa3,0xf0,0x02,0x27,0x27,0x02, +0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x90,0x42,0x00,0xe0,0x60,0x4f,0x7b,0xd4,0x7a,0x94,0x8b,0x05,0x8a, +0x04,0x12,0x03,0x55,0x05,0x00,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0, +0xfb,0x8b,0x05,0x7b,0xe0,0x7a,0x45,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x12,0x03, +0x55,0x05,0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x12, +0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00,0x12,0x03,0xc7, +0x12,0x05,0xe4,0x12,0x03,0x0a,0x80,0x3a,0x12,0x03,0x55,0x05,0x00,0x8b,0x05,0x7b, +0xe0,0x7a,0x45,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x05,0x00,0x7a, +0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x05, +0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12, +0x03,0x0a,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03, +0x55,0x04,0x00,0x8b,0x05,0x7b,0x09,0x12,0x01,0x28,0x60,0x03,0x02,0x05,0x9c,0x7b, +0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x78,0x03, +0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x90,0x42,0x58,0xea,0xf0,0xeb,0xa3,0xf0, +0x12,0x03,0x55,0x05,0x00,0x8b,0x05,0x90,0x42,0x58,0xe0,0xfa,0xa3,0xe0,0xfb,0x12, +0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4, +0x12,0x03,0x0a,0x90,0x42,0x58,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x3b, +0xe5,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55, +0x04,0x00,0x8b,0x05,0x7b,0x09,0x12,0x01,0x28,0x60,0x03,0x02,0x05,0x9c,0x12,0x03, +0x61,0x05,0x00,0x12,0x04,0x68,0x00,0x00,0x00,0x02,0x2a,0x54,0x29,0x22,0x29,0x74, +0x29,0xe2,0x12,0x03,0x55,0x07,0x00,0x8b,0x05,0x7b,0x0c,0x12,0x00,0xa9,0x60,0x07, +0x7b,0x0c,0x12,0x03,0x94,0x07,0x00,0x12,0x03,0x55,0x07,0x00,0x8b,0x05,0x7b,0xe0, +0x7a,0x45,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x05,0x00,0x7a,0x00, +0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x05,0xc8, +0x8b,0x05,0x8a,0x04,0x7b,0x05,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03, +0x0a,0x02,0x2a,0x54,0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04, +0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x90,0x42,0x5a, +0xea,0xf0,0xeb,0xa3,0xf0,0x12,0x03,0x55,0x07,0x00,0xeb,0x33,0xe4,0x95,0xe0,0xfa, +0x8b,0x05,0x8a,0x04,0x7b,0xc0,0x7a,0xff,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x7b, +0x01,0x12,0x02,0xdf,0x8b,0x05,0x90,0x42,0x5a,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05, +0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x08,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12, +0x03,0x0a,0x90,0x42,0x5a,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x3b,0xe5, +0x80,0x72,0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a, +0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x90,0x42,0x5a,0xea,0xf0, +0xeb,0xa3,0xf0,0x12,0x03,0x55,0x07,0x00,0xeb,0x33,0xe4,0x95,0xe0,0xfa,0x8b,0x05, +0x8a,0x04,0x7b,0xc0,0x7a,0xff,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x7b,0x80,0x7a, +0x00,0x12,0x03,0xd8,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5a,0xe0,0xfa,0xa3,0xe0,0xfb, +0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x06,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05, +0xf2,0x12,0x03,0x12,0x90,0x42,0x5a,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12, +0x3b,0xe5,0x80,0x00,0x02,0x05,0x9c,0xe4,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x90, +0x00,0x00,0x12,0x1d,0x3e,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05, +0x58,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0xf0,0x7a,0x00, +0x12,0x01,0x2c,0x60,0x09,0x7b,0x01,0x90,0x46,0xc1,0xeb,0xf0,0x80,0x5b,0x90,0x46, +0xc1,0xe0,0xfb,0x8b,0x05,0x7b,0x02,0x12,0x01,0x28,0x60,0x0a,0x7b,0xc1,0x7a,0x46, +0x12,0x02,0x42,0x01,0x80,0x43,0x90,0x46,0xc1,0xe0,0xfb,0x8b,0x05,0x7b,0x05,0x12, +0x01,0x18,0x60,0x35,0x7b,0x44,0x7a,0x88,0x8b,0x05,0x8a,0x04,0x90,0x46,0xc1,0xe0, +0xfb,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x12,0x03, +0x55,0x04,0x00,0x12,0x01,0x28,0x60,0x0a,0x7b,0xc1,0x7a,0x46,0x12,0x02,0x42,0x01, +0x80,0x07,0x7b,0xe7,0x90,0x46,0xc1,0xeb,0xf0,0x90,0x46,0xc1,0xe0,0xfb,0x8b,0x05, +0x7b,0x06,0x12,0x01,0x28,0x60,0x06,0x90,0x00,0x00,0x12,0x1a,0xf2,0x02,0x05,0x9c, +0x74,0x02,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x61,0x04,0x00,0x8a,0x83, +0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61,0x06,0x00,0x12, +0x00,0x8e,0x60,0x26,0x12,0x03,0x61,0x04,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a, +0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04, +0x7b,0x80,0x7a,0xff,0x12,0x03,0xc7,0x02,0x05,0x9c,0x7b,0x00,0x7a,0x00,0x90,0x42, +0x5c,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x5c,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05, +0x8a,0x04,0x7b,0x03,0x7a,0x00,0x12,0x00,0xc4,0x70,0x03,0x02,0x2d,0x2a,0x12,0x03, +0x61,0x04,0x00,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12, +0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xf2, +0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x12, +0x03,0x61,0x06,0x00,0x12,0x00,0x8e,0x70,0x03,0x02,0x2d,0x1f,0x12,0x03,0x61,0x04, +0x00,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x5c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0, +0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x80,0x7a,0xff,0x12,0x03,0xc7,0x8b,0x05, +0x8a,0x04,0x12,0x03,0x61,0x04,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42, +0x5c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xc7,0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x7a,0x00,0x12,0x04,0x1c,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x12,0x03, +0x61,0x08,0x00,0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04, +0x12,0x03,0x61,0x06,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00, +0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5c, +0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00, +0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0xc7,0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61,0x08,0x00, +0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05, +0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5c,0xe0,0xfa,0xa3,0xe0,0xfb, +0x12,0x03,0xc7,0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x12,0x03, +0xcf,0x12,0x05,0xf2,0x12,0x03,0xd8,0x12,0x05,0xf2,0x12,0x05,0xd6,0x8b,0x05,0x8a, +0x04,0x12,0x03,0x61,0x06,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5c, +0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00, +0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0xc7,0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82, +0xe0,0xfb,0x7a,0x00,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61,0x08,0x00, +0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12, +0x03,0xc7,0x12,0x05,0xf2,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x12,0x03,0xcf, +0x12,0x05,0xf2,0x12,0x03,0xed,0x12,0x05,0xf2,0x12,0x03,0xc7,0x02,0x05,0x9c,0x7b, +0x5c,0x7a,0x42,0x12,0x02,0x42,0x02,0x02,0x2b,0x56,0x12,0x03,0x61,0x04,0x00,0x8b, +0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x7b,0x03, +0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x8b,0x05,0x8a, +0x04,0x7b,0x80,0x7a,0xff,0x12,0x03,0xc7,0x02,0x05,0x9c,0x74,0x02,0x78,0x00,0x79, +0x04,0x12,0x05,0x58,0x12,0x03,0x61,0x04,0x00,0x12,0x03,0x3e,0x04,0x00,0x12,0x03, +0x38,0x02,0x00,0x90,0x42,0x5e,0xeb,0xf0,0x7b,0x00,0x7a,0x00,0x90,0x42,0x61,0xea, +0xf0,0xeb,0xa3,0xf0,0x7b,0xb3,0x7a,0x80,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5e,0xe0, +0xfb,0x12,0x05,0xd6,0x8b,0x05,0x7b,0x04,0x7c,0x00,0x12,0x02,0xc4,0x12,0x05,0xf2, +0x7a,0x00,0xeb,0x2b,0xfb,0xea,0x3a,0xfa,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x12,0x03,0x61,0x04,0x00,0x12,0x03,0x38, +0x03,0x00,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x7a,0x00,0x90, +0x42,0x5f,0xea,0xf0,0xeb,0xa3,0xf0,0x12,0x03,0x61,0x04,0x00,0x12,0x03,0x38,0x01, +0x00,0x8b,0x05,0x7b,0x09,0x12,0x01,0x37,0x70,0x03,0x02,0x2e,0x7b,0x12,0x03,0x61, +0x04,0x00,0x12,0x03,0x3e,0x04,0x00,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x7b, +0x0f,0xeb,0x5d,0xfb,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5e,0xe0,0xfb,0x12, +0x05,0xd6,0x8b,0x05,0x7b,0x0f,0xeb,0x5d,0xfb,0x12,0x05,0xf2,0x7a,0x00,0x12,0x05, +0xd6,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x12,0x02,0xdf,0x12,0x05,0xf2,0x12,0x03,0xc7, +0x8b,0x05,0x8a,0x04,0x7b,0x5f,0x7a,0x42,0x12,0x00,0x53,0x12,0x03,0x61,0x04,0x00, +0x12,0x03,0x38,0x02,0x00,0x7a,0x00,0x12,0x05,0xcf,0x7b,0xcb,0x7a,0x80,0x8b,0x05, +0x8a,0x04,0x12,0x03,0x61,0x06,0x00,0x12,0x03,0x3e,0x04,0x00,0x12,0x03,0x38,0x10, +0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x08,0x12,0x03,0xc7,0x90,0x00,0x04, +0x12,0x2b,0x00,0x90,0x42,0x61,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x5f,0xe0,0xfa, +0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x7e,0x7a,0x00,0x12,0x00,0x8e,0x60,0x0c, +0x7b,0x7e,0x7a,0x00,0x90,0x42,0x5f,0xea,0xf0,0xeb,0xa3,0xf0,0x12,0x03,0x61,0x04, +0x00,0x12,0x03,0x3e,0x04,0x00,0x12,0x03,0x38,0x0a,0x00,0x8b,0x05,0x7b,0x01,0x7c, +0x00,0x12,0x02,0xc4,0x7a,0x00,0x12,0x04,0x1c,0x8b,0x05,0x8a,0x04,0x7b,0x7f,0x7a, +0x00,0x12,0x03,0xc7,0x90,0x42,0x63,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x61,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x63,0x7a,0x42,0x12,0x00,0x53,0x90, +0x42,0x63,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x7f,0x7a,0x00,0x12, +0x00,0x8e,0x60,0x0c,0x7b,0x7f,0x7a,0x00,0x90,0x42,0x63,0xea,0xf0,0xeb,0xa3,0xf0, +0x90,0x42,0x63,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x01,0x7a,0x00, +0x12,0x00,0xc4,0x60,0x0c,0x7b,0x01,0x7a,0x00,0x90,0x42,0x63,0xea,0xf0,0xeb,0xa3, +0xf0,0x7b,0x7f,0x7a,0x00,0x8b,0x05,0x8a,0x04,0x90,0x42,0x5f,0xe0,0xfa,0xa3,0xe0, +0xfb,0x12,0x03,0xcf,0x8b,0x05,0x8a,0x04,0x90,0x42,0x63,0xe0,0xfa,0xa3,0xe0,0xfb, +0x12,0x03,0xd8,0x8b,0x05,0x8a,0x04,0x7b,0x7f,0x7a,0x00,0x12,0x03,0xed,0x90,0x42, +0x63,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03, +0x61,0x04,0x00,0x12,0x03,0x38,0x01,0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00, +0x0e,0x12,0x03,0xc7,0x12,0x03,0x38,0x0c,0x00,0x7a,0x00,0x12,0x04,0x1c,0x8b,0x05, +0x8a,0x04,0x7b,0x7f,0x7a,0x00,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x90,0x42,0x63, +0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xd8,0x8b,0x05,0x8a,0x04,0x7b,0x7f,0x7a,0x00, +0x12,0x03,0xed,0x90,0x42,0x63,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x7f,0x7a,0x00,0x8b, +0x05,0x8a,0x04,0x90,0x42,0x63,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0xcf,0x90,0x42, +0x63,0xea,0xf0,0xeb,0xa3,0xf0,0x12,0x03,0x61,0x04,0x00,0x12,0x03,0x38,0x01,0x00, +0x8b,0x05,0x7b,0x09,0x12,0x01,0x28,0x60,0x12,0x90,0x46,0xc0,0xe0,0xfb,0x7a,0x00, +0x8b,0x05,0x8a,0x04,0x7b,0x63,0x7a,0x42,0x12,0x00,0x53,0x90,0x42,0x63,0xe0,0xfa, +0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x7e,0x7a,0x00,0x12,0x00,0x8e,0x60,0x0c, +0x7b,0x7e,0x7a,0x00,0x90,0x42,0x63,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x63,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x00,0xc4,0x60, +0x0c,0x7b,0x00,0x7a,0x00,0x90,0x42,0x63,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x01,0x12, +0x05,0xc1,0x90,0x42,0x63,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc1,0x12,0x03,0x61, +0x06,0x00,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x03,0x12,0x39,0xbc,0x02,0x05, +0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x7b,0x4a,0x7a,0x88,0x8b,0x05, +0x8a,0x04,0x7b,0xe0,0x7a,0x45,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55, +0x06,0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x12,0x05, +0xf2,0x12,0x03,0x38,0x03,0x00,0x7a,0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0, +0xfb,0x8b,0x05,0x7b,0xe0,0x7a,0x45,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x12,0x03, +0x55,0x05,0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x12, +0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x0c,0x7a,0x00,0x12,0x03,0xc7, +0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x45,0xdc,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x42, +0x65,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x65,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05, +0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x3b,0x60,0x3e,0x90,0x42,0x65,0xe0,0xfa, +0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x8b,0x05,0x12,0x03,0x55,0x04,0x00,0x12, +0x01,0x28,0x60,0x0e,0x90,0x42,0x65,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12, +0x2d,0x5b,0x90,0x42,0x65,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x3e,0x08,0x00,0x90, +0x42,0x65,0xea,0xf0,0xeb,0xa3,0xf0,0x80,0xad,0x02,0x05,0x9c,0x74,0x02,0x78,0x00, +0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x61,0x04,0x00,0x8a,0x83,0x8b,0x82,0xe0,0xfb, +0x90,0x00,0x01,0x12,0x39,0xf6,0x7b,0x80,0x8b,0x05,0x12,0x03,0x61,0x04,0x00,0x12, +0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x02,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4, +0x12,0x03,0x0a,0x12,0x03,0x61,0x04,0x00,0x12,0x05,0xcf,0x7b,0xdc,0x7a,0x45,0x90, +0x00,0x04,0x12,0x3a,0x87,0x12,0x03,0x61,0x04,0x00,0x12,0x05,0xcf,0x7b,0xd8,0x7a, +0x45,0x90,0x00,0x04,0x12,0x3a,0x30,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x90,0x45,0xdc,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x67,0xea,0xf0, +0xeb,0xa3,0xf0,0x90,0x42,0x67,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b, +0x00,0x7a,0x00,0x12,0x01,0x3b,0x60,0x4e,0x90,0x42,0x67,0xe0,0xfa,0xa3,0xe0,0xfb, +0x12,0x03,0x3e,0x08,0x00,0x90,0x42,0x69,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x67, +0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x8b,0x05,0x12,0x03,0x55,0x04, +0x00,0x12,0x01,0x28,0x60,0x0e,0x90,0x42,0x67,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x00, +0x02,0x12,0x31,0x2c,0x90,0x42,0x69,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x67,0xea, +0xf0,0xeb,0xa3,0xf0,0x80,0x9d,0x02,0x05,0x9c,0xe4,0x78,0x00,0x79,0x04,0x12,0x05, +0x58,0x7b,0x00,0x90,0x42,0x6b,0xeb,0xf0,0x90,0x42,0x6b,0xe0,0xfb,0x8b,0x05,0x7b, +0x10,0x12,0x00,0xdb,0x60,0x15,0x90,0x42,0x6b,0xe0,0xfb,0x90,0x00,0x01,0x12,0x31, +0x8a,0x7b,0x6b,0x7a,0x42,0x12,0x02,0x42,0x01,0x80,0xdd,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12, +0x03,0x55,0x04,0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7, +0x90,0x42,0x6c,0xea,0xf0,0xeb,0xa3,0xf0,0x7b,0x00,0x8b,0x05,0x90,0x42,0x6c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x02,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x64,0x8b,0x05,0x90,0x42,0x6c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x03,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x40,0x8b,0x05,0x90,0x42,0x6c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x04,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x02,0x8b,0x05,0x90,0x42,0x6c,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x05,0x7a,0x00,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x7a,0x00,0x8b,0x05,0x8a,0x04, +0x90,0x42,0x6c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b,0x05,0x8a,0x04,0x7b, +0x06,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0x12,0x7b,0x00,0x8b,0x05, +0x90,0x42,0x6c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b, +0x08,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x8b,0x05, +0x90,0x42,0x6c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b, +0x09,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x8b,0x05, +0x90,0x42,0x6c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b, +0x0d,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x7b,0x00,0x7a,0x00, +0x8b,0x05,0x8a,0x04,0x90,0x42,0x6c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xd6,0x8b, +0x05,0x8a,0x04,0x7b,0x0a,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xf2,0x12,0x03,0x12, +0x90,0x88,0xae,0xe0,0xfb,0x8b,0x05,0x90,0x42,0x6c,0xe0,0xfa,0xa3,0xe0,0xfb,0x12, +0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x0c,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4, +0x12,0x03,0x0a,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02, +0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02, +0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x02,0x05,0x9c,0x74,0x01,0x78,0x00,0x79,0x04, +0x12,0x05,0x58,0x7b,0x33,0x7a,0x88,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x05,0x00, +0x12,0x05,0xd6,0x8b,0x05,0x7b,0x03,0x7c,0x00,0x12,0x02,0xc4,0x12,0x05,0xf2,0x7a, +0x00,0x12,0x03,0xc7,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x42,0x70,0xeb,0xf0,0x90, +0x42,0x70,0xe0,0xfb,0x8b,0x05,0x7b,0xe0,0x7a,0x45,0x12,0x05,0xc8,0x8b,0x05,0x8a, +0x04,0x12,0x03,0x55,0x05,0x00,0x7a,0x00,0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12, +0x03,0xc7,0x12,0x05,0xe4,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b,0x09,0x7a,0x00, +0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x45,0xdc,0xe0,0xfa,0xa3,0xe0, +0xfb,0x90,0x42,0x6e,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x6e,0xe0,0xfa,0xa3,0xe0, +0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x3b,0x60,0x4c,0x90,0x42, +0x6e,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x8b,0x05,0x12,0x03,0x55, +0x04,0x00,0x12,0x01,0x28,0x60,0x1c,0x90,0x42,0x70,0xe0,0xfb,0x12,0x05,0xc1,0x90, +0x42,0x6e,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x90,0x00,0x02, +0x12,0x0a,0xaa,0x90,0x42,0x6e,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x3e,0x08,0x00, +0x90,0x42,0x6e,0xea,0xf0,0xeb,0xa3,0xf0,0x80,0x9f,0x02,0x05,0x9c,0x74,0x01,0x78, +0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x05,0x00,0x7a,0x00,0x12,0x04,0x68, +0x00,0x07,0x00,0x5b,0x36,0x9b,0x35,0xb0,0x36,0x9b,0x36,0x9b,0x36,0x33,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x61,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b, +0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x9b,0x36,0x86, +0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x78, +0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x8b,0x05,0x8a,0x04,0x7b,0x03,0x7a, +0x00,0x12,0x03,0xc7,0x90,0x42,0x71,0xea,0xf0,0xeb,0xa3,0xf0,0x12,0x03,0x61,0x06, +0x00,0x8b,0x05,0x8a,0x04,0x7b,0x07,0x12,0x02,0xc4,0x8b,0x05,0x8a,0x04,0x7b,0x7c, +0x7a,0x00,0x12,0x02,0xfa,0x90,0x42,0x73,0xeb,0xf0,0x90,0x42,0x71,0xe0,0xfa,0xa3, +0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb,0x8b,0x05,0x90,0x42,0x73,0xe0,0xfb,0x12, +0x01,0x37,0x60,0x1d,0x90,0x42,0x73,0xe0,0xfb,0x8b,0x05,0x90,0x42,0x71,0xe0,0xfa, +0xa3,0xe0,0xfb,0x12,0x03,0x0a,0x12,0x03,0x55,0x04,0x00,0x90,0x00,0x01,0x12,0x30, +0x51,0x80,0x68,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x09,0x12,0x01,0x28,0x60, +0x02,0x80,0x58,0x12,0x03,0x61,0x06,0x00,0x8b,0x05,0x8a,0x04,0x7b,0x07,0x12,0x02, +0xc4,0x12,0x05,0xc1,0x12,0x03,0x55,0x05,0x00,0x90,0x00,0x02,0x12,0x34,0x0a,0x80, +0x3a,0x12,0x03,0x55,0x04,0x00,0x8b,0x05,0x7b,0x09,0x12,0x01,0x28,0x60,0x02,0x80, +0x2a,0x12,0x03,0x61,0x06,0x00,0x12,0x05,0xc1,0x12,0x03,0x55,0x05,0x00,0x90,0x00, +0x02,0x12,0x37,0xa0,0x80,0x15,0x12,0x03,0x61,0x06,0x00,0x12,0x05,0xc1,0x12,0x03, +0x55,0x05,0x00,0x90,0x00,0x02,0x12,0x36,0x9e,0x80,0x00,0x02,0x05,0x9c,0x74,0x01, +0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x05,0x00,0x8b,0x05,0x7b,0x40, +0x12,0x01,0x0b,0x60,0x09,0x7b,0x01,0x90,0x42,0x79,0xeb,0xf0,0x80,0x07,0x7b,0x00, +0x90,0x42,0x79,0xeb,0xf0,0x90,0x42,0x79,0xe0,0xfb,0x90,0x42,0x76,0xeb,0xf0,0x7b, +0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a,0x00,0x78,0x03, +0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x90,0x42,0x77,0xea,0xf0,0xeb,0xa3,0xf0, +0x90,0x42,0x77,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x0d,0x00,0x8b,0x05,0x7b, +0xfe,0xeb,0x5d,0xfb,0x8b,0x05,0x90,0x42,0x76,0xe0,0xfb,0xeb,0x4d,0xfb,0x8b,0x05, +0x90,0x42,0x77,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a,0x04,0x7b, +0x0d,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x45,0xdc,0xe0, +0xfa,0xa3,0xe0,0xfb,0x90,0x42,0x74,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x74,0xe0, +0xfa,0xa3,0xe0,0xfb,0x8b,0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x3b,0x60, +0x4c,0x90,0x42,0x74,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x8b,0x05, +0x12,0x03,0x55,0x04,0x00,0x12,0x01,0x28,0x60,0x1c,0x90,0x42,0x76,0xe0,0xfb,0x12, +0x05,0xc1,0x90,0x42,0x74,0xe0,0xfa,0xa3,0xe0,0xfb,0x8a,0x83,0x8b,0x82,0xe0,0xfb, +0x90,0x00,0x02,0x12,0x3a,0x0d,0x90,0x42,0x74,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03, +0x3e,0x08,0x00,0x90,0x42,0x74,0xea,0xf0,0xeb,0xa3,0xf0,0x80,0x9f,0x02,0x05,0x9c, +0x74,0x01,0x78,0x00,0x79,0x04,0x12,0x05,0x58,0x12,0x03,0x55,0x05,0x00,0x8b,0x05, +0x7b,0x40,0x12,0x01,0x0b,0x60,0x09,0x7b,0x00,0x90,0x42,0x7f,0xeb,0xf0,0x80,0x07, +0x7b,0x00,0x90,0x42,0x7f,0xeb,0xf0,0x90,0x42,0x7f,0xe0,0xfb,0x90,0x42,0x7a,0xeb, +0xf0,0x7b,0xe0,0x7a,0x45,0x8b,0x05,0x8a,0x04,0x12,0x03,0x55,0x04,0x00,0x7a,0x00, +0x78,0x03,0x12,0x01,0x46,0x00,0x0e,0x12,0x03,0xc7,0x90,0x42,0x7b,0xea,0xf0,0xeb, +0xa3,0xf0,0x90,0x42,0x7b,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x0d,0x00,0x8b, +0x05,0x7b,0xff,0xeb,0x5d,0xfb,0x8b,0x05,0x90,0x42,0x7a,0xe0,0xfb,0xeb,0x4d,0xfb, +0x8b,0x05,0x90,0x42,0x7b,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x05,0xc8,0x8b,0x05,0x8a, +0x04,0x7b,0x0d,0x7a,0x00,0x12,0x03,0xc7,0x12,0x05,0xe4,0x12,0x03,0x0a,0x90,0x42, +0x7a,0xe0,0x60,0x03,0x02,0x38,0xb0,0x90,0x45,0xdc,0xe0,0xfa,0xa3,0xe0,0xfb,0x90, +0x42,0x7d,0xea,0xf0,0xeb,0xa3,0xf0,0x90,0x42,0x7d,0xe0,0xfa,0xa3,0xe0,0xfb,0x8b, +0x05,0x8a,0x04,0x7b,0x00,0x7a,0x00,0x12,0x01,0x3b,0x60,0x54,0x90,0x42,0x7d,0xe0, +0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38,0x01,0x00,0x8b,0x05,0x12,0x03,0x55,0x04,0x00, +0x12,0x01,0x28,0x60,0x24,0x90,0x42,0x7d,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x03,0x38, +0x02,0x00,0x8b,0x05,0x7b,0x81,0x12,0x01,0x28,0x60,0x0e,0x90,0x42,0x7d,0xe0,0xfa, +0xa3,0xe0,0xfb,0x90,0x00,0x02,0x12,0x31,0x2c,0x90,0x42,0x7d,0xe0,0xfa,0xa3,0xe0, +0xfb,0x12,0x03,0x3e,0x08,0x00,0x90,0x42,0x7d,0xea,0xf0,0xeb,0xa3,0xf0,0x80,0x97, +0x02,0x05,0x9c,0x8b,0xf0,0x12,0x05,0xdd,0xa9,0x03,0xa8,0xf0,0x80,0x00,0xc2,0xb4, +0x90,0xff,0xc4,0xe8,0xf0,0xa3,0xe9,0x00,0xf0,0x74,0x82,0x28,0xf5,0x82,0x74,0x42, +0x34,0x00,0xf5,0x83,0xe9,0xf0,0xd2,0xb4,0x22,0xc2,0xb4,0x7c,0x03,0x7d,0xe8,0x90, +0xff,0xc0,0xe0,0x30,0xe1,0x04,0xdd,0xf7,0xdc,0xf5,0xd2,0xb4,0x12,0x05,0xf2,0xeb, +0x24,0x80,0xf5,0xf0,0xa8,0xf0,0x8c,0x83,0x8d,0x82,0xe0,0xa3,0xac,0x83,0xad,0x82, +0x54,0x3f,0xf9,0x12,0x38,0xbe,0xe5,0xf0,0x24,0x18,0xf5,0xf0,0x7a,0x03,0xa8,0xf0, +0x8c,0x83,0x8d,0x82,0xe0,0xa3,0xac,0x83,0xad,0x82,0xf9,0x12,0x38,0xbe,0xe5,0xf0, +0x24,0x18,0xf5,0xf0,0xda,0xe8,0xa8,0xf0,0x8c,0x83,0x8d,0x82,0xe0,0xa3,0xac,0x83, +0xad,0x82,0x54,0x07,0xf9,0x02,0x38,0xbe,0x22,0xc0,0x03,0x12,0x05,0xe4,0x12,0x05, +0xeb,0xd0,0x00,0xa9,0x05,0x80,0x00,0xe8,0x24,0x38,0xfc,0x74,0x82,0x2c,0xf5,0x82, +0x74,0x42,0x34,0x00,0xf5,0x83,0xe0,0x54,0x08,0xfd,0xe9,0x54,0x0f,0xc4,0x4d,0xfd, +0xeb,0x33,0xea,0x33,0x54,0x07,0x4d,0xf9,0xa8,0x04,0x12,0x38,0xbe,0xec,0xc3,0x94, +0x18,0xfc,0x24,0x82,0xf5,0x82,0x74,0x42,0x34,0x00,0xf5,0x83,0xe0,0x54,0x01,0xfd, +0xeb,0xc3,0x33,0x4d,0xa8,0x04,0xf9,0x02,0x38,0xbe,0x22,0x12,0x05,0xe4,0xc0,0x05, +0x12,0x05,0xe4,0xaa,0x05,0xd0,0x01,0xa8,0x03,0x80,0x00,0xe8,0x24,0x20,0xf8,0x74, +0x82,0x28,0xf5,0x82,0x74,0x42,0x34,0x00,0xf5,0x83,0xe0,0x54,0xfe,0x49,0xf9,0x12, +0x38,0xbe,0xe8,0x24,0xe8,0xf8,0xa9,0x02,0x02,0x38,0xbe,0x22,0x12,0x05,0xe4,0xc0, +0x05,0x12,0x05,0xe4,0xaa,0x05,0xd0,0x01,0xa8,0x03,0x80,0x00,0xe8,0x24,0x50,0xf8, +0xea,0x13,0xe9,0x33,0xf9,0x02,0x38,0xbe,0x22,0x12,0x05,0xe4,0xeb,0x24,0x68,0xf8, +0x74,0x82,0x28,0xf5,0x82,0x74,0x42,0x34,0x00,0xf5,0x83,0xe0,0x54,0x30,0x44,0x80, +0x4d,0xf9,0x02,0x38,0xbe,0x22,0xeb,0x24,0x68,0xf8,0x74,0x82,0x28,0xf5,0x82,0x74, +0x42,0x34,0x00,0xf5,0x83,0xe0,0x54,0x7f,0xf9,0x02,0x38,0xbe,0x22,0x12,0x05,0xe4, +0x80,0x00,0xeb,0x24,0x38,0xf8,0x74,0x82,0x28,0xf5,0x82,0x74,0x42,0x34,0x00,0xf5, +0x83,0xe0,0xbd,0x00,0x05,0x54,0xf7,0x02,0x3a,0x2c,0x44,0x08,0xf9,0x02,0x38,0xbe, +0x12,0x05,0xf2,0xac,0x05,0x02,0x3a,0x38,0x75,0xa0,0x00,0xeb,0x24,0x01,0xf5,0x82, +0xea,0x34,0x00,0xf5,0x83,0xe0,0x70,0x1f,0xec,0xf0,0xe5,0x82,0x24,0x02,0xf5,0x82, +0xe5,0x83,0x34,0x00,0xf5,0x83,0xec,0xf0,0xec,0x24,0x07,0xf8,0xe4,0xf2,0xec,0x24, +0x09,0xf8,0xe4,0xf2,0x02,0x3a,0x86,0xeb,0x24,0x03,0xf5,0x82,0xea,0x34,0x00,0xf5, +0x83,0xe0,0xf9,0x24,0x09,0xf8,0xec,0xf2,0xec,0x24,0x09,0xf8,0xe4,0xf2,0xec,0x24, +0x07,0xf8,0xe9,0xf2,0xec,0xf0,0x22,0x12,0x05,0xf2,0xac,0x05,0x02,0x3a,0x8f,0x75, +0xa0,0x00,0xec,0x24,0x09,0xf8,0xe2,0x70,0x13,0xeb,0x24,0x03,0xf5,0x82,0xea,0x34, +0x00,0xf5,0x83,0xec,0x24,0x07,0xf8,0xe2,0xf0,0x02,0x3a,0xbe,0xec,0x24,0x07,0xf8, +0xe2,0xf5,0xf0,0xec,0x24,0x09,0xf8,0xe2,0x24,0x07,0xf8,0xe5,0xf0,0xf2,0xec,0x24, +0x07,0xf8,0xe2,0x70,0x13,0xeb,0x24,0x01,0xf5,0x82,0xea,0x34,0x00,0xf5,0x83,0xec, +0x24,0x09,0xf8,0xe2,0xf0,0x02,0x3a,0xea,0xec,0x24,0x09,0xf8,0xe2,0xf5,0xf0,0xec, +0x24,0x07,0xf8,0xe2,0x24,0x09,0xf8,0xe5,0xf0,0xf2,0x22,0x90,0x45,0xd9,0xe0,0x60, +0x16,0xf5,0x25,0x7a,0x45,0x7b,0xd8,0xfc,0x12,0x3a,0x8f,0x7a,0x45,0x7b,0xdc,0xac, +0x25,0x12,0x3a,0x38,0x02,0x3b,0x26,0x90,0x45,0xdd,0xe0,0x60,0x16,0xf5,0x25,0x7a, +0x45,0x7b,0xdc,0xfc,0x12,0x3a,0x8f,0x7a,0x45,0x7b,0xdc,0xac,0x25,0x12,0x3a,0x38, +0x02,0x3b,0x26,0x75,0x25,0x00,0x7a,0x00,0xab,0x25,0x22,0x75,0xa0,0x00,0xeb,0x24, +0x02,0xf8,0xe2,0xc3,0x13,0xfc,0xe4,0x92,0xe7,0xfd,0xeb,0x24,0x05,0xf8,0xe2,0x24, +0x05,0x92,0xd5,0xf5,0x82,0xeb,0x24,0x04,0xf8,0xe2,0xa2,0xd5,0x34,0x00,0xf5,0x83, +0xe0,0x30,0xe7,0x04,0x7c,0x1e,0x7d,0x00,0xe5,0x82,0x24,0x03,0xf5,0x82,0xe5,0x83, +0x34,0x00,0xf5,0x83,0xe0,0xf9,0xa3,0xe0,0x2d,0xfd,0xe9,0x3c,0xfc,0xeb,0x24,0x01, +0xf8,0xe2,0x75,0xf0,0x0e,0xa4,0x24,0xea,0xf5,0x82,0xe5,0xf0,0x34,0x45,0xf5,0x83, +0xe0,0xf9,0xa3,0xe0,0x2d,0xfd,0xe9,0x3c,0xfc,0xed,0xc3,0x94,0x00,0xec,0x94,0x60, +0x40,0x04,0x7c,0x5f,0x7d,0xff,0xed,0x33,0xec,0x33,0x75,0xf0,0x0c,0x84,0x94,0x08, +0xfa,0xed,0xc3,0x33,0x24,0xca,0xf5,0x82,0xe5,0xf0,0x34,0x88,0xf5,0x83,0xe0,0xfc, +0xa3,0xe0,0xfd,0xeb,0x24,0x00,0xf8,0xe2,0xf8,0xa9,0x02,0xaa,0x04,0xab,0x05,0x12, +0x39,0x47,0x22,0x12,0x05,0xe4,0x80,0x00,0xbb,0x09,0x01,0x22,0xeb,0x75,0xf0,0x0e, +0xa4,0x24,0xe4,0xf5,0x82,0xe5,0xf0,0x34,0x45,0xf5,0x83,0xed,0xf0,0xa9,0x03,0xaa, +0x83,0xab,0x82,0x80,0x12,0x8b,0x82,0x8a,0x83,0xe0,0xf9,0x80,0x00,0x74,0x04,0x2b, +0xf5,0x82,0xea,0x34,0x00,0xf5,0x83,0xe0,0x24,0xc0,0xc3,0x33,0x92,0xd5,0x50,0x02, +0xf4,0x04,0xfb,0x89,0x24,0xe5,0x82,0x24,0x01,0xf5,0x82,0xe5,0x83,0x34,0x00,0xf5, +0x83,0xe0,0x8b,0xf0,0xa4,0x30,0xd5,0x0a,0xf4,0x24,0x01,0xc5,0xf0,0xf4,0x34,0x00, +0xc5,0xf0,0xaa,0xf0,0xfb,0x74,0x01,0x25,0x82,0xf5,0x82,0xe5,0x83,0x34,0x00,0xf5, +0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0x74,0x01,0x25,0x82,0xf5,0x82,0xe5,0x83,0x34,0x00, +0xf5,0x83,0xe0,0xa2,0xe7,0x92,0xd5,0x2d,0xfd,0xec,0x75,0xf0,0x00,0x30,0xd5,0x03, +0x75,0xf0,0xff,0x35,0xf0,0xfc,0xed,0x2b,0xfd,0xec,0x3a,0xfc,0xe5,0x82,0x24,0x02, +0xf5,0x82,0xe5,0x83,0x34,0x00,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x45,0xdd, +0xe0,0xf5,0x23,0x75,0xa0,0x00,0x60,0x16,0x24,0x01,0xf8,0xe2,0xb5,0x24,0x05,0xab, +0x23,0x12,0x3b,0x2b,0xe5,0x23,0x24,0x09,0xf8,0xe2,0xf5,0x23,0x80,0xe5,0x22,0x75, +0xa0,0x00,0xeb,0x24,0x04,0xf8,0xe2,0xf5,0xf0,0xe8,0x04,0xf8,0xe2,0x24,0x0a,0xf5, +0x82,0xe5,0xf0,0x34,0x00,0xf5,0x83,0xc0,0x83,0xc0,0x82,0xe0,0xc3,0x13,0xfa,0x79, +0x00,0xeb,0x24,0x01,0xf8,0xe2,0xfc,0x75,0xf0,0x0e,0xa4,0x24,0xec,0xf5,0x82,0xe5, +0xf0,0x34,0x45,0xf5,0x83,0xe0,0x2a,0xfa,0xe9,0x34,0x00,0xf9,0xd0,0xe0,0x24,0xf8, +0xf5,0x82,0xd0,0xe0,0x34,0xff,0xf5,0x83,0xe0,0xc4,0x54,0x0f,0xc3,0x33,0x24,0xb3, +0xf5,0x82,0x74,0x80,0x34,0x00,0xf5,0x83,0xe0,0xf5,0xf0,0xa3,0xe0,0xf5,0x82,0x85, +0xf0,0x83,0xeb,0x24,0x03,0xf8,0xe2,0x25,0x82,0xf5,0x82,0xe5,0x83,0x34,0x00,0xf5, +0x83,0xe0,0x2a,0xfa,0xe9,0x34,0x00,0xf9,0xbc,0x09,0x0a,0x90,0x46,0xc0,0xe0,0x2a, +0xfa,0xe9,0x34,0x00,0xf9,0xc3,0xea,0x94,0x7e,0xe9,0x94,0x00,0x40,0x02,0x7a,0x7e, +0xeb,0x24,0x00,0xf8,0xe2,0xf8,0xa9,0x02,0x7a,0x01,0x12,0x39,0xcc,0x22,0x74,0xaa, +0x90,0xff,0xe1,0xf0,0x12,0x40,0x19,0x12,0x4c,0x48,0x22,0x12,0x40,0x3d,0xc3,0x33, +0x40,0x05,0x90,0x3d,0x59,0x80,0x03,0x90,0x3e,0x59,0xf5,0xf0,0x93,0xc5,0xf0,0xa3, +0x93,0x85,0xf0,0x83,0xf5,0x82,0xe4,0x73,0x22,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0x5f,0x40,0x16,0x40,0x16,0x40, +0x16,0x3f,0x67,0x40,0x16,0x3f,0x6d,0x3f,0x73,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0x79,0x40,0x16,0x40,0x16,0x40, +0x16,0x3f,0x81,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0x87,0x3f,0x8f,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0x92,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0x98,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x3f,0x9e,0x3f,0xa4,0x3f,0xaa,0x3f,0xb0,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0x59,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0xb6,0x3f,0xc1,0x40,0x16,0x3f, +0xc4,0x3f,0xc7,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0xcc,0x3f,0xd6,0x3f,0xe3,0x40, +0x16,0x3f,0xf5,0x40,0x16,0x40,0x16,0x40,0x16,0x3f,0xfd,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x05,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x0e,0x40,0x16,0x40,0x16,0x40, +0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x40,0x16,0x12,0x40,0xb7,0x02,0x3d,0x58,0x12, +0x40,0x2a,0xf5,0x90,0x02,0x3d,0x58,0x12,0x40,0xa7,0x02,0x3d,0x58,0x12,0x40,0x9f, +0x02,0x3d,0x58,0x12,0x40,0x9f,0x02,0x3d,0x58,0x74,0x00,0x12,0x40,0x42,0x02,0x3d, +0x58,0x12,0x40,0xaf,0x02,0x3d,0x58,0x74,0xf8,0x12,0x40,0x42,0x02,0x3d,0x58,0x02, +0x3d,0x58,0x12,0x40,0x2a,0x02,0x3d,0x58,0x12,0x40,0xbf,0x02,0x3d,0x58,0x12,0x40, +0x87,0x02,0x3d,0x58,0x12,0x40,0x93,0x02,0x3d,0x58,0x12,0x40,0x9f,0x02,0x3d,0x58, +0x12,0x40,0x9f,0x02,0x3d,0x58,0xc2,0xa9,0x74,0x00,0x90,0xff,0xe4,0xf0,0x02,0x3d, +0x58,0x02,0x3d,0x58,0x02,0x3d,0x58,0xd2,0xa9,0x02,0x3d,0x58,0x12,0x40,0x2a,0xf4, +0x12,0x40,0x42,0x02,0x3d,0x58,0x74,0x01,0x12,0x40,0x42,0x74,0x05,0x12,0x40,0x42, +0x02,0x3d,0x58,0x12,0x40,0x2a,0x12,0x4c,0x4e,0x12,0x40,0x42,0x74,0x01,0x90,0xff, +0xe4,0xf0,0x02,0x3d,0x58,0x12,0x40,0x2a,0xf5,0x26,0x02,0x3d,0x58,0xe5,0x26,0x12, +0x40,0x42,0x02,0x3d,0x58,0x74,0x01,0x90,0xff,0xe5,0xf0,0x02,0x3d,0x58,0x74,0x00, +0x12,0x40,0x42,0x02,0x3d,0x58,0x02,0x3d,0x58,0xe5,0x89,0x54,0xf0,0x44,0x02,0xf5, +0x89,0x75,0x8c,0x83,0x75,0x8a,0x83,0xd2,0x8c,0x22,0x90,0xff,0xe2,0x75,0x27,0x00, +0x75,0x28,0x00,0xe0,0x20,0xe0,0x06,0xd5,0x27,0xf9,0xd5,0x28,0xf6,0x90,0xff,0xe0, +0xe0,0x22,0xc0,0xe0,0x90,0xff,0xe3,0x75,0x27,0x00,0x75,0x28,0x00,0xe0,0x30,0xe0, +0x06,0xd5,0x27,0xf9,0xd5,0x28,0xf6,0xd0,0xe0,0x90,0xff,0xe1,0xf0,0x22,0x12,0x40, +0x2a,0xf5,0x2a,0x12,0x40,0x2a,0xf5,0x29,0x30,0x08,0x14,0xc2,0x09,0xe5,0x2a,0x20, +0xe0,0x02,0xd2,0x09,0xe5,0x29,0xc3,0x13,0xf5,0x29,0xe5,0x2a,0x13,0xf5,0x2a,0xe4, +0x90,0xff,0xe4,0xf0,0xd2,0xa9,0x22,0xc2,0x00,0xc2,0x07,0xd2,0x01,0xd2,0x05,0xc2, +0x06,0x80,0xcb,0xc2,0x00,0xc2,0x07,0xd2,0x01,0xd2,0x05,0xd2,0x06,0x80,0xbf,0xc2, +0x00,0xc2,0x07,0xd2,0x01,0x80,0xb7,0xc2,0x00,0xc2,0x07,0xc2,0x01,0x80,0xaf,0xd2, +0x00,0xc2,0x07,0xc2,0x01,0x80,0xa7,0xc2,0x00,0xc2,0x01,0xd2,0x07,0x80,0x9f,0x12, +0x40,0x2a,0xc2,0x08,0xb4,0xce,0x00,0x40,0x04,0xc3,0x33,0xd2,0x08,0xc3,0x94,0x80, +0x40,0x06,0xc2,0x03,0x33,0x02,0x40,0xdc,0x24,0x80,0xd2,0x03,0xf5,0x8c,0xf5,0x8a, +0x22,0x30,0x03,0x07,0xb2,0x04,0x20,0x04,0x02,0x80,0x76,0x30,0x00,0x03,0x02,0x42, +0x4b,0x20,0x01,0x6e,0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xc0,0xe0,0x20,0x07,0x43,0x30, +0x08,0x21,0x30,0x09,0x05,0xc2,0x09,0x02,0x41,0x23,0x74,0x01,0x90,0xff,0xe4,0xf0, +0x90,0xff,0xd2,0x75,0x27,0x00,0x75,0x28,0x00,0xe0,0x30,0xe4,0x06,0xd5,0x27,0xf9, +0xd5,0x28,0xf6,0x74,0x01,0x90,0xff,0xe4,0xf0,0x90,0xff,0xd2,0x75,0x27,0x00,0x75, +0x28,0x00,0xe0,0x30,0xe4,0x06,0xd5,0x27,0xf9,0xd5,0x28,0xf6,0x90,0xff,0xe4,0xe0, +0xf5,0x90,0xe5,0x2a,0xc3,0x94,0x01,0xf5,0x2a,0xe5,0x29,0x94,0x00,0xf5,0x29,0x50, +0x08,0xc2,0xa9,0x74,0x01,0x90,0xff,0xe5,0xf0,0xd0,0xe0,0xd0,0x82,0xd0,0x83,0xd0, +0xd0,0x32,0xc0,0xd0,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x30,0x05,0x36,0x74,0x01,0x90, +0xff,0xe4,0xf0,0x90,0xff,0xd2,0x75,0x27,0x00,0x75,0x28,0x00,0xe0,0x30,0xe4,0x06, +0xd5,0x27,0xf9,0xd5,0x28,0xf6,0x90,0xff,0xe4,0xe0,0xf5,0x2b,0xe5,0x2a,0xc3,0x94, +0x01,0xf5,0x2a,0xe5,0x29,0x94,0x00,0xf5,0x29,0x50,0x08,0xc2,0xa9,0x74,0x01,0x90, +0xff,0xe5,0xf0,0x30,0x06,0x0e,0x85,0x2b,0x2c,0x75,0x2d,0x01,0x85,0x2b,0x90,0xc2, +0x06,0x02,0x42,0x3a,0xb2,0x05,0xe5,0x2b,0xc4,0xf5,0x2b,0x85,0x2d,0x2f,0xe5,0x2d, +0xc3,0x33,0xf5,0x2e,0xe5,0x2b,0x30,0xe0,0x06,0xe5,0x2f,0x25,0x2e,0xf5,0x2f,0xe5, +0x2e,0xc3,0x33,0xf5,0x2e,0xe5,0x2b,0x30,0xe1,0x06,0xe5,0x2f,0x25,0x2e,0xf5,0x2f, +0xe5,0x2e,0xc3,0x33,0xf5,0x2e,0xe5,0x2b,0x30,0xe2,0x06,0xe5,0x2f,0x25,0x2e,0xf5, +0x2f,0xe5,0x2b,0x30,0xe3,0x11,0xe5,0x2f,0xc3,0x13,0xc3,0xc5,0x2c,0x95,0x2c,0x50, +0x02,0x74,0x00,0xf5,0x2c,0x80,0x0c,0xe5,0x2f,0xc3,0x13,0x25,0x2c,0x50,0x02,0x74, +0xff,0xf5,0x2c,0xe5,0x2b,0x54,0x07,0x24,0x29,0x83,0x30,0xe0,0x06,0xe5,0x2d,0xc3, +0x13,0x80,0x07,0x30,0xe1,0x11,0xe5,0x2d,0xc3,0x33,0x70,0x02,0x74,0x01,0xb4,0x09, +0x00,0x40,0x02,0x74,0x08,0xf5,0x2d,0x85,0x2c,0x90,0xd0,0xe0,0xd0,0x83,0xd0,0x82, +0xd0,0xd0,0x32,0x01,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0xc0,0xd0,0xc0,0x83,0xc0, +0x82,0xc0,0xe0,0x90,0xff,0xe1,0xe4,0xf0,0x74,0x01,0x90,0xff,0xe4,0xf0,0xe5,0x2a, +0xc3,0x94,0x01,0xf5,0x2a,0xe5,0x29,0x94,0x00,0xf5,0x29,0x50,0x08,0xc2,0xa9,0x74, +0x01,0x90,0xff,0xe5,0xf0,0xd0,0xe0,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0x32,0x90,0x01, +0x00,0xe4,0xf0,0xa3,0xf0,0xe4,0xf5,0x30,0xf5,0x31,0xf5,0x32,0xf5,0x33,0xe4,0xf5, +0x34,0xf5,0x35,0xf5,0x36,0xf5,0x37,0xe4,0xf5,0x3c,0xf5,0x3d,0xf5,0x3e,0xf5,0x3f, +0xe4,0xf5,0x38,0xf5,0x39,0xf5,0x3a,0xf5,0x3b,0xc2,0x14,0xc2,0x15,0xc2,0x16,0x90, +0x42,0x08,0xe0,0xb4,0x41,0x07,0xa3,0xe0,0xb4,0x50,0x02,0x80,0x1d,0x90,0x42,0x08, +0x74,0x41,0xf0,0xa3,0x74,0x50,0xf0,0x90,0x42,0x01,0x74,0x0a,0xf0,0xc2,0x10,0xd2, +0x11,0xc2,0x12,0xd2,0x13,0x90,0x42,0x00,0xe4,0xf0,0xe4,0x90,0x42,0x02,0xf0,0x90, +0x42,0x03,0xf0,0x90,0x00,0x00,0x12,0x0e,0x40,0x90,0xff,0xd0,0xe0,0x90,0xff,0xd1, +0xe0,0x90,0xff,0xe0,0xe0,0x90,0xff,0xe4,0xe0,0xd2,0xaa,0xd2,0xaf,0x30,0x16,0x18, +0xc2,0x16,0x90,0x00,0x00,0x12,0x32,0x09,0xc2,0xaf,0x85,0x3a,0x38,0x85,0x3b,0x39, +0x85,0x32,0x30,0x85,0x33,0x31,0xd2,0xaf,0x30,0x11,0x36,0x90,0xff,0xd2,0xe0,0x30, +0xe6,0x2f,0xe5,0x3d,0xb5,0x3f,0x08,0xe5,0x3c,0xb5,0x3e,0x03,0xc3,0x80,0x1c,0xe5, +0x3c,0x24,0x00,0xf5,0x82,0x74,0x32,0x35,0x3d,0xf5,0x83,0xe5,0x3c,0x24,0x01,0xf5, +0x3c,0xe5,0x3d,0x34,0x00,0x54,0x0f,0xf5,0x3d,0xe0,0xd3,0x50,0x04,0x90,0xff,0xd0, +0xf0,0xe5,0x39,0xb5,0x3b,0x08,0xe5,0x38,0xb5,0x3a,0x03,0xc3,0x80,0x1c,0xe5,0x38, +0x24,0x00,0xf5,0x82,0x74,0x22,0x35,0x39,0xf5,0x83,0xe5,0x38,0x24,0x01,0xf5,0x38, +0xe5,0x39,0x34,0x00,0x54,0x0f,0xf5,0x39,0xe0,0xd3,0x50,0x14,0x30,0x13,0x0b,0xc0, +0xe0,0xfb,0x90,0x00,0x01,0x12,0x19,0x59,0xd0,0xe0,0x30,0x12,0x03,0x12,0x44,0x00, +0xe5,0x31,0xb5,0x33,0x08,0xe5,0x30,0xb5,0x32,0x03,0xc3,0x80,0x1c,0xe5,0x30,0x24, +0x00,0xf5,0x82,0x74,0x02,0x35,0x31,0xf5,0x83,0xe5,0x30,0x24,0x01,0xf5,0x30,0xe5, +0x31,0x34,0x00,0x54,0x0f,0xf5,0x31,0xe0,0xd3,0x50,0x42,0x30,0x10,0x0b,0xc0,0xe0, +0xfb,0x90,0x00,0x01,0x12,0x19,0x59,0xd0,0xe0,0x30,0x11,0x31,0xf5,0xf0,0xe5,0x3e, +0x24,0x01,0xf5,0x42,0xe5,0x3f,0x34,0x00,0x54,0x0f,0xf5,0x43,0xb5,0x3d,0x08,0xe5, +0x42,0xb5,0x3c,0x03,0xd3,0x80,0x16,0x74,0x00,0x25,0x3e,0xf5,0x82,0x74,0x32,0x35, +0x3f,0xf5,0x83,0xe5,0xf0,0xf0,0x85,0x42,0x3e,0x85,0x43,0x3f,0xc3,0x02,0x42,0xfd, +0xc2,0xaf,0x20,0x14,0x06,0xf5,0x99,0xd2,0x14,0x80,0x31,0xf5,0xf0,0xe5,0x36,0x24, +0x01,0xf5,0x42,0xe5,0x37,0x34,0x00,0x54,0x0f,0xf5,0x43,0xb5,0x35,0x08,0xe5,0x42, +0xb5,0x34,0x03,0xd3,0x80,0x16,0x74,0x00,0x25,0x36,0xf5,0x82,0x74,0x12,0x35,0x37, +0xf5,0x83,0xe5,0xf0,0xf0,0x85,0x42,0x36,0x85,0x43,0x37,0xc3,0xd2,0xaf,0x22,0xc0, +0xd0,0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0x90,0xff,0xd2,0xe0,0x20,0xe4,0x12, +0x90,0xff,0xe2,0xe0,0x20,0xe0,0x06,0x90,0xff,0xe4,0xe0,0x80,0x63,0x12,0x3d,0x3b, +0x80,0x5e,0x30,0xe7,0x4f,0x90,0xff,0xd0,0xe0,0xf5,0xf0,0xe5,0x3a,0x24,0x01,0xf5, +0x40,0xe5,0x3b,0x34,0x00,0x54,0x0f,0xf5,0x41,0xb5,0x39,0x08,0xe5,0x40,0xb5,0x38, +0x03,0xd3,0x80,0x16,0x74,0x00,0x25,0x3a,0xf5,0x82,0x74,0x22,0x35,0x3b,0xf5,0x83, +0xe5,0xf0,0xf0,0x85,0x40,0x3a,0x85,0x41,0x3b,0xc3,0x50,0x24,0xd2,0x16,0x85,0x3a, +0x38,0x85,0x3b,0x39,0x90,0x42,0x0b,0xe0,0x24,0x01,0xf0,0x90,0x42,0x0a,0xe0,0x34, +0x00,0xf0,0x80,0x0c,0x30,0xe5,0x09,0x90,0xff,0xd1,0xe0,0xf5,0xf0,0x12,0x45,0x50, +0xd0,0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0xd0,0xd0,0x32,0xc0,0xd0,0xc0,0xe0,0xc0, +0xf0,0xc0,0x83,0xc0,0x82,0x30,0x99,0x35,0xc2,0x99,0xe5,0x35,0xb5,0x37,0x08,0xe5, +0x34,0xb5,0x36,0x03,0xc3,0x80,0x1c,0xe5,0x34,0x24,0x00,0xf5,0x82,0x74,0x12,0x35, +0x35,0xf5,0x83,0xe5,0x34,0x24,0x01,0xf5,0x34,0xe5,0x35,0x34,0x00,0x54,0x0f,0xf5, +0x35,0xe0,0xd3,0x50,0x06,0xf5,0x99,0xd2,0x14,0x80,0x02,0xc2,0x14,0x30,0x98,0x35, +0xe5,0x99,0xc2,0x98,0xf5,0xf0,0xe5,0x32,0x24,0x01,0xf5,0x40,0xe5,0x33,0x34,0x00, +0x54,0x0f,0xf5,0x41,0xb5,0x31,0x08,0xe5,0x40,0xb5,0x30,0x03,0xd3,0x80,0x16,0x74, +0x00,0x25,0x32,0xf5,0x82,0x74,0x02,0x35,0x33,0xf5,0x83,0xe5,0xf0,0xf0,0x85,0x40, +0x32,0x85,0x41,0x33,0xc3,0xd0,0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0xd0,0xd0,0x32, +0x20,0x15,0x06,0x90,0xff,0xd0,0x74,0xfe,0xf0,0x90,0x42,0x03,0xe0,0xb4,0x00,0x4e, +0x90,0x42,0x02,0xe0,0x70,0x1b,0xe5,0xf0,0xb4,0x3f,0x05,0xd2,0x15,0x02,0x47,0x47, +0xb4,0xff,0x05,0xc2,0x15,0x02,0x47,0x47,0xb4,0xb9,0x05,0xd2,0x16,0x02,0x47,0x47, +0xe0,0x24,0xca,0xf5,0x82,0x74,0x94,0x34,0x00,0xf5,0x83,0xe0,0xc3,0x95,0xf0,0x60, +0x08,0x90,0x42,0x02,0xe4,0xf0,0x02,0x47,0x47,0x90,0x42,0x02,0xe0,0x04,0xf0,0x24, +0xf8,0x70,0x08,0xe4,0xf0,0x90,0x42,0x03,0x74,0x01,0xf0,0x02,0x47,0x47,0xb4,0x01, +0x74,0x90,0x42,0x03,0xe5,0xf0,0xb4,0x00,0x06,0x74,0x02,0xf0,0x02,0x47,0x47,0xb4, +0x01,0x06,0x74,0x03,0xf0,0x02,0x47,0x47,0xb4,0x02,0x06,0x74,0x04,0xf0,0x02,0x47, +0x47,0xb4,0x03,0x1d,0x90,0x42,0x0a,0x74,0x00,0xf0,0xa3,0xf0,0x90,0x42,0x04,0x74, +0x42,0xf0,0xa3,0x74,0x01,0xf0,0x90,0x42,0x06,0xe4,0xf0,0xa3,0x04,0xf0,0x02,0x46, +0xb7,0xb4,0x04,0x15,0x90,0x42,0x04,0x74,0x42,0xf0,0xa3,0x74,0x00,0xf0,0x90,0x42, +0x06,0xe4,0xf0,0xa3,0x04,0xf0,0x02,0x46,0xb7,0xb4,0x05,0x16,0x90,0x42,0x04,0x74, +0x94,0xf0,0xa3,0x74,0xca,0xf0,0x90,0x42,0x06,0xe4,0xf0,0xa3,0x74,0x0a,0xf0,0x02, +0x46,0xb7,0x02,0x47,0x42,0xb4,0x02,0x27,0xc2,0x10,0xc2,0x11,0xc2,0x12,0xc2,0x13, +0xe5,0xf0,0x54,0x0f,0x90,0x42,0x01,0xf0,0x30,0xe0,0x02,0xd2,0x10,0x30,0xe1,0x02, +0xd2,0x11,0x30,0xe2,0x02,0xd2,0x12,0x30,0xe3,0x02,0xd2,0x13,0x02,0x47,0x42,0xb4, +0x03,0x10,0xe5,0xf0,0x70,0x03,0xe4,0x80,0x02,0x74,0x01,0x90,0x42,0x00,0xf0,0x02, +0x47,0x42,0xb4,0x04,0x0f,0xe5,0xf0,0x90,0x42,0x04,0xf0,0x90,0x42,0x03,0x74,0x05, +0xf0,0x02,0x47,0x47,0xb4,0x05,0x0f,0xe5,0xf0,0x90,0x42,0x05,0xf0,0x90,0x42,0x03, +0x74,0x06,0xf0,0x02,0x47,0x47,0xb4,0x06,0x0f,0xe5,0xf0,0x90,0x42,0x06,0xf0,0x90, +0x42,0x03,0x74,0x07,0xf0,0x02,0x47,0x47,0xb4,0x07,0x0f,0xe5,0xf0,0x90,0x42,0x07, +0xf0,0x90,0x42,0x03,0x74,0x08,0xf0,0x02,0x47,0x47,0xb4,0x08,0x07,0xe5,0xf0,0x60, +0x06,0x02,0x47,0x09,0x02,0x47,0x42,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0x90, +0x42,0x06,0xe0,0x04,0xf8,0xa3,0xe0,0x04,0xf9,0x90,0x42,0x04,0xe0,0xc0,0xe0,0xa3, +0xe0,0xc0,0xe0,0x02,0x46,0xf6,0x7a,0xc4,0x7b,0x51,0x90,0xff,0xd2,0xe0,0x20,0xe6, +0x07,0xdb,0xfa,0xda,0xf8,0x02,0x46,0xfa,0xd0,0x82,0xd0,0x83,0xe0,0xa3,0xc0,0x83, +0xc0,0x82,0x90,0xff,0xd0,0xf0,0xd9,0xde,0xd8,0xdc,0xd0,0xe0,0xd0,0xe0,0xd0,0x03, +0xd0,0x02,0xd0,0x01,0xd0,0x00,0x02,0x47,0x42,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0, +0x03,0x90,0x42,0x07,0xe0,0x04,0xf9,0x90,0x42,0x05,0xe0,0xf8,0x80,0x17,0x7a,0xc4, +0x7b,0x51,0x90,0xff,0xd2,0xe0,0x20,0xe6,0x06,0xdb,0xfa,0xda,0xf8,0x80,0x08,0xe6, +0x08,0x90,0xff,0xd0,0xf0,0xd9,0xe7,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x02, +0x47,0x42,0x90,0x42,0x03,0xe4,0xf0,0x22,0xa5,0x69,0x5a,0x96,0xa4,0x68,0x5b,0x97, +0xa7,0x6b,0x58,0x94,0xa6,0x6a,0x59,0x95,0xa1,0x6d,0x5e,0x92,0xa0,0x6c,0x5f,0x93, +0xa3,0x6f,0x5c,0x90,0xa2,0x6e,0x5d,0x91,0xad,0x61,0x52,0x9e,0xac,0x60,0x53,0x9f, +0xaf,0x63,0x50,0x9c,0xae,0x62,0x51,0x9d,0xa9,0x65,0x56,0x9a,0xa8,0x64,0x57,0x9b, +0xab,0x67,0x54,0x98,0xaa,0x66,0x55,0x99,0xb5,0x79,0x4a,0x86,0xb4,0x78,0x4b,0x87, +0xb7,0x7b,0x48,0x84,0xb6,0x7a,0x49,0x85,0xb1,0x7d,0x4e,0x82,0xb0,0x7c,0x4f,0x83, +0xb3,0x7f,0x4c,0x80,0xb2,0x7e,0x4d,0x81,0xbd,0x71,0x42,0x8e,0xbc,0x70,0x43,0x8f, +0xbf,0x73,0x40,0x8c,0xbe,0x72,0x41,0x8d,0xb9,0x75,0x46,0x8a,0xb8,0x74,0x47,0x8b, +0xbb,0x77,0x44,0x88,0xba,0x76,0x45,0x89,0x85,0x49,0x7a,0xb6,0x84,0x48,0x7b,0xb7, +0x87,0x4b,0x78,0xb4,0x86,0x4a,0x79,0xb5,0x81,0x4d,0x7e,0xb2,0x80,0x4c,0x7f,0xb3, +0x83,0x4f,0x7c,0xb0,0x82,0x4e,0x7d,0xb1,0x8d,0x41,0x72,0xbe,0x8c,0x40,0x73,0xbf, +0x8f,0x43,0x70,0xbc,0x8e,0x42,0x71,0xbd,0x89,0x45,0x76,0xba,0x88,0x44,0x77,0xbb, +0x8b,0x47,0x74,0xb8,0x8a,0x46,0x75,0xb9,0x95,0x59,0x6a,0xa6,0x94,0x58,0x6b,0xa7, +0x97,0x5b,0x68,0xa4,0x96,0x5a,0x69,0xa5,0x91,0x5d,0x6e,0xa2,0x90,0x5c,0x6f,0xa3, +0x93,0x5f,0x6c,0xa0,0x92,0x5e,0x6d,0xa1,0x9d,0x51,0x62,0xae,0x9c,0x50,0x63,0xaf, +0x9f,0x53,0x60,0xac,0x9e,0x52,0x61,0xad,0x99,0x55,0x66,0xaa,0x98,0x54,0x67,0xab, +0x9b,0x57,0x64,0xa8,0x9a,0x56,0x65,0xa9,0xe5,0x29,0x1a,0xd6,0xe4,0x28,0x1b,0xd7, +0xe7,0x2b,0x18,0xd4,0xe6,0x2a,0x19,0xd5,0xe1,0x2d,0x1e,0xd2,0xe0,0x2c,0x1f,0xd3, +0xe3,0x2f,0x1c,0xd0,0xe2,0x2e,0x1d,0xd1,0xed,0x21,0x12,0xde,0xec,0x20,0x13,0xdf, +0xef,0x23,0x10,0xdc,0xee,0x22,0x11,0xdd,0xe9,0x25,0x16,0xda,0xe8,0x24,0x17,0xdb, +0xeb,0x27,0x14,0xd8,0xea,0x26,0x15,0xd9,0xf5,0x39,0x0a,0xc6,0xf4,0x38,0x0b,0xc7, +0xf7,0x3b,0x08,0xc4,0xf6,0x3a,0x09,0xc5,0xf1,0x3d,0x0e,0xc2,0xf0,0x3c,0x0f,0xc3, +0xf3,0x3f,0x0c,0xc0,0xf2,0x3e,0x0d,0xc1,0xfd,0x31,0x02,0xce,0xfc,0x30,0x03,0xcf, +0xff,0x33,0x00,0xcc,0xfe,0x32,0x01,0xcd,0xf9,0x35,0x06,0xca,0xf8,0x34,0x07,0xcb, +0xfb,0x37,0x04,0xc8,0xfa,0x36,0x05,0xc9,0xc5,0x09,0x3a,0xf6,0xc4,0x08,0x3b,0xf7, +0xc7,0x0b,0x38,0xf4,0xc6,0x0a,0x39,0xf5,0xc1,0x0d,0x3e,0xf2,0xc0,0x0c,0x3f,0xf3, +0xc3,0x0f,0x3c,0xf0,0xc2,0x0e,0x3d,0xf1,0xcd,0x01,0x32,0xfe,0xcc,0x00,0x33,0xff, +0xcf,0x03,0x30,0xfc,0xce,0x02,0x31,0xfd,0xc9,0x05,0x36,0xfa,0xc8,0x04,0x37,0xfb, +0xcb,0x07,0x34,0xf8,0xca,0x06,0x35,0xf9,0xd5,0x19,0x2a,0xe6,0xd4,0x18,0x2b,0xe7, +0xd7,0x1b,0x28,0xe4,0xd6,0x1a,0x29,0xe5,0xd1,0x1d,0x2e,0xe2,0xd0,0x1c,0x2f,0xe3, +0xd3,0x1f,0x2c,0xe0,0xd2,0x1e,0x2d,0xe1,0xdd,0x11,0x22,0xee,0xdc,0x10,0x23,0xef, +0xdf,0x13,0x20,0xec,0xde,0x12,0x21,0xed,0xd9,0x15,0x26,0xea,0xd8,0x14,0x27,0xeb, +0xdb,0x17,0x24,0xe8,0xda,0x16,0x25,0xe9,0x25,0xe9,0xda,0x16,0x24,0xe8,0xdb,0x17, +0x27,0xeb,0xd8,0x14,0x26,0xea,0xd9,0x15,0x21,0xed,0xde,0x12,0x20,0xec,0xdf,0x13, +0x23,0xef,0xdc,0x10,0x22,0xee,0xdd,0x11,0x2d,0xe1,0xd2,0x1e,0x2c,0xe0,0xd3,0x1f, +0x2f,0xe3,0xd0,0x1c,0x2e,0xe2,0xd1,0x1d,0x29,0xe5,0xd6,0x1a,0x28,0xe4,0xd7,0x1b, +0x2b,0xe7,0xd4,0x18,0x2a,0xe6,0xd5,0x19,0x35,0xf9,0xca,0x06,0x34,0xf8,0xcb,0x07, +0x37,0xfb,0xc8,0x04,0x36,0xfa,0xc9,0x05,0x31,0xfd,0xce,0x02,0x30,0xfc,0xcf,0x03, +0x33,0xff,0xcc,0x00,0x32,0xfe,0xcd,0x01,0x3d,0xf1,0xc2,0x0e,0x3c,0xf0,0xc3,0x0f, +0x3f,0xf3,0xc0,0x0c,0x3e,0xf2,0xc1,0x0d,0x39,0xf5,0xc6,0x0a,0x38,0xf4,0xc7,0x0b, +0x3b,0xf7,0xc4,0x08,0x3a,0xf6,0xc5,0x09,0x05,0xc9,0xfa,0x36,0x04,0xc8,0xfb,0x37, +0x07,0xcb,0xf8,0x34,0x06,0xca,0xf9,0x35,0x01,0xcd,0xfe,0x32,0x00,0xcc,0xff,0x33, +0x03,0xcf,0xfc,0x30,0x02,0xce,0xfd,0x31,0x0d,0xc1,0xf2,0x3e,0x0c,0xc0,0xf3,0x3f, +0x0f,0xc3,0xf0,0x3c,0x0e,0xc2,0xf1,0x3d,0x09,0xc5,0xf6,0x3a,0x08,0xc4,0xf7,0x3b, +0x0b,0xc7,0xf4,0x38,0x0a,0xc6,0xf5,0x39,0x15,0xd9,0xea,0x26,0x14,0xd8,0xeb,0x27, +0x17,0xdb,0xe8,0x24,0x16,0xda,0xe9,0x25,0x11,0xdd,0xee,0x22,0x10,0xdc,0xef,0x23, +0x13,0xdf,0xec,0x20,0x12,0xde,0xed,0x21,0x1d,0xd1,0xe2,0x2e,0x1c,0xd0,0xe3,0x2f, +0x1f,0xd3,0xe0,0x2c,0x1e,0xd2,0xe1,0x2d,0x19,0xd5,0xe6,0x2a,0x18,0xd4,0xe7,0x2b, +0x1b,0xd7,0xe4,0x28,0x1a,0xd6,0xe5,0x29,0x65,0xa9,0x9a,0x56,0x64,0xa8,0x9b,0x57, +0x67,0xab,0x98,0x54,0x66,0xaa,0x99,0x55,0x61,0xad,0x9e,0x52,0x60,0xac,0x9f,0x53, +0x63,0xaf,0x9c,0x50,0x62,0xae,0x9d,0x51,0x6d,0xa1,0x92,0x5e,0x6c,0xa0,0x93,0x5f, +0x6f,0xa3,0x90,0x5c,0x6e,0xa2,0x91,0x5d,0x69,0xa5,0x96,0x5a,0x68,0xa4,0x97,0x5b, +0x6b,0xa7,0x94,0x58,0x6a,0xa6,0x95,0x59,0x75,0xb9,0x8a,0x46,0x74,0xb8,0x8b,0x47, +0x77,0xbb,0x88,0x44,0x76,0xba,0x89,0x45,0x71,0xbd,0x8e,0x42,0x70,0xbc,0x8f,0x43, +0x73,0xbf,0x8c,0x40,0x72,0xbe,0x8d,0x41,0x7d,0xb1,0x82,0x4e,0x7c,0xb0,0x83,0x4f, +0x7f,0xb3,0x80,0x4c,0x7e,0xb2,0x81,0x4d,0x79,0xb5,0x86,0x4a,0x78,0xb4,0x87,0x4b, +0x7b,0xb7,0x84,0x48,0x7a,0xb6,0x85,0x49,0x45,0x89,0xba,0x76,0x44,0x88,0xbb,0x77, +0x47,0x8b,0xb8,0x74,0x46,0x8a,0xb9,0x75,0x41,0x8d,0xbe,0x72,0x40,0x8c,0xbf,0x73, +0x43,0x8f,0xbc,0x70,0x42,0x8e,0xbd,0x71,0x4d,0x81,0xb2,0x7e,0x4c,0x80,0xb3,0x7f, +0x4f,0x83,0xb0,0x7c,0x4e,0x82,0xb1,0x7d,0x49,0x85,0xb6,0x7a,0x48,0x84,0xb7,0x7b, +0x4b,0x87,0xb4,0x78,0x4a,0x86,0xb5,0x79,0x55,0x99,0xaa,0x66,0x54,0x98,0xab,0x67, +0x57,0x9b,0xa8,0x64,0x56,0x9a,0xa9,0x65,0x51,0x9d,0xae,0x62,0x50,0x9c,0xaf,0x63, +0x53,0x9f,0xac,0x60,0x52,0x9e,0xad,0x61,0x5d,0x91,0xa2,0x6e,0x5c,0x90,0xa3,0x6f, +0x5f,0x93,0xa0,0x6c,0x5e,0x92,0xa1,0x6d,0x59,0x95,0xa6,0x6a,0x58,0x94,0xa7,0x6b, +0x5b,0x97,0xa4,0x68,0x5a,0x96,0xa5,0x69,0x40,0x41,0x3e,0x3f,0x3c,0x3d,0x3a,0x3b, +0x48,0x49,0x46,0x47,0x44,0x45,0x42,0x43,0x30,0x31,0x2e,0x2f,0x2c,0x2d,0x2a,0x2b, +0x38,0x39,0x36,0x37,0x34,0x35,0x32,0x33,0x60,0x61,0x5e,0x5f,0x5c,0x5d,0x5a,0x5b, +0x68,0x69,0x66,0x67,0x64,0x65,0x62,0x63,0x50,0x51,0x4e,0x4f,0x4c,0x4d,0x4a,0x4b, +0x58,0x59,0x56,0x57,0x54,0x55,0x52,0x53,0x80,0x81,0x7e,0x7f,0x7c,0x7d,0x7a,0x7b, +0x88,0x89,0x86,0x87,0x84,0x85,0x82,0x83,0x70,0x71,0x6e,0x6f,0x6c,0x6d,0x6a,0x6b, +0x78,0x79,0x76,0x77,0x74,0x75,0x72,0x73,0xa0,0xa1,0x9e,0x9f,0x9c,0x9d,0x9a,0x9b, +0xa8,0xa9,0xa6,0xa7,0xa4,0xa5,0xa2,0xa3,0x90,0x91,0x8e,0x8f,0x8c,0x8d,0x8a,0x8b, +0x98,0x99,0x96,0x97,0x94,0x95,0x92,0x93,0xc0,0xc1,0xbe,0xbf,0xbc,0xbd,0xba,0xbb, +0xc8,0xc9,0xc6,0xc7,0xc4,0xc5,0xc2,0xc3,0xb0,0xb1,0xae,0xaf,0xac,0xad,0xaa,0xab, +0xb8,0xb9,0xb6,0xb7,0xb4,0xb5,0xb2,0xb3,0xe0,0xe1,0xde,0xdf,0xdc,0xdd,0xda,0xdb, +0xe8,0xe9,0xe6,0xe7,0xe4,0xe5,0xe2,0xe3,0xd0,0xd1,0xce,0xcf,0xcc,0xcd,0xca,0xcb, +0xd8,0xd9,0xd6,0xd7,0xd4,0xd5,0xd2,0xd3,0x00,0x01,0xfe,0xff,0xfc,0xfd,0xfa,0xfb, +0x08,0x09,0x06,0x07,0x04,0x05,0x02,0x03,0xf0,0xf1,0xee,0xef,0xec,0xed,0xea,0xeb, +0xf8,0xf9,0xf6,0xf7,0xf4,0xf5,0xf2,0xf3,0x20,0x21,0x1e,0x1f,0x1c,0x1d,0x1a,0x1b, +0x28,0x29,0x26,0x27,0x24,0x25,0x22,0x23,0x10,0x11,0x0e,0x0f,0x0c,0x0d,0x0a,0x0b, +0x18,0x19,0x16,0x17,0x14,0x15,0x12,0x13,0x75,0x44,0x00,0xd2,0x02,0x22,0x30,0x02, +0x0b,0x90,0x4b,0x48,0x93,0xc2,0x02,0xf5,0x45,0x02,0x4c,0x82,0x75,0xf0,0x00,0xc3, +0x33,0xc5,0xf0,0x33,0xc5,0xf0,0xc3,0x33,0xc5,0xf0,0x33,0xc5,0xf0,0x24,0x48,0xf5, +0x82,0xe5,0xf0,0x34,0x47,0xf5,0x83,0xe5,0x44,0x54,0x03,0x93,0x25,0x45,0xf5,0x45, +0x05,0x44,0x22,0xff,0xc0,0x01,0x30,0x10,0x00,0xcb,0x80,0xba,0x3c,0x3d,0x00,0x00, +0x0b,0x38,0xc9,0x1c,0x0c,0xa0,0x00,0x00,0x00,0x20,0xc4,0x82,0xcf,0x3c,0x42,0x00, +0x00,0x1f,0x00,0x97,0x19,0x09,0xa0,0x00,0x00,0x00,0x28,0xc4,0x86,0xd1,0x3c,0x7f, +0x00,0x00,0x15,0x00,0x61,0x01,0x07,0xa0,0x00,0x00,0x00,0x20,0xc4,0x82,0xd0,0x3c, +0x42,0x00,0x00,0x15,0x00,0xf7,0x19,0x09,0xa0,0x00,0x00,0x00,0x28,0xc4,0x86,0xd0, +0x3c,0x42,0x00,0x00,0x15,0x00,0x81,0x01,0x07,0xa0,0x00,0x00,0x00,0x00,0xc3,0x80, +0xc7,0x3c,0x6f,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0x00,0x00,0x00,0xd1, +0x82,0xcc,0x3c,0x0a,0x00,0x00,0x29,0x00,0xf0,0x05,0x05,0xa0,0x00,0x00,0x00,0x00, +0xd2,0x82,0xbe,0x3c,0x77,0x00,0x00,0x33,0x00,0xf0,0x00,0x09,0xa0,0x00,0x00,0x00, +0x00,0x11,0x82,0xce,0x3c,0x42,0x00,0x00,0x15,0x00,0xf0,0x16,0x06,0xa0,0x00,0x00, +0x00,0x00,0xd2,0x82,0xca,0x3c,0x74,0x00,0x00,0x29,0x00,0xf0,0x00,0x06,0xa0,0x00, +0x00,0x00,0x00,0x11,0x82,0xcc,0x3c,0x42,0x00,0x00,0x15,0x00,0xf0,0x16,0x06,0xa0, +0x00,0x00,0x00,0x00,0x11,0x82,0xca,0x3c,0x52,0x00,0x00,0x15,0x00,0xf0,0x00,0x06, +0xa0,0x00,0x00,0x00,0x00,0xd2,0x82,0xca,0x3c,0x74,0x00,0x00,0x29,0x00,0xf0,0x00, +0x06,0xa0,0x00,0x00,0x00,0x00,0xd1,0x82,0xca,0x3c,0x0a,0x00,0x00,0x29,0x00,0xf0, +0x05,0x05,0xa0,0x00,0xf0,0x00,0x00,0x0a,0x82,0xca,0x3c,0x73,0x00,0x00,0x29,0x00, +0xf0,0x00,0x09,0xa0,0x00,0x00,0x00,0x00,0xd1,0x82,0xc8,0x3c,0x0a,0x00,0x00,0x23, +0x00,0xf0,0x07,0x07,0xa0,0x00,0xc0,0x00,0x00,0xc8,0x82,0xcb,0x3c,0x52,0x00,0x00, +0x29,0x00,0xf6,0x16,0x06,0xa0,0x00,0x20,0x00,0x00,0x79,0x82,0xbc,0x3c,0x50,0x00, +0x00,0x1f,0x00,0xf5,0x19,0x09,0xa0,0x00,0xd0,0x00,0x00,0xc8,0x82,0xc8,0x3c,0x52, +0x00,0x00,0x29,0x00,0xf6,0x16,0x06,0xa0,0x00,0x20,0x00,0x00,0x7b,0x82,0xbd,0x3c, +0x57,0x00,0x00,0x29,0x00,0xf0,0x00,0x09,0xa0,0x00,0xe0,0x00,0x00,0xc8,0x82,0xc2, +0x3c,0x52,0x00,0x00,0x29,0x00,0xf6,0x16,0x06,0xa0,0x00,0x20,0x00,0x00,0x7a,0x82, +0xc0,0x3c,0x7a,0x00,0x00,0x29,0x00,0xf0,0x00,0x05,0xa0,0x00,0x20,0x00,0x00,0xc7, +0x82,0xc3,0x3c,0x01,0x00,0x00,0x1f,0x00,0xf6,0x17,0x07,0xa0,0x00,0x30,0x00,0x00, +0xc7,0x82,0xc0,0x3c,0x52,0x00,0x00,0x1f,0x00,0xf6,0x17,0x07,0xa0,0x00,0x20,0x00, +0x00,0x31,0x88,0xca,0x3c,0x6b,0x00,0x00,0x15,0x00,0xf0,0x05,0x05,0xa0,0x00,0x40, +0x00,0x00,0xc7,0x82,0xbc,0x3c,0x52,0x00,0x00,0x1f,0x00,0xf6,0x17,0x07,0xa0,0x00, +0xe0,0x00,0x00,0x2e,0x84,0xca,0x3c,0x67,0x00,0x00,0x15,0x00,0xf0,0x05,0x05,0xa0, +0x00,0xe0,0x00,0x00,0x7a,0x84,0xd4,0x3c,0x01,0x00,0x00,0x15,0x00,0xf2,0x15,0x05, +0xa0,0x00,0xd0,0x00,0x00,0x21,0x84,0xc9,0x3c,0x6a,0x00,0x00,0x29,0x00,0xf0,0x05, +0x05,0xa0,0x00,0x10,0x00,0x00,0x25,0x82,0xc4,0x3c,0x6b,0x00,0x00,0x1f,0x00,0xf0, +0x00,0x09,0xa0,0x00,0xf0,0x00,0x00,0x31,0x86,0xc3,0x3c,0x67,0x00,0x00,0x15,0x00, +0xf5,0x16,0x06,0xa0,0x00,0x20,0x00,0x00,0x1d,0x80,0xca,0x3c,0x6b,0x00,0x00,0x1f, +0x00,0xf0,0x00,0x09,0xa0,0x00,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20, +0x59,0x41,0x4d,0x41,0x48,0x41,0x00,0xe0,0x00,0x00,0x31,0x88,0xc8,0x3c,0x67,0x00, +0x00,0x15,0x00,0xf4,0x16,0x06,0xa0,0x00,0xc0,0x00,0x00,0x9d,0x84,0xc9,0x3c,0x0a, +0x00,0x00,0x1f,0x00,0xf4,0x17,0x07,0xa0,0x00,0xe0,0x00,0x00,0x2e,0x84,0xc8,0x3c, +0x73,0x00,0x00,0x15,0x00,0xf0,0x06,0x06,0xa0,0x00,0x40,0x00,0x00,0x1c,0x82,0xc7, +0x3c,0x61,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0x40,0x00,0x00,0x1c,0x82, +0xc8,0x3c,0x43,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0xbd,0x91,0x90,0x87, +0x8e,0x97,0x99,0x98,0xe0,0xa7,0xbf,0xb3,0xbf,0xb8,0xbf,0xf6,0x00,0xd0,0x00,0x00, +0x1e,0x82,0xca,0x3c,0x72,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0xd0,0x00, +0x00,0x1f,0x82,0xca,0x3c,0x63,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0xe0, +0x00,0x00,0x1f,0x82,0xcd,0x3c,0x4f,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00, +0x20,0x00,0x00,0x9c,0x82,0xc9,0x3c,0x6e,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0, +0x00,0x20,0x00,0x00,0x9c,0x82,0xcd,0x3c,0x70,0x00,0x00,0x15,0x00,0xf0,0x00,0x09, +0xa0,0x00,0xc0,0x00,0x00,0x0b,0x80,0xc7,0x3c,0x43,0x00,0x00,0x15,0x00,0xf0,0x00, +0x09,0xa0,0x00,0xc0,0x00,0x00,0x0b,0x80,0xcb,0x3c,0x13,0x00,0x00,0x15,0x00,0xf0, +0x00,0x09,0xa0,0x00,0xc0,0x00,0x00,0x2f,0x82,0xc7,0x3c,0x73,0x00,0x00,0x29,0x00, +0xf0,0x00,0x09,0xa0,0x00,0xc0,0x00,0x00,0x30,0x82,0xc8,0x3c,0x79,0x00,0x00,0x29, +0x00,0xf0,0x00,0x09,0xa0,0x00,0x40,0x00,0x08,0x44,0x83,0xc9,0x3c,0x67,0x00,0x00, +0x15,0x00,0xf0,0x00,0x0b,0xa0,0x00,0x40,0x00,0x08,0x44,0x85,0xcc,0x3c,0x4f,0x00, +0x00,0x15,0x00,0xf0,0x00,0x0b,0xa0,0x00,0x30,0x00,0x00,0x24,0x82,0xba,0x3c,0x48, +0x00,0x00,0x1f,0x00,0xf0,0x00,0x09,0xa0,0x00,0x30,0x00,0x08,0x24,0x84,0xcc,0x3c, +0x70,0x00,0x00,0x33,0x00,0xf0,0x00,0x09,0xa0,0x00,0x20,0x00,0x00,0x20,0x80,0xcd, +0x3c,0x61,0x00,0x00,0x1f,0x00,0xf0,0x00,0x09,0xa0,0x00,0x40,0x00,0x00,0x2c,0x80, +0xca,0x3c,0x72,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0x40,0x00,0x00,0x2c, +0x80,0xd0,0x3c,0x5c,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0xe0,0x00,0x00, +0x22,0x82,0xcc,0x3c,0x61,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0xe0,0x00, +0x00,0x23,0x82,0xcc,0x3c,0x73,0x00,0x00,0x15,0x00,0xf0,0x00,0x09,0xa0,0x00,0xc0, +0x00,0x00,0x32,0x80,0xca,0x3c,0x7c,0x00,0x00,0x29,0x00,0xf0,0x08,0x09,0xa0,0x00, +0xc0,0x00,0x00,0x32,0x84,0xca,0x3c,0x61,0x00,0x00,0x29,0x00,0xf0,0x00,0x09,0xa0, +0x00,0xf0,0x00,0x00,0x2f,0x82,0xbe,0x3c,0x6f,0x00,0x00,0x29,0x00,0xf0,0x00,0x09, +0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xc5,0x46,0xd6,0x46,0xe7,0x46,0xf8,0x47,0x09,0x00,0x00,0x47,0x1a, +0x47,0x2b,0x47,0x3c,0x47,0x4d,0x00,0x00,0x47,0x6f,0x47,0x80,0x47,0x91,0x47,0xa2, +0x47,0xb3,0x47,0xc4,0x47,0xd5,0x47,0xe6,0x47,0xf7,0x48,0x08,0x48,0x19,0x48,0x2a, +0x48,0x3b,0x48,0x4c,0x48,0x5d,0x48,0x6e,0x48,0x7f,0x48,0x90,0x48,0xa1,0x48,0xb2, +0x48,0xc3,0x48,0xd4,0x48,0xf6,0x49,0x07,0x49,0x18,0x49,0x29,0x49,0x3a,0x49,0x5c, +0x49,0x6d,0x49,0x7e,0x49,0x8f,0x49,0xa0,0x49,0xb1,0x49,0xc2,0x49,0xd3,0x49,0xe4, +0x49,0xf5,0x4a,0x06,0x4a,0x17,0x4a,0x28,0x4a,0x39,0x4a,0x4a,0x4a,0x5b,0x4a,0x6c, +0x4a,0x7d,0x4a,0x8e,0x4a,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, +0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, +0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0xff,0x27,0x28,0x29,0x2a,0x2b,0x2a,0x2d, +0x2a,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d, +0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x47,0x49,0x49,0x4b,0x4c,0x4d, +0x4e,0x4e,0x50,0x50,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d, +0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d, +0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d, +0x7e,0x7f,0x00,0x10,0x00,0x2c,0x81,0x32,0x3c,0x72,0x00,0x00,0x37,0x20,0xf2,0x13, +0x08,0xa0,0x00,0x00,0x10,0x00,0x2d,0x81,0x37,0x3c,0x60,0x00,0x00,0x37,0x20,0xf2, +0x14,0x08,0xa0,0x00,0x00,0x10,0x00,0x2e,0x81,0x3e,0x3c,0x4b,0x00,0x00,0x37,0x20, +0xf2,0x14,0x08,0xa0,0x00,0x00,0x10,0x00,0x2f,0x81,0x43,0x3c,0x6a,0x00,0x00,0x37, +0x20,0xf2,0x14,0x08,0xa0,0x00,0x0a,0x10,0x00,0x30,0x81,0x4b,0x3c,0x64,0x00,0x00, +0x37,0x20,0xf2,0x14,0x08,0xa0,0x00,0x0a,0x10,0x00,0x31,0x81,0x50,0x3c,0x69,0x00, +0x00,0x37,0x20,0xf2,0x14,0x08,0xa0,0x00,0x04,0x10,0x00,0x32,0x81,0x54,0x3c,0x6c, +0x00,0x00,0x37,0x20,0xf2,0x14,0x08,0xa0,0x00,0x03,0x10,0x00,0x33,0x81,0x5c,0x3c, +0x61,0x00,0x00,0x37,0x20,0xf2,0x14,0x18,0xa0,0x00,0x07,0x10,0x00,0x34,0x81,0x61, +0x3c,0x64,0x00,0x00,0x37,0x20,0xf3,0x14,0x18,0xa0,0x00,0x00,0x10,0x00,0x35,0x81, +0x5d,0x3c,0x3b,0x00,0x00,0x37,0x20,0xf4,0x15,0x08,0xa0,0x00,0x00,0x10,0x00,0x2c, +0x81,0x32,0x3c,0x72,0x00,0x00,0x37,0x20,0xf2,0x13,0x08,0xa0,0x01,0x00,0x10,0x00, +0x2d,0x81,0x37,0x3c,0x60,0x00,0x00,0x37,0x20,0xf2,0x14,0x08,0xa0,0x01,0x00,0x10, +0x00,0x2e,0x81,0x3e,0x3c,0x4b,0x00,0x00,0x37,0x20,0xf2,0x14,0x08,0xa0,0x01,0x00, +0x10,0x00,0x2f,0x81,0x43,0x3c,0x6a,0x00,0x00,0x37,0x20,0xf2,0x14,0x08,0xa0,0x01, +0x0a,0x10,0x00,0x30,0x81,0x4b,0x3c,0x64,0x00,0x00,0x37,0x20,0xf2,0x14,0x08,0xa0, +0x01,0x0a,0x10,0x00,0x31,0x81,0x50,0x3c,0x69,0x00,0x00,0x37,0x20,0xf2,0x14,0x08, +0xa0,0x01,0x04,0x10,0x00,0x32,0x81,0x54,0x3c,0x6c,0x00,0x00,0x37,0x20,0xf2,0x14, +0x08,0xa0,0x01,0x07,0x10,0x00,0x33,0x81,0x5c,0x3c,0x61,0x00,0x00,0x37,0x20,0xf2, +0x14,0x18,0xa0,0x01,0x0a,0x10,0x00,0x34,0x81,0x61,0x3c,0x64,0x00,0x00,0x37,0x20, +0xf3,0x14,0x18,0xa0,0x01,0x00,0x10,0x00,0x35,0x81,0x5d,0x3c,0x3b,0x00,0x00,0x37, +0x20,0xf4,0x15,0x08,0xa0,0x01,0x10,0x10,0x00,0x2c,0x81,0x32,0x3c,0x74,0x00,0x00, +0x51,0x20,0xf2,0x13,0x07,0xa0,0x02,0x10,0x10,0x00,0x2d,0x81,0x37,0x3c,0x62,0x00, +0x00,0x51,0x20,0xf2,0x14,0x07,0xa0,0x02,0x10,0x10,0x00,0x2e,0x81,0x3e,0x3c,0x4d, +0x00,0x00,0x51,0x20,0xf2,0x14,0x07,0xa0,0x02,0x10,0x10,0x00,0x2f,0x81,0x43,0x3c, +0x6c,0x00,0x00,0x51,0x20,0xf2,0x14,0x07,0xa0,0x02,0x10,0x10,0x00,0x30,0x81,0x4b, +0x3c,0x66,0x00,0x00,0x51,0x20,0xf2,0x14,0x07,0xa0,0x02,0x10,0x10,0x00,0x31,0x81, +0x50,0x3c,0x6b,0x00,0x00,0x51,0x20,0xf2,0x14,0x07,0xa0,0x02,0x10,0x10,0x00,0x32, +0x81,0x54,0x3c,0x6e,0x00,0x00,0x51,0x20,0xf2,0x14,0x07,0xa0,0x02,0x10,0x10,0x00, +0x33,0x81,0x5c,0x3c,0x63,0x00,0x00,0x51,0x20,0xf2,0x14,0x17,0xa0,0x02,0x10,0x10, +0x00,0x34,0x81,0x61,0x3c,0x66,0x00,0x00,0x51,0x20,0xf3,0x14,0x17,0xa0,0x02,0x10, +0x10,0x00,0x35,0x81,0x5d,0x3c,0x3d,0x00,0x00,0x51,0x20,0xf4,0x15,0x07,0xa0,0x02, +0xf0,0x10,0x00,0x6c,0x80,0x3a,0x2e,0x27,0x00,0x00,0x3d,0x28,0xf4,0x23,0x18,0xa0, +0x03,0x00,0x10,0x00,0x2c,0x81,0x32,0x3c,0x72,0x00,0x00,0x4b,0x20,0xf2,0x13,0x08, +0xa0,0x04,0x00,0x10,0x00,0x2d,0x81,0x37,0x3c,0x60,0x00,0x00,0x4b,0x20,0xf2,0x14, +0x08,0xa0,0x04,0x00,0x10,0x00,0x2e,0x81,0x3e,0x3c,0x4b,0x00,0x00,0x4b,0x20,0xf2, +0x14,0x08,0xa0,0x04,0x00,0x10,0x00,0x2f,0x81,0x43,0x3c,0x6a,0x00,0x00,0x4b,0x20, +0xf2,0x14,0x08,0xa0,0x04,0x0a,0x10,0x00,0x30,0x81,0x4b,0x3c,0x64,0x00,0x00,0x4b, +0x20,0xf2,0x14,0x08,0xa0,0x04,0x0a,0x10,0x00,0x31,0x81,0x50,0x3c,0x69,0x00,0x00, +0x4b,0x20,0xf2,0x14,0x08,0xa0,0x04,0x04,0x10,0x00,0x32,0x81,0x54,0x3c,0x6c,0x00, +0x00,0x4b,0x20,0xf2,0x14,0x08,0xa0,0x04,0x03,0x10,0x00,0x33,0x81,0x5c,0x3c,0x61, +0x00,0x00,0x4b,0x20,0xf2,0x14,0x18,0xa0,0x04,0x07,0x10,0x00,0x34,0x81,0x61,0x3c, +0x64,0x00,0x00,0x4b,0x20,0xf3,0x14,0x18,0xa0,0x04,0x00,0x10,0x00,0x35,0x81,0x5d, +0x3c,0x3b,0x00,0x00,0x4b,0x20,0xf4,0x15,0x08,0xa0,0x04,0x00,0x10,0x00,0x2c,0x81, +0x32,0x3c,0x7e,0x00,0x00,0x4b,0x20,0xf2,0x13,0x08,0xa0,0x04,0x00,0x10,0x00,0x2d, +0x81,0x37,0x3c,0x53,0x00,0x00,0x4b,0x20,0xf2,0x14,0x08,0xa0,0x04,0x00,0x10,0x00, +0x2e,0x81,0x3e,0x3c,0x58,0x00,0x00,0x4b,0x20,0xf2,0x14,0x08,0xa0,0x04,0x00,0x10, +0x00,0x2f,0x81,0x43,0x3c,0x5b,0x00,0x00,0x4b,0x20,0xf2,0x14,0x08,0xa0,0x04,0x0a, +0x10,0x00,0x30,0x81,0x4b,0x3c,0x72,0x00,0x00,0x4b,0x20,0xf2,0x14,0x08,0xa0,0x04, +0x0a,0x10,0x00,0x31,0x81,0x50,0x3c,0x5b,0x00,0x00,0x4b,0x20,0xf2,0x14,0x08,0xa0, +0x04,0x04,0x10,0x00,0x32,0x81,0x54,0x3c,0x79,0x00,0x00,0x4b,0x20,0xf2,0x14,0x08, +0xa0,0x04,0x07,0x10,0x00,0x33,0x81,0x5c,0x3c,0x5a,0x00,0x00,0x4b,0x20,0xf2,0x14, +0x18,0xa0,0x04,0x01,0x10,0x00,0x34,0x81,0x61,0x3c,0x71,0x00,0x00,0x4b,0x20,0xf3, +0x14,0x18,0xa0,0x04,0x00,0x10,0x00,0x35,0x81,0x5d,0x3c,0x2f,0x00,0x00,0x4b,0x20, +0xf4,0x15,0x08,0xa0,0x04,0x00,0x10,0x00,0x0b,0xa0,0x51,0x3c,0x6a,0x00,0x00,0xd7, +0x38,0xf0,0x00,0x0c,0xa0,0x05,0x00,0x12,0x00,0x6c,0x80,0x3a,0x3c,0x27,0x00,0x00, +0x4f,0x22,0xf4,0x23,0x19,0xa0,0x06,0x00,0x10,0x00,0x2c,0x81,0x32,0x3c,0x74,0x00, +0x00,0x5d,0x1b,0xf2,0x13,0x08,0xa0,0x07,0x00,0x10,0x00,0x2d,0x81,0x37,0x3c,0x62, +0x00,0x00,0x5d,0x1b,0xf2,0x14,0x08,0xa0,0x07,0x00,0x10,0x00,0x2e,0x81,0x3e,0x3c, +0x4d,0x00,0x00,0x5d,0x1b,0xf2,0x14,0x08,0xa0,0x07,0x00,0x10,0x00,0x2f,0x81,0x43, +0x3c,0x6c,0x00,0x00,0x5d,0x1b,0xf2,0x14,0x08,0xa0,0x07,0x0a,0x10,0x00,0x30,0x81, +0x4b,0x3c,0x66,0x00,0x00,0x5d,0x1b,0xf2,0x14,0x08,0xa0,0x07,0x0a,0x10,0x00,0x31, +0x81,0x50,0x3c,0x6b,0x00,0x00,0x5d,0x1b,0xf2,0x14,0x08,0xa0,0x07,0x04,0x10,0x00, +0x32,0x81,0x54,0x3c,0x6e,0x00,0x00,0x5d,0x1b,0xf2,0x14,0x08,0xa0,0x07,0x03,0x10, +0x00,0x33,0x81,0x5c,0x3c,0x63,0x00,0x00,0x5d,0x1b,0xf2,0x14,0x18,0xa0,0x07,0x07, +0x10,0x00,0x34,0x81,0x61,0x3c,0x66,0x00,0x00,0x5d,0x1b,0xf3,0x14,0x18,0xa0,0x07, +0x00,0x10,0x00,0x35,0x81,0x5d,0x3c,0x3d,0x00,0x00,0x5d,0x1b,0xf4,0x15,0x08,0xa0, +0x07,0x00,0x10,0x00,0x2c,0x81,0x32,0x68,0x70,0x00,0x00,0x5d,0x18,0xf2,0x13,0x08, +0xa0,0x04,0x00,0x10,0x00,0x2d,0x81,0x37,0x68,0x5e,0x00,0x00,0x5d,0x18,0xf2,0x14, +0x08,0xa0,0x04,0x00,0x10,0x00,0x2e,0x81,0x3e,0x68,0x49,0x00,0x00,0x5d,0x18,0xf2, +0x14,0x08,0xa0,0x04,0x00,0x10,0x00,0x2f,0x81,0x43,0x68,0x68,0x00,0x00,0x5d,0x18, +0xf2,0x14,0x08,0xa0,0x04,0x0a,0x10,0x00,0x30,0x81,0x4b,0x68,0x62,0x00,0x00,0x5d, +0x18,0xf2,0x14,0x08,0xa0,0x04,0x0a,0x10,0x00,0x31,0x81,0x50,0x68,0x67,0x00,0x00, +0x5d,0x18,0xf2,0x14,0x08,0xa0,0x04,0x04,0x10,0x00,0x32,0x81,0x54,0x68,0x6a,0x00, +0x00,0x5d,0x18,0xf2,0x14,0x08,0xa0,0x04,0x07,0x10,0x00,0x33,0x81,0x5c,0x68,0x5f, +0x00,0x00,0x5d,0x18,0xf2,0x14,0x18,0xa0,0x04,0x0a,0x10,0x00,0x34,0x81,0x61,0x68, +0x62,0x00,0x00,0x5d,0x18,0xf3,0x14,0x18,0xa0,0x04,0x00,0x10,0x00,0x35,0x81,0x5d, +0x68,0x39,0x00,0x00,0x5d,0x18,0xf4,0x15,0x08,0xa0,0x04,0x00,0x10,0x00,0x80,0x80, +0x44,0x3c,0x66,0x00,0x00,0x4d,0x20,0xf5,0x24,0x19,0xa0,0x08,0x00,0x10,0x00,0x81, +0x80,0x4a,0x3c,0x78,0x00,0x00,0x4d,0x20,0xf5,0x25,0x09,0xa0,0x08,0x00,0x10,0x00, +0x82,0x80,0x50,0x3c,0x66,0x00,0x00,0x4d,0x20,0xf5,0x25,0x09,0xa0,0x08,0x00,0x10, +0x00,0x83,0x80,0x56,0x3c,0x5b,0x00,0x00,0x4d,0x20,0xf5,0x25,0x19,0xa0,0x08,0x00, +0x10,0x00,0x84,0x80,0x62,0x3c,0x5b,0x00,0x00,0x4d,0x20,0xf5,0x25,0x29,0xa0,0x08, +0x00,0x10,0x00,0x27,0x90,0x51,0x3c,0x51,0x00,0x00,0x2d,0x28,0xf5,0x13,0x2b,0xa0, +0x09,0x00,0x10,0x00,0x28,0x90,0x5d,0x3c,0x67,0x00,0x00,0x2d,0x28,0xf5,0x13,0x3b, +0xa0,0x09,0x00,0x10,0x00,0x2b,0x80,0x52,0x3c,0x03,0x00,0x00,0x23,0x20,0xf4,0x15, +0x07,0xa3,0x0a,0x00,0x10,0x00,0xf3,0x60,0x52,0x3c,0x5d,0x00,0x00,0x3d,0x28,0xf6, +0x25,0x25,0xa0,0x0b,0x00,0x10,0x00,0xf3,0x80,0x52,0x3c,0x62,0x00,0x00,0x49,0x20, +0xa6,0x25,0x25,0xa0,0x0c,0x00,0x10,0x00,0x01,0x81,0x47,0x75,0x65,0x00,0x00,0x55, +0x20,0xd4,0x14,0x16,0xa0,0x0d,0x00,0x10,0x70,0x01,0x81,0x47,0x3c,0x6a,0x00,0x00, +0x3f,0x28,0xf4,0x14,0x16,0xa4,0x0e,0x00,0x10,0x00,0xf4,0x80,0x47,0x3c,0x6a,0x00, +0x00,0x3b,0x38,0xf7,0x47,0x08,0xa0,0x0f,0x00,0x10,0x00,0xf5,0x80,0x53,0x3c,0x51, +0x00,0x00,0x3b,0x38,0xf7,0x47,0x08,0xa0,0x0f,0x00,0x10,0x00,0xf5,0x80,0x53,0x3c, +0x51,0x00,0x00,0x3b,0x38,0xf7,0x48,0x08,0xa0,0x0f,0x00,0x10,0x00,0xf5,0x80,0x53, +0x3c,0x52,0x00,0x00,0x3b,0x38,0xf7,0x48,0x18,0xa0,0x0f,0x00,0x10,0x00,0x36,0x81, +0x5e,0x3c,0x01,0x00,0x00,0x2d,0x38,0xf0,0x06,0x36,0xa0,0x10,0x00,0x10,0x10,0xff, +0x80,0x4d,0x3c,0x5f,0x00,0x00,0x01,0x21,0xf4,0xa3,0x25,0xa1,0x11,0x00,0x14,0x00, +0x3f,0x80,0x4b,0x3c,0x4c,0x00,0x00,0x43,0x29,0xf5,0x16,0x07,0xa0,0x12,0x0e,0x13, +0x00,0x40,0x80,0x4b,0x3c,0x4c,0x00,0x00,0x6b,0x2a,0xf5,0x16,0x07,0xa0,0x13,0x04, +0x12,0x01,0x8e,0x80,0x4a,0x3c,0x6a,0x00,0x00,0x3d,0x3a,0xf0,0x00,0x0a,0xa0,0x14, +0x00,0x13,0x00,0x8c,0x80,0x3d,0x3c,0x6e,0x00,0x00,0x41,0x3b,0xf0,0x00,0x09,0xa0, +0x15,0x00,0x13,0x00,0x8d,0x80,0x55,0x3c,0x68,0x00,0x00,0x41,0x3b,0xf0,0x00,0x09, +0xa0,0x15,0x00,0x10,0x00,0x28,0x81,0x39,0x3c,0x6e,0x00,0x00,0x33,0x39,0xf0,0x00, +0x0a,0xa0,0x16,0x00,0x10,0x00,0x29,0x81,0x45,0x3c,0x70,0x00,0x00,0x33,0x39,0xf0, +0x00,0x0a,0xa0,0x16,0x00,0x10,0x00,0x2a,0x81,0x51,0x3c,0x6a,0x00,0x00,0x33,0x39, +0xf0,0x00,0x0a,0xa0,0x16,0x00,0x10,0x00,0x2b,0x81,0x5d,0x3c,0x65,0x00,0x00,0x33, +0x39,0xf0,0x00,0x0a,0xa0,0x16,0x00,0x10,0x00,0x27,0x71,0x5d,0x3c,0x67,0x00,0x00, +0x33,0x39,0xf0,0x00,0x0a,0xa0,0x16,0x00,0x10,0x00,0x87,0x80,0x32,0x3c,0x6a,0x00, +0x00,0x3b,0x11,0xf0,0x00,0x09,0xa0,0x17,0x00,0x10,0x00,0x88,0x80,0x3a,0x3c,0x78, +0x00,0x00,0x3b,0x11,0xf0,0x00,0x09,0xa0,0x17,0x00,0x10,0x00,0x89,0x80,0x42,0x3c, +0x74,0x00,0x00,0x3b,0x11,0xf0,0x00,0x09,0xa0,0x17,0x00,0x10,0x00,0x8a,0x80,0x4a, +0x3c,0x78,0x00,0x00,0x3b,0x11,0xf0,0x00,0x09,0xa0,0x17,0x00,0x10,0x00,0x8b,0x80, +0x51,0x3c,0x0e,0x00,0x00,0x3b,0x11,0xf0,0x00,0x09,0xa0,0x17,0x06,0x10,0x00,0xac, +0x80,0x40,0x3c,0x02,0x00,0x00,0x3f,0x38,0xf0,0x00,0x09,0xa1,0x18,0x00,0x10,0x00, +0xad,0x80,0x58,0x3c,0x01,0x00,0x00,0x3f,0x38,0xf0,0x00,0x09,0xa1,0x18,0x00,0x10, +0x00,0x06,0x80,0x4b,0x3c,0x65,0x00,0x00,0x5b,0x22,0x90,0x00,0x09,0xa0,0x19,0x00, +0x10,0x00,0x07,0x80,0x60,0x3c,0x3a,0x00,0x00,0x5b,0x22,0x90,0x00,0x09,0xa0,0x19, +0x00,0x10,0x00,0x70,0x80,0x4a,0x63,0x67,0x00,0x00,0x75,0x23,0xa0,0x00,0x09,0xa0, +0x1a,0x00,0x1c,0x00,0x70,0x80,0x4a,0x3c,0x78,0x00,0x00,0x51,0x30,0xa0,0x00,0x09, +0xa2,0x1b,0x00,0x10,0x00,0xac,0x80,0x40,0x3c,0x05,0x00,0x00,0x51,0x38,0xf0,0x00, +0x09,0xa0,0x1c,0x00,0x10,0x00,0xad,0x80,0x58,0x3c,0x04,0x00,0x00,0x51,0x38,0xf0, +0x00,0x09,0xa0,0x1c,0x00,0x10,0x00,0x41,0xa0,0x42,0x6b,0x5f,0x00,0x00,0x95,0x3a, +0x75,0x20,0x0a,0xa0,0x1d,0x05,0x10,0x00,0xb3,0x80,0x36,0x3c,0x74,0x00,0x00,0x35, +0x28,0xf5,0x34,0x09,0xa0,0x1e,0x0c,0x10,0x00,0xb7,0x80,0x41,0x3c,0x7f,0x00,0x00, +0x35,0x28,0xf5,0x34,0x09,0xa0,0x1e,0x00,0x10,0x00,0xb5,0x80,0x48,0x3c,0x6d,0x00, +0x00,0x35,0x28,0xf6,0x34,0x09,0xa0,0x1e,0x00,0x10,0x00,0xb4,0x80,0x4e,0x3c,0x74, +0x00,0x00,0x35,0x28,0xf6,0x35,0x09,0xa0,0x1e,0x00,0x10,0x00,0xb6,0x80,0x57,0x3c, +0x63,0x00,0x00,0x35,0x28,0xf6,0x35,0x19,0xa0,0x1e,0x00,0x13,0x00,0x0c,0x80,0x36, +0x3c,0x59,0x00,0x00,0x43,0x28,0xf0,0x04,0x19,0xa0,0x1f,0x00,0x13,0x00,0x0d,0x80, +0x42,0x3c,0x62,0x00,0x00,0x43,0x28,0xf0,0x05,0x09,0xa0,0x1f,0x00,0x13,0x00,0x0e, +0x80,0x4a,0x3c,0x5b,0x00,0x00,0x43,0x28,0xf5,0x94,0x09,0xa0,0x1f,0x00,0x13,0x00, +0x0f,0x80,0x56,0x3c,0x5b,0x00,0x00,0x43,0x28,0xf6,0x95,0x09,0xa0,0x1f,0x00,0x10, +0x00,0x5a,0x80,0x37,0x3c,0x70,0x00,0x00,0x35,0x28,0xf6,0x34,0x09,0xa0,0x20,0x00, +0x10,0x00,0x5b,0x80,0x46,0x3c,0x61,0x00,0x00,0x35,0x28,0xf6,0x34,0x09,0xa0,0x20, +0x00,0x10,0x00,0x5c,0x80,0x53,0x3c,0x52,0x00,0x00,0x35,0x28,0xf6,0x34,0x09,0xa0, +0x20,0x00,0x15,0x20,0x61,0x80,0x35,0x3c,0x4d,0x00,0x00,0x4b,0x29,0xf5,0x54,0x0a, +0xa0,0x21,0x00,0x15,0x20,0x60,0x80,0x3a,0x3c,0x62,0x00,0x00,0x4b,0x29,0xf5,0x54, +0x0a,0xa0,0x21,0x00,0x15,0x20,0x63,0x80,0x3f,0x3c,0x44,0x00,0x00,0x41,0x29,0xf5, +0x55,0x0a,0xa0,0x21,0x00,0x15,0x20,0x62,0x80,0x48,0x3c,0x53,0x00,0x00,0x4b,0x29, +0xf5,0x55,0x0a,0xa0,0x21,0x00,0x15,0x20,0x65,0x80,0x4d,0x3c,0x3b,0x00,0x00,0x4b, +0x29,0xf5,0x55,0x1a,0xa0,0x21,0x00,0x15,0x20,0x64,0x80,0x52,0x3c,0x31,0x00,0x00, +0x4b,0x29,0xf5,0x55,0x1a,0xa0,0x21,0x00,0x15,0x20,0x66,0x80,0x59,0x3c,0x5e,0x00, +0x00,0x4b,0x29,0xf5,0x55,0x2a,0xa0,0x21,0x00,0x15,0x20,0x67,0x80,0x62,0x3c,0x5b, +0x00,0x00,0x4b,0x29,0xf6,0x56,0x0a,0xa0,0x21,0x00,0x10,0x00,0x68,0x80,0x4a,0x3c, +0x78,0x00,0x00,0x33,0x28,0xf6,0x15,0x09,0xa0,0x22,0x00,0x13,0x00,0xa5,0x80,0x39, +0x3c,0x7d,0x00,0x00,0x3f,0x29,0xf2,0x11,0x09,0xa0,0x23,0x00,0x13,0x00,0xa6,0x80, +0x42,0x3c,0x74,0x00,0x00,0x3f,0x29,0xf2,0x11,0x09,0xa0,0x23,0x00,0x12,0x00,0x51, +0x80,0x36,0x3c,0x50,0x00,0x00,0x43,0x21,0xa2,0x12,0x0a,0xa0,0x24,0x00,0x12,0x00, +0x52,0x80,0x3a,0x3c,0x61,0x00,0x00,0x43,0x21,0xa2,0x12,0x0a,0xa0,0x24,0x00,0x12, +0x00,0x53,0x80,0x3e,0x3c,0x78,0x00,0x00,0x43,0x21,0xa2,0x12,0x0a,0xa0,0x24,0x00, +0x12,0x00,0x54,0x80,0x42,0x3c,0x4f,0x00,0x00,0x43,0x21,0xa2,0x12,0x0a,0xa0,0x24, +0x00,0x12,0x00,0x55,0x80,0x46,0x3c,0x61,0x00,0x00,0x43,0x21,0xa2,0x12,0x0a,0xa0, +0x24,0x00,0x12,0x00,0x56,0x80,0x4a,0x3c,0x78,0x00,0x00,0x43,0x21,0xa2,0x12,0x0a, +0xa0,0x24,0x00,0x12,0x00,0x57,0x80,0x4e,0x3c,0x74,0x00,0x00,0x43,0x21,0xa2,0x12, +0x0a,0xa0,0x24,0x00,0x12,0x00,0x58,0x80,0x52,0x3c,0x61,0x00,0x00,0x43,0x21,0xa2, +0x12,0x0a,0xa0,0x24,0x00,0x12,0x00,0x59,0x80,0x56,0x3c,0x20,0x00,0x00,0x43,0x21, +0xa2,0x12,0x0a,0xa0,0x24,0x00,0x10,0x00,0x5e,0x90,0x4d,0x3c,0x3b,0x00,0x00,0x31, +0x28,0xf4,0x24,0x09,0xa0,0x25,0x00,0x10,0x00,0x5d,0x90,0x52,0x3c,0x32,0x00,0x00, +0x1d,0x28,0xf4,0x24,0x09,0xa0,0x25,0x00,0x10,0x00,0x5f,0x90,0x57,0x3c,0x63,0x00, +0x00,0x31,0x28,0xf4,0x24,0x09,0xa0,0x25,0x00,0x10,0x00,0x04,0x80,0x2d,0x3c,0x35, +0x00,0x00,0x1d,0x18,0xf5,0x15,0x09,0xa0,0x26,0x00,0x10,0x00,0x05,0x80,0x47,0x3c, +0x52,0x00,0x00,0x1d,0x18,0xf5,0x15,0x09,0xa0,0x26,0x00,0x10,0x00,0x4a,0x80,0x28, +0x3c,0x7a,0x00,0x00,0x21,0x18,0xf6,0x14,0x09,0xa0,0x27,0x00,0x10,0x00,0x4b,0x80, +0x2d,0x3c,0x72,0x00,0x00,0x21,0x18,0xf6,0x14,0x09,0xa0,0x27,0x00,0x10,0x00,0x4c, +0x80,0x32,0x3c,0x73,0x00,0x00,0x21,0x18,0xf6,0x14,0x09,0xa0,0x27,0x00,0x10,0x00, +0x4d,0x80,0x37,0x3c,0x79,0x00,0x00,0x21,0x18,0xf6,0x14,0x09,0xa0,0x27,0x00,0x12, +0x00,0x4f,0x90,0x3a,0x3c,0x52,0x00,0x00,0x33,0x18,0xf3,0x90,0x0a,0xa0,0x28,0x05, +0x12,0x00,0x50,0x90,0x3f,0x3c,0x56,0x00,0x00,0x33,0x18,0xf3,0x90,0x1a,0xa0,0x28, +0x00,0x12,0x00,0x6b,0x90,0x44,0x3c,0x3e,0x00,0x00,0x33,0x18,0xf3,0x90,0x2a,0xa0, +0x28,0x00,0x12,0x00,0x69,0x90,0x49,0x3c,0x4f,0x00,0x00,0x33,0x18,0xf5,0xb0,0x0a, +0xa0,0x28,0x00,0x12,0x00,0x6a,0x90,0x4e,0x3c,0x51,0x00,0x00,0x33,0x18,0xf5,0xb0, +0x0a,0xa0,0x28,0x00,0x10,0x00,0x4e,0x80,0x43,0x3c,0x71,0x00,0x00,0x2d,0x10,0xf3, +0x63,0x19,0xa0,0x29,0x00,0x12,0x00,0xa3,0x90,0x3d,0x3c,0x76,0x00,0x00,0x21,0x19, +0xf5,0x32,0x1a,0xa0,0x2a,0x00,0x10,0x00,0xa2,0x90,0x44,0x3c,0x66,0x00,0x00,0x25, +0x20,0xb0,0x03,0x09,0xa0,0x2b,0x00,0x12,0x00,0xbe,0x90,0x3e,0x3c,0x6a,0x00,0x00, +0x47,0x39,0xf4,0x14,0x09,0xa0,0x2c,0x00,0x12,0x00,0x17,0x81,0x2d,0x3c,0x67,0x00, +0x00,0x35,0x39,0xf3,0x50,0x08,0xa0,0x2d,0x00,0x13,0x00,0x05,0x81,0x44,0x3c,0x66, +0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00,0x13,0x00,0x02,0x81,0x47,0x3c, +0x52,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00,0x13,0x00,0x06,0x81,0x4c, +0x3c,0x64,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00,0x13,0x00,0x07,0x81, +0x4c,0x3c,0x01,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00,0x13,0x00,0x08, +0x81,0x50,0x3c,0x3c,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00,0x13,0x00, +0x0a,0x81,0x55,0x3c,0x4d,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00,0x13, +0x00,0x0b,0x81,0x57,0x3c,0x64,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e,0x00, +0x13,0x00,0x0c,0x81,0x58,0x3c,0x22,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0,0x2e, +0x00,0x13,0x00,0x0d,0x81,0x5b,0x3c,0x36,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09,0xa0, +0x2e,0x00,0x13,0x00,0x09,0x81,0x5e,0x3c,0x61,0x00,0x00,0x33,0x3b,0xf3,0x20,0x09, +0xa0,0x2e,0x00,0x12,0x00,0x03,0x81,0x3f,0x3c,0x54,0x00,0x00,0x3b,0x3b,0xa3,0x20, +0x09,0xa0,0x2f,0x00,0x12,0x00,0x04,0x81,0x41,0x3c,0x5e,0x00,0x00,0x3b,0x3b,0xa3, +0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x05,0x81,0x44,0x3c,0x66,0x00,0x00,0x3b,0x3b, +0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x02,0x81,0x47,0x3c,0x52,0x00,0x00,0x35, +0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x06,0x81,0x4c,0x3c,0x64,0x00,0x00, +0x3b,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x07,0x81,0x4c,0x3c,0x01,0x00, +0x00,0x3b,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x08,0x81,0x50,0x3c,0x3c, +0x00,0x00,0x2f,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x0a,0x81,0x55,0x3c, +0x4d,0x00,0x00,0x35,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x0b,0x81,0x57, +0x3c,0x64,0x00,0x00,0x2f,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x0c,0x81, +0x58,0x3c,0x22,0x00,0x00,0x35,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00,0x0d, +0x81,0x5b,0x3c,0x36,0x00,0x00,0x2f,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x12,0x00, +0x09,0x81,0x5e,0x3c,0x61,0x00,0x00,0x2f,0x3b,0xa3,0x20,0x09,0xa0,0x2f,0x00,0x13, +0x00,0x12,0x91,0x45,0x3c,0x51,0x00,0x00,0x3f,0x33,0xa0,0x00,0x08,0xa0,0x30,0x00, +0x13,0x00,0x13,0x91,0x4b,0x3c,0x44,0x00,0x00,0x3f,0x33,0xa0,0x00,0x08,0xa0,0x30, +0x00,0x13,0x00,0x15,0x91,0x56,0x3c,0x5a,0x00,0x00,0x3f,0x33,0xa0,0x00,0x18,0xa0, +0x30,0x00,0x13,0x00,0x16,0x91,0x59,0x3c,0x5e,0x00,0x00,0x3f,0x33,0xa0,0x00,0x18, +0xa0,0x30,0x00,0x13,0x00,0x14,0x91,0x5f,0x3c,0x52,0x00,0x00,0x3f,0x33,0xa0,0x00, +0x18,0xa0,0x30,0x00,0x13,0x00,0x10,0x81,0x30,0x3c,0x61,0x00,0x00,0x3d,0x19,0x90, +0x00,0x09,0xa0,0x31,0x00,0x13,0x00,0x11,0x81,0x3c,0x3c,0x52,0x00,0x00,0x3d,0x19, +0x90,0x00,0x09,0xa0,0x31,0x0a,0x12,0x00,0xb0,0x80,0x46,0x3c,0x0a,0x00,0x00,0x21, +0x38,0xf0,0x00,0x07,0xa6,0x32,0x05,0x12,0x00,0x35,0x80,0x4c,0x3c,0x03,0x00,0x00, +0x21,0x38,0xf0,0x00,0x07,0xa6,0x32,0x05,0x12,0x00,0x33,0x80,0x54,0x3c,0x79,0x00, +0x00,0x21,0x38,0xf0,0x00,0x07,0xa6,0x32,0x05,0x12,0x00,0x34,0x80,0x57,0x3c,0x01, +0x00,0x00,0x21,0x38,0xf0,0x00,0x07,0xa6,0x32,0x00,0x12,0x00,0xaf,0x80,0x65,0x3c, +0x68,0x00,0x00,0x21,0x38,0xf0,0x00,0x07,0xa6,0x32,0x00,0x10,0x00,0xb8,0x80,0x3c, +0x3c,0x6a,0x00,0x00,0x43,0x28,0xf0,0x00,0x05,0xa0,0x33,0x00,0x10,0x00,0xb9,0x80, +0x45,0x3c,0x67,0x00,0x00,0x43,0x28,0xf0,0x00,0x05,0xa0,0x33,0x00,0x10,0x00,0xbb, +0x80,0x4c,0x3c,0x72,0x00,0x00,0x43,0x28,0xf0,0x00,0x05,0xa0,0x33,0x00,0x10,0x00, +0xba,0x80,0x53,0x3c,0x6d,0x00,0x00,0x3d,0x28,0xf0,0x00,0x05,0xa0,0x33,0x00,0x10, +0x00,0xbc,0x80,0x5a,0x3c,0x70,0x00,0x00,0x43,0x28,0xf0,0x00,0x05,0xa0,0x33,0x00, +0x10,0x00,0x7e,0x80,0x4f,0x3c,0x5c,0x00,0x00,0x2d,0x29,0xf5,0x25,0x07,0xa0,0x34, +0x00,0x10,0x00,0x7f,0x80,0x5a,0x3c,0x4f,0x00,0x00,0x2d,0x29,0xf5,0x25,0x07,0xa0, +0x34,0x00,0x10,0x70,0x00,0x81,0x39,0x3c,0x6a,0x00,0x00,0x15,0x28,0xf0,0x05,0x16, +0xa0,0x35,0x00,0x10,0x00,0x3c,0x81,0x46,0x3c,0x06,0x00,0x00,0x37,0x20,0x80,0x00, +0x07,0xa0,0x36,0x00,0x10,0x00,0x3e,0x81,0x4c,0x3c,0x03,0x00,0x00,0x37,0x20,0x80, +0x00,0x07,0xa0,0x36,0x00,0x10,0x00,0x3d,0x81,0x54,0x3c,0x72,0x00,0x00,0x37,0x20, +0x80,0x00,0x07,0xa0,0x36,0x00,0x10,0x00,0x3f,0x81,0x57,0x3c,0x05,0x00,0x00,0x41, +0x20,0x80,0x00,0x07,0xa0,0x36,0x00,0x10,0x00,0x40,0x81,0x65,0x3c,0x76,0x00,0x00, +0x41,0x20,0x80,0x00,0x07,0xa0,0x36,0x0a,0x10,0x00,0xb0,0x80,0x46,0x3c,0x0a,0x00, +0x00,0x41,0x19,0xf0,0x00,0x07,0xa0,0x37,0x05,0x10,0x00,0x35,0x80,0x4c,0x3c,0x03, +0x00,0x00,0x41,0x19,0xf0,0x00,0x07,0xa0,0x37,0x05,0x10,0x00,0x33,0x80,0x54,0x3c, +0x79,0x00,0x00,0x41,0x19,0xf0,0x00,0x07,0xa0,0x37,0x05,0x10,0x00,0x34,0x80,0x57, +0x3c,0x01,0x00,0x00,0x41,0x19,0xf0,0x00,0x07,0xa0,0x37,0x00,0x10,0x00,0xaf,0x80, +0x65,0x3c,0x68,0x00,0x00,0x41,0x19,0xf0,0x00,0x07,0xa0,0x37,0xe0,0x10,0x00,0x02, +0x90,0x49,0x3c,0x5d,0x00,0x00,0x59,0x20,0x93,0x22,0x06,0xa0,0x38,0x20,0x10,0x00, +0xae,0x70,0x47,0x3a,0x7d,0x00,0x00,0x39,0x20,0x70,0x01,0x06,0xa0,0x39,0x50,0x10, +0x00,0x02,0x90,0x55,0x3c,0x61,0x00,0x00,0x4b,0x19,0x70,0x00,0x06,0xa0,0x3a,0xb0, +0x10,0x00,0x02,0x90,0x55,0x79,0x55,0x00,0x00,0x4b,0x19,0x70,0x00,0x06,0xa0,0x3b, +0x00,0x10,0x00,0x18,0x80,0x45,0x3c,0x52,0x00,0x00,0x3d,0x1a,0x70,0x00,0x08,0xa0, +0x3c,0x00,0x10,0x00,0x19,0x80,0x4a,0x3c,0x52,0x00,0x00,0x3d,0x1a,0x70,0x00,0x08, +0xa0,0x3c,0x00,0x10,0x00,0x1a,0x80,0x51,0x3c,0x56,0x00,0x00,0x3d,0x1a,0x70,0x00, +0x08,0xa0,0x3c,0x00,0x10,0x00,0x1b,0x80,0x5b,0x3c,0x55,0x00,0x00,0x3d,0x1a,0x70, +0x00,0x08,0xa0,0x3c,0x00,0x10,0x00,0x29,0x80,0x50,0x3c,0x4c,0x00,0x00,0x19,0x20, +0xf7,0x20,0x08,0xa0,0x3d,0x00,0x10,0x00,0x2a,0x80,0x51,0x3c,0x5a,0x00,0x00,0x3d, +0x19,0x85,0x21,0x07,0xa0,0x3e,0x00,0x10,0x00,0x49,0x70,0x3e,0x3c,0x6a,0x00,0x00, +0x01,0x30,0x80,0x05,0x05,0xa0,0x3f,0x00,0x12,0x00,0xf6,0x80,0x47,0x3c,0x22,0x00, +0x00,0x29,0x32,0xf3,0x20,0x0a,0xa0,0x40,0x00,0x12,0x00,0xf8,0x80,0x4e,0x3c,0x76, +0x00,0x00,0x29,0x32,0xf3,0x20,0x0a,0xa0,0x40,0x00,0x12,0x00,0xf7,0x80,0x54,0x3c, +0x6e,0x00,0x00,0x29,0x32,0xf3,0x20,0x0a,0xa0,0x40,0x00,0x12,0x00,0xfa,0x80,0x5a, +0x3c,0x52,0x00,0x00,0x29,0x32,0xf3,0x20,0x0a,0xa0,0x40,0x00,0x12,0x00,0xf9,0x80, +0x5f,0x3c,0x22,0x00,0x00,0x29,0x32,0xf3,0x20,0x0a,0xa0,0x40,0x00,0x12,0x00,0xfb, +0x80,0x66,0x3c,0x52,0x00,0x00,0x29,0x32,0xf3,0x20,0x0a,0xa0,0x40,0x00,0x13,0x00, +0xf0,0x80,0x45,0x3c,0x7d,0x00,0x00,0x29,0x21,0xf0,0x00,0x09,0xa0,0x41,0x00,0x13, +0x00,0xf1,0x80,0x4a,0x3c,0x02,0x00,0x00,0x29,0x21,0xf0,0x00,0x09,0xa0,0x41,0x00, +0x13,0x00,0xf2,0x80,0x50,0x3c,0x3c,0x00,0x00,0x29,0x21,0xf0,0x00,0x09,0xa0,0x41, +0x00,0x13,0x00,0x85,0x80,0x35,0x3c,0x78,0x00,0x00,0x21,0x21,0xf5,0x10,0x09,0xa0, +0x42,0x00,0x13,0x00,0x86,0x80,0x3d,0x3c,0x3e,0x00,0x00,0x21,0x21,0xf5,0x10,0x09, +0xa0,0x42,0x00,0x15,0x00,0xb1,0x80,0x4c,0x3c,0x67,0x00,0x00,0x33,0x28,0xf3,0xf0, +0x0a,0xa1,0x43,0x00,0x15,0x00,0xb2,0x80,0x58,0x3c,0x67,0x00,0x00,0x33,0x28,0x83, +0xf0,0x0a,0xa1,0x43,0x00,0x13,0x00,0x7c,0x80,0x50,0x3c,0x68,0x00,0x00,0x2f,0x1a, +0xf0,0x00,0x09,0xa0,0x44,0x00,0x13,0x00,0x7d,0x80,0x57,0x3c,0x28,0x00,0x00,0x2f, +0x1a,0xf0,0x00,0x09,0xa0,0x44,0x00,0x1a,0x00,0xfc,0x80,0x4a,0x3c,0x57,0x00,0x00, +0x29,0x28,0xf0,0x00,0x0a,0xa0,0x45,0x00,0x1a,0x00,0xfd,0x80,0x56,0x3c,0x66,0x00, +0x00,0x29,0x28,0xf0,0x00,0x0a,0xa0,0x45,0xf0,0x14,0x00,0xd3,0x80,0x25,0x3c,0x49, +0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0,0x14,0x00,0xda,0x80,0x2b,0x3c, +0x52,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0,0x14,0x00,0xd4,0x80,0x31, +0x3c,0x49,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0,0x14,0x00,0xdb,0x80, +0x37,0x3c,0x44,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0,0x14,0x00,0xd5, +0x80,0x3d,0x3c,0x5d,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0,0x14,0x00, +0xdc,0x80,0x43,0x3c,0x4c,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0,0x14, +0x00,0xd6,0x80,0x49,0x3c,0x50,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46,0xf0, +0x14,0x00,0xdd,0x80,0x4f,0x3c,0x60,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0,0x46, +0xf0,0x14,0x00,0xd7,0x80,0x54,0x3c,0x07,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08,0xa0, +0x46,0xf0,0x14,0x00,0xde,0x80,0x5b,0x3c,0x3a,0xfc,0x04,0x41,0x18,0xa5,0x11,0x08, +0xa0,0x46,0xf0,0x14,0x00,0xd8,0x80,0x61,0x3c,0x50,0xfc,0x04,0x41,0x18,0xa5,0x11, +0x08,0xa0,0x46,0xf0,0x14,0x00,0xd9,0x80,0x6d,0x3c,0x50,0xfc,0x04,0x41,0x18,0xa5, +0x11,0x08,0xa0,0x46,0x10,0x12,0x00,0x18,0x81,0x25,0x79,0x57,0xfc,0x04,0x41,0x19, +0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x19,0x81,0x2b,0x79,0x5c,0xfc,0x04,0x41, +0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x1a,0x81,0x31,0x79,0x55,0xfc,0x04, +0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x1b,0x81,0x37,0x79,0x5c,0xfc, +0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x1c,0x81,0x3d,0x79,0x62, +0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x1d,0x81,0x43,0x79, +0x65,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x1e,0x81,0x49, +0x79,0x70,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x1f,0x81, +0x4f,0x79,0x65,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00,0x20, +0x81,0x54,0x79,0x0c,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12,0x00, +0x21,0x81,0x5b,0x79,0x3e,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10,0x12, +0x00,0x22,0x81,0x61,0x79,0x55,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47,0x10, +0x12,0x00,0x23,0x81,0x6d,0x79,0x55,0xfc,0x04,0x41,0x19,0x85,0x23,0x08,0xa0,0x47, +0x30,0x10,0x00,0x18,0x81,0x25,0x3c,0x59,0x00,0x00,0x51,0x26,0x85,0x23,0x08,0xa0, +0x48,0x30,0x10,0x00,0x19,0x81,0x2b,0x3c,0x5e,0x00,0x00,0x51,0x26,0x85,0x23,0x08, +0xa0,0x48,0x30,0x10,0x00,0x1a,0x81,0x31,0x3c,0x57,0x00,0x00,0x51,0x26,0x85,0x23, +0x08,0xa0,0x48,0x30,0x10,0x00,0x1b,0x81,0x37,0x3c,0x5e,0x00,0x00,0x51,0x26,0x85, +0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x1c,0x81,0x3d,0x3c,0x64,0x00,0x00,0x51,0x26, +0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x1d,0x81,0x43,0x3c,0x67,0x00,0x00,0x51, +0x26,0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x1e,0x81,0x49,0x3c,0x72,0x00,0x00, +0x51,0x26,0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x1f,0x81,0x4f,0x3c,0x67,0x00, +0x00,0x51,0x26,0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x20,0x81,0x54,0x3c,0x0e, +0x00,0x00,0x51,0x26,0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x21,0x81,0x5b,0x3c, +0x40,0x00,0x00,0x51,0x26,0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x22,0x81,0x61, +0x3c,0x57,0x00,0x00,0x51,0x26,0x85,0x23,0x08,0xa0,0x48,0x30,0x10,0x00,0x23,0x81, +0x6d,0x3c,0x57,0x00,0x00,0x51,0x26,0x85,0x23,0x08,0xa0,0x48,0xd0,0x10,0x00,0x24, +0x71,0x40,0x79,0x02,0x00,0x00,0x15,0x22,0x85,0x23,0x08,0xa0,0x49,0x00,0x12,0x00, +0xe3,0x80,0x4b,0x3c,0x44,0x00,0x00,0x37,0x21,0xf5,0x20,0x0a,0xa0,0x4a,0x00,0x12, +0x00,0xe4,0x80,0x51,0x3c,0x67,0x00,0x00,0x37,0x21,0xf5,0x20,0x0a,0xa0,0x4a,0x00, +0x12,0x00,0xe5,0x80,0x57,0x3c,0x24,0x00,0x00,0x29,0x21,0xf5,0x20,0x0a,0xa0,0x4a, +0x00,0x12,0x00,0xe6,0x80,0x5c,0x3c,0x12,0x00,0x00,0x29,0x21,0xf5,0x20,0x0a,0xa0, +0x4a,0x00,0x12,0x00,0xe7,0x80,0x63,0x3c,0x62,0x00,0x00,0x29,0x21,0xf5,0x20,0x0a, +0xa0,0x4a,0x00,0x12,0x00,0xe8,0x80,0x5e,0x3c,0x02,0x00,0x00,0x37,0x21,0xf5,0x20, +0x0a,0xa0,0x4a,0x00,0x12,0x00,0x92,0x80,0x3c,0x3c,0x7c,0x00,0x00,0x41,0x19,0xf5, +0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x96,0x80,0x3f,0x3c,0x74,0x00,0x00,0x41,0x19, +0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x99,0x80,0x42,0x3c,0x06,0x00,0x00,0x41, +0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x8f,0x80,0x44,0x3c,0x14,0x00,0x00, +0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x93,0x80,0x47,0x3c,0x22,0x00, +0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x97,0x80,0x4a,0x3c,0x21, +0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x9a,0x80,0x4e,0x3c, +0x75,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x90,0x80,0x51, +0x3c,0x69,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x94,0x80, +0x54,0x3c,0x6f,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00,0x98, +0x80,0x57,0x3c,0x66,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12,0x00, +0x9b,0x80,0x59,0x3c,0x19,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00,0x12, +0x00,0x91,0x80,0x5c,0x3c,0x68,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b,0x00, +0x12,0x00,0x95,0x80,0x5e,0x3c,0x04,0x00,0x00,0x41,0x19,0xf5,0x20,0x0b,0xa0,0x4b, +0x00,0x12,0x00,0xe9,0x80,0x3b,0x3c,0x5d,0x00,0x00,0x43,0x19,0xf4,0x10,0x0b,0xa0, +0x4c,0x00,0x12,0x00,0xea,0x80,0x3f,0x3c,0x55,0x00,0x00,0x43,0x19,0xf4,0x10,0x0b, +0xa0,0x4c,0x00,0x12,0x00,0xeb,0x80,0x45,0x3c,0x7d,0x00,0x00,0x43,0x19,0xf4,0x10, +0x0b,0xa0,0x4c,0x00,0x12,0x00,0xed,0x80,0x4b,0x3c,0x05,0x00,0x00,0x43,0x19,0xf4, +0x10,0x0b,0xa0,0x4c,0x00,0x12,0x00,0xec,0x80,0x53,0x3c,0x52,0x00,0x00,0x43,0x19, +0xf4,0x10,0x0b,0xa0,0x4c,0x00,0x12,0x00,0xee,0x80,0x59,0x3c,0x5e,0x00,0x00,0x43, +0x19,0xf4,0x10,0x0b,0xa0,0x4c,0x00,0x12,0x00,0xef,0x80,0x61,0x3c,0x4d,0x00,0x00, +0x43,0x19,0xf4,0x10,0x0b,0xa0,0x4c,0x00,0x12,0x00,0xdf,0x80,0x38,0x3c,0x7a,0x00, +0x00,0x31,0x19,0xf0,0x00,0x0a,0xa0,0x4d,0x00,0x12,0x00,0xe1,0x80,0x41,0x3c,0x70, +0x00,0x00,0x31,0x19,0xf0,0x00,0x0a,0xa0,0x4d,0x00,0x12,0x00,0xe2,0x80,0x44,0x3c, +0x7a,0x00,0x00,0x31,0x19,0xf0,0x00,0x0a,0xa0,0x4d,0x00,0x12,0x00,0xe0,0x80,0x49, +0x3c,0x15,0x00,0x00,0x31,0x19,0xf0,0x00,0x0a,0xa0,0x4d,0x00,0x12,0x00,0x42,0x80, +0x49,0x3c,0x4d,0x00,0x00,0x19,0x39,0xf4,0x10,0x0a,0xa0,0x4e,0x00,0x12,0x00,0x44, +0x80,0x4f,0x3c,0x36,0x00,0x00,0x23,0x39,0xf4,0x10,0x0a,0xa0,0x4e,0x00,0x12,0x00, +0x43,0x80,0x55,0x3c,0x4c,0x00,0x00,0x23,0x39,0xf4,0x10,0x0a,0xa0,0x4e,0x00,0x12, +0x00,0x46,0x80,0x5b,0x3c,0x36,0x00,0x00,0x23,0x39,0xf4,0x10,0x0a,0xa0,0x4e,0x00, +0x12,0x00,0x45,0x80,0x61,0x3c,0x4c,0x00,0x00,0x23,0x39,0xf4,0x10,0x0a,0xa0,0x4e, +0x00,0x12,0x00,0x47,0x80,0x67,0x3c,0x36,0x00,0x00,0x19,0x39,0xf4,0x10,0x0a,0xa0, +0x4e,0x00,0x12,0x00,0x3c,0x80,0x44,0x3c,0x2a,0x00,0x00,0x3b,0x31,0xf0,0x00,0x09, +0xa0,0x4f,0x00,0x12,0x00,0x3b,0x80,0x4a,0x3c,0x03,0x00,0x00,0x3b,0x31,0xf0,0x00, +0x09,0xa0,0x4f,0x00,0x12,0x00,0x3d,0x80,0x50,0x3c,0x14,0x00,0x00,0x3b,0x31,0xf0, +0x00,0x09,0xa0,0x4f,0x00,0x13,0x00,0x38,0x80,0x2f,0x3c,0x59,0x00,0x00,0x39,0x31, +0xf0,0x00,0x0b,0xa0,0x50,0x00,0x13,0x00,0x3a,0x80,0x35,0x3c,0x5e,0x00,0x00,0x39, +0x31,0xf0,0x00,0x0b,0xa0,0x50,0x00,0x13,0x00,0x39,0x80,0x3b,0x3c,0x5e,0x00,0x00, +0x39,0x31,0xf0,0x00,0x0b,0xa0,0x50,0x00,0x13,0x00,0x9e,0x80,0x3e,0x3c,0x4c,0x00, +0x00,0x37,0x29,0xf3,0x20,0x0a,0xa0,0x51,0x00,0x13,0x00,0xa0,0x80,0x44,0x3c,0x66, +0x00,0x00,0x37,0x29,0xf3,0x20,0x0a,0xa0,0x51,0x00,0x13,0x00,0x9f,0x80,0x4b,0x3c, +0x64,0x00,0x00,0x37,0x29,0xf3,0x20,0x0a,0xa0,0x51,0x00,0x13,0x00,0xa1,0x80,0x55, +0x3c,0x4d,0x00,0x00,0x37,0x29,0xf3,0x20,0x0a,0xa0,0x51,0x00,0x10,0x00,0x71,0x80, +0x46,0x3c,0x03,0x00,0x00,0x19,0x38,0xf0,0x00,0x0a,0xa2,0x52,0x00,0x10,0x00,0x72, +0x80,0x52,0x3c,0x32,0x00,0x00,0x19,0x38,0xf0,0x00,0x0a,0xa2,0x52,0x00,0x10,0x00, +0x73,0x80,0x5e,0x3c,0x03,0x00,0x00,0x19,0x38,0xf0,0x00,0x0a,0xa2,0x52,0x00,0x10, +0x00,0x74,0x80,0x5c,0x3c,0x65,0x00,0x00,0x19,0x38,0xf0,0x00,0x0a,0xa2,0x52,0x00, +0x10,0x00,0x75,0x80,0x61,0x3c,0x4d,0x00,0x00,0x19,0x38,0xf0,0x00,0x0a,0xa2,0x52, +0x00,0x16,0x00,0x71,0x80,0x46,0x3c,0x03,0x00,0x00,0x23,0x38,0xf0,0x00,0x0a,0xa2, +0x53,0x00,0x16,0x00,0x72,0x80,0x52,0x3c,0x32,0x00,0x00,0x23,0x38,0xf0,0x00,0x0a, +0xa2,0x53,0x00,0x16,0x00,0x73,0x80,0x5e,0x3c,0x03,0x00,0x00,0x19,0x38,0xf0,0x00, +0x0a,0xa2,0x53,0x00,0x10,0x00,0xbd,0x80,0x46,0x3c,0x61,0x00,0x00,0x13,0x30,0x70, +0x00,0x09,0xa1,0x54,0x00,0x10,0x00,0x77,0x80,0x5a,0x3c,0x77,0x00,0x00,0x21,0x38, +0xf0,0x00,0x09,0xa3,0x55,0x00,0x13,0x00,0x77,0x80,0x5a,0x3c,0x77,0x00,0x00,0x37, +0x38,0xf0,0x00,0x09,0xa1,0x56,0x0e,0x10,0x01,0x25,0x81,0x52,0x3c,0x6d,0xfa,0x12, +0x7f,0x00,0xf0,0x00,0x09,0xa0,0x57,0x00,0x10,0x00,0xab,0x80,0x48,0x3c,0x04,0x00, +0x00,0x29,0x30,0xf0,0x00,0x0a,0xa3,0x58,0x00,0x12,0x00,0x76,0x80,0x4f,0x3c,0x44, +0x00,0x00,0x5d,0x28,0x70,0x00,0x09,0xa2,0x59,0x00,0x10,0x00,0xaa,0x80,0x5e,0x3c, +0x03,0xfb,0x01,0x2d,0x2c,0x70,0x00,0x0a,0xa0,0x5a,0x00,0x10,0x00,0xaa,0x80,0x5e, +0x3c,0x03,0x00,0x00,0x31,0x29,0x90,0x00,0x0a,0xa1,0x5b,0x30,0x10,0x00,0xcc,0x90, +0x2b,0x3c,0x3d,0x00,0x00,0x53,0x38,0xc6,0x21,0x09,0xa0,0x5c,0x30,0x10,0x00,0xcd, +0x80,0x37,0x3c,0x41,0x00,0x00,0x53,0x38,0xc6,0x21,0x09,0xa0,0x5c,0x30,0x10,0x00, +0xca,0x80,0x43,0x3c,0x40,0x00,0x00,0x53,0x38,0xc6,0x21,0x09,0xa0,0x5c,0x30,0x10, +0x00,0xcf,0x80,0x4f,0x3c,0x41,0x00,0x00,0x53,0x38,0xc6,0x21,0x09,0xa0,0x5c,0x30, +0x10,0x00,0xce,0x80,0x5b,0x3c,0x40,0x00,0x00,0x53,0x38,0xc6,0x21,0x09,0xa0,0x5c, +0x30,0x10,0x00,0xcb,0x80,0x67,0x3c,0x40,0x00,0x00,0x53,0x38,0xc6,0x21,0x09,0xa0, +0x5c,0xd0,0x10,0x00,0xcc,0x90,0x2b,0x79,0x34,0x00,0x00,0x53,0x08,0xc6,0x21,0x09, +0xa0,0x5d,0xd0,0x10,0x00,0xcd,0x80,0x37,0x79,0x38,0x00,0x00,0x53,0x08,0xc6,0x21, +0x09,0xa0,0x5d,0xd0,0x10,0x00,0xca,0x80,0x43,0x79,0x37,0x00,0x00,0x53,0x08,0xc6, +0x21,0x09,0xa0,0x5d,0xd0,0x10,0x00,0xcf,0x80,0x4f,0x79,0x38,0x00,0x00,0x53,0x08, +0xc6,0x21,0x09,0xa0,0x5d,0xd0,0x10,0x00,0xce,0x80,0x5b,0x79,0x37,0x00,0x00,0x53, +0x08,0xc6,0x21,0x09,0xa0,0x5d,0xd0,0x10,0x00,0xcb,0x80,0x67,0x79,0x37,0x00,0x00, +0x53,0x08,0xc6,0x21,0x09,0xa0,0x5d,0x00,0x10,0x00,0x18,0x81,0x25,0x3c,0x54,0x00, +0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x19,0x81,0x2b,0x3c,0x59, +0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1a,0x81,0x31,0x3c, +0x52,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1b,0x81,0x37, +0x3c,0x59,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1c,0x81, +0x3d,0x3c,0x5f,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1d, +0x81,0x43,0x3c,0x62,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00, +0x1e,0x81,0x49,0x3c,0x6d,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10, +0x00,0x1f,0x81,0x4f,0x3c,0x62,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00, +0x10,0x00,0x20,0x81,0x54,0x3c,0x09,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e, +0x00,0x10,0x00,0x21,0x81,0x5b,0x3c,0x3b,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0, +0x5e,0x00,0x10,0x00,0x22,0x81,0x61,0x3c,0x52,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a, +0xa0,0x5e,0x00,0x10,0x00,0x23,0x81,0x6d,0x3c,0x52,0x00,0x00,0x37,0x30,0xf2,0x22, +0x0a,0xa0,0x5e,0x00,0x10,0x00,0x18,0x81,0x25,0x3c,0x4a,0x00,0x00,0x37,0x30,0xf2, +0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x19,0x81,0x2b,0x3c,0x4f,0x00,0x00,0x37,0x30, +0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1a,0x81,0x31,0x3c,0x48,0x00,0x00,0x37, +0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1b,0x81,0x37,0x3c,0x4f,0x00,0x00, +0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1c,0x81,0x3d,0x3c,0x55,0x00, +0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1d,0x81,0x43,0x3c,0x58, +0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1e,0x81,0x49,0x3c, +0x63,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x1f,0x81,0x4f, +0x3c,0x58,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x20,0x81, +0x55,0x3c,0x7f,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00,0x21, +0x81,0x5b,0x3c,0x31,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10,0x00, +0x22,0x81,0x61,0x3c,0x48,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00,0x10, +0x00,0x23,0x81,0x6d,0x3c,0x48,0x00,0x00,0x37,0x30,0xf2,0x22,0x0a,0xa0,0x5e,0x00, +0x10,0x00,0xaa,0x80,0x5e,0x3c,0x03,0x00,0x00,0x3d,0x28,0x90,0x00,0x0a,0xa2,0x5f, +0x00,0x10,0x00,0x76,0x80,0x4f,0x79,0x44,0x00,0x00,0x49,0x28,0xb0,0x00,0x09,0xa2, +0x60,0x00,0x12,0x00,0x3a,0x71,0x43,0x3c,0x11,0x00,0x00,0x33,0x2a,0xf0,0x00,0x09, +0xa1,0x61,0x00,0x10,0x00,0xfe,0x80,0x4f,0x79,0x0c,0x00,0x00,0x41,0x28,0xf3,0x00, +0x17,0xa0,0x62,0x00,0x12,0x00,0xa5,0x80,0x38,0x3c,0x02,0x00,0x00,0x45,0x33,0xf2, +0x11,0x09,0xa0,0x63,0x00,0x12,0x00,0xa6,0x80,0x42,0x3c,0x79,0x00,0x00,0x45,0x33, +0xf2,0x11,0x09,0xa0,0x63,0x00,0x13,0x00,0x18,0x81,0x25,0x79,0x4a,0x00,0x00,0x5b, +0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x19,0x81,0x2b,0x79,0x4f,0x00,0x00, +0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x1a,0x81,0x31,0x79,0x48,0x00, +0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x1b,0x81,0x37,0x79,0x4f, +0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x1c,0x81,0x3d,0x79, +0x55,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x1d,0x81,0x43, +0x79,0x58,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x1e,0x81, +0x49,0x79,0x63,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00,0x1f, +0x81,0x4f,0x79,0x58,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13,0x00, +0x20,0x81,0x55,0x79,0x7f,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00,0x13, +0x00,0x21,0x81,0x5b,0x79,0x31,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64,0x00, +0x13,0x00,0x22,0x81,0x61,0x79,0x48,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0,0x64, +0x00,0x13,0x00,0x23,0x81,0x6d,0x79,0x48,0x00,0x00,0x5b,0x2a,0xf2,0x22,0x0e,0xa0, +0x64,0x00,0x10,0x00,0xaa,0x80,0x5e,0x3c,0x0b,0x00,0x00,0x73,0x2e,0x90,0x00,0x0a, +0xa0,0x65,0x00,0x10,0x00,0x2a,0x80,0x51,0x79,0x52,0x00,0x00,0x27,0x29,0xf0,0x05, +0x0a,0xa0,0x66,0x00,0x10,0x00,0x18,0x81,0x2a,0x3c,0x54,0x00,0x00,0x2f,0x32,0xf5, +0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x19,0x81,0x30,0x3c,0x59,0x00,0x00,0x2f,0x32, +0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x1a,0x81,0x36,0x3c,0x52,0x00,0x00,0x2f, +0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x1b,0x81,0x3c,0x3c,0x59,0x00,0x00, +0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x1c,0x81,0x42,0x3c,0x5f,0x00, +0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x1d,0x81,0x48,0x3c,0x62, +0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x1e,0x81,0x4e,0x3c, +0x6d,0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x1f,0x81,0x54, +0x3c,0x62,0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x20,0x81, +0x59,0x3c,0x09,0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00,0x21, +0x81,0x60,0x3c,0x3b,0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10,0x00, +0x22,0x81,0x66,0x3c,0x52,0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00,0x10, +0x00,0x23,0x81,0x72,0x3c,0x52,0x00,0x00,0x2f,0x32,0xf5,0x20,0x08,0xa0,0x67,0x00, +0x10,0x00,0x02,0x90,0x55,0x79,0x57,0x00,0x00,0x47,0x31,0xb3,0x20,0x0b,0xa0,0x68, +0x00,0x10,0x00,0x17,0x81,0x2d,0x3c,0x6d,0x00,0x00,0x43,0x29,0xf1,0x50,0x08,0xa0, +0x69,0x00,0x10,0x00,0x18,0x81,0x25,0x79,0x49,0x00,0x00,0x43,0x2a,0xf2,0x20,0x0a, +0xa0,0x6a,0x00,0x10,0x00,0x19,0x81,0x2b,0x79,0x4e,0x00,0x00,0x43,0x2a,0xf2,0x20, +0x0a,0xa0,0x6a,0x00,0x10,0x00,0x1a,0x81,0x31,0x79,0x47,0x00,0x00,0x43,0x2a,0xf2, +0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x1b,0x81,0x37,0x79,0x4e,0x00,0x00,0x43,0x2a, +0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x1c,0x81,0x3d,0x79,0x54,0x00,0x00,0x43, +0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x1d,0x81,0x43,0x79,0x57,0x00,0x00, +0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x1e,0x81,0x49,0x79,0x62,0x00, +0x00,0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x1f,0x81,0x4f,0x79,0x57, +0x00,0x00,0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x20,0x81,0x55,0x79, +0x7e,0x00,0x00,0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x21,0x81,0x5b, +0x79,0x30,0x00,0x00,0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x22,0x81, +0x61,0x79,0x47,0x00,0x00,0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x10,0x00,0x23, +0x81,0x6d,0x79,0x47,0x00,0x00,0x43,0x2a,0xf2,0x20,0x0a,0xa0,0x6a,0x00,0x12,0x00, +0x02,0x90,0x55,0x3c,0x55,0x00,0x00,0x5b,0x24,0x80,0x01,0x05,0xa0,0x6b,0x00,0x12, +0x30,0xf3,0x80,0x4b,0x3c,0x5d,0x00,0x00,0x73,0x23,0xa2,0x14,0x06,0xa1,0x6c,0x20, +0x10,0x30,0x4e,0x80,0x43,0x3c,0x7a,0x00,0x00,0x6d,0x2a,0x34,0x23,0x05,0xa2,0x6d, +0xe0,0x10,0x00,0x29,0x80,0x50,0x3c,0x37,0x00,0x00,0x41,0x22,0x31,0x23,0x06,0xa0, +0x6e,0x00,0x15,0x10,0x18,0x81,0x25,0x3c,0x57,0x00,0x00,0x45,0x23,0xf0,0x20,0x07, +0xa1,0x6f,0x00,0x15,0x10,0x19,0x81,0x2b,0x3c,0x5c,0x00,0x00,0x45,0x23,0xf0,0x20, +0x07,0xa1,0x6f,0x00,0x15,0x10,0x1a,0x81,0x31,0x3c,0x55,0x00,0x00,0x45,0x23,0xf0, +0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x1b,0x81,0x37,0x3c,0x5c,0x00,0x00,0x45,0x23, +0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x1c,0x81,0x3d,0x3c,0x62,0x00,0x00,0x45, +0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x1d,0x81,0x43,0x3c,0x65,0x00,0x00, +0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x1e,0x81,0x49,0x3c,0x70,0x00, +0x00,0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x1f,0x81,0x4f,0x3c,0x65, +0x00,0x00,0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x00,0x20,0x81,0x54,0x3c, +0x0c,0x00,0x00,0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x21,0x81,0x5b, +0x3c,0x3e,0x00,0x00,0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x22,0x81, +0x61,0x3c,0x55,0x00,0x00,0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x15,0x10,0x23, +0x81,0x6d,0x3c,0x55,0x00,0x00,0x45,0x23,0xf0,0x20,0x07,0xa1,0x6f,0x00,0x12,0x30, +0x24,0x71,0x41,0x3c,0x78,0x00,0x00,0x45,0x22,0xe2,0x21,0x08,0xa0,0x70,0x00,0x10, +0x00,0x18,0x80,0x45,0x3c,0x52,0x00,0x00,0x4f,0x25,0x70,0x00,0x06,0xa0,0x71,0x00, +0x10,0x00,0x19,0x80,0x4a,0x3c,0x52,0x00,0x00,0x4f,0x25,0x70,0x00,0x06,0xa0,0x71, +0x00,0x10,0x00,0x1a,0x80,0x51,0x3c,0x56,0x00,0x00,0x4f,0x25,0x70,0x00,0x06,0xa0, +0x71,0x00,0x10,0x00,0x1b,0x80,0x5b,0x3c,0x55,0x00,0x00,0x4f,0x25,0x70,0x00,0x06, +0xa0,0x71,0x00,0x10,0x00,0x2a,0x80,0x51,0x79,0x5a,0x00,0x00,0x57,0x24,0x65,0x21, +0x06,0xa0,0x72,0xf0,0x10,0x00,0x01,0x81,0x47,0x3c,0x76,0x00,0x00,0x41,0x19,0x44, +0x14,0x16,0xa0,0x73,0x10,0x10,0x00,0xaa,0x80,0x5f,0x79,0x78,0x00,0x00,0x6b,0x19, +0x40,0x00,0x06,0xa0,0x74,0x00,0x10,0x00,0x0c,0x80,0x36,0x3c,0x5f,0x00,0x00,0x51, +0x0a,0x60,0x01,0x06,0xa0,0x75,0x00,0x10,0x00,0x0d,0x80,0x42,0x3c,0x68,0x00,0x00, +0x51,0x0a,0x60,0x01,0x06,0xa0,0x75,0x00,0x10,0x00,0x0e,0x80,0x4a,0x3c,0x61,0x00, +0x00,0x51,0x0a,0x60,0x01,0x06,0xa0,0x75,0x00,0x10,0x00,0x0f,0x80,0x56,0x3c,0x61, +0x00,0x00,0x51,0x0a,0x60,0x01,0x06,0xa0,0x75,0x00,0x10,0x00,0x3f,0x80,0x4b,0x79, +0x40,0x00,0x00,0x59,0x31,0x65,0x12,0x07,0xa0,0x76,0x00,0x10,0x00,0x24,0x71,0x40, +0x3c,0x06,0x00,0x00,0x59,0x1a,0x85,0x23,0x08,0xa0,0x77,0x00,0x10,0x00,0x2a,0x80, +0x51,0x79,0x4f,0x00,0x00,0x3f,0x1b,0xc0,0x05,0x06,0xa0,0x78,0x00,0x10,0x70,0xd3, +0x80,0x25,0x3c,0x4c,0x00,0x00,0x29,0x19,0x33,0x11,0x06,0xa0,0x79,0x00,0x10,0x70, +0xda,0x80,0x2b,0x3c,0x55,0x00,0x00,0x29,0x19,0x33,0x11,0x06,0xa0,0x79,0x00,0x10, +0x70,0xd4,0x80,0x31,0x3c,0x4c,0x00,0x00,0x29,0x19,0x33,0x11,0x06,0xa0,0x79,0x00, +0x10,0x70,0xdb,0x80,0x37,0x3c,0x47,0x00,0x00,0x29,0x19,0x33,0x11,0x06,0xa0,0x79, +0x00,0x10,0x70,0xd5,0x80,0x3d,0x3c,0x60,0x00,0x00,0x29,0x19,0x33,0x11,0x06,0xa0, +0x79,0x00,0x10,0x70,0xdc,0x80,0x43,0x3c,0x4f,0x00,0x00,0x29,0x19,0x33,0x11,0x06, +0xa0,0x79,0x00,0x10,0x70,0xd6,0x80,0x49,0x3c,0x53,0x00,0x00,0x29,0x19,0x33,0x11, +0x06,0xa0,0x79,0x00,0x10,0x70,0xdd,0x80,0x4f,0x3c,0x63,0x00,0x00,0x29,0x19,0x33, +0x11,0x06,0xa0,0x79,0x00,0x10,0x70,0xd7,0x80,0x54,0x3c,0x0a,0x00,0x00,0x29,0x19, +0x33,0x11,0x06,0xa0,0x79,0x00,0x10,0x70,0xde,0x80,0x5b,0x3c,0x3d,0x00,0x00,0x29, +0x19,0x33,0x11,0x06,0xa0,0x79,0x00,0x10,0x70,0xd8,0x80,0x61,0x3c,0x53,0x00,0x00, +0x29,0x19,0x33,0x11,0x06,0xa0,0x79,0x00,0x10,0x70,0xd9,0x80,0x6d,0x3c,0x53,0x00, +0x00,0x29,0x19,0x33,0x11,0x06,0xa0,0x79,0x00,0x10,0x70,0xd3,0x80,0x25,0x3c,0x40, +0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00,0x10,0x70,0xda,0x80,0x2b,0x3c, +0x49,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00,0x10,0x70,0xd4,0x80,0x31, +0x3c,0x40,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00,0x10,0x70,0xdb,0x80, +0x37,0x3c,0x3b,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00,0x10,0x70,0xd5, +0x80,0x3d,0x3c,0x54,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00,0x10,0x70, +0xdc,0x80,0x43,0x3c,0x43,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00,0x10, +0x70,0xd6,0x80,0x49,0x3c,0x47,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a,0x00, +0x10,0x70,0xdd,0x80,0x4f,0x3c,0x57,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0,0x7a, +0x00,0x10,0x70,0xd7,0x80,0x55,0x3c,0x7e,0x00,0x00,0x29,0x18,0x33,0x11,0x06,0xa0, +0x7a,0x00,0x10,0x70,0xde,0x80,0x5b,0x3c,0x31,0x00,0x00,0x29,0x18,0x33,0x11,0x06, +0xa0,0x7a,0x00,0x10,0x70,0xd8,0x80,0x61,0x3c,0x47,0x00,0x00,0x29,0x18,0x33,0x11, +0x06,0xa0,0x7a,0x00,0x10,0x70,0xd9,0x80,0x6d,0x3c,0x47,0x00,0x00,0x29,0x18,0x33, +0x11,0x06,0xa0,0x7a,0x00,0x10,0x00,0x4e,0x80,0x43,0x3c,0x71,0xfd,0x01,0x33,0x22, +0xa3,0x63,0x17,0xa0,0x7b,0x00,0x10,0x30,0x43,0x61,0x47,0x5b,0x7d,0x2b,0x2a,0x91, +0x2a,0xf0,0x05,0x05,0x20,0x7c,0x00,0x10,0x00,0x02,0x90,0x55,0x3c,0x55,0x00,0x00, +0x49,0x2a,0x60,0x01,0x05,0xa0,0x7d,0x00,0x10,0x30,0xf3,0x70,0x57,0x79,0x48,0x00, +0x00,0x57,0x2d,0x52,0x14,0x06,0xa2,0x7e,0x00,0x10,0x00,0xf3,0x70,0x52,0x3c,0x62, +0x00,0x00,0x47,0x33,0xf6,0x25,0x25,0xa0,0x7f,0x00,0x10,0x00,0x6d,0x80,0x32,0x3c, +0x5e,0x00,0x00,0x53,0x3b,0x85,0x24,0x06,0xa0,0x80,0x00,0x10,0x00,0x6e,0x80,0x3e, +0x3c,0x65,0x00,0x00,0x53,0x3b,0x85,0x24,0x06,0xa0,0x80,0x09,0x10,0x00,0x6f,0x80, +0x4a,0x3c,0x73,0x00,0x00,0x53,0x3b,0x85,0x24,0x06,0xa0,0x80,0x00,0x12,0x00,0x02, +0x90,0x55,0x3c,0x5d,0x00,0x00,0x37,0x32,0x73,0x22,0x06,0xa1,0x81,0x05,0x12,0x00, +0xb3,0x80,0x36,0x79,0x74,0x00,0x00,0x3d,0x32,0xf5,0x34,0x07,0xa2,0x82,0x0c,0x12, +0x00,0xb7,0x80,0x41,0x79,0x7f,0x00,0x00,0x3d,0x32,0xf5,0x34,0x07,0xa2,0x82,0x00, +0x12,0x00,0xb5,0x80,0x48,0x79,0x6d,0x00,0x00,0x3d,0x32,0xf6,0x34,0x07,0xa2,0x82, +0x00,0x12,0x00,0xb4,0x80,0x4e,0x79,0x74,0x00,0x00,0x3d,0x32,0xf6,0x35,0x07,0xa2, +0x82,0x00,0x12,0x00,0xb6,0x80,0x57,0x79,0x63,0x00,0x00,0x3d,0x32,0xf6,0x35,0x17, +0xa2,0x82,0x00,0x10,0x00,0x37,0x91,0x4f,0x3c,0x65,0x00,0x00,0x41,0x2a,0xf5,0x18, +0x08,0xa0,0x83,0x00,0x10,0x00,0x2a,0x80,0x51,0x79,0x59,0x00,0x00,0x37,0x29,0xc0, +0x05,0x05,0xa0,0x84,0xf0,0x10,0x00,0x02,0x90,0x55,0x3c,0x55,0x00,0x00,0x35,0x2a, +0x30,0x00,0x05,0xa0,0x85,0x10,0x10,0x30,0x09,0x70,0x44,0x52,0x52,0xef,0x01,0xc3, +0x0c,0x20,0x00,0x06,0x20,0x86,0x00,0x10,0x00,0x2a,0x80,0x51,0x3c,0x5f,0x00,0x00, +0x51,0x2b,0xf5,0x21,0x06,0xa0,0x87,0x00,0x10,0x00,0x24,0x71,0x41,0x79,0x7b,0x00, +0x00,0x51,0x2b,0x85,0x23,0x07,0xa0,0x88,0x00,0x10,0x30,0x0c,0x80,0x36,0x3c,0x5c, +0x00,0x00,0x01,0x2b,0x90,0x05,0x06,0xa3,0x89,0x00,0x10,0x30,0x0d,0x80,0x42,0x3c, +0x65,0x00,0x00,0x01,0x2b,0x90,0x05,0x06,0xa3,0x89,0x00,0x10,0x30,0x0e,0x80,0x4a, +0x3c,0x5e,0x00,0x00,0x01,0x2b,0x90,0x05,0x06,0xa3,0x89,0x00,0x10,0x30,0x0f,0x80, +0x56,0x3c,0x5e,0x00,0x00,0x01,0x2b,0x90,0x05,0x06,0xa3,0x89,0x00,0x10,0x00,0x02, +0x90,0x55,0x3c,0x52,0x00,0x00,0x01,0x22,0x80,0x01,0x05,0xa0,0x8a,0x00,0x10,0x00, +0x0f,0x81,0x4a,0x3c,0x78,0x00,0x00,0x01,0x32,0xf4,0x15,0x16,0xa1,0x8b,0x00,0x10, +0x00,0x13,0x80,0x40,0x3c,0x75,0x00,0x00,0x23,0x38,0xf0,0x05,0x09,0xa0,0x8c,0x00, +0x10,0x00,0x14,0x80,0x45,0x3c,0x51,0x00,0x00,0x23,0x38,0xf0,0x05,0x09,0xa0,0x8c, +0x00,0x10,0x00,0x12,0x80,0x49,0x3c,0x68,0x00,0x00,0x23,0x38,0xf0,0x05,0x09,0xa0, +0x8c,0x00,0x10,0x00,0x15,0x80,0x50,0x3c,0x66,0x00,0x00,0x23,0x38,0xf0,0x05,0x09, +0xa0,0x8c,0x00,0x10,0x00,0x17,0x80,0x57,0x3c,0x25,0x00,0x00,0x23,0x38,0xf0,0x05, +0x09,0xa0,0x8c,0x00,0x10,0x00,0x16,0x80,0x5f,0x3c,0x20,0x00,0x00,0x23,0x38,0xf0, +0x05,0x09,0xa0,0x8c,0x00,0x10,0x20,0x0e,0x81,0x52,0x3c,0x09,0x00,0x00,0x07,0x28, +0xf7,0x35,0x45,0xa2,0x8d,0x00,0x12,0x00,0xa9,0x80,0x4c,0x3c,0x01,0x00,0x00,0x39, +0x20,0xf0,0x04,0x07,0xa0,0x8e,0x00,0x10,0x00,0x37,0x81,0x4f,0x3c,0x65,0x00,0x00, +0x31,0x38,0xf5,0x18,0x08,0xa0,0x8f,0x00,0x12,0x20,0xa4,0x80,0x30,0x3c,0x43,0x00, +0x00,0x1f,0x1c,0xf0,0x00,0x09,0xa0,0x90,0x00,0x10,0x20,0xa7,0x80,0x30,0x61,0x40, +0x00,0x00,0x1f,0x19,0xf0,0x00,0x09,0xa0,0x91,0x00,0x10,0x20,0xa8,0x80,0x4f,0x61, +0x31,0x00,0x00,0x1f,0x19,0xf0,0x00,0x09,0xa0,0x91,0x00,0x12,0x00,0x05,0x81,0x44, +0x3c,0x66,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0,0x92,0x00,0x12,0x00,0x02,0x81, +0x47,0x3c,0x52,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0,0x92,0x00,0x12,0x00,0x06, +0x81,0x4c,0x3c,0x64,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0,0x92,0x00,0x12,0x00, +0x07,0x81,0x4c,0x3c,0x01,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0,0x92,0x00,0x12, +0x00,0x08,0x81,0x50,0x3c,0x3c,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0,0x92,0x00, +0x12,0x00,0x0a,0x81,0x55,0x3c,0x4d,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0,0x92, +0x00,0x12,0x00,0x0b,0x81,0x57,0x3c,0x64,0x00,0x00,0x35,0x31,0xf3,0x20,0x09,0xa0, +0x92,0x00,0x12,0x00,0x0c,0x81,0x58,0x3c,0x22,0x00,0x00,0x35,0x31,0xf3,0x20,0x09, +0xa0,0x92,0x00,0x12,0x00,0x0d,0x81,0x5b,0x3c,0x36,0x00,0x00,0x35,0x31,0xf3,0x20, +0x09,0xa0,0x92,0x00,0x12,0x00,0x09,0x81,0x5e,0x3c,0x61,0x00,0x00,0x35,0x31,0xf3, +0x20,0x09,0xa0,0x92,0x00,0x13,0x00,0x41,0x90,0x42,0x3c,0x62,0x00,0x00,0x3b,0x31, +0x95,0x20,0x09,0xa0,0x93,0x00,0x10,0x00,0xf3,0x70,0x52,0x3c,0x5d,0x00,0x00,0x37, +0x3b,0xd6,0x25,0x25,0xa0,0x94,0x00,0x10,0x00,0x37,0x91,0x4c,0x6e,0x65,0x00,0x00, +0x99,0x3b,0xf5,0x18,0x08,0xa0,0x95,0x00,0x10,0x00,0x0b,0x80,0x59,0x3c,0x6a,0x00, +0x00,0x2d,0x38,0xf0,0x00,0x09,0xa0,0x96,0x00,0x10,0x00,0xfe,0x80,0x4f,0x3c,0x16, +0x00,0x00,0x35,0x38,0xf3,0x06,0x17,0xa1,0x04,0x00,0x10,0x00,0x00,0xa1,0x39,0x74, +0x42,0x00,0x00,0xab,0x38,0xb0,0x05,0x16,0xa1,0x04,0x07,0x10,0x00,0x2c,0x80,0x55, +0x3c,0x53,0x00,0x00,0x2b,0x00,0xf0,0x00,0x09,0x50,0x04,0x00,0x10,0x10,0x3e,0x50, +0x3f,0x3c,0x6a,0x00,0x00,0x21,0x38,0xf0,0x04,0x04,0x50,0x04,0x00,0x10,0x00,0xc7, +0x80,0x3a,0x3c,0x52,0x00,0x00,0x1b,0x38,0xf0,0x05,0x01,0x50,0x04,0x00,0x10,0x00, +0x26,0x80,0x4e,0x3c,0x7a,0x00,0x00,0x2f,0x38,0xf0,0x04,0x04,0x50,0x04,0x00,0x10, +0x00,0x31,0x80,0x4c,0x3c,0x6a,0x00,0x00,0x01,0x38,0x3a,0xf0,0x09,0x50,0x04,0x00, +0x10,0x00,0x38,0x81,0x43,0x3c,0x52,0x00,0x00,0x5f,0x38,0xf0,0x00,0x09,0xa0,0x04, +0x0e,0x10,0x01,0x25,0x81,0x4b,0x3c,0x6d,0x00,0x00,0x2f,0x38,0xf0,0x00,0x09,0xa0, +0x04,0xe0,0x10,0x00,0x08,0x80,0x55,0x3c,0x55,0x00,0x00,0x01,0x00,0x20,0x03,0x04, +0x20,0x04,0x24,0x10,0x01,0x37,0x80,0x4a,0x3c,0x6a,0x00,0x00,0x01,0x00,0x20,0x04, +0x05,0x20,0x04,0xc0,0x10,0x00,0x09,0x70,0x37,0xba,0x52,0xbf,0x50,0x3d,0x0f,0x22, +0x12,0x07,0x08,0x04,0x40,0x10,0x00,0x09,0x70,0x46,0xbc,0x52,0x0f,0x32,0x51,0x15, +0x72,0x12,0x07,0x08,0x04,0x00,0x10,0x00,0x03,0x80,0x50,0x3c,0x52,0x00,0x00,0x31, +0x00,0xf0,0x00,0x0f,0x10,0x04,0xe0,0x10,0x00,0x01,0x80,0x55,0x3c,0x55,0x00,0x00, +0x1f,0x08,0x30,0x01,0x07,0x10,0x04,0x24,0x10,0x04,0x37,0x80,0x4a,0x3c,0x6a,0x00, +0x00,0x89,0x00,0x30,0x01,0x07,0x10,0x04,0xa0,0x10,0x00,0x36,0x80,0x49,0x3c,0x01, +0xf1,0x02,0x3b,0x0f,0x40,0x01,0x07,0x20,0x04,0x60,0x10,0x00,0x36,0x80,0x4e,0x3e, +0x70,0xf9,0x02,0x39,0x07,0x40,0x01,0x07,0x08,0x04,0x00,0x10,0x10,0x39,0x81,0x56, +0x3c,0x6a,0x00,0x00,0x0f,0x38,0xf0,0x03,0x03,0x20,0x04,0x00,0x15,0x20,0x67,0x80, +0x62,0x3c,0x5b,0x00,0x00,0x01,0x32,0xf4,0x15,0x16,0xa1,0x8b,0x7f,0x7d,0x7c,0x7a, +0x78,0x77,0x75,0x73,0x71,0x70,0x6e,0x6c,0x6b,0x69,0x67,0x66,0x64,0x62,0x60,0x5e, +0x5c,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4c,0x4a,0x48,0x46,0x45,0x44,0x43, +0x42,0x41,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x34,0x33,0x32,0x31, +0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x22,0x21, +0x20,0x20,0x1f,0x1e,0x1e,0x1d,0x1c,0x1c,0x1b,0x1a,0x1a,0x19,0x18,0x18,0x17,0x17, +0x16,0x15,0x15,0x14,0x13,0x13,0x12,0x11,0x11,0x10,0x0f,0x0f,0x0e,0x0e,0x0d,0x0d, +0x0c,0x0c,0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x09,0x08,0x08,0x07,0x07,0x06,0x06,0x05, +0x05,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x00,0x00,0x7f,0x7e,0x7e,0x7d, +0x7c,0x7c,0x7b,0x7b,0x7a,0x79,0x79,0x78,0x77,0x77,0x76,0x76,0x75,0x74,0x72,0x71, +0x70,0x6f,0x6d,0x6c,0x6b,0x6a,0x68,0x67,0x66,0x65,0x63,0x62,0x61,0x60,0x5e,0x5d, +0x5c,0x5a,0x59,0x58,0x56,0x55,0x54,0x53,0x51,0x50,0x4f,0x4d,0x4c,0x4b,0x49,0x48, +0x47,0x45,0x44,0x43,0x41,0x40,0x3f,0x3e,0x3c,0x3b,0x3a,0x38,0x37,0x36,0x35,0x34, +0x33,0x32,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x28,0x27,0x26, +0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17, +0x17,0x16,0x15,0x14,0x13,0x12,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0d,0x0c,0x0b,0x0a, +0x09,0x08,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x00,0x7f,0x7d,0x7c,0x7a, +0x78,0x77,0x75,0x73,0x71,0x70,0x6e,0x6c,0x6b,0x69,0x67,0x66,0x64,0x62,0x5f,0x5d, +0x5b,0x58,0x56,0x54,0x51,0x4f,0x4d,0x4b,0x48,0x46,0x44,0x41,0x3f,0x3e,0x3d,0x3c, +0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a, +0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x1a,0x19, +0x19,0x18,0x18,0x17,0x16,0x16,0x15,0x15,0x14,0x14,0x13,0x13,0x12,0x11,0x11,0x10, +0x10,0x0f,0x0f,0x0e,0x0d,0x0d,0x0c,0x0c,0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x08,0x08, +0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x03, +0x03,0x03,0x03,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x00,0x00,0x7f,0x7e,0x7d,0x7c, +0x7b,0x7a,0x79,0x78,0x77,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,0x6f,0x6d,0x6c, +0x6b,0x69,0x68,0x67,0x65,0x64,0x63,0x62,0x60,0x5f,0x5e,0x5c,0x5b,0x59,0x57,0x55, +0x53,0x52,0x50,0x4e,0x4c,0x4a,0x48,0x46,0x44,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37, +0x35,0x34,0x32,0x30,0x2e,0x2c,0x2a,0x28,0x26,0x25,0x23,0x21,0x1f,0x1e,0x1e,0x1d, +0x1c,0x1c,0x1b,0x1a,0x1a,0x19,0x18,0x18,0x17,0x16,0x16,0x15,0x14,0x14,0x13,0x13, +0x12,0x11,0x11,0x10,0x0f,0x0f,0x0e,0x0d,0x0d,0x0c,0x0b,0x0b,0x0a,0x0a,0x09,0x09, +0x09,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x05,0x04,0x04, +0x04,0x03,0x03,0x03,0x02,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x0b,0x0b,0x0a,0x0a,0x0a,0x09,0x09,0x08,0x08,0x08,0x07,0x07,0x06,0x06,0x05,0x05, +0x05,0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x01,0x01,0x00,0x00,0x7f,0x7d,0x7c,0x7a, +0x78,0x77,0x75,0x74,0x72,0x70,0x6f,0x6d,0x6b,0x6a,0x68,0x67,0x65,0x63,0x61,0x5f, +0x5d,0x5c,0x5a,0x58,0x56,0x54,0x52,0x50,0x4e,0x4d,0x4b,0x49,0x47,0x46,0x45,0x44, +0x43,0x42,0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x35,0x34,0x33,0x32, +0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x23,0x22, +0x21,0x21,0x20,0x1f,0x1f,0x1e,0x1d,0x1d,0x1c,0x1b,0x1b,0x1a,0x19,0x19,0x18,0x18, +0x17,0x16,0x16,0x15,0x15,0x14,0x13,0x13,0x12,0x11,0x11,0x10,0x0f,0x0d,0x0c,0x0c, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7c,0x79,0x77, +0x74,0x71,0x6e,0x6c,0x69,0x65,0x62,0x5e,0x5b,0x57,0x54,0x50,0x4d,0x4b,0x48,0x46, +0x44,0x42,0x3f,0x3d,0x3b,0x3a,0x39,0x38,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x2f, +0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x26,0x25,0x24,0x23,0x22,0x21,0x20, +0x1f,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x18,0x17,0x16,0x15,0x14,0x14,0x13, +0x12,0x12,0x11,0x11,0x10,0x0f,0x0f,0x0e,0x0e,0x0d,0x0d,0x0d,0x0d,0x0c,0x0c,0x0b, +0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x08,0x08,0x08,0x07,0x07,0x07,0x07,0x06,0x06,0x06, +0x06,0x05,0x05,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02, +0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x7f,0x7c,0x7a,0x78, +0x76,0x74,0x72,0x70,0x6d,0x6a,0x68,0x65,0x63,0x60,0x5d,0x5b,0x58,0x56,0x53,0x51, +0x4f,0x4d,0x4a,0x48,0x46,0x44,0x43,0x41,0x3f,0x3d,0x3c,0x3a,0x38,0x37,0x36,0x35, +0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2b,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25, +0x23,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1b,0x1b,0x1a,0x19,0x18,0x17,0x17,0x16, +0x15,0x15,0x14,0x14,0x13,0x12,0x12,0x11,0x11,0x10,0x10,0x10,0x0f,0x0e,0x0e,0x0d, +0x0d,0x0d,0x0c,0x0c,0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x08,0x08,0x08,0x07,0x07,0x07, +0x07,0x06,0x06,0x05,0x05,0x05,0x05,0x05,0x05,0x04,0x04,0x04,0x03,0x03,0x03,0x02, +0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00, +0x14,0x27,0x4c,0x41,0x28,0x2d,0x4c,0x52,0x2e,0x33,0x4c,0x63,0x34,0x39,0x4c,0x74, +0x3a,0x3f,0x4c,0x85,0x40,0x45,0x4c,0x96,0x46,0x4b,0x4c,0xa7,0x4c,0x52,0x4c,0xb8, +0x53,0x58,0x4c,0xc9,0x59,0x6d,0x4c,0xda,0x0a,0x00,0x00,0x00,0x14,0x2d,0x4c,0xeb, +0x2e,0x33,0x4c,0xfc,0x34,0x39,0x4d,0x0d,0x3a,0x3f,0x4d,0x1e,0x40,0x45,0x4d,0x2f, +0x46,0x4b,0x4d,0x40,0x4c,0x52,0x4d,0x51,0x53,0x58,0x4d,0x62,0x59,0x5e,0x4d,0x73, +0x5f,0x6d,0x4d,0x84,0x0b,0x00,0x00,0x00,0x14,0x2d,0x4d,0x95,0x2e,0x33,0x4d,0xa6, +0x34,0x39,0x4d,0xb7,0x3a,0x3f,0x4d,0xc8,0x40,0x45,0x4d,0xd9,0x46,0x4b,0x4d,0xea, +0x4c,0x52,0x4d,0xfb,0x53,0x58,0x4e,0x0c,0x59,0x5e,0x4e,0x1d,0x5f,0x6d,0x4e,0x2e, +0x00,0x7f,0x4e,0x3f,0x14,0x00,0x00,0x00,0x14,0x27,0x4e,0x50,0x28,0x2d,0x4e,0x61, +0x2e,0x33,0x4e,0x72,0x34,0x39,0x4e,0x83,0x3a,0x3f,0x4e,0x94,0x40,0x45,0x4e,0xa5, +0x46,0x4b,0x4e,0xb6,0x4c,0x52,0x4e,0xc7,0x53,0x58,0x4e,0xd8,0x59,0x6d,0x4e,0xe9, +0x14,0x27,0x4e,0xfa,0x28,0x2d,0x4f,0x0b,0x2e,0x33,0x4f,0x1c,0x34,0x39,0x4f,0x2d, +0x3a,0x3f,0x4f,0x3e,0x40,0x45,0x4f,0x4f,0x46,0x4b,0x4f,0x60,0x4c,0x52,0x4f,0x71, +0x53,0x58,0x4f,0x82,0x59,0x6d,0x4f,0x93,0x02,0x00,0x00,0x00,0x00,0x7f,0x4f,0xb5, +0x15,0x6c,0x4f,0xa4,0x14,0x00,0x00,0x00,0x14,0x27,0x4f,0xc6,0x28,0x2d,0x4f,0xd7, +0x2e,0x33,0x4f,0xe8,0x34,0x39,0x4f,0xf9,0x3a,0x3f,0x50,0x0a,0x40,0x45,0x50,0x1b, +0x46,0x4b,0x50,0x2c,0x4c,0x52,0x50,0x3d,0x53,0x58,0x50,0x4e,0x59,0x6d,0x50,0x5f, +0x14,0x2d,0x50,0x70,0x2e,0x33,0x50,0x81,0x34,0x39,0x50,0x92,0x3a,0x3f,0x50,0xa3, +0x40,0x45,0x50,0xb4,0x46,0x4b,0x50,0xc5,0x4c,0x52,0x50,0xd6,0x53,0x58,0x50,0xe7, +0x59,0x5e,0x50,0xf8,0x5f,0x6d,0x51,0x09,0x05,0x00,0x00,0x00,0x15,0x39,0x51,0x1a, +0x3a,0x3f,0x51,0x2b,0x40,0x45,0x51,0x3c,0x46,0x4d,0x51,0x4d,0x4e,0x6c,0x51,0x5e, +0x02,0x00,0x00,0x00,0x15,0x51,0x51,0x6f,0x52,0x6c,0x51,0x80,0x01,0x00,0x00,0x00, +0x15,0x6c,0x51,0x91,0x01,0x00,0x00,0x00,0x15,0x6c,0x51,0xa2,0x02,0x00,0x00,0x00, +0x15,0x6c,0x51,0xb3,0x15,0x6c,0x51,0xc4,0x01,0x00,0x00,0x00,0x15,0x6c,0x51,0xd5, +0x04,0x00,0x00,0x00,0x15,0x3f,0x51,0xe6,0x40,0x4c,0x51,0xf7,0x4d,0x5a,0x52,0x08, +0x5b,0x7f,0x52,0x19,0x01,0x00,0x00,0x00,0x00,0x7f,0x52,0x2a,0x01,0x00,0x00,0x00, +0x01,0x7f,0x52,0x3b,0x02,0x00,0x00,0x00,0x00,0x7f,0x52,0x4c,0x00,0x7f,0x52,0x5d, +0x01,0x00,0x00,0x00,0x01,0x7f,0x52,0x6e,0x02,0x00,0x00,0x00,0x15,0x3b,0x52,0x7f, +0x3c,0x6c,0x52,0x90,0x05,0x00,0x00,0x00,0x15,0x30,0x52,0xa1,0x31,0x3c,0x52,0xb2, +0x3d,0x48,0x52,0xc3,0x49,0x54,0x52,0xd4,0x55,0x6c,0x52,0xe5,0x05,0x00,0x00,0x00, +0x15,0x29,0x52,0xf6,0x2a,0x30,0x53,0x07,0x31,0x38,0x53,0x18,0x39,0x41,0x53,0x29, +0x42,0x6c,0x53,0x3a,0x02,0x00,0x00,0x00,0x00,0x53,0x53,0x4b,0x54,0x7f,0x53,0x5c, +0x03,0x00,0x00,0x00,0x15,0x4c,0x53,0x6d,0x4d,0x6c,0x53,0x7e,0x15,0x6c,0x53,0x8f, +0x01,0x00,0x00,0x00,0x15,0x6c,0x53,0xa0,0x03,0x00,0x00,0x00,0x00,0x53,0x53,0xb1, +0x54,0x7f,0x53,0xc2,0x15,0x6c,0x53,0xd3,0x05,0x00,0x00,0x00,0x15,0x2f,0x53,0xe4, +0x30,0x36,0x53,0xf5,0x37,0x3c,0x54,0x06,0x3d,0x43,0x54,0x17,0x44,0x60,0x54,0x28, +0x04,0x00,0x00,0x00,0x15,0x31,0x54,0x39,0x32,0x38,0x54,0x4a,0x39,0x47,0x54,0x5b, +0x48,0x6c,0x54,0x6c,0x03,0x00,0x00,0x00,0x15,0x31,0x54,0x7d,0x32,0x3f,0x54,0x8e, +0x40,0x6c,0x54,0x9f,0x08,0x00,0x00,0x00,0x15,0x2c,0x54,0xb0,0x2d,0x31,0x54,0xc1, +0x32,0x38,0x54,0xd2,0x39,0x3f,0x54,0xe3,0x40,0x44,0x54,0xf4,0x45,0x4b,0x55,0x05, +0x4c,0x54,0x55,0x16,0x55,0x6c,0x55,0x27,0x01,0x00,0x00,0x00,0x01,0x7f,0x55,0x38, +0x02,0x00,0x00,0x00,0x00,0x40,0x55,0x49,0x41,0x7f,0x55,0x5a,0x09,0x00,0x00,0x00, +0x15,0x2a,0x55,0x6b,0x2b,0x2e,0x55,0x7c,0x2f,0x32,0x55,0x8d,0x33,0x36,0x55,0x9e, +0x37,0x3a,0x55,0xaf,0x3b,0x3e,0x55,0xc0,0x3f,0x42,0x55,0xd1,0x43,0x46,0x55,0xe2, +0x47,0x6c,0x55,0xf3,0x03,0x00,0x00,0x00,0x15,0x44,0x56,0x04,0x45,0x49,0x56,0x15, +0x4a,0x6c,0x56,0x26,0x02,0x00,0x00,0x00,0x15,0x30,0x56,0x37,0x31,0x6c,0x56,0x48, +0x04,0x00,0x00,0x00,0x01,0x20,0x56,0x59,0x21,0x25,0x56,0x6a,0x26,0x2a,0x56,0x7b, +0x2b,0x7f,0x56,0x8c,0x05,0x00,0x00,0x00,0x15,0x23,0x56,0x9d,0x24,0x2a,0x56,0xae, +0x2b,0x2f,0x56,0xbf,0x30,0x47,0x56,0xd0,0x48,0x6c,0x56,0xe1,0x01,0x00,0x00,0x00, +0x01,0x7f,0x56,0xf2,0x01,0x00,0x00,0x00,0x15,0x6c,0x57,0x03,0x01,0x00,0x00,0x00, +0x01,0x7f,0x57,0x14,0x01,0x00,0x00,0x00,0x15,0x6c,0x57,0x25,0x01,0x00,0x00,0x00, +0x00,0x7f,0x57,0x36,0x0a,0x00,0x00,0x00,0x15,0x3a,0x57,0x47,0x3b,0x3f,0x57,0x58, +0x40,0x41,0x57,0x69,0x42,0x44,0x57,0x7a,0x45,0x47,0x57,0x8b,0x48,0x4a,0x57,0x9c, +0x4b,0x4c,0x57,0xad,0x4d,0x4e,0x57,0xbe,0x4f,0x51,0x57,0xcf,0x52,0x6c,0x57,0xe0, +0x0c,0x00,0x00,0x00,0x15,0x32,0x57,0xf1,0x33,0x35,0x58,0x02,0x36,0x38,0x58,0x13, +0x39,0x3d,0x58,0x24,0x3e,0x3f,0x58,0x35,0x40,0x42,0x58,0x46,0x43,0x45,0x58,0x57, +0x46,0x48,0x58,0x68,0x49,0x4a,0x58,0x79,0x4b,0x4c,0x58,0x8a,0x4d,0x4f,0x58,0x9b, +0x50,0x6c,0x58,0xac,0x05,0x00,0x00,0x00,0x15,0x2d,0x58,0xbd,0x2e,0x37,0x58,0xce, +0x38,0x3e,0x58,0xdf,0x3f,0x44,0x58,0xf0,0x45,0x6c,0x59,0x01,0x02,0x00,0x00,0x00, +0x15,0x29,0x59,0x12,0x2a,0x6c,0x59,0x23,0x05,0x00,0x00,0x00,0x15,0x3b,0x59,0x34, +0x3c,0x41,0x59,0x45,0x42,0x47,0x59,0x56,0x48,0x52,0x59,0x67,0x53,0x6c,0x59,0x78, +0x05,0x00,0x00,0x00,0x15,0x32,0x59,0x89,0x33,0x3b,0x59,0x9a,0x3c,0x42,0x59,0xab, +0x43,0x48,0x59,0xbc,0x49,0x6c,0x59,0xcd,0x02,0x00,0x00,0x00,0x15,0x46,0x59,0xde, +0x47,0x6c,0x59,0xef,0x01,0x00,0x00,0x00,0x15,0x6c,0x5a,0x00,0x05,0x00,0x00,0x00, +0x15,0x3b,0x5a,0x11,0x3c,0x41,0x5a,0x22,0x42,0x47,0x5a,0x33,0x48,0x52,0x5a,0x44, +0x53,0x6c,0x5a,0x55,0x05,0x00,0x00,0x00,0x15,0x3b,0x5a,0x66,0x3c,0x41,0x5a,0x77, +0x42,0x47,0x5a,0x88,0x48,0x52,0x5a,0x99,0x53,0x6c,0x5a,0xaa,0x02,0x00,0x00,0x00, +0x05,0x71,0x5a,0xbb,0x15,0x6c,0x5a,0xcc,0x02,0x00,0x00,0x00,0x15,0x6c,0x5a,0xdd, +0x15,0x6c,0x5a,0xee,0x04,0x00,0x00,0x00,0x15,0x3a,0x5a,0xff,0x3b,0x40,0x5b,0x10, +0x41,0x47,0x5b,0x21,0x48,0x6c,0x5b,0x32,0x01,0x00,0x00,0x00,0x15,0x6c,0x5b,0x43, +0x01,0x00,0x00,0x00,0x15,0x6c,0x5b,0x54,0x01,0x00,0x00,0x00,0x15,0x6c,0x5b,0x65, +0x06,0x00,0x00,0x00,0x15,0x3c,0x5b,0x76,0x3d,0x43,0x5b,0x87,0x44,0x48,0x5b,0x98, +0x49,0x4e,0x5b,0xa9,0x4f,0x55,0x5b,0xba,0x56,0x6c,0x5b,0xcb,0x03,0x00,0x00,0x00, +0x15,0x3a,0x5b,0xdc,0x3b,0x3f,0x5b,0xed,0x40,0x6c,0x5b,0xfe,0x02,0x00,0x00,0x00, +0x15,0x2d,0x5c,0x0f,0x2e,0x6c,0x5c,0x20,0x02,0x00,0x00,0x00,0x15,0x45,0x5c,0x31, +0x46,0x6c,0x5c,0x42,0x02,0x00,0x00,0x00,0x15,0x49,0x5c,0x53,0x4a,0x6c,0x5c,0x64, +0x02,0x00,0x00,0x00,0x15,0x42,0x5c,0x75,0x43,0x6c,0x5c,0x86,0x18,0x00,0x00,0x00, +0x01,0x27,0x5c,0x97,0x28,0x2d,0x5c,0xa8,0x2e,0x33,0x5c,0xb9,0x34,0x39,0x5c,0xca, +0x3a,0x3f,0x5c,0xdb,0x40,0x45,0x5c,0xec,0x46,0x4b,0x5c,0xfd,0x4c,0x51,0x5d,0x0e, +0x52,0x57,0x5d,0x1f,0x58,0x5d,0x5d,0x30,0x5e,0x63,0x5d,0x41,0x64,0x7f,0x5d,0x52, +0x01,0x27,0x5d,0x63,0x28,0x2d,0x5d,0x74,0x2e,0x33,0x5d,0x85,0x34,0x39,0x5d,0x96, +0x3a,0x3f,0x5d,0xa7,0x40,0x45,0x5d,0xb8,0x46,0x4b,0x5d,0xc9,0x4c,0x51,0x5d,0xda, +0x52,0x57,0x5d,0xeb,0x58,0x5d,0x5d,0xfc,0x5e,0x64,0x5e,0x0d,0x65,0x7f,0x5e,0x1e, +0x0d,0x00,0x00,0x00,0x01,0x27,0x5e,0x2f,0x28,0x2d,0x5e,0x40,0x2e,0x33,0x5e,0x51, +0x34,0x39,0x5e,0x62,0x3a,0x3f,0x5e,0x73,0x40,0x45,0x5e,0x84,0x46,0x4b,0x5e,0x95, +0x4c,0x51,0x5e,0xa6,0x52,0x57,0x5e,0xb7,0x58,0x5d,0x5e,0xc8,0x5e,0x64,0x5e,0xd9, +0x65,0x7f,0x5e,0xea,0x00,0x7f,0x5e,0xfb,0x06,0x00,0x00,0x00,0x15,0x3f,0x5f,0x0c, +0x40,0x45,0x5f,0x1d,0x46,0x4b,0x5f,0x2e,0x4c,0x51,0x5f,0x3f,0x52,0x59,0x5f,0x50, +0x59,0x6c,0x5f,0x61,0x0d,0x00,0x00,0x00,0x15,0x32,0x5f,0x72,0x33,0x35,0x5f,0x83, +0x36,0x3a,0x5f,0x94,0x3b,0x3b,0x5f,0xa5,0x3c,0x3e,0x5f,0xb6,0x3f,0x41,0x5f,0xc7, +0x42,0x44,0x5f,0xd8,0x45,0x47,0x5f,0xe9,0x48,0x4a,0x5f,0xfa,0x4b,0x4d,0x60,0x0b, +0x4e,0x50,0x60,0x1c,0x51,0x53,0x60,0x2d,0x54,0x6c,0x60,0x3e,0x07,0x00,0x00,0x00, +0x24,0x30,0x60,0x4f,0x31,0x34,0x60,0x60,0x35,0x3a,0x60,0x71,0x3b,0x41,0x60,0x82, +0x42,0x47,0x60,0x93,0x48,0x51,0x60,0xa4,0x52,0x6c,0x60,0xb5,0x04,0x00,0x00,0x00, +0x15,0x2d,0x60,0xc6,0x2e,0x34,0x60,0xd7,0x35,0x39,0x60,0xe8,0x3a,0x6c,0x60,0xf9, +0x06,0x00,0x00,0x00,0x15,0x3c,0x61,0x0a,0x3d,0x43,0x61,0x1b,0x44,0x49,0x61,0x2c, +0x4a,0x4f,0x61,0x3d,0x50,0x55,0x61,0x4e,0x56,0x6c,0x61,0x5f,0x03,0x00,0x00,0x00, +0x15,0x38,0x61,0x70,0x39,0x3e,0x61,0x81,0x3f,0x6c,0x61,0x92,0x03,0x00,0x00,0x00, +0x15,0x22,0x61,0xa3,0x23,0x2e,0x61,0xb4,0x2f,0x6c,0x61,0xc5,0x04,0x00,0x00,0x00, +0x15,0x3b,0x61,0xd6,0x3c,0x41,0x61,0xe7,0x42,0x4a,0x61,0xf8,0x4b,0x6c,0x62,0x09, +0x05,0x00,0x00,0x00,0x15,0x40,0x62,0x1a,0x41,0x4d,0x62,0x2b,0x4e,0x53,0x62,0x3c, +0x54,0x5f,0x62,0x4d,0x60,0x6c,0x62,0x5e,0x03,0x00,0x00,0x00,0x15,0x40,0x62,0x6f, +0x41,0x4d,0x62,0x80,0x4e,0x6c,0x62,0x91,0x01,0x00,0x00,0x00,0x15,0x6f,0x62,0xa2, +0x01,0x00,0x00,0x00,0x15,0x6c,0x62,0xb3,0x02,0x00,0x00,0x00,0x15,0x6c,0x62,0xc4, +0x01,0x7f,0x62,0xd5,0x02,0x00,0x00,0x00,0x00,0x7f,0x62,0xe6,0x15,0x6c,0x62,0xf7, +0x01,0x00,0x00,0x00,0x00,0x7f,0x63,0x08,0x01,0x00,0x00,0x00,0x00,0x7f,0x63,0x19, +0x0c,0x00,0x00,0x00,0x01,0x2a,0x63,0x2a,0x2b,0x36,0x63,0x3b,0x37,0x42,0x63,0x4c, +0x43,0x4e,0x63,0x5d,0x4f,0x5a,0x63,0x6e,0x5b,0x7f,0x63,0x7f,0x01,0x2a,0x63,0x90, +0x2b,0x36,0x63,0xa1,0x37,0x42,0x63,0xb2,0x43,0x4e,0x63,0xc3,0x4f,0x5a,0x63,0xd4, +0x5b,0x7f,0x63,0xe5,0x18,0x00,0x00,0x00,0x01,0x27,0x63,0xf6,0x28,0x2d,0x64,0x07, +0x2e,0x33,0x64,0x18,0x34,0x39,0x64,0x29,0x3a,0x3f,0x64,0x3a,0x40,0x45,0x64,0x4b, +0x46,0x4b,0x64,0x5c,0x4c,0x51,0x64,0x6d,0x52,0x57,0x64,0x7e,0x58,0x5d,0x64,0x8f, +0x5e,0x66,0x64,0xa0,0x67,0x7f,0x64,0xb1,0x01,0x27,0x64,0xc2,0x28,0x2d,0x64,0xd3, +0x2e,0x33,0x64,0xe4,0x34,0x39,0x64,0xf5,0x3a,0x3f,0x65,0x06,0x40,0x45,0x65,0x17, +0x46,0x4b,0x65,0x28,0x4c,0x51,0x65,0x39,0x52,0x57,0x65,0x4a,0x58,0x5d,0x65,0x5b, +0x5e,0x66,0x65,0x6c,0x67,0x7f,0x65,0x7d,0x02,0x00,0x00,0x00,0x00,0x7f,0x65,0x8e, +0x15,0x6c,0x65,0x9f,0x02,0x00,0x00,0x00,0x00,0x7f,0x65,0xb0,0x01,0x7f,0x65,0xc1, +0x0e,0x00,0x00,0x00,0x00,0x40,0x65,0xd2,0x41,0x7f,0x65,0xe3,0x01,0x27,0x65,0xf4, +0x28,0x2d,0x66,0x05,0x2e,0x33,0x66,0x16,0x34,0x39,0x66,0x27,0x3a,0x3f,0x66,0x38, +0x40,0x45,0x66,0x49,0x46,0x4b,0x66,0x5a,0x4c,0x51,0x66,0x6b,0x52,0x57,0x66,0x7c, +0x58,0x5d,0x66,0x8d,0x5e,0x66,0x66,0x9e,0x67,0x7f,0x66,0xaf,0x02,0x00,0x00,0x00, +0x00,0x7f,0x66,0xc0,0x15,0x6c,0x66,0xd1,0x0d,0x00,0x00,0x00,0x01,0x27,0x66,0xe2, +0x28,0x2d,0x66,0xf3,0x2e,0x33,0x67,0x04,0x34,0x39,0x67,0x15,0x3a,0x3f,0x67,0x26, +0x40,0x45,0x67,0x37,0x46,0x4b,0x67,0x48,0x4c,0x51,0x67,0x59,0x52,0x57,0x67,0x6a, +0x58,0x5d,0x67,0x7b,0x5e,0x64,0x67,0x8c,0x65,0x7f,0x67,0x9d,0x05,0x71,0x67,0xae, +0x0d,0x00,0x00,0x00,0x00,0x7f,0x67,0xbf,0x01,0x27,0x67,0xd0,0x28,0x2d,0x67,0xe1, +0x2e,0x33,0x67,0xf2,0x34,0x39,0x68,0x03,0x3a,0x3f,0x68,0x14,0x40,0x45,0x68,0x25, +0x46,0x4b,0x68,0x36,0x4c,0x51,0x68,0x47,0x52,0x57,0x68,0x58,0x58,0x5d,0x68,0x69, +0x5e,0x66,0x68,0x7a,0x67,0x7f,0x68,0x8b,0x02,0x00,0x00,0x00,0x15,0x6c,0x68,0x9c, +0x15,0x6c,0x68,0xad,0x02,0x00,0x00,0x00,0x15,0x6c,0x68,0xbe,0x15,0x6c,0x68,0xcf, +0x0d,0x00,0x00,0x00,0x01,0x27,0x68,0xe0,0x28,0x2d,0x68,0xf1,0x2e,0x33,0x69,0x02, +0x34,0x39,0x69,0x13,0x3a,0x3f,0x69,0x24,0x40,0x45,0x69,0x35,0x46,0x4b,0x69,0x46, +0x4c,0x51,0x69,0x57,0x52,0x57,0x69,0x68,0x58,0x5d,0x69,0x79,0x5e,0x66,0x69,0x8a, +0x67,0x7f,0x69,0x9b,0x00,0x7f,0x69,0xac,0x05,0x00,0x00,0x00,0x15,0x3a,0x69,0xbd, +0x3b,0x40,0x69,0xce,0x41,0x47,0x69,0xdf,0x48,0x6c,0x69,0xf0,0x15,0x6c,0x6a,0x01, +0x02,0x00,0x00,0x00,0x15,0x6c,0x6a,0x12,0x00,0x7f,0x6a,0x23,0x05,0x00,0x00,0x00, +0x15,0x31,0x6a,0x34,0x32,0x38,0x6a,0x45,0x39,0x47,0x6a,0x56,0x48,0x6c,0x6a,0x67, +0x00,0x7f,0x6a,0x78,0x02,0x00,0x00,0x00,0x00,0x7f,0x6a,0x89,0x15,0x6c,0x6a,0x9a, +0x18,0x00,0x00,0x00,0x01,0x27,0x6a,0xab,0x28,0x2d,0x6a,0xbc,0x2e,0x33,0x6a,0xcd, +0x34,0x39,0x6a,0xde,0x3a,0x3f,0x6a,0xef,0x40,0x45,0x6b,0x00,0x46,0x4b,0x6b,0x11, +0x4c,0x51,0x6b,0x22,0x52,0x57,0x6b,0x33,0x58,0x5d,0x6b,0x44,0x5e,0x63,0x6b,0x55, +0x64,0x7f,0x6b,0x66,0x01,0x27,0x6b,0x77,0x28,0x2d,0x6b,0x88,0x2e,0x33,0x6b,0x99, +0x34,0x39,0x6b,0xaa,0x3a,0x3f,0x6b,0xbb,0x40,0x45,0x6b,0xcc,0x46,0x4b,0x6b,0xdd, +0x4c,0x51,0x6b,0xee,0x52,0x57,0x6b,0xff,0x58,0x5d,0x6c,0x10,0x5e,0x63,0x6c,0x21, +0x64,0x7f,0x6c,0x32,0x02,0x00,0x00,0x00,0x01,0x7f,0x6c,0x43,0x00,0x7f,0x6c,0x54, +0x02,0x00,0x00,0x00,0x15,0x6c,0x6c,0x65,0x15,0x6c,0x6c,0x76,0x04,0x00,0x00,0x00, +0x15,0x6c,0x6c,0x87,0x15,0x2c,0x6c,0x98,0x2d,0x36,0x6c,0xa9,0x37,0x6c,0x6c,0xba, +0x06,0x00,0x00,0x00,0x05,0x71,0x6c,0xcb,0x15,0x2f,0x6c,0xdc,0x30,0x36,0x6c,0xed, +0x37,0x3c,0x6c,0xfe,0x3d,0x43,0x6d,0x0f,0x44,0x60,0x6d,0x20,0x02,0x00,0x00,0x00, +0x00,0x7f,0x6d,0x31,0x15,0x6c,0x6d,0x42,0x02,0x00,0x00,0x00,0x15,0x6c,0x6d,0x53, +0x15,0x6c,0x6d,0x64,0x02,0x00,0x00,0x00,0x15,0x6c,0x6d,0x75,0x00,0x7f,0x6d,0x86, +0x05,0x00,0x00,0x00,0x15,0x31,0x6d,0x97,0x32,0x38,0x6d,0xa8,0x39,0x47,0x6d,0xb9, +0x48,0x6c,0x6d,0xca,0x15,0x6c,0x6d,0xdb,0x02,0x00,0x00,0x00,0x00,0x83,0x6d,0xec, +0x84,0x7f,0x70,0xfa,0x06,0x00,0x00,0x00,0x15,0x34,0x6d,0xfd,0x35,0x38,0x6e,0x0e, +0x39,0x3c,0x6e,0x1f,0x3d,0x44,0x6e,0x30,0x45,0x4c,0x6e,0x41,0x4d,0x6d,0x6e,0x52, +0x01,0x00,0x00,0x00,0x15,0x6c,0x6e,0x63,0x01,0x00,0x00,0x00,0x00,0x7f,0x6e,0x74, +0x01,0x00,0x00,0x00,0x00,0x7f,0x6e,0x85,0x03,0x00,0x00,0x00,0x15,0x39,0x6e,0x96, +0x15,0x39,0x6e,0xa7,0x3a,0x6c,0x6e,0xb8,0x0a,0x00,0x00,0x00,0x15,0x3a,0x6e,0xc9, +0x3b,0x3f,0x6e,0xda,0x40,0x41,0x6e,0xeb,0x42,0x44,0x6e,0xfc,0x45,0x47,0x6f,0x0d, +0x48,0x4a,0x6f,0x1e,0x4b,0x4c,0x6f,0x2f,0x4d,0x4e,0x6f,0x40,0x4f,0x51,0x6f,0x51, +0x52,0x6c,0x6f,0x62,0x01,0x00,0x00,0x00,0x15,0x6c,0x6f,0x73,0x02,0x00,0x00,0x00, +0x15,0x6c,0x6f,0x84,0x00,0x7f,0x6f,0x95,0x01,0x00,0x00,0x00,0x15,0x6c,0x6f,0xa6, +0x02,0x00,0x00,0x00,0x01,0x7f,0x6f,0xb7,0x15,0x6c,0x6f,0xc8,0x01,0x00,0x00,0x00, +0x15,0x6c,0x6f,0xd9,0x01,0x00,0x00,0x00,0x13,0x6c,0x6f,0xea,0x01,0x00,0x00,0x00, +0x15,0x6c,0x6f,0xfb,0x01,0x00,0x00,0x00,0x15,0x6c,0x70,0x0c,0x01,0x00,0x00,0x00, +0x15,0x6c,0x70,0x1d,0x01,0x00,0x00,0x00,0x15,0x6c,0x70,0x2e,0x01,0x00,0x00,0x00, +0x01,0x7f,0x70,0x3f,0x02,0x00,0x00,0x00,0x15,0x6c,0x70,0x50,0x01,0x7f,0x70,0x61, +0x02,0x00,0x00,0x00,0x15,0x6c,0x70,0x72,0x15,0x6c,0x70,0x83,0x01,0x00,0x00,0x00, +0x15,0x6c,0x70,0x94,0x02,0x00,0x00,0x00,0x0c,0x7f,0x70,0xa5,0x01,0x7f,0x70,0xb6, +0x02,0x00,0x00,0x00,0x15,0x6c,0x70,0xc7,0x15,0x6c,0x70,0xd8,0x01,0x00,0x00,0x00, +0x15,0x6c,0x70,0xe9,0x75,0x0b,0x75,0x37,0x75,0x63,0x75,0x93,0x75,0xe7,0x75,0xf3, +0x76,0x47,0x76,0x5f,0x76,0x6b,0x76,0x73,0x76,0x7b,0x76,0x87,0x76,0x8f,0x76,0xa3, +0x76,0xab,0x76,0xb3,0x76,0xbf,0x76,0xc7,0x76,0xd3,0x76,0xeb,0x77,0x03,0x77,0x0f, +0x77,0x1f,0x77,0x27,0x77,0x37,0x77,0x4f,0x77,0x63,0x77,0x73,0x77,0x97,0x77,0x9f, +0x77,0xab,0x77,0xd3,0x77,0xe3,0x77,0xef,0x78,0x03,0x78,0x1b,0x78,0x23,0x78,0x2b, +0x78,0x33,0x78,0x3b,0x78,0x43,0x78,0x6f,0x78,0xa3,0x78,0xbb,0x78,0xc7,0x78,0xdf, +0x78,0xf7,0x79,0x03,0x79,0x0b,0x79,0x23,0x79,0x3b,0x79,0x47,0x79,0x53,0x79,0x67, +0x79,0x6f,0x79,0x77,0x79,0x7f,0x79,0x9b,0x79,0xab,0x79,0xb7,0x79,0xc3,0x79,0xcf, +0x79,0xdb,0x7a,0x3f,0x7a,0x77,0x7a,0x93,0x7a,0xcb,0x7a,0xeb,0x7a,0xff,0x7b,0x1b, +0x7b,0x2b,0x7b,0x3b,0x7b,0x4f,0x7b,0x67,0x7b,0x77,0x7b,0x7f,0x7b,0x87,0x7b,0x93, +0x7b,0x9f,0x7b,0xa7,0x7b,0xaf,0x7b,0xe3,0x7c,0x47,0x7c,0x53,0x7c,0x5f,0x7c,0x9b, +0x7c,0xa7,0x7c,0xdf,0x7d,0x17,0x7d,0x23,0x7d,0x2f,0x7d,0x67,0x7d,0x7f,0x7d,0x8b, +0x7d,0xa3,0x7d,0xaf,0x7e,0x13,0x7e,0x1f,0x7e,0x2b,0x7e,0x3f,0x7e,0x5b,0x7e,0x67, +0x7e,0x73,0x7e,0x7f,0x7e,0x97,0x7e,0xa3,0x7e,0xbf,0x7e,0xc7,0x7e,0xcf,0x7e,0xd7, +0x7e,0xe7,0x7f,0x13,0x7f,0x1b,0x7f,0x27,0x7f,0x2f,0x7f,0x3b,0x7f,0x43,0x7f,0x4b, +0x7f,0x53,0x7f,0x5b,0x7f,0x63,0x7f,0x6b,0x7f,0x73,0x7f,0x7f,0x7f,0x8b,0x7f,0x93, +0x7f,0x9f,0x7f,0xab,0x71,0x0b,0x71,0x8b,0x72,0x0b,0x72,0x8b,0x73,0x0b,0x73,0x8b, +0x74,0x0b,0x74,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x40,0x4d,0x5c, +0x80,0x80,0x79,0x73,0x30,0x3c,0x54,0x60,0x6c,0x80,0x76,0x6c,0x40,0x40,0x40,0x69, +0x80,0x80,0x80,0x39,0x40,0x40,0x40,0x69,0x80,0x80,0x80,0x4f,0x18,0x1a,0x3c,0x54, +0x6b,0x76,0x76,0x76,0x1d,0x35,0x48,0x53,0x73,0x80,0x80,0x73,0x40,0x40,0x4c,0x5c, +0x80,0x80,0x7d,0x69,0x40,0x40,0x57,0x6c,0x80,0x80,0x6f,0x4f,0x40,0x40,0x4a,0x6b, +0x80,0x80,0x7b,0x61,0x1c,0x40,0x5a,0x6b,0x61,0x80,0x65,0x38,0x28,0x40,0x58,0x70, +0x67,0x75,0x81,0x79,0x18,0x24,0x3c,0x54,0x8a,0x6e,0x82,0x7d,0x1c,0x32,0x40,0x65, +0x59,0x80,0x80,0x65,0x1a,0x33,0x5a,0x69,0x4f,0x80,0x80,0x67,0x40,0x40,0x54,0x69, +0x80,0x80,0x7b,0x65,0x40,0x40,0x53,0x68,0x80,0x80,0x7d,0x63,0x1b,0x3c,0x56,0x6c, +0x5f,0x80,0x7d,0x77,0x24,0x30,0x48,0x54,0x72,0x78,0x78,0x70,0x40,0x40,0x5e,0x6d, +0x80,0x80,0x6f,0x2d,0x40,0x40,0x5d,0x6c,0x80,0x80,0x75,0x2b,0x40,0x40,0x54,0x71, +0x80,0x80,0x5f,0x35,0x40,0x40,0x49,0x6a,0x80,0x80,0x79,0x5b,0x40,0x40,0x5a,0x73, +0x80,0x80,0x7b,0x49,0x40,0x40,0x5a,0x68,0x80,0x80,0x6b,0x4d,0x40,0x40,0x56,0x74, +0x80,0x80,0x75,0x5d,0x2b,0x40,0x5d,0x74,0x76,0x80,0x6b,0x53,0x40,0x40,0x5b,0x6e, +0x76,0x80,0x61,0x3e,0x40,0x40,0x5b,0x62,0x80,0x80,0x65,0x1f,0x40,0x40,0x5b,0x68, +0x80,0x80,0x7b,0x63,0x40,0x40,0x5b,0x6a,0x80,0x80,0x79,0x63,0x40,0x40,0x57,0x60, +0x80,0x80,0x7a,0x49,0x40,0x4d,0x58,0x67,0x80,0x80,0x7a,0x4b,0x40,0x4e,0x5a,0x67, +0x80,0x80,0x79,0x5f,0x40,0x4d,0x5d,0x6f,0x80,0x80,0x79,0x4d,0x40,0x40,0x4e,0x6d, +0x80,0x80,0x6a,0x4c,0x40,0x4e,0x58,0x6e,0x80,0x80,0x7b,0x31,0x40,0x40,0x58,0x69, +0x80,0x80,0x7c,0x29,0x18,0x3c,0x48,0x54,0x8d,0x87,0x9a,0x7a,0x1f,0x25,0x40,0x54, +0x8b,0x80,0x75,0x4b,0x1c,0x28,0x40,0x68,0x8b,0x80,0x80,0x2e,0x40,0x40,0x56,0x67, +0x80,0x80,0x6f,0x4f,0x40,0x40,0x50,0x61,0x80,0x80,0x59,0x2d,0x40,0x40,0x4e,0x67, +0x80,0x80,0x6c,0x2a,0x40,0x40,0x50,0x64,0x80,0x80,0x63,0x21,0x40,0x40,0x54,0x66, +0x80,0x80,0x71,0x45,0x40,0x40,0x5c,0x6c,0x80,0x80,0x6f,0x4b,0x40,0x40,0x5a,0x6d, +0x80,0x80,0x73,0x29,0x40,0x40,0x56,0x6a,0x80,0x80,0x65,0x27,0x18,0x30,0x48,0x54, +0x86,0x86,0x7d,0x69,0x40,0x40,0x44,0x67,0x80,0x80,0x79,0x29,0x40,0x40,0x5e,0x77, +0x80,0x80,0x73,0x62,0x40,0x40,0x52,0x63,0x80,0x80,0x73,0x61,0x40,0x40,0x54,0x65, +0x80,0x80,0x79,0x63,0x24,0x3c,0x48,0x54,0x7b,0x79,0x6c,0x48,0x40,0x40,0x5e,0x70, +0x80,0x80,0x7b,0x72,0x40,0x40,0x61,0x70,0x80,0x80,0x7b,0x71,0x20,0x40,0x5a,0x75, +0x80,0x80,0x71,0x2b,0x2b,0x40,0x5d,0x75,0x80,0x80,0x71,0x24,0x40,0x40,0x51,0x63, +0x80,0x80,0x6d,0x3d,0x40,0x40,0x52,0x5f,0x80,0x80,0x73,0x51,0x40,0x40,0x56,0x69, +0x80,0x80,0x6b,0x37,0x40,0x4e,0x63,0x75,0x80,0x80,0x76,0x4e,0x40,0x4c,0x5b,0x68, +0x80,0x80,0x77,0x63,0x24,0x30,0x48,0x54,0x6b,0x72,0x78,0x75,0x40,0x40,0x54,0x66, +0x80,0x80,0x7f,0x5f,0x40,0x40,0x52,0x60,0x80,0x80,0x77,0x23,0x40,0x40,0x52,0x68, +0x80,0x80,0x75,0x43,0x40,0x40,0x56,0x67,0x80,0x80,0x78,0x49,0x40,0x4d,0x5b,0x67, +0x80,0x80,0x78,0x32,0x40,0x55,0x5b,0x66,0x80,0x7d,0x6f,0x07,0x40,0x4c,0x57,0x6c, +0x80,0x80,0x77,0x2d,0x40,0x4c,0x54,0x67,0x80,0x80,0x77,0x4b,0x2d,0x40,0x50,0x5d, +0x6d,0x80,0x76,0x24,0x40,0x40,0x4f,0x5b,0x80,0x80,0x75,0x3f,0x40,0x40,0x40,0x73, +0x80,0x80,0x80,0x29,0x40,0x40,0x55,0x70,0x80,0x80,0x7a,0x07,0x40,0x40,0x53,0x6f, +0x80,0x80,0x7b,0x11,0x40,0x40,0x56,0x62,0x80,0x80,0x80,0x0d,0x2d,0x39,0x4d,0x69, +0x71,0x80,0x7b,0x68,0x40,0x40,0x5e,0x6f,0x80,0x80,0x71,0x47,0x40,0x40,0x4e,0x5f, +0x80,0x80,0x79,0x42,0x40,0x40,0x55,0x66,0x80,0x80,0x6b,0x43,0x25,0x40,0x58,0x65, +0x69,0x80,0x79,0x73,0x40,0x40,0x55,0x61,0x80,0x80,0x7b,0x63,0x18,0x3c,0x48,0x54, +0x72,0x63,0x5f,0x63,0x29,0x40,0x5c,0x67,0x6e,0x80,0x7a,0x58,0x2d,0x40,0x59,0x68, +0x73,0x80,0x75,0x59,0x40,0x40,0x5f,0x75,0x80,0x80,0x73,0x64,0x40,0x40,0x55,0x6e, +0x80,0x80,0x73,0x49,0x40,0x40,0x48,0x5a,0x80,0x80,0x73,0x5f,0x1c,0x40,0x5e,0x67, +0x5f,0x80,0x77,0x61,0x1c,0x40,0x5b,0x67,0x71,0x80,0x73,0x5b,0x40,0x40,0x5c,0x6f, +0x80,0x80,0x73,0x57,0x40,0x40,0x5e,0x6f,0x80,0x80,0x71,0x49,0x40,0x4c,0x5b,0x6c, +0x80,0x80,0x76,0x58,0x40,0x40,0x5e,0x6b,0x80,0x80,0x73,0x57,0x40,0x40,0x5c,0x72, +0x80,0x80,0x6f,0x4e,0x40,0x40,0x59,0x6c,0x80,0x80,0x71,0x59,0x40,0x40,0x5c,0x6e, +0x80,0x80,0x71,0x45,0x40,0x40,0x58,0x6d,0x80,0x80,0x71,0x54,0x40,0x40,0x63,0x74, +0x80,0x80,0x6e,0x51,0x40,0x4e,0x5f,0x6c,0x80,0x80,0x6d,0x59,0x40,0x4c,0x5d,0x72, +0x80,0x80,0x71,0x56,0x40,0x40,0x56,0x69,0x80,0x80,0x6d,0x4f,0x40,0x40,0x5c,0x6f, +0x80,0x80,0x6b,0x49,0x18,0x30,0x48,0x54,0x8c,0x7a,0x7a,0x78,0x40,0x4c,0x5d,0x74, +0x80,0x80,0x77,0x55,0x40,0x40,0x60,0x71,0x80,0x80,0x71,0x53,0x33,0x4c,0x5a,0x6d, +0x74,0x80,0x77,0x62,0x40,0x40,0x5d,0x6d,0x80,0x80,0x70,0x4b,0x40,0x40,0x5c,0x6b, +0x80,0x80,0x6c,0x47,0x30,0x3c,0x48,0x54,0x78,0x73,0x72,0x71,0x30,0x3c,0x48,0x54, +0x78,0x73,0x72,0x71,0x18,0x30,0x3c,0x54,0x8b,0x88,0x8a,0x82,0x18,0x30,0x3c,0x54, +0x8b,0x88,0x8a,0x82,0x40,0x40,0x5c,0x6c,0x80,0x80,0x73,0x5a,0x40,0x40,0x58,0x71, +0x80,0x80,0x73,0x5c,0x40,0x40,0x5c,0x6b,0x80,0x80,0x73,0x61,0x40,0x40,0x5b,0x6c, +0x80,0x80,0x71,0x4e,0x40,0x40,0x5d,0x6e,0x80,0x80,0x73,0x4e,0x40,0x40,0x64,0x71, +0x80,0x80,0x71,0x4b,0x24,0x3c,0x48,0x54,0x5a,0x6e,0x79,0x76,0x40,0x40,0x60,0x73, +0x80,0x80,0x65,0x4d,0x40,0x4c,0x5b,0x6b,0x80,0x80,0x75,0x5d,0x40,0x48,0x5c,0x6b, +0x80,0x80,0x75,0x61,0x40,0x49,0x60,0x6f,0x80,0x80,0x75,0x65,0x40,0x51,0x63,0x72, +0x7e,0x80,0x76,0x62,0x40,0x40,0x5f,0x75,0x80,0x80,0x75,0x63,0x40,0x40,0x5a,0x70, +0x80,0x80,0x75,0x5b,0x40,0x40,0x63,0x76,0x80,0x80,0x77,0x55,0x40,0x40,0x5f,0x70, +0x80,0x80,0x73,0x55,0x40,0x40,0x5a,0x6a,0x80,0x80,0x6c,0x4d,0x40,0x40,0x55,0x6c, +0x80,0x80,0x75,0x4a,0x40,0x40,0x5c,0x73,0x80,0x80,0x71,0x5d,0x40,0x40,0x5b,0x6f, +0x80,0x80,0x74,0x51,0x40,0x40,0x63,0x75,0x80,0x80,0x75,0x58,0x40,0x40,0x5f,0x74, +0x80,0x80,0x73,0x55,0x24,0x3c,0x48,0x54,0x6e,0x6a,0x5d,0x64,0x24,0x3c,0x48,0x54, +0x6e,0x6a,0x5d,0x64,0x24,0x30,0x48,0x54,0x73,0x78,0x7d,0x76,0x40,0x40,0x54,0x68, +0x80,0x80,0x80,0x4f,0x24,0x3c,0x48,0x54,0x7b,0x7f,0x83,0x6e,0x40,0x40,0x54,0x67, +0x80,0x80,0x67,0x42,0x40,0x40,0x55,0x68,0x80,0x80,0x77,0x57,0x24,0x3c,0x48,0x54, +0x77,0x7e,0x7a,0x68,0x24,0x3c,0x48,0x54,0x77,0x7e,0x7a,0x68,0x18,0x24,0x3c,0x54, +0x67,0x5e,0x79,0x84,0x40,0x40,0x54,0x63,0x80,0x80,0x73,0x2f,0x40,0x40,0x54,0x6c, +0x80,0x80,0x71,0x2b,0x40,0x40,0x4e,0x5f,0x80,0x80,0x69,0x47,0x40,0x40,0x48,0x6c, +0x80,0x80,0x80,0x8c,0x40,0x40,0x5e,0x72,0x80,0x80,0x75,0x67,0x40,0x40,0x60,0x71, +0x80,0x80,0x75,0x61,0x40,0x40,0x60,0x6a,0x80,0x80,0x7b,0x31,0x40,0x40,0x59,0x73, +0x80,0x80,0x7b,0x6b,0x40,0x40,0x55,0x60,0x80,0x80,0x7b,0x31,0x40,0x40,0x5e,0x6f, +0x80,0x80,0x67,0x53,0x40,0x40,0x54,0x6a,0x80,0x80,0x6f,0x43,0x40,0x40,0x5c,0x73, +0x80,0x80,0x75,0x52,0x40,0x40,0x59,0x75,0x80,0x80,0x71,0x52,0x40,0x40,0x5f,0x75, +0x80,0x80,0x75,0x5d,0x40,0x40,0x60,0x79,0x80,0x80,0x71,0x59,0x40,0x40,0x65,0x75, +0x80,0x80,0x77,0x5b,0x40,0x40,0x61,0x73,0x80,0x80,0x79,0x5f,0x40,0x40,0x58,0x69, +0x80,0x80,0x75,0x57,0x40,0x40,0x55,0x66,0x80,0x80,0x6b,0x51,0x40,0x40,0x51,0x66, +0x80,0x80,0x6d,0x53,0x40,0x40,0x55,0x6a,0x80,0x80,0x71,0x61,0x40,0x40,0x54,0x62, +0x80,0x80,0x79,0x61,0x40,0x40,0x5b,0x6c,0x80,0x80,0x75,0x65,0x40,0x40,0x60,0x70, +0x80,0x80,0x73,0x59,0x40,0x40,0x61,0x6d,0x80,0x80,0x77,0x63,0x40,0x40,0x59,0x6a, +0x80,0x80,0x73,0x5d,0x40,0x40,0x51,0x69,0x80,0x80,0x79,0x69,0x40,0x40,0x57,0x69, +0x80,0x80,0x73,0x61,0x40,0x40,0x56,0x67,0x80,0x80,0x75,0x6b,0x40,0x40,0x5b,0x6d, +0x80,0x80,0x77,0x69,0x40,0x40,0x5c,0x69,0x80,0x80,0x75,0x65,0x40,0x40,0x5b,0x6c, +0x80,0x80,0x71,0x5b,0x40,0x49,0x56,0x62,0x80,0x80,0x6f,0x21,0x40,0x55,0x62,0x6e, +0x80,0x80,0x6f,0x25,0x40,0x40,0x5d,0x70,0x80,0x80,0x73,0x59,0x40,0x40,0x5e,0x76, +0x80,0x80,0x69,0x29,0x40,0x41,0x41,0x42,0x80,0x80,0x80,0x00,0x41,0x42,0x55,0x66, +0x00,0x80,0x75,0x55,0x40,0x40,0x57,0x68,0x80,0x80,0x73,0x49,0x40,0x40,0x52,0x68, +0x80,0x80,0x65,0x47,0x40,0x40,0x56,0x66,0x80,0x80,0x71,0x43,0x40,0x40,0x54,0x63, +0x80,0x80,0x71,0x4f,0x40,0x40,0x51,0x69,0x80,0x80,0x65,0x3d,0x40,0x40,0x53,0x68, +0x80,0x80,0x67,0x3f,0x40,0x40,0x55,0x67,0x80,0x80,0x65,0x35,0x40,0x40,0x55,0x68, +0x80,0x80,0x5d,0x39,0x40,0x40,0x59,0x72,0x80,0x80,0x6b,0x47,0x40,0x40,0x59,0x71, +0x80,0x80,0x6b,0x47,0x40,0x53,0x5b,0x6d,0x80,0x80,0x65,0x45,0x40,0x52,0x5c,0x73, +0x80,0x80,0x75,0x61,0x40,0x51,0x5f,0x6b,0x80,0x80,0x65,0x51,0x40,0x4d,0x60,0x6d, +0x80,0x80,0x6d,0x59,0x40,0x40,0x5a,0x6b,0x80,0x80,0x71,0x60,0x40,0x40,0x5a,0x72, +0x80,0x80,0x73,0x61,0x40,0x40,0x5b,0x6f,0x80,0x80,0x69,0x43,0x40,0x40,0x5a,0x6a, +0x80,0x80,0x77,0x57,0x40,0x49,0x54,0x60,0x80,0x80,0x79,0x4b,0x40,0x40,0x4f,0x67, +0x80,0x80,0x7a,0x4b,0x40,0x40,0x56,0x68,0x80,0x80,0x77,0x59,0x40,0x40,0x4d,0x54, +0x80,0x80,0x79,0x4d,0x40,0x40,0x5b,0x60,0x80,0x80,0x71,0x2c,0x40,0x5b,0x60,0x65, +0x00,0x00,0x80,0x64,0x40,0x40,0x55,0x62,0x80,0x80,0x6b,0x43,0x40,0x40,0x53,0x65, +0x80,0x80,0x6d,0x57,0x40,0x40,0x52,0x66,0x80,0x80,0x71,0x63,0x40,0x40,0x52,0x68, +0x80,0x80,0x69,0x53,0x40,0x40,0x5c,0x6e,0x80,0x80,0x73,0x4f,0x40,0x40,0x54,0x66, +0x80,0x80,0x6f,0x4f,0x40,0x4f,0x5d,0x6e,0x80,0x80,0x6d,0x4f,0x40,0x40,0x5b,0x6f, +0x80,0x80,0x73,0x55,0x40,0x40,0x55,0x66,0x80,0x80,0x71,0x5d,0x40,0x40,0x54,0x69, +0x80,0x80,0x73,0x5a,0x40,0x40,0x40,0x4c,0x80,0x80,0x82,0x02,0x35,0x41,0x59,0x6b, +0x00,0x80,0x67,0x2f,0x40,0x40,0x62,0x71,0x80,0x80,0x73,0x53,0x40,0x40,0x62,0x73, +0x80,0x80,0x73,0x57,0x40,0x40,0x5a,0x6d,0x80,0x80,0x77,0x63,0x40,0x40,0x5c,0x6d, +0x80,0x80,0x75,0x67,0x40,0x40,0x66,0x6f,0x80,0x80,0x71,0x4d,0x40,0x40,0x66,0x6e, +0x80,0x80,0x65,0x37,0x40,0x40,0x61,0x6d,0x80,0x80,0x73,0x5d,0x40,0x40,0x5e,0x6c, +0x80,0x80,0x6f,0x57,0x40,0x40,0x5f,0x6f,0x80,0x80,0x6d,0x4f,0x40,0x40,0x5b,0x72, +0x80,0x80,0x71,0x57,0x40,0x40,0x63,0x72,0x80,0x80,0x75,0x48,0x40,0x56,0x69,0x77, +0x80,0x80,0x6c,0x51,0x40,0x4f,0x64,0x74,0x80,0x80,0x6b,0x53,0x1e,0x2a,0x36,0x37, +0x80,0x80,0x80,0x00,0x40,0x40,0x5a,0x69,0x80,0x80,0x6c,0x4b,0x40,0x40,0x55,0x68, +0x80,0x80,0x71,0x4d,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00,0x00,0x01,0x02,0x03, +0x04,0x05,0x06,0x07,0x01,0xf0,0x7e,0x00,0x09,0x01,0xf7,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7a,0x75,0x71,0x6d,0x69,0x66,0x62,0x5f,0x5d,0x5a,0x58,0x55, +0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,0x46,0x44,0x42,0x41,0x3f,0x3e,0x3d,0x3b,0x3a, +0x39,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29, +0x28,0x27,0x26,0x25,0x25,0x24,0x23,0x22,0x21,0x21,0x20,0x1f,0x1f,0x1e,0x1d,0x1c, +0x1c,0x1b,0x1a,0x1a,0x19,0x19,0x18,0x17,0x17,0x16,0x15,0x15,0x14,0x14,0x13,0x13, +0x12,0x12,0x11,0x10,0x10,0x0f,0x0f,0x0e,0x0e,0x0d,0x0d,0x0c,0x0c,0x0c,0x0b,0x0b, +0x0a,0x0a,0x09,0x09,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x05,0x05,0x05,0x04,0x04, +0x03,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00,0x04,0x00, +0x04,0x00,0x05,0x00,0x05,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x07,0x00,0x07,0x00, +0x08,0x00,0x08,0x00,0x09,0x00,0x09,0x00,0x0a,0x00,0x0a,0x00,0x0b,0x00,0x0b,0x00, +0x0c,0x00,0x0c,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0e,0x00,0x0e,0x00,0x0f,0x00, +0x0f,0x00,0x10,0x00,0x10,0x00,0x11,0x00,0x11,0x00,0x12,0x00,0x12,0x00,0x13,0x00, +0x13,0x00,0x14,0x00,0x14,0x00,0x15,0x00,0x15,0x00,0x15,0x00,0x16,0x00,0x16,0x00, +0x17,0x00,0x17,0x00,0x18,0x00,0x18,0x00,0x19,0x00,0x19,0x00,0x1a,0x00,0x1a,0x00, +0x1b,0x00,0x1b,0x00,0x1c,0x00,0x1c,0x00,0x1d,0x00,0x1d,0x00,0x1e,0x00,0x1e,0x00, +0x1e,0x00,0x1f,0x00,0x1f,0x00,0x20,0x00,0x20,0x00,0x21,0x00,0x21,0x00,0x22,0x00, +0x22,0x00,0x23,0x00,0x23,0x00,0x24,0x00,0x24,0x00,0x25,0x00,0x25,0x00,0x26,0x00, +0x26,0x00,0x27,0x00,0x27,0x00,0x28,0x00,0x28,0x00,0x29,0x00,0x29,0x00,0x29,0x00, +0x2a,0x00,0x2a,0x00,0x2b,0x00,0x2b,0x00,0x2c,0x00,0x2c,0x00,0x2d,0x00,0x2d,0x00, +0x2e,0x00,0x2e,0x00,0x2f,0x00,0x2f,0x00,0x30,0x00,0x30,0x00,0x31,0x00,0x31,0x00, +0x32,0x00,0x32,0x00,0x33,0x00,0x33,0x00,0x34,0x00,0x34,0x00,0x35,0x00,0x35,0x00, +0x36,0x00,0x36,0x00,0x37,0x00,0x37,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x39,0x00, +0x39,0x00,0x3a,0x00,0x3a,0x00,0x3b,0x00,0x3b,0x00,0x3c,0x00,0x3c,0x00,0x3d,0x00, +0x3d,0x00,0x3e,0x00,0x3e,0x00,0x3f,0x00,0x3f,0x00,0x40,0x00,0x40,0x00,0x41,0x00, +0x41,0x00,0x42,0x00,0x42,0x00,0x43,0x00,0x43,0x00,0x44,0x00,0x44,0x00,0x45,0x00, +0x45,0x00,0x46,0x00,0x46,0x00,0x47,0x00,0x47,0x00,0x48,0x00,0x48,0x00,0x49,0x00, +0x49,0x00,0x4a,0x00,0x4a,0x00,0x4b,0x00,0x4b,0x00,0x4c,0x00,0x4c,0x00,0x4d,0x00, +0x4d,0x00,0x4e,0x00,0x4e,0x00,0x4f,0x00,0x4f,0x00,0x50,0x00,0x50,0x00,0x51,0x00, +0x51,0x00,0x52,0x00,0x52,0x00,0x53,0x00,0x53,0x00,0x54,0x00,0x54,0x00,0x55,0x00, +0x55,0x00,0x56,0x00,0x56,0x00,0x57,0x00,0x57,0x00,0x58,0x00,0x58,0x00,0x59,0x00, +0x59,0x00,0x5a,0x00,0x5a,0x00,0x5b,0x00,0x5b,0x00,0x5c,0x00,0x5c,0x00,0x5d,0x00, +0x5d,0x00,0x5e,0x00,0x5e,0x00,0x5f,0x00,0x5f,0x00,0x60,0x00,0x60,0x00,0x61,0x00, +0x61,0x00,0x62,0x00,0x62,0x00,0x63,0x00,0x63,0x00,0x64,0x00,0x64,0x00,0x65,0x00, +0x65,0x00,0x66,0x00,0x66,0x00,0x67,0x00,0x67,0x00,0x68,0x00,0x68,0x00,0x69,0x00, +0x69,0x00,0x6a,0x00,0x6a,0x00,0x6b,0x00,0x6b,0x00,0x6c,0x00,0x6c,0x00,0x6d,0x00, +0x6d,0x00,0x6e,0x00,0x6e,0x00,0x6f,0x00,0x6f,0x00,0x70,0x00,0x71,0x00,0x71,0x00, +0x72,0x00,0x72,0x00,0x73,0x00,0x73,0x00,0x74,0x00,0x74,0x00,0x75,0x00,0x75,0x00, +0x76,0x00,0x76,0x00,0x77,0x00,0x77,0x00,0x78,0x00,0x78,0x00,0x79,0x00,0x79,0x00, +0x7a,0x00,0x7a,0x00,0x7b,0x00,0x7b,0x00,0x7c,0x00,0x7c,0x00,0x7d,0x00,0x7d,0x00, +0x7e,0x00,0x7e,0x00,0x7f,0x00,0x7f,0x00,0x80,0x00,0x81,0x00,0x81,0x00,0x82,0x00, +0x82,0x00,0x83,0x00,0x83,0x00,0x84,0x00,0x84,0x00,0x85,0x00,0x85,0x00,0x86,0x00, +0x86,0x00,0x87,0x00,0x87,0x00,0x88,0x00,0x88,0x00,0x89,0x00,0x89,0x00,0x8a,0x00, +0x8a,0x00,0x8b,0x00,0x8c,0x00,0x8c,0x00,0x8d,0x00,0x8d,0x00,0x8e,0x00,0x8e,0x00, +0x8f,0x00,0x8f,0x00,0x90,0x00,0x90,0x00,0x91,0x00,0x91,0x00,0x92,0x00,0x92,0x00, +0x93,0x00,0x93,0x00,0x94,0x00,0x94,0x00,0x95,0x00,0x96,0x00,0x96,0x00,0x97,0x00, +0x97,0x00,0x98,0x00,0x98,0x00,0x99,0x00,0x99,0x00,0x9a,0x00,0x9a,0x00,0x9b,0x00, +0x9b,0x00,0x9c,0x00,0x9c,0x00,0x9d,0x00,0x9e,0x00,0x9e,0x00,0x9f,0x00,0x9f,0x00, +0xa0,0x00,0xa0,0x00,0xa1,0x00,0xa1,0x00,0xa2,0x00,0xa2,0x00,0xa3,0x00,0xa3,0x00, +0xa4,0x00,0xa4,0x00,0xa5,0x00,0xa6,0x00,0xa6,0x00,0xa7,0x00,0xa7,0x00,0xa8,0x00, +0xa8,0x00,0xa9,0x00,0xa9,0x00,0xaa,0x00,0xaa,0x00,0xab,0x00,0xab,0x00,0xac,0x00, +0xad,0x00,0xad,0x00,0xae,0x00,0xae,0x00,0xaf,0x00,0xaf,0x00,0xb0,0x00,0xb0,0x00, +0xb1,0x00,0xb1,0x00,0xb2,0x00,0xb3,0x00,0xb3,0x00,0xb4,0x00,0xb4,0x00,0xb5,0x00, +0xb5,0x00,0xb6,0x00,0xb6,0x00,0xb7,0x00,0xb7,0x00,0xb8,0x00,0xb8,0x00,0xb9,0x00, +0xba,0x00,0xba,0x00,0xbb,0x00,0xbb,0x00,0xbc,0x00,0xbc,0x00,0xbd,0x00,0xbd,0x00, +0xbe,0x00,0xbf,0x00,0xbf,0x00,0xc0,0x00,0xc0,0x00,0xc1,0x00,0xc1,0x00,0xc2,0x00, +0xc2,0x00,0xc3,0x00,0xc3,0x00,0xc4,0x00,0xc5,0x00,0xc5,0x00,0xc6,0x00,0xc6,0x00, +0xc7,0x00,0xc7,0x00,0xc8,0x00,0xc8,0x00,0xc9,0x00,0xca,0x00,0xca,0x00,0xcb,0x00, +0xcb,0x00,0xcc,0x00,0xcc,0x00,0xcd,0x00,0xcd,0x00,0xce,0x00,0xcf,0x00,0xcf,0x00, +0xd0,0x00,0xd0,0x00,0xd1,0x00,0xd1,0x00,0xd2,0x00,0xd2,0x00,0xd3,0x00,0xd4,0x00, +0xd4,0x00,0xd5,0x00,0xd5,0x00,0xd6,0x00,0xd6,0x00,0xd7,0x00,0xd7,0x00,0xd8,0x00, +0xd9,0x00,0xd9,0x00,0xda,0x00,0xda,0x00,0xdb,0x00,0xdb,0x00,0xdc,0x00,0xdc,0x00, +0xdd,0x00,0xde,0x00,0xde,0x00,0xdf,0x00,0xdf,0x00,0xe0,0x00,0xe0,0x00,0xe1,0x00, +0xe2,0x00,0xe2,0x00,0xe3,0x00,0xe3,0x00,0xe4,0x00,0xe4,0x00,0xe5,0x00,0xe5,0x00, +0xe6,0x00,0xe7,0x00,0xe7,0x00,0xe8,0x00,0xe8,0x00,0xe9,0x00,0xe9,0x00,0xea,0x00, +0xeb,0x00,0xeb,0x00,0xec,0x00,0xec,0x00,0xed,0x00,0xed,0x00,0xee,0x00,0xef,0x00, +0xef,0x00,0xf0,0x00,0xf0,0x00,0xf1,0x00,0xf1,0x00,0xf2,0x00,0xf3,0x00,0xf3,0x00, +0xf4,0x00,0xf4,0x00,0xf5,0x00,0xf5,0x00,0xf6,0x00,0xf7,0x00,0xf7,0x00,0xf8,0x00, +0xf8,0x00,0xf9,0x00,0xf9,0x00,0xfa,0x00,0xfb,0x00,0xfb,0x00,0xfc,0x00,0xfc,0x00, +0xfd,0x00,0xfd,0x00,0xfe,0x00,0xff,0x00,0xff,0x01,0x00,0x01,0x00,0x01,0x01,0x01, +0x02,0x01,0x02,0x01,0x03,0x01,0x03,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0x06,0x01, +0x06,0x01,0x07,0x01,0x07,0x01,0x08,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0a,0x01, +0x0b,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0d,0x01,0x0e,0x01,0x0e,0x01,0x0f,0x01, +0x0f,0x01,0x10,0x01,0x11,0x01,0x11,0x01,0x12,0x01,0x12,0x01,0x13,0x01,0x14,0x01, +0x14,0x01,0x15,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x17,0x01,0x18,0x01,0x18,0x01, +0x19,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1b,0x01,0x1c,0x01,0x1c,0x01,0x1d,0x01, +0x1e,0x01,0x1e,0x01,0x1f,0x01,0x1f,0x01,0x20,0x01,0x21,0x01,0x21,0x01,0x22,0x01, +0x22,0x01,0x23,0x01,0x24,0x01,0x24,0x01,0x25,0x01,0x25,0x01,0x26,0x01,0x27,0x01, +0x27,0x01,0x28,0x01,0x28,0x01,0x29,0x01,0x29,0x01,0x2a,0x01,0x2b,0x01,0x2b,0x01, +0x2c,0x01,0x2c,0x01,0x2d,0x01,0x2e,0x01,0x2e,0x01,0x2f,0x01,0x2f,0x01,0x30,0x01, +0x31,0x01,0x31,0x01,0x32,0x01,0x32,0x01,0x33,0x01,0x34,0x01,0x34,0x01,0x35,0x01, +0x35,0x01,0x36,0x01,0x37,0x01,0x37,0x01,0x38,0x01,0x38,0x01,0x39,0x01,0x3a,0x01, +0x3a,0x01,0x3b,0x01,0x3c,0x01,0x3c,0x01,0x3d,0x01,0x3d,0x01,0x3e,0x01,0x3f,0x01, +0x3f,0x01,0x40,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x42,0x01,0x43,0x01,0x43,0x01, +0x44,0x01,0x45,0x01,0x45,0x01,0x46,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x48,0x01, +0x49,0x01,0x49,0x01,0x4a,0x01,0x4b,0x01,0x4b,0x01,0x4c,0x01,0x4d,0x01,0x4d,0x01, +0x4e,0x01,0x4e,0x01,0x4f,0x01,0x50,0x01,0x50,0x01,0x51,0x01,0x51,0x01,0x52,0x01, +0x53,0x01,0x53,0x01,0x54,0x01,0x55,0x01,0x55,0x01,0x56,0x01,0x56,0x01,0x57,0x01, +0x58,0x01,0x58,0x01,0x59,0x01,0x59,0x01,0x5a,0x01,0x5b,0x01,0x5b,0x01,0x5c,0x01, +0x5d,0x01,0x5d,0x01,0x5e,0x01,0x5e,0x01,0x5f,0x01,0x60,0x01,0x60,0x01,0x61,0x01, +0x62,0x01,0x62,0x01,0x63,0x01,0x63,0x01,0x64,0x01,0x65,0x01,0x65,0x01,0x66,0x01, +0x67,0x01,0x67,0x01,0x68,0x01,0x68,0x01,0x69,0x01,0x6a,0x01,0x6a,0x01,0x6b,0x01, +0x6c,0x01,0x6c,0x01,0x6d,0x01,0x6d,0x01,0x6e,0x01,0x6f,0x01,0x6f,0x01,0x70,0x01, +0x71,0x01,0x71,0x01,0x72,0x01,0x72,0x01,0x73,0x01,0x74,0x01,0x74,0x01,0x75,0x01, +0x76,0x01,0x76,0x01,0x77,0x01,0x77,0x01,0x78,0x01,0x79,0x01,0x79,0x01,0x7a,0x01, +0x7b,0x01,0x7b,0x01,0x7c,0x01,0x7d,0x01,0x7d,0x01,0x7e,0x01,0x7e,0x01,0x7f,0x01, +0x80,0x01,0x80,0x01,0x81,0x01,0x82,0x01,0x82,0x01,0x83,0x01,0x84,0x01,0x84,0x01, +0x85,0x01,0x85,0x01,0x86,0x01,0x87,0x01,0x87,0x01,0x88,0x01,0x89,0x01,0x89,0x01, +0x8a,0x01,0x8b,0x01,0x8b,0x01,0x8c,0x01,0x8c,0x01,0x8d,0x01,0x8e,0x01,0x8e,0x01, +0x8f,0x01,0x90,0x01,0x90,0x01,0x91,0x01,0x92,0x01,0x92,0x01,0x93,0x01,0x94,0x01, +0x94,0x01,0x95,0x01,0x95,0x01,0x96,0x01,0x97,0x01,0x97,0x01,0x98,0x01,0x99,0x01, +0x99,0x01,0x9a,0x01,0x9b,0x01,0x9b,0x01,0x9c,0x01,0x9d,0x01,0x9d,0x01,0x9e,0x01, +0x9f,0x01,0x9f,0x01,0xa0,0x01,0xa0,0x01,0xa1,0x01,0xa2,0x01,0xa2,0x01,0xa3,0x01, +0xa4,0x01,0xa4,0x01,0xa5,0x01,0xa6,0x01,0xa6,0x01,0xa7,0x01,0xa8,0x01,0xa8,0x01, +0xa9,0x01,0xaa,0x01,0xaa,0x01,0xab,0x01,0xac,0x01,0xac,0x01,0xad,0x01,0xae,0x01, +0xae,0x01,0xaf,0x01,0xb0,0x01,0xb0,0x01,0xb1,0x01,0xb1,0x01,0xb2,0x01,0xb3,0x01, +0xb3,0x01,0xb4,0x01,0xb5,0x01,0xb5,0x01,0xb6,0x01,0xb7,0x01,0xb7,0x01,0xb8,0x01, +0xb9,0x01,0xb9,0x01,0xba,0x01,0xbb,0x01,0xbb,0x01,0xbc,0x01,0xbd,0x01,0xbd,0x01, +0xbe,0x01,0xbf,0x01,0xbf,0x01,0xc0,0x01,0xc1,0x01,0xc1,0x01,0xc2,0x01,0xc3,0x01, +0xc3,0x01,0xc4,0x01,0xc5,0x01,0xc5,0x01,0xc6,0x01,0xc7,0x01,0xc7,0x01,0xc8,0x01, +0xc9,0x01,0xc9,0x01,0xca,0x01,0xcb,0x01,0xcb,0x01,0xcc,0x01,0xcd,0x01,0xcd,0x01, +0xce,0x01,0xcf,0x01,0xcf,0x01,0xd0,0x01,0xd1,0x01,0xd1,0x01,0xd2,0x01,0xd3,0x01, +0xd3,0x01,0xd4,0x01,0xd5,0x01,0xd5,0x01,0xd6,0x01,0xd7,0x01,0xd7,0x01,0xd8,0x01, +0xd9,0x01,0xda,0x01,0xda,0x01,0xdb,0x01,0xdc,0x01,0xdc,0x01,0xdd,0x01,0xde,0x01, +0xde,0x01,0xdf,0x01,0xe0,0x01,0xe0,0x01,0xe1,0x01,0xe2,0x01,0xe2,0x01,0xe3,0x01, +0xe4,0x01,0xe4,0x01,0xe5,0x01,0xe6,0x01,0xe6,0x01,0xe7,0x01,0xe8,0x01,0xe8,0x01, +0xe9,0x01,0xea,0x01,0xeb,0x01,0xeb,0x01,0xec,0x01,0xed,0x01,0xed,0x01,0xee,0x01, +0xef,0x01,0xef,0x01,0xf0,0x01,0xf1,0x01,0xf1,0x01,0xf2,0x01,0xf3,0x01,0xf3,0x01, +0xf4,0x01,0xf5,0x01,0xf5,0x01,0xf6,0x01,0xf7,0x01,0xf8,0x01,0xf8,0x01,0xf9,0x01, +0xfa,0x01,0xfa,0x01,0xfb,0x01,0xfc,0x01,0xfc,0x01,0xfd,0x01,0xfe,0x01,0xfe,0x01, +0xff,0x02,0x00,0x02,0x01,0x02,0x01,0x02,0x02,0x02,0x03,0x02,0x03,0x02,0x04,0x02, +0x05,0x02,0x05,0x02,0x06,0x02,0x07,0x02,0x07,0x02,0x08,0x02,0x09,0x02,0x0a,0x02, +0x0a,0x02,0x0b,0x02,0x0c,0x02,0x0c,0x02,0x0d,0x02,0x0e,0x02,0x0e,0x02,0x0f,0x02, +0x10,0x02,0x11,0x02,0x11,0x02,0x12,0x02,0x13,0x02,0x13,0x02,0x14,0x02,0x15,0x02, +0x15,0x02,0x16,0x02,0x17,0x02,0x18,0x02,0x18,0x02,0x19,0x02,0x1a,0x02,0x1a,0x02, +0x1b,0x02,0x1c,0x02,0x1d,0x02,0x1d,0x02,0x1e,0x02,0x1f,0x02,0x1f,0x02,0x20,0x02, +0x21,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x24,0x02,0x24,0x02,0x25,0x02,0x26,0x02, +0x26,0x02,0x27,0x02,0x28,0x02,0x29,0x02,0x29,0x02,0x2a,0x02,0x2b,0x02,0x2b,0x02, +0x2c,0x02,0x2d,0x02,0x2e,0x02,0x2e,0x02,0x2f,0x02,0x30,0x02,0x30,0x02,0x31,0x02, +0x32,0x02,0x33,0x02,0x33,0x02,0x34,0x02,0x35,0x02,0x35,0x02,0x36,0x02,0x37,0x02, +0x38,0x02,0x38,0x02,0x39,0x02,0x3a,0x02,0x3a,0x02,0x3b,0x02,0x3c,0x02,0x3d,0x02, +0x3d,0x02,0x3e,0x02,0x3f,0x02,0x40,0x02,0x40,0x02,0x41,0x02,0x42,0x02,0x42,0x02, +0x43,0x02,0x44,0x02,0x45,0x02,0x45,0x02,0x46,0x02,0x47,0x02,0x47,0x02,0x48,0x02, +0x49,0x02,0x4a,0x02,0x4a,0x02,0x4b,0x02,0x4c,0x02,0x4d,0x02,0x4d,0x02,0x4e,0x02, +0x4f,0x02,0x4f,0x02,0x50,0x02,0x51,0x02,0x52,0x02,0x52,0x02,0x53,0x02,0x54,0x02, +0x55,0x02,0x55,0x02,0x56,0x02,0x57,0x02,0x58,0x02,0x58,0x02,0x59,0x02,0x5a,0x02, +0x5a,0x02,0x5b,0x02,0x5c,0x02,0x5d,0x02,0x5d,0x02,0x5e,0x02,0x5f,0x02,0x60,0x02, +0x60,0x02,0x61,0x02,0x62,0x02,0x63,0x02,0x63,0x02,0x64,0x02,0x65,0x02,0x66,0x02, +0x66,0x02,0x67,0x02,0x68,0x02,0x68,0x02,0x69,0x02,0x6a,0x02,0x6b,0x02,0x6b,0x02, +0x6c,0x02,0x6d,0x02,0x6e,0x02,0x6e,0x02,0x6f,0x02,0x70,0x02,0x71,0x02,0x71,0x02, +0x72,0x02,0x73,0x02,0x74,0x02,0x74,0x02,0x75,0x02,0x76,0x02,0x77,0x02,0x77,0x02, +0x78,0x02,0x79,0x02,0x7a,0x02,0x7a,0x02,0x7b,0x02,0x7c,0x02,0x7d,0x02,0x7d,0x02, +0x7e,0x02,0x7f,0x02,0x80,0x02,0x80,0x02,0x81,0x02,0x82,0x02,0x83,0x02,0x83,0x02, +0x84,0x02,0x85,0x02,0x86,0x02,0x86,0x02,0x87,0x02,0x88,0x02,0x89,0x02,0x89,0x02, +0x8a,0x02,0x8b,0x02,0x8c,0x02,0x8c,0x02,0x8d,0x02,0x8e,0x02,0x8f,0x02,0x8f,0x02, +0x90,0x02,0x91,0x02,0x92,0x02,0x92,0x02,0x93,0x02,0x94,0x02,0x95,0x02,0x96,0x02, +0x96,0x02,0x97,0x02,0x98,0x02,0x99,0x02,0x99,0x02,0x9a,0x02,0x9b,0x02,0x9c,0x02, +0x9c,0x02,0x9d,0x02,0x9e,0x02,0x9f,0x02,0x9f,0x02,0xa0,0x02,0xa1,0x02,0xa2,0x02, +0xa2,0x02,0xa3,0x02,0xa4,0x02,0xa5,0x02,0xa6,0x02,0xa6,0x02,0xa7,0x02,0xa8,0x02, +0xa9,0x02,0xa9,0x02,0xaa,0x02,0xab,0x02,0xac,0x02,0xac,0x02,0xad,0x02,0xae,0x02, +0xaf,0x02,0xb0,0x02,0xb0,0x02,0xb1,0x02,0xb2,0x02,0xb3,0x02,0xb3,0x02,0xb4,0x02, +0xb5,0x02,0xb6,0x02,0xb7,0x02,0xb7,0x02,0xb8,0x02,0xb9,0x02,0xba,0x02,0xba,0x02, +0xbb,0x02,0xbc,0x02,0xbd,0x02,0xbe,0x02,0xbe,0x02,0xbf,0x02,0xc0,0x02,0xc1,0x02, +0xc1,0x02,0xc2,0x02,0xc3,0x02,0xc4,0x02,0xc5,0x02,0xc5,0x02,0xc6,0x02,0xc7,0x02, +0xc8,0x02,0xc8,0x02,0xc9,0x02,0xca,0x02,0xcb,0x02,0xcc,0x02,0xcc,0x02,0xcd,0x02, +0xce,0x02,0xcf,0x02,0xd0,0x02,0xd0,0x02,0xd1,0x02,0xd2,0x02,0xd3,0x02,0xd3,0x02, +0xd4,0x02,0xd5,0x02,0xd6,0x02,0xd7,0x02,0xd7,0x02,0xd8,0x02,0xd9,0x02,0xda,0x02, +0xdb,0x02,0xdb,0x02,0xdc,0x02,0xdd,0x02,0xde,0x02,0xdf,0x02,0xdf,0x02,0xe0,0x02, +0xe1,0x02,0xe2,0x02,0xe3,0x02,0xe3,0x02,0xe4,0x02,0xe5,0x02,0xe6,0x02,0xe7,0x02, +0xe7,0x02,0xe8,0x02,0xe9,0x02,0xea,0x02,0xeb,0x02,0xeb,0x02,0xec,0x02,0xed,0x02, +0xee,0x02,0xef,0x02,0xef,0x02,0xf0,0x02,0xf1,0x02,0xf2,0x02,0xf3,0x02,0xf3,0x02, +0xf4,0x02,0xf5,0x02,0xf6,0x02,0xf7,0x02,0xf7,0x02,0xf8,0x02,0xf9,0x02,0xfa,0x02, +0xfb,0x02,0xfb,0x02,0xfc,0x02,0xfd,0x02,0xfe,0x02,0xff,0x02,0xff,0x03,0x00,0x03, +0x01,0x03,0x02,0x03,0x03,0x03,0x03,0x03,0x04,0x03,0x05,0x03,0x06,0x03,0x07,0x03, +0x08,0x03,0x08,0x03,0x09,0x03,0x0a,0x03,0x0b,0x03,0x0c,0x03,0x0c,0x03,0x0d,0x03, +0x0e,0x03,0x0f,0x03,0x10,0x03,0x10,0x03,0x11,0x03,0x12,0x03,0x13,0x03,0x14,0x03, +0x15,0x03,0x15,0x03,0x16,0x03,0x17,0x03,0x18,0x03,0x19,0x03,0x19,0x03,0x1a,0x03, +0x1b,0x03,0x1c,0x03,0x1d,0x03,0x1e,0x03,0x1e,0x03,0x1f,0x03,0x20,0x03,0x21,0x03, +0x22,0x03,0x23,0x03,0x23,0x03,0x24,0x03,0x25,0x03,0x26,0x03,0x27,0x03,0x27,0x03, +0x28,0x03,0x29,0x03,0x2a,0x03,0x2b,0x03,0x2c,0x03,0x2c,0x03,0x2d,0x03,0x2e,0x03, +0x2f,0x03,0x30,0x03,0x31,0x03,0x31,0x03,0x32,0x03,0x33,0x03,0x34,0x03,0x35,0x03, +0x36,0x03,0x36,0x03,0x37,0x03,0x38,0x03,0x39,0x03,0x3a,0x03,0x3b,0x03,0x3b,0x03, +0x3c,0x03,0x3d,0x03,0x3e,0x03,0x3f,0x03,0x40,0x03,0x40,0x03,0x41,0x03,0x42,0x03, +0x43,0x03,0x44,0x03,0x45,0x03,0x45,0x03,0x46,0x03,0x47,0x03,0x48,0x03,0x49,0x03, +0x4a,0x03,0x4b,0x03,0x4b,0x03,0x4c,0x03,0x4d,0x03,0x4e,0x03,0x4f,0x03,0x50,0x03, +0x50,0x03,0x51,0x03,0x52,0x03,0x53,0x03,0x54,0x03,0x55,0x03,0x56,0x03,0x56,0x03, +0x57,0x03,0x58,0x03,0x59,0x03,0x5a,0x03,0x5b,0x03,0x5b,0x03,0x5c,0x03,0x5d,0x03, +0x5e,0x03,0x5f,0x03,0x60,0x03,0x61,0x03,0x61,0x03,0x62,0x03,0x63,0x03,0x64,0x03, +0x65,0x03,0x66,0x03,0x67,0x03,0x67,0x03,0x68,0x03,0x69,0x03,0x6a,0x03,0x6b,0x03, +0x6c,0x03,0x6d,0x03,0x6d,0x03,0x6e,0x03,0x6f,0x03,0x70,0x03,0x71,0x03,0x72,0x03, +0x73,0x03,0x73,0x03,0x74,0x03,0x75,0x03,0x76,0x03,0x77,0x03,0x78,0x03,0x79,0x03, +0x79,0x03,0x7a,0x03,0x7b,0x03,0x7c,0x03,0x7d,0x03,0x7e,0x03,0x7f,0x03,0x80,0x03, +0x80,0x03,0x81,0x03,0x82,0x03,0x83,0x03,0x84,0x03,0x85,0x03,0x86,0x03,0x86,0x03, +0x87,0x03,0x88,0x03,0x89,0x03,0x8a,0x03,0x8b,0x03,0x8c,0x03,0x8d,0x03,0x8d,0x03, +0x8e,0x03,0x8f,0x03,0x90,0x03,0x91,0x03,0x92,0x03,0x93,0x03,0x94,0x03,0x94,0x03, +0x95,0x03,0x96,0x03,0x97,0x03,0x98,0x03,0x99,0x03,0x9a,0x03,0x9b,0x03,0x9b,0x03, +0x9c,0x03,0x9d,0x03,0x9e,0x03,0x9f,0x03,0xa0,0x03,0xa1,0x03,0xa2,0x03,0xa2,0x03, +0xa3,0x03,0xa4,0x03,0xa5,0x03,0xa6,0x03,0xa7,0x03,0xa8,0x03,0xa9,0x03,0xaa,0x03, +0xaa,0x03,0xab,0x03,0xac,0x03,0xad,0x03,0xae,0x03,0xaf,0x03,0xb0,0x03,0xb1,0x03, +0xb2,0x03,0xb2,0x03,0xb3,0x03,0xb4,0x03,0xb5,0x03,0xb6,0x03,0xb7,0x03,0xb8,0x03, +0xb9,0x03,0xba,0x03,0xba,0x03,0xbb,0x03,0xbc,0x03,0xbd,0x03,0xbe,0x03,0xbf,0x03, +0xc0,0x03,0xc1,0x03,0xc2,0x03,0xc3,0x03,0xc3,0x03,0xc4,0x03,0xc5,0x03,0xc6,0x03, +0xc7,0x03,0xc8,0x03,0xc9,0x03,0xca,0x03,0xcb,0x03,0xcb,0x03,0xcc,0x03,0xcd,0x03, +0xce,0x03,0xcf,0x03,0xd0,0x03,0xd1,0x03,0xd2,0x03,0xd3,0x03,0xd4,0x03,0xd5,0x03, +0xd5,0x03,0xd6,0x03,0xd7,0x03,0xd8,0x03,0xd9,0x03,0xda,0x03,0xdb,0x03,0xdc,0x03, +0xdd,0x03,0xde,0x03,0xde,0x03,0xdf,0x03,0xe0,0x03,0xe1,0x03,0xe2,0x03,0xe3,0x03, +0xe4,0x03,0xe5,0x03,0xe6,0x03,0xe7,0x03,0xe8,0x03,0xe9,0x03,0xe9,0x03,0xea,0x03, +0xeb,0x03,0xec,0x03,0xed,0x03,0xee,0x03,0xef,0x03,0xf0,0x03,0xf1,0x03,0xf2,0x03, +0xf3,0x03,0xf4,0x03,0xf4,0x03,0xf5,0x03,0xf6,0x03,0xf7,0x03,0xf8,0x03,0xf9,0x03, +0xfa,0x03,0xfb,0x03,0xfc,0x03,0xfd,0x03,0xfe,0x03,0xff,0x54,0x52,0x49,0x58,0x2d, +0x50,0x52,0x4f,0x01,0x0a,0x00,0x01,0x02,0x03,0x04,0x05,0x04,0x03,0x10,0x10,0x48, +0x12,0x13,0x14,0x15,0x17,0x06,0x06,0x06,0x06,0x07,0x07,0x08,0x08,0x3e,0x3f,0x3e, +0x3f,0x27,0x27,0x51,0x26,0x58,0x5e,0x36,0x5c,0x61,0x63,0x62,0x6d,0x66,0x60,0x44, +0x5d,0x50,0x51,0x09,0x50,0x30,0x30,0x31,0x2d,0x28,0x29,0x2a,0x2a,0x2b,0x2e,0x2e, +0x18,0x19,0x1a,0x1b,0x68,0x20,0x21,0x22,0x22,0x24,0x25,0x23,0x20,0x49,0x49,0x48, +0x48,0x4a,0x4b,0x40,0x41,0x42,0x43,0x47,0x47,0x44,0x45,0x46,0x16,0x38,0x38,0x39, +0x39,0x3c,0x3c,0x3a,0x3d,0x3e,0x0b,0x62,0x2e,0x64,0x09,0x0e,0x0d,0x0c,0x6b,0x56, +0x52,0x4e,0x4e,0x4b,0x5e,0x2f,0x75,0x76,0x76,0x76,0x74,0x73,0x77,0x73,0x09,0x37, +0x7c,0x7b,0x7d,0x70,0x52 +}; + diff --git a/sys/i386/isa/sound/ultrasound.h b/sys/i386/isa/sound/ultrasound.h new file mode 100644 index 000000000000..40e2443e6f65 --- /dev/null +++ b/sys/i386/isa/sound/ultrasound.h @@ -0,0 +1,121 @@ +#ifndef _ULTRASOUND_H_ +#define _ULTRASOUND_H_ +/* + * Copyright by Hannu Savolainen 1993 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * ultrasound.h - Macros for programming the Gravis Ultrasound + * These macros are extremely device dependent + * and not portable. + */ + +/* + * Private events for Gravis Ultrasound (GUS) + * + * Format: + * byte 0 - SEQ_PRIVATE (0xfe) + * byte 1 - Synthesizer device number (0-N) + * byte 2 - Command (see below) + * byte 3 - Voice number (0-31) + * bytes 4 and 5 - parameter P1 (unsigned short) + * bytes 6 and 7 - parameter P2 (unsigned short) + * + * Commands: + * Each command affects one voice defined in byte 3. + * Unused parameters (P1 and/or P2 *MUST* be initialized to zero). + * _GUS_NUMVOICES - Sets max. number of concurrent voices (P1=14-31, default 16) + * _GUS_VOICESAMPLE- ************ OBSOLETE ************* + * _GUS_VOICEON - Starts voice (P1=voice mode) + * _GUS_VOICEOFF - Stops voice (no parameters) + * _GUS_VOICEFADE - Stops the voice smoothly. + * _GUS_VOICEMODE - Alters the voice mode, don't start or stop voice (P1=voice mode) + * _GUS_VOICEBALA - Sets voice balence (P1, 0=left, 7=middle and 15=right, default 7) + * _GUS_VOICEFREQ - Sets voice (sample) playback frequency (P1=Hz) + * _GUS_VOICEVOL - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off) + * _GUS_VOICEVOL2 - Sets voice volume (P1=volume, 0xfff=max, 0xeff=half, 0x000=off) + * (Like GUS_VOICEVOL but doesn't change the hw + * volume. It just updates volume in the voice table). + * + * _GUS_RAMPRANGE - Sets limits for volume ramping (P1=low volume, P2=high volume) + * _GUS_RAMPRATE - Sets the speed for volume ramping (P1=scale, P2=rate) + * _GUS_RAMPMODE - Sets the volume ramping mode (P1=ramping mode) + * _GUS_RAMPON - Starts volume ramping (no parameters) + * _GUS_RAMPOFF - Stops volume ramping (no parameters) + * _GUS_VOLUME_SCALE - Changes the volume calculation constants + * for all voices. + */ + +#define _GUS_NUMVOICES 0x00 +#define _GUS_VOICESAMPLE 0x01 /* OBSOLETE */ +#define _GUS_VOICEON 0x02 +#define _GUS_VOICEOFF 0x03 +#define _GUS_VOICEMODE 0x04 +#define _GUS_VOICEBALA 0x05 +#define _GUS_VOICEFREQ 0x06 +#define _GUS_VOICEVOL 0x07 +#define _GUS_RAMPRANGE 0x08 +#define _GUS_RAMPRATE 0x09 +#define _GUS_RAMPMODE 0x0a +#define _GUS_RAMPON 0x0b +#define _GUS_RAMPOFF 0x0c +#define _GUS_VOICEFADE 0x0d +#define _GUS_VOLUME_SCALE 0x0e +#define _GUS_VOICEVOL2 0x0f +#define _GUS_VOICE_POS 0x10 + +/* + * GUS API macros + */ + +#define _GUS_CMD(chn, voice, cmd, p1, p2) \ + {_SEQ_NEEDBUF(8); _seqbuf[_seqbufptr] = SEQ_PRIVATE;\ + _seqbuf[_seqbufptr+1] = (chn); _seqbuf[_seqbufptr+2] = cmd;\ + _seqbuf[_seqbufptr+3] = voice;\ + *(unsigned short*)&_seqbuf[_seqbufptr+4] = p1;\ + *(unsigned short*)&_seqbuf[_seqbufptr+6] = p2;\ + _SEQ_ADVBUF(8);} + +#define GUS_NUMVOICES(chn, p1) _GUS_CMD(chn, 0, _GUS_NUMVOICES, (p1), 0) +#define GUS_VOICESAMPLE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICESAMPLE, (p1), 0) /* OBSOLETE */ +#define GUS_VOICEON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEON, (p1), 0) +#define GUS_VOICEOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEOFF, 0, 0) +#define GUS_VOICEFADE(chn, voice) _GUS_CMD(chn, voice, _GUS_VOICEFADE, 0, 0) +#define GUS_VOICEMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEMODE, (p1), 0) +#define GUS_VOICEBALA(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEBALA, (p1), 0) +#define GUS_VOICEFREQ(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICEFREQ, \ + (p) & 0xffff, ((p) >> 16) & 0xffff) +#define GUS_VOICEVOL(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL, (p1), 0) +#define GUS_VOICEVOL2(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_VOICEVOL2, (p1), 0) +#define GUS_RAMPRANGE(chn, voice, low, high) _GUS_CMD(chn, voice, _GUS_RAMPRANGE, (low), (high)) +#define GUS_RAMPRATE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_RAMPRATE, (p1), (p2)) +#define GUS_RAMPMODE(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPMODE, (p1), 0) +#define GUS_RAMPON(chn, voice, p1) _GUS_CMD(chn, voice, _GUS_RAMPON, (p1), 0) +#define GUS_RAMPOFF(chn, voice) _GUS_CMD(chn, voice, _GUS_RAMPOFF, 0, 0) +#define GUS_VOLUME_SCALE(chn, voice, p1, p2) _GUS_CMD(chn, voice, _GUS_VOLUME_SCALE, (p1), (p2)) +#define GUS_VOICE_POS(chn, voice, p) _GUS_CMD(chn, voice, _GUS_VOICE_POS, \ + (p) & 0xffff, ((p) >> 16) & 0xffff) + +#endif |