Linux-2.6.12-rc2
[linux-2.6] / Documentation / sound / oss / MultiSound
1 #! /bin/sh
2 #
3 #  Turtle Beach MultiSound Driver Notes
4 #  -- Andrew Veliath <andrewtv@usa.net>
5 #
6 #  Last update:                      September 10, 1998
7 #  Corresponding msnd driver:        0.8.3
8 #
9 # ** This file is a README (top part) and shell archive (bottom part).
10 #    The corresponding archived utility sources can be unpacked by
11 #    running `sh MultiSound' (the utilities are only needed for the
12 #    Pinnacle and Fiji cards). **
13 #
14 #
15 #  -=-=- Getting Firmware -=-=-
16 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 #  
18 #  See the section `Obtaining and Creating Firmware Files' in this
19 #  document for instructions on obtaining the necessary firmware
20 #  files.
21 #  
22 #  
23 #  Supported Features
24 #  ~~~~~~~~~~~~~~~~~~
25 #  
26 #  Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is
27 #  not currently available) and mixer functionality (/dev/mixer) are
28 #  supported (memory mapped digital audio is not yet supported).
29 #  Digital transfers and monitoring can be done as well if you have
30 #  the digital daughterboard (see the section on using the S/PDIF port
31 #  for more information).
32 #
33 #  Support for the Turtle Beach MultiSound Hurricane architecture is
34 #  composed of the following modules (these can also operate compiled
35 #  into the kernel):
36 #  
37 #  msnd               - MultiSound base (requires soundcore)
38 #
39 #  msnd_classic       - Base audio/mixer support for Classic, Monetery and
40 #                       Tahiti cards
41 #
42 #  msnd_pinnacle      - Base audio/mixer support for Pinnacle and Fiji cards
43 #  
44 #  
45 #  Important Notes - Read Before Using
46 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 #  
48 #  The firmware files are not included (may change in future).  You
49 #  must obtain these images from Turtle Beach (they are included in
50 #  the MultiSound Development Kits), and place them in /etc/sound for
51 #  example, and give the full paths in the Linux configuration.  If
52 #  you are compiling in support for the MultiSound driver rather than
53 #  using it as a module, these firmware files must be accessible
54 #  during kernel compilation.
55 #
56 #  Please note these files must be binary files, not assembler.  See
57 #  the section later in this document for instructions to obtain these
58 #  files.
59 #  
60 #  
61 #  Configuring Card Resources
62 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~
63 #
64 #  ** This section is very important, as your card may not work at all
65 #     or your machine may crash if you do not do this correctly. **
66 #
67 #  * Classic/Monterey/Tahiti
68 #  
69 #  These cards are configured through the driver msnd_classic.  You must
70 #  know the io port, then the driver will select the irq and memory resources
71 #  on the card.  It is up to you to know if these are free locations or now,
72 #  a conflict can lock the machine up.
73 #
74 #  * Pinnacle/Fiji
75 #
76 #  The Pinnacle and Fiji cards have an extra config port, either
77 #  0x250, 0x260 or 0x270.  This port can be disabled to have the card
78 #  configured strictly through PnP, however you lose the ability to
79 #  access the IDE controller and joystick devices on this card when
80 #  using PnP.  The included pinnaclecfg program in this shell archive
81 #  can be used to configure the card in non-PnP mode, and in PnP mode
82 #  you can use isapnptools.  These are described briefly here.
83 #
84 #  pinnaclecfg is not required; you can use the msnd_pinnacle module
85 #  to fully configure the card as well.  However, pinnaclecfg can be
86 #  used to change the resource values of a particular device after the
87 #  msnd_pinnacle module has been loaded.  If you are compiling the
88 #  driver into the kernel, you must set these values during compile
89 #  time, however other peripheral resource values can be changed with
90 #  the pinnaclecfg program after the kernel is loaded.
91 #
92 #
93 #  *** PnP mode
94 #  
95 #  Use pnpdump to obtain a sample configuration if you can; I was able
96 #  to obtain one with the command `pnpdump 1 0x203' -- this may vary
97 #  for you (running pnpdump by itself did not work for me).  Then,
98 #  edit this file and use isapnp to uncomment and set the card values.
99 #  Use these values when inserting the msnd_pinnacle module.  Using
100 #  this method, you can set the resources for the DSP and the Kurzweil
101 #  synth (Pinnacle).  Since Linux does not directly support PnP
102 #  devices, you may have difficulty when using the card in PnP mode
103 #  when it the driver is compiled into the kernel.  Using non-PnP mode
104 #  is preferable in this case.
105 #
106 #  Here is an example mypinnacle.conf for isapnp that sets the card to
107 #  io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil
108 #  synth to 0x330 and irq 9 (may need editing for your system):
109 #
110 #  (READPORT 0x0203)
111 #  (CSN 2)
112 #  (IDENTIFY *)
113 #  
114 #  # DSP
115 #  (CONFIGURE BVJ0440/-1 (LD 0
116 #          (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000))
117 #          (ACT Y)))
118 #  
119 #  # Kurzweil Synth (Pinnacle Only)
120 #  (CONFIGURE BVJ0440/-1 (LD 1
121 #          (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E)))
122 #          (ACT Y)))
123 #  
124 #  (WAITFORKEY)
125 #
126 #
127 #  *** Non-PnP mode
128 #  
129 #  The second way is by running the card in non-PnP mode.  This
130 #  actually has some advantages in that you can access some other
131 #  devices on the card, such as the joystick and IDE controller.  To
132 #  configure the card, unpack this shell archive and build the
133 #  pinnaclecfg program.  Using this program, you can assign the
134 #  resource values to the card's devices, or disable the devices.  As
135 #  an alternative to using pinnaclecfg, you can specify many of the
136 #  configuration values when loading the msnd_pinnacle module (or
137 #  during kernel configuration when compiling the driver into the
138 #  kernel).
139 #
140 #  If you specify cfg=0x250 for the msnd_pinnacle module, it
141 #  automatically configure the card to the given io, irq and memory
142 #  values using that config port (the config port is jumper selectable
143 #  on the card to 0x250, 0x260 or 0x270).
144 #
145 #  See the `msnd_pinnacle Additional Options' section below for more
146 #  information on these parameters (also, if you compile the driver
147 #  directly into the kernel, these extra parameters can be useful
148 #  here).
149 #
150 #
151 # ** It is very easy to cause problems in your machine if you choose a
152 #    resource value which is incorrect. **
153 #  
154 #
155 #  Examples
156 #  ~~~~~~~~
157 #  
158 #  * MultiSound Classic/Monterey/Tahiti:
159 #  
160 #  modprobe soundcore
161 #  insmod msnd
162 #  insmod msnd_classic io=0x290 irq=7 mem=0xd0000
163 #  
164 #  * MultiSound Pinnacle in PnP mode:
165 #  
166 #  modprobe soundcore
167 #  insmod msnd
168 #  isapnp mypinnacle.conf
169 #  insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values
170 #  
171 #  * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port,
172 #    one of 0x250, 0x260 or 0x270):
173 #  
174 #  insmod soundcore
175 #  insmod msnd
176 #  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000
177 #  
178 # * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP
179 #   mode, add the following (assumes you did `isapnp mypinnacle.conf'):
180 #  
181 #  insmod sound
182 #  insmod mpu401 io=0x330 irq=9                    <-- match mypinnacle.conf values
183 #  
184 # * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP
185 #   mode, add the following.  Note how we first configure the peripheral's
186 #   resources, _then_ install a Linux driver for it:
187 #  
188 #  insmod sound
189 #  pinnaclecfg 0x250 mpu 0x330 9
190 #  insmod mpu401 io=0x330 irq=9
191 #
192 #  -- OR you can use the following sequence without pinnaclecfg in non-PnP mode:
193 #
194 #  insmod soundcore
195 #  insmod msnd
196 #  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9
197 #  insmod sound
198 #  insmod mpu401 io=0x330 irq=9
199 #
200 # * To setup the joystick port on the Pinnacle in non-PnP mode (though
201 #   you have to find the actual Linux joystick driver elsewhere), you
202 #   can use pinnaclecfg:
203 #
204 #   pinnaclecfg 0x250 joystick 0x200
205 #
206 #  -- OR you can configure this using msnd_pinnacle with the following:
207 #
208 #  insmod soundcore
209 #  insmod msnd
210 #  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200
211 #
212 #  
213 #  msnd_classic, msnd_pinnacle Required Options
214 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215 #  
216 #  If the following options are not given, the module will not load.
217 #  Examine the kernel message log for informative error messages.
218 #  WARNING--probing isn't supported so try to make sure you have the
219 #  correct shared memory area, otherwise you may experience problems.
220 #  
221 #  io                   I/O base of DSP, e.g. io=0x210
222 #  irq                  IRQ number, e.g. irq=5
223 #  mem                  Shared memory area, e.g. mem=0xd8000
224 #  
225 #  
226 #  msnd_classic, msnd_pinnacle Additional Options
227 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
228 #  
229 #  fifosize             The digital audio FIFOs, in kilobytes.  If not
230 #                       specified, the default will be used.  Increasing
231 #                       this value will reduce the chance of a FIFO
232 #                       underflow at the expense of increasing overall
233 #                       latency.  For example, fifosize=512 will
234 #                       allocate 512kB read and write FIFOs (1MB total).
235 #                       While this may reduce dropouts, a heavy machine
236 #                       load will undoubtedly starve the FIFO of data
237 #                       and you will eventually get dropouts.  One
238 #                       option is to alter the scheduling priority of
239 #                       the playback process, using `nice' or some form
240 #                       of POSIX soft real-time scheduling.
241 #
242 #  calibrate_signal     Setting this to one calibrates the ADCs to the
243 #                       signal, zero calibrates to the card (defaults
244 #                       to zero).
245 #  
246 #  
247 #  msnd_pinnacle Additional Options
248 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
249 #
250 #  digital              Specify digital=1 to enable the S/PDIF input
251 #                       if you have the digital daughterboard
252 #                       adapter. This will enable access to the
253 #                       DIGITAL1 input for the soundcard in the mixer.
254 #                       Some mixer programs might have trouble setting
255 #                       the DIGITAL1 source as an input.  If you have
256 #                       trouble, you can try the setdigital.c program
257 #                       at the bottom of this document.
258 #
259 #  cfg                  Non-PnP configuration port for the Pinnacle
260 #                       and Fiji (typically 0x250, 0x260 or 0x270,
261 #                       depending on the jumper configuration).  If
262 #                       this option is omitted, then it is assumed
263 #                       that the card is in PnP mode, and that the
264 #                       specified DSP resource values are already
265 #                       configured with PnP (i.e. it won't attempt to
266 #                       do any sort of configuration).
267 #
268 #  When the Pinnacle is in non-PnP mode, you can use the following
269 #  options to configure particular devices.  If a full specification
270 #  for a device is not given, then the device is not configured.  Note
271 #  that you still must use a Linux driver for any of these devices
272 #  once their resources are setup (such as the Linux joystick driver,
273 #  or the MPU401 driver from OSS for the Kurzweil synth).
274 #
275 #  mpu_io               I/O port of MPU (on-board Kurzweil synth)
276 #  mpu_irq              IRQ of MPU (on-board Kurzweil synth)
277 #  ide_io0              First I/O port of IDE controller
278 #  ide_io1              Second I/O port of IDE controller
279 #  ide_irq              IRQ IDE controller
280 #  joystick_io          I/O port of joystick
281 #  
282 #  
283 #  Obtaining and Creating Firmware Files
284 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
285 #  
286 #       For the Classic/Tahiti/Monterey
287 #       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
288 #  
289 #  Download to /tmp and unzip the following file from Turtle Beach:
290 #  
291 #       ftp://ftp.voyetra.com/pub/tbs/msndcl/msndvkit.zip
292 #  
293 #  When unzipped, unzip the file named MsndFiles.zip.  Then copy the
294 #  following firmware files to /etc/sound (note the file renaming):
295 #  
296 #    cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin
297 #    cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin
298 #  
299 #  When configuring the Linux kernel, specify /etc/sound/msndinit.bin and
300 #  /etc/sound/msndperm.bin for the two firmware files (Linux kernel
301 #  versions older than 2.2 do not ask for firmware paths, and are
302 #  hardcoded to /etc/sound).
303 #
304 #  If you are compiling the driver into the kernel, these files must
305 #  be accessible during compilation, but will not be needed later.
306 #  The files must remain, however, if the driver is used as a module.
307 #  
308 #  
309 #       For the Pinnacle/Fiji
310 #       ~~~~~~~~~~~~~~~~~~~~~
311 #  
312 #  Download to /tmp and unzip the following file from Turtle Beach (be
313 #  sure to use the entire URL; some have had trouble navigating to the
314 #  URL):
315 #  
316 #       ftp://ftp.voyetra.com/pub/tbs/pinn/pnddk100.zip
317 #
318 #  Unpack this shell archive, and run make in the created directory
319 #  (you need a C compiler and flex to build the utilities).  This
320 #  should give you the executables conv, pinnaclecfg and setdigital.
321 #  conv is only used temporarily here to create the firmware files,
322 #  while pinnaclecfg is used to configure the Pinnacle or Fiji card in
323 #  non-PnP mode, and setdigital can be used to set the S/PDIF input on
324 #  the mixer (pinnaclecfg and setdigital should be copied to a
325 #  convenient place, possibly run during system initialization).
326 #
327 #  To generating the firmware files with the `conv' program, we create
328 #  the binary firmware files by doing the following conversion
329 #  (assuming the archive unpacked into a directory named PINNDDK):
330 #  
331 #    ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin
332 #    ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin
333 #  
334 #  The conv (and conv.l) program is not needed after conversion and can
335 #  be safely deleted.  Then, when configuring the Linux kernel, specify
336 #  /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two
337 #  firmware files (Linux kernel versions older than 2.2 do not ask for
338 #  firmware paths, and are hardcoded to /etc/sound).
339 #  
340 #  If you are compiling the driver into the kernel, these files must
341 #  be accessible during compilation, but will not be needed later.
342 #  The files must remain, however, if the driver is used as a module.
343 #
344 #  
345 #  Using Digital I/O with the S/PDIF Port
346 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
347 #
348 #  If you have a Pinnacle or Fiji with the digital daughterboard and
349 #  want to set it as the input source, you can use this program if you
350 #  have trouble trying to do it with a mixer program (be sure to
351 #  insert the module with the digital=1 option, or say Y to the option
352 #  during compiled-in kernel operation).  Upon selection of the S/PDIF
353 #  port, you should be able monitor and record from it.
354 #
355 #  There is something to note about using the S/PDIF port.  Digital
356 #  timing is taken from the digital signal, so if a signal is not
357 #  connected to the port and it is selected as recording input, you
358 #  will find PCM playback to be distorted in playback rate.  Also,
359 #  attempting to record at a sampling rate other than the DAT rate may
360 #  be problematic (i.e. trying to record at 8000Hz when the DAT signal
361 #  is 44100Hz).  If you have a problem with this, set the recording
362 #  input to analog if you need to record at a rate other than that of
363 #  the DAT rate.
364 #
365 #
366 #  -- Shell archive attached below, just run `sh MultiSound' to extract.
367 #     Contains Pinnacle/Fiji utilities to convert firmware, configure
368 #     in non-PnP mode, and select the DIGITAL1 input for the mixer.
369 #
370 #
371 #!/bin/sh
372 # This is a shell archive (produced by GNU sharutils 4.2).
373 # To extract the files from this archive, save it to some FILE, remove
374 # everything before the `!/bin/sh' line above, then type `sh FILE'.
375 #
376 # Made on 1998-12-04 10:07 EST by <andrewtv@ztransform.velsoft.com>.
377 # Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'.
378 #
379 # Existing files will *not* be overwritten unless `-c' is specified.
380 #
381 # This shar contains:
382 # length mode       name
383 # ------ ---------- ------------------------------------------
384 #   2046 -rw-rw-r-- MultiSound.d/setdigital.c
385 #  10235 -rw-rw-r-- MultiSound.d/pinnaclecfg.c
386 #    106 -rw-rw-r-- MultiSound.d/Makefile
387 #    141 -rw-rw-r-- MultiSound.d/conv.l
388 #   1472 -rw-rw-r-- MultiSound.d/msndreset.c
389 #
390 save_IFS="${IFS}"
391 IFS="${IFS}:"
392 gettext_dir=FAILED
393 locale_dir=FAILED
394 first_param="$1"
395 for dir in $PATH
396 do
397   if test "$gettext_dir" = FAILED && test -f $dir/gettext \
398      && ($dir/gettext --version >/dev/null 2>&1)
399   then
400     set `$dir/gettext --version 2>&1`
401     if test "$3" = GNU
402     then
403       gettext_dir=$dir
404     fi
405   fi
406   if test "$locale_dir" = FAILED && test -f $dir/shar \
407      && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
408   then
409     locale_dir=`$dir/shar --print-text-domain-dir`
410   fi
411 done
412 IFS="$save_IFS"
413 if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
414 then
415   echo=echo
416 else
417   TEXTDOMAINDIR=$locale_dir
418   export TEXTDOMAINDIR
419   TEXTDOMAIN=sharutils
420   export TEXTDOMAIN
421   echo="$gettext_dir/gettext -s"
422 fi
423 touch -am 1231235999 $$.touch >/dev/null 2>&1
424 if test ! -f 1231235999 && test -f $$.touch; then
425   shar_touch=touch
426 else
427   shar_touch=:
428   echo
429   $echo 'WARNING: not restoring timestamps.  Consider getting and'
430   $echo "installing GNU \`touch', distributed in GNU File Utilities..."
431   echo
432 fi
433 rm -f 1231235999 $$.touch
434 #
435 if mkdir _sh01426; then
436   $echo 'x -' 'creating lock directory'
437 else
438   $echo 'failed to create lock directory'
439   exit 1
440 fi
441 # ============= MultiSound.d/setdigital.c ==============
442 if test ! -d 'MultiSound.d'; then
443   $echo 'x -' 'creating directory' 'MultiSound.d'
444   mkdir 'MultiSound.d'
445 fi
446 if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then
447   $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)'
448 else
449   $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)'
450   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' &&
451 /*********************************************************************
452 X *
453 X * setdigital.c - sets the DIGITAL1 input for a mixer
454 X *
455 X * Copyright (C) 1998 Andrew Veliath
456 X *
457 X * This program is free software; you can redistribute it and/or modify
458 X * it under the terms of the GNU General Public License as published by
459 X * the Free Software Foundation; either version 2 of the License, or
460 X * (at your option) any later version.
461 X *
462 X * This program is distributed in the hope that it will be useful,
463 X * but WITHOUT ANY WARRANTY; without even the implied warranty of
464 X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
465 X * GNU General Public License for more details.
466 X *
467 X * You should have received a copy of the GNU General Public License
468 X * along with this program; if not, write to the Free Software
469 X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
470 X *
471 X ********************************************************************/
472 X
473 #include <stdio.h>
474 #include <unistd.h>
475 #include <fcntl.h>
476 #include <sys/types.h>
477 #include <sys/stat.h>
478 #include <sys/ioctl.h>
479 #include <sys/soundcard.h>
480 X
481 int main(int argc, char *argv[])
482 {
483 X       int fd;
484 X       unsigned long recmask, recsrc;
485 X
486 X       if (argc != 2) {
487 X               fprintf(stderr, "usage: setdigital <mixer device>\n");
488 X               exit(1);
489 X       }
490 X
491 X       if ((fd = open(argv[1], O_RDWR)) < 0) {
492 X               perror(argv[1]);
493 X               exit(1);
494 X       }
495 X
496 X       if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) {
497 X               fprintf(stderr, "error: ioctl read recording mask failed\n");
498 X               perror("ioctl");
499 X               close(fd);
500 X               exit(1);
501 X       }
502 X
503 X       if (!(recmask & SOUND_MASK_DIGITAL1)) {
504 X               fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n");
505 X               close(fd);
506 X               exit(1);
507 X       }
508 X
509 X       if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) {
510 X               fprintf(stderr, "error: ioctl read recording source failed\n");
511 X               perror("ioctl");
512 X               close(fd);
513 X               exit(1);
514 X       }
515 X
516 X       recsrc |= SOUND_MASK_DIGITAL1;
517 X       
518 X       if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) {
519 X               fprintf(stderr, "error: ioctl write recording source failed\n");
520 X               perror("ioctl");
521 X               close(fd);
522 X               exit(1);
523 X       }
524 X
525 X       close(fd);
526 X       
527 X       return 0;
528 }
529 SHAR_EOF
530   $shar_touch -am 1204092598 'MultiSound.d/setdigital.c' &&
531   chmod 0664 'MultiSound.d/setdigital.c' ||
532   $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed'
533   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
534   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
535     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
536     || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed'
537 e87217fc3e71288102ba41fd81f71ec4  MultiSound.d/setdigital.c
538 SHAR_EOF
539   else
540     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`"
541     test 2046 -eq "$shar_count" ||
542     $echo 'MultiSound.d/setdigital.c:' 'original size' '2046,' 'current size' "$shar_count!"
543   fi
544 fi
545 # ============= MultiSound.d/pinnaclecfg.c ==============
546 if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then
547   $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)'
548 else
549   $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)'
550   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' &&
551 /*********************************************************************
552 X *
553 X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program
554 X *
555 X * This is for NON-PnP mode only.  For PnP mode, use isapnptools.
556 X *
557 X * This is Linux-specific, and must be run with root permissions.
558 X *
559 X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux
560 X *
561 X * Copyright (C) 1998 Andrew Veliath
562 X *
563 X * This program is free software; you can redistribute it and/or modify
564 X * it under the terms of the GNU General Public License as published by
565 X * the Free Software Foundation; either version 2 of the License, or
566 X * (at your option) any later version.
567 X *
568 X * This program is distributed in the hope that it will be useful,
569 X * but WITHOUT ANY WARRANTY; without even the implied warranty of
570 X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
571 X * GNU General Public License for more details.
572 X *
573 X * You should have received a copy of the GNU General Public License
574 X * along with this program; if not, write to the Free Software
575 X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
576 X *
577 X ********************************************************************/
578 X
579 #include <stdio.h>
580 #include <stdlib.h>
581 #include <string.h>
582 #include <errno.h>
583 #include <unistd.h>
584 #include <asm/io.h>
585 #include <asm/types.h>
586 X
587 #define IREG_LOGDEVICE          0x07
588 #define IREG_ACTIVATE           0x30
589 #define LD_ACTIVATE             0x01
590 #define LD_DISACTIVATE          0x00
591 #define IREG_EECONTROL          0x3F
592 #define IREG_MEMBASEHI          0x40
593 #define IREG_MEMBASELO          0x41
594 #define IREG_MEMCONTROL         0x42
595 #define IREG_MEMRANGEHI         0x43
596 #define IREG_MEMRANGELO         0x44
597 #define MEMTYPE_8BIT            0x00
598 #define MEMTYPE_16BIT           0x02
599 #define MEMTYPE_RANGE           0x00
600 #define MEMTYPE_HIADDR          0x01
601 #define IREG_IO0_BASEHI         0x60
602 #define IREG_IO0_BASELO         0x61
603 #define IREG_IO1_BASEHI         0x62
604 #define IREG_IO1_BASELO         0x63
605 #define IREG_IRQ_NUMBER         0x70
606 #define IREG_IRQ_TYPE           0x71
607 #define IRQTYPE_HIGH            0x02
608 #define IRQTYPE_LOW             0x00
609 #define IRQTYPE_LEVEL           0x01
610 #define IRQTYPE_EDGE            0x00
611 X
612 #define HIBYTE(w)               ((BYTE)(((WORD)(w) >> 8) & 0xFF))
613 #define LOBYTE(w)               ((BYTE)(w))
614 #define MAKEWORD(low,hi)        ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8)))
615 X
616 typedef __u8                    BYTE;
617 typedef __u16                   USHORT;
618 typedef __u16                   WORD;
619 X
620 static int config_port = -1;
621 X
622 static int msnd_write_cfg(int cfg, int reg, int value)
623 {
624 X       outb(reg, cfg);
625 X       outb(value, cfg + 1);
626 X       if (value != inb(cfg + 1)) {
627 X               fprintf(stderr, "error: msnd_write_cfg: I/O error\n");
628 X               return -EIO;
629 X       }
630 X       return 0;
631 }
632 X
633 static int msnd_read_cfg(int cfg, int reg)
634 {
635 X       outb(reg, cfg);
636 X       return inb(cfg + 1);
637 }
638 X
639 static int msnd_write_cfg_io0(int cfg, int num, WORD io)
640 {
641 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
642 X               return -EIO;
643 X       if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
644 X               return -EIO;
645 X       if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
646 X               return -EIO;
647 X       return 0;
648 }
649 X
650 static int msnd_read_cfg_io0(int cfg, int num, WORD *io)
651 {
652 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
653 X               return -EIO;
654 X       
655 X       *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO),
656 X                      msnd_read_cfg(cfg, IREG_IO0_BASEHI));
657 X
658 X       return 0;
659 }
660 X
661 static int msnd_write_cfg_io1(int cfg, int num, WORD io)
662 {
663 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
664 X               return -EIO;
665 X       if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
666 X               return -EIO;
667 X       if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
668 X               return -EIO;
669 X       return 0;
670 }
671 X
672 static int msnd_read_cfg_io1(int cfg, int num, WORD *io)
673 {
674 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
675 X               return -EIO;
676 X       
677 X       *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO),
678 X                      msnd_read_cfg(cfg, IREG_IO1_BASEHI));
679 X
680 X       return 0;
681 }
682 X
683 static int msnd_write_cfg_irq(int cfg, int num, WORD irq)
684 {
685 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
686 X               return -EIO;
687 X       if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
688 X               return -EIO;
689 X       if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
690 X               return -EIO;
691 X       return 0;
692 }
693 X
694 static int msnd_read_cfg_irq(int cfg, int num, WORD *irq)
695 {
696 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
697 X               return -EIO;
698 X       
699 X       *irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER);
700 X
701 X       return 0;
702 }
703 X
704 static int msnd_write_cfg_mem(int cfg, int num, int mem)
705 {
706 X       WORD wmem;
707 X
708 X       mem >>= 8;
709 X       mem &= 0xfff;
710 X       wmem = (WORD)mem;
711 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
712 X               return -EIO;
713 X       if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
714 X               return -EIO;
715 X       if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
716 X               return -EIO;
717 X       if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
718 X               return -EIO;
719 X       return 0;
720 }
721 X
722 static int msnd_read_cfg_mem(int cfg, int num, int *mem)
723 {
724 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
725 X               return -EIO;
726 X       
727 X       *mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO),
728 X                       msnd_read_cfg(cfg, IREG_MEMBASEHI));
729 X       *mem <<= 8;
730 X
731 X       return 0;
732 }
733 X
734 static int msnd_activate_logical(int cfg, int num)
735 {
736 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
737 X               return -EIO;
738 X       if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
739 X               return -EIO;
740 X       return 0;
741 }
742 X
743 static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
744 {
745 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
746 X               return -EIO;
747 X       if (msnd_write_cfg_io0(cfg, num, io0))
748 X               return -EIO;
749 X       if (msnd_write_cfg_io1(cfg, num, io1))
750 X               return -EIO;
751 X       if (msnd_write_cfg_irq(cfg, num, irq))
752 X               return -EIO;
753 X       if (msnd_write_cfg_mem(cfg, num, mem))
754 X               return -EIO;
755 X       if (msnd_activate_logical(cfg, num))
756 X               return -EIO;
757 X       return 0;
758 }
759 X
760 static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem)
761 {
762 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
763 X               return -EIO;
764 X       if (msnd_read_cfg_io0(cfg, num, io0))
765 X               return -EIO;
766 X       if (msnd_read_cfg_io1(cfg, num, io1))
767 X               return -EIO;
768 X       if (msnd_read_cfg_irq(cfg, num, irq))
769 X               return -EIO;
770 X       if (msnd_read_cfg_mem(cfg, num, mem))
771 X               return -EIO;
772 X       return 0;
773 }
774 X
775 static void usage(void)
776 {
777 X       fprintf(stderr,
778 X               "\n"
779 X               "pinnaclecfg 1.0\n"
780 X               "\n"
781 X               "usage: pinnaclecfg <config port> [device config]\n"
782 X               "\n"
783 X               "This is for use with the card in NON-PnP mode only.\n"
784 X               "\n"
785 X               "Available devices (not all available for Fiji):\n"
786 X               "\n"
787 X               "        Device                       Description\n"
788 X               "        -------------------------------------------------------------------\n"
789 X               "        reset                        Reset all devices (i.e. disable)\n"
790 X               "        show                         Display current device configurations\n"
791 X               "\n"
792 X               "        dsp <io> <irq> <mem>         Audio device\n"
793 X               "        mpu <io> <irq>               Internal Kurzweil synth\n"
794 X               "        ide <io0> <io1> <irq>        On-board IDE controller\n"
795 X               "        joystick <io>                Joystick port\n"
796 X               "\n");
797 X       exit(1);
798 }
799 X
800 static int cfg_reset(void)
801 {
802 X       int i;
803 X
804 X       for (i = 0; i < 4; ++i)
805 X               msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0);
806 X       
807 X       return 0;
808 }
809 X
810 static int cfg_show(void)
811 {
812 X       int i;
813 X       int count = 0;
814 X
815 X       for (i = 0; i < 4; ++i) {
816 X               WORD io0, io1, irq;
817 X               int mem;
818 X               msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem);
819 X               switch (i) {
820 X               case 0:
821 X                       if (io0 || irq || mem) {
822 X                               printf("dsp 0x%x %d 0x%x\n", io0, irq, mem);
823 X                               ++count;
824 X                       }
825 X                       break;
826 X               case 1:
827 X                       if (io0 || irq) {
828 X                               printf("mpu 0x%x %d\n", io0, irq);
829 X                               ++count;
830 X                       }
831 X                       break;
832 X               case 2:
833 X                       if (io0 || io1 || irq) {
834 X                               printf("ide 0x%x 0x%x %d\n", io0, io1, irq);
835 X                               ++count;
836 X                       }
837 X                       break;
838 X               case 3:
839 X                       if (io0) {
840 X                               printf("joystick 0x%x\n", io0);
841 X                               ++count;
842 X                       }
843 X                       break;
844 X               }
845 X       }
846 X
847 X       if (count == 0)
848 X               fprintf(stderr, "no devices configured\n");
849 X       
850 X       return 0;
851 }
852 X
853 static int cfg_dsp(int argc, char *argv[])
854 {
855 X       int io, irq, mem;
856 X
857 X       if (argc < 3 ||
858 X           sscanf(argv[0], "0x%x", &io) != 1 ||
859 X           sscanf(argv[1], "%d", &irq) != 1 ||
860 X           sscanf(argv[2], "0x%x", &mem) != 1)
861 X               usage();
862 X
863 X       if (!(io == 0x290 ||
864 X             io == 0x260 ||
865 X             io == 0x250 ||
866 X             io == 0x240 ||
867 X             io == 0x230 ||
868 X             io == 0x220 ||
869 X             io == 0x210 ||
870 X             io == 0x3e0)) {
871 X               fprintf(stderr, "error: io must be one of "
872 X                       "210, 220, 230, 240, 250, 260, 290, or 3E0\n");
873 X               usage();
874 X       }
875 X       
876 X       if (!(irq == 5 ||
877 X             irq == 7 ||
878 X             irq == 9 ||
879 X             irq == 10 ||
880 X             irq == 11 ||
881 X             irq == 12)) {
882 X               fprintf(stderr, "error: irq must be one of "
883 X                       "5, 7, 9, 10, 11 or 12\n");
884 X               usage();
885 X       }
886 X
887 X       if (!(mem == 0xb0000 ||
888 X             mem == 0xc8000 ||
889 X             mem == 0xd0000 ||
890 X             mem == 0xd8000 ||
891 X             mem == 0xe0000 ||
892 X             mem == 0xe8000)) {
893 X               fprintf(stderr, "error: mem must be one of "
894 X                       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
895 X               usage();
896 X       }
897 X
898 X       return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem);
899 }
900 X
901 static int cfg_mpu(int argc, char *argv[])
902 {
903 X       int io, irq;
904 X
905 X       if (argc < 2 ||
906 X           sscanf(argv[0], "0x%x", &io) != 1 ||
907 X           sscanf(argv[1], "%d", &irq) != 1)
908 X               usage();
909 X       
910 X       return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0);
911 }
912 X
913 static int cfg_ide(int argc, char *argv[])
914 {
915 X       int io0, io1, irq;
916 X
917 X       if (argc < 3 ||
918 X           sscanf(argv[0], "0x%x", &io0) != 1 ||
919 X           sscanf(argv[0], "0x%x", &io1) != 1 ||
920 X           sscanf(argv[1], "%d", &irq) != 1)
921 X               usage();
922 X       
923 X       return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0);
924 }
925 X
926 static int cfg_joystick(int argc, char *argv[])
927 {
928 X       int io;
929 X
930 X       if (argc < 1 ||
931 X           sscanf(argv[0], "0x%x", &io) != 1)
932 X               usage();
933 X       
934 X       return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0);
935 }
936 X
937 int main(int argc, char *argv[])
938 {
939 X       char *device;
940 X       int rv = 0;
941 X
942 X       --argc; ++argv;
943 X
944 X       if (argc < 2)
945 X               usage();
946 X
947 X       sscanf(argv[0], "0x%x", &config_port);
948 X       if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) {
949 X               fprintf(stderr, "error: <config port> must be 0x250, 0x260 or 0x270\n");
950 X               exit(1);
951 X       }
952 X       if (ioperm(config_port, 2, 1)) {
953 X               perror("ioperm");
954 X               fprintf(stderr, "note: pinnaclecfg must be run as root\n");
955 X               exit(1);
956 X       }
957 X       device = argv[1];
958 X
959 X       argc -= 2; argv += 2;
960 X
961 X       if (strcmp(device, "reset") == 0)
962 X               rv = cfg_reset();
963 X       else if (strcmp(device, "show") == 0)
964 X               rv = cfg_show();
965 X       else if (strcmp(device, "dsp") == 0)
966 X               rv = cfg_dsp(argc, argv);
967 X       else if (strcmp(device, "mpu") == 0)
968 X               rv = cfg_mpu(argc, argv);
969 X       else if (strcmp(device, "ide") == 0)
970 X               rv = cfg_ide(argc, argv);
971 X       else if (strcmp(device, "joystick") == 0)
972 X               rv = cfg_joystick(argc, argv);
973 X       else {
974 X               fprintf(stderr, "error: unknown device %s\n", device);
975 X               usage();
976 X       }
977 X
978 X       if (rv)
979 X               fprintf(stderr, "error: device configuration failed\n");
980 X       
981 X       return 0;
982 }
983 SHAR_EOF
984   $shar_touch -am 1204092598 'MultiSound.d/pinnaclecfg.c' &&
985   chmod 0664 'MultiSound.d/pinnaclecfg.c' ||
986   $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed'
987   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
988   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
989     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
990     || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed'
991 366bdf27f0db767a3c7921d0a6db20fe  MultiSound.d/pinnaclecfg.c
992 SHAR_EOF
993   else
994     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`"
995     test 10235 -eq "$shar_count" ||
996     $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10235,' 'current size' "$shar_count!"
997   fi
998 fi
999 # ============= MultiSound.d/Makefile ==============
1000 if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then
1001   $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)'
1002 else
1003   $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)'
1004   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' &&
1005 CC      = gcc
1006 CFLAGS  = -O
1007 PROGS   = setdigital msndreset pinnaclecfg conv
1008 X
1009 all: $(PROGS)
1010 X
1011 clean:
1012 X       rm -f $(PROGS)
1013 SHAR_EOF
1014   $shar_touch -am 1204092398 'MultiSound.d/Makefile' &&
1015   chmod 0664 'MultiSound.d/Makefile' ||
1016   $echo 'restore of' 'MultiSound.d/Makefile' 'failed'
1017   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1018   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1019     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1020     || $echo 'MultiSound.d/Makefile:' 'MD5 check failed'
1021 76ca8bb44e3882edcf79c97df6c81845  MultiSound.d/Makefile
1022 SHAR_EOF
1023   else
1024     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`"
1025     test 106 -eq "$shar_count" ||
1026     $echo 'MultiSound.d/Makefile:' 'original size' '106,' 'current size' "$shar_count!"
1027   fi
1028 fi
1029 # ============= MultiSound.d/conv.l ==============
1030 if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then
1031   $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)'
1032 else
1033   $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)'
1034   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' &&
1035 %%
1036 [ \n\t,\r]
1037 \;.*
1038 DB
1039 [0-9A-Fa-f]+H   { int n; sscanf(yytext, "%xH", &n); printf("%c", n); }
1040 %%
1041 int yywrap() { return 1; }
1042 main() { yylex(); }
1043 SHAR_EOF
1044   $shar_touch -am 0828231798 'MultiSound.d/conv.l' &&
1045   chmod 0664 'MultiSound.d/conv.l' ||
1046   $echo 'restore of' 'MultiSound.d/conv.l' 'failed'
1047   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1048   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1049     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1050     || $echo 'MultiSound.d/conv.l:' 'MD5 check failed'
1051 d2411fc32cd71a00dcdc1f009e858dd2  MultiSound.d/conv.l
1052 SHAR_EOF
1053   else
1054     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`"
1055     test 141 -eq "$shar_count" ||
1056     $echo 'MultiSound.d/conv.l:' 'original size' '141,' 'current size' "$shar_count!"
1057   fi
1058 fi
1059 # ============= MultiSound.d/msndreset.c ==============
1060 if test -f 'MultiSound.d/msndreset.c' && test "$first_param" != -c; then
1061   $echo 'x -' SKIPPING 'MultiSound.d/msndreset.c' '(file already exists)'
1062 else
1063   $echo 'x -' extracting 'MultiSound.d/msndreset.c' '(text)'
1064   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/msndreset.c' &&
1065 /*********************************************************************
1066 X *
1067 X * msndreset.c - resets the MultiSound card
1068 X *
1069 X * Copyright (C) 1998 Andrew Veliath
1070 X *
1071 X * This program is free software; you can redistribute it and/or modify
1072 X * it under the terms of the GNU General Public License as published by
1073 X * the Free Software Foundation; either version 2 of the License, or
1074 X * (at your option) any later version.
1075 X *
1076 X * This program is distributed in the hope that it will be useful,
1077 X * but WITHOUT ANY WARRANTY; without even the implied warranty of
1078 X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1079 X * GNU General Public License for more details.
1080 X *
1081 X * You should have received a copy of the GNU General Public License
1082 X * along with this program; if not, write to the Free Software
1083 X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1084 X *
1085 X ********************************************************************/
1086 X
1087 #include <stdio.h>
1088 #include <unistd.h>
1089 #include <fcntl.h>
1090 #include <sys/types.h>
1091 #include <sys/stat.h>
1092 #include <sys/ioctl.h>
1093 #include <sys/soundcard.h>
1094 X
1095 int main(int argc, char *argv[])
1096 {
1097 X       int fd;
1098 X
1099 X       if (argc != 2) {
1100 X               fprintf(stderr, "usage: msndreset <mixer device>\n");
1101 X               exit(1);
1102 X       }
1103 X
1104 X       if ((fd = open(argv[1], O_RDWR)) < 0) {
1105 X               perror(argv[1]);
1106 X               exit(1);
1107 X       }
1108 X
1109 X       if (ioctl(fd, SOUND_MIXER_PRIVATE1, 0) < 0) {
1110 X               fprintf(stderr, "error: msnd ioctl reset failed\n");
1111 X               perror("ioctl");
1112 X               close(fd);
1113 X               exit(1);
1114 X       }
1115 X
1116 X       close(fd);
1117 X       
1118 X       return 0;
1119 }
1120 SHAR_EOF
1121   $shar_touch -am 1204100698 'MultiSound.d/msndreset.c' &&
1122   chmod 0664 'MultiSound.d/msndreset.c' ||
1123   $echo 'restore of' 'MultiSound.d/msndreset.c' 'failed'
1124   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1125   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1126     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1127     || $echo 'MultiSound.d/msndreset.c:' 'MD5 check failed'
1128 c52f876521084e8eb25e12e01dcccb8a  MultiSound.d/msndreset.c
1129 SHAR_EOF
1130   else
1131     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/msndreset.c'`"
1132     test 1472 -eq "$shar_count" ||
1133     $echo 'MultiSound.d/msndreset.c:' 'original size' '1472,' 'current size' "$shar_count!"
1134   fi
1135 fi
1136 rm -fr _sh01426
1137 exit 0