@UltraSound HPC-HelpKit v0.85eta

:GUS HelpKit:HPC-Kit About

^Gravis UltraSound HPC-HelpKit version 0.85eta
^by Condor/Accession,BloodBrothers!

%About

    This HelpKit is made for only those, who program Gravis Ultrasound
    at the lowest possible level. So I haven't included any C or Pascal
    codes, only assembler and pseudo code is used in exampled. Also, I
    haven't included any function descriptions from GUS SDK Lowlevel
    programmer's kit. If you want them, I don't give a shit.

%NOTE

    This HelpKit is combined from various sources(see below). So any
    misinformation is NOT my fault. For more information about programming
    GUS, read these documents.

%Credits

    I can't take much credits from this HelpKit, because I have only
    converted texts to HelpPC format. Also additional editing was required.
    (see above) But here are the persons, whose texts I have included to
    this HelpKit:

         Kurt Kennett and Mike Travers (GUS SDK 2.10)
         Tran/Renaissance and Joshua Jensen (UltraDOX 1.0)
         Tran and Cyberstrike of Renaissance (UltraDOX 2.0)
         ? (GUS SDK 2.20)
         Thunder (MODFIL v1.0)
         Lars "ZAP" Hamre/Amiga Freelancers (Protracker 1.1B Mod Format)
         Freejack of Elven Nation (ULT File Format)
         ? (S3M and STM File Format)

%History

%   Version 0.85eta
        - ULT, S3M and STM File format added to HelpKit
        - i'm tired of these minor fixes to indexes, but if you notice
          bugs on them, please let me know.

%   Version 0.80
        - MODFIL10.TXT added to HelpKit
        - Protracker 1.1b Module Format added to HelpKit
        - and more minor fixes to indexes

%   Version 0.70
        - Information from GUS SDK 2.20 added to HelpKit
        - more minor fixes to indexes

%   Version 0.60
        - UltraDOX added to HelpKit
        - some minor fixes to indexes

%   Version 0.50
        - GUS SDK 2.10 added to HelpKit


%   How to contact me
        Well, from these boards you can contact me:

            Metropoli       +358-(9)0-615 00029     (you can also connect
                                                     via internet to here)
            The DarkSide    +358-(9)0-294 0467
                         or +358-(9)0-294 1594
            Xception 13     (not opened yet)

                        Mika Mannermaa alias Condor/Accession,
                                                    BloodBrothers!
:1_HPC_MAIN_

^Gravis UltraSound HPC-HelpKit version 0.85eta
^by Condor/Accession,BloodBrothers!

^MAIN MENU

      ~HPC-Kit About~       - Information about GUS HPC-HelpKit

%   Port Information
      ~GUS Port Map~        - All ports of Gravis Ultrasound card

      ~Global registers~    - Voice independent registers
      ~Voice registers~     - Voice specific registers
      ~Revision Level~      - Port where to check GUS Revision level
      ~UltraMAX Control~    - Control port of UltraMAX

%   General Information
      ~GF1~                 - Information about GF1
      ~Mixer~               - Info about mixer (Rev. 3.7+)
      ~Codec~               - Info about codec functions (Rev 3.7+)
      ~MIDI Interface~      - Information about GUS MIDI Interface

      ~Freq calculation~    - How to calculate output frequency
      ~U_Freq calculation~  - Same as above,but more programming info
      ~U_DRAM Addressing~   - Info about GUS DRAM addressing
      ~U_Poke DRAM~         - How to poke/peek data to/from GUS DRAM?
      ~U_Probe~             - How to autodetect GUS?
      ~U_Memory amount~     - How to autodetect memory amount of GUS?
      ~U_UltraReset~        - Example code to reset GUS

      ~Volume ramping~      - How GUS Volume ramping works?
      ~Ultra clicks~        - Tips for removing ultraclicks(tm)
      ~Rollover~            - Tips for using the rollover feature of samples
      ~Patch file format~   - File format of Ultrasound Patches
      ~Modulation tables~   - Tables for GUS Patch file format

%   Module Player Information
      ~Module Player~       - Main menu of Module Player section
      ~M_FileFormat~        - MOD File format
      ~M_ProFile~           - Protracker 1.1b MOD Format
      ~M_S3M File Format~   - S3M and STM File Format
      ~M_ULT File Format~   - ULT File Format
      ~M_EffectList~        - List of standard effects


:Freq calculation:GF1:Frequency

^Calculating the Frequency - GF1

%Information about GF1

 The GF1 is basically a pipeline processor.  It constantly loops from  voice
 #0 to the  end of the  active voices (how  to define the  number of  active
 voices is shown later). Every 1.6  microseconds, the GF1 performs a  series
 of operations on a particular voice.  The more active voices there are, the
 longer it takes  between each time  a particular voice  is serviced.   This
 puts a limit on  the rate at which  playback can occur.   14 active  voices
 will allow a maximum of 44.1  kHz playback.  28  voices will allow 22  kHz.

%The formula for calculating the playback rate is:

%      Frequency   Active Voices    Frequency  Active Voices
         44100          14            25725          24
         41160          15            24696          25
         38587          16            23746          26
         36317          17            22866          27
         34300          18            22050          28
         32494          19            21289          29
         30870          20            20580          30
         29400          21            19916          31
         28063          22            19293          32
         26843          23

 This table is calculated by knowing that 14 active voices will give exactly
 44.1 kHz  playback.    Therefore,  the voice  servicing  rate  'X'  can  be
 calculated from:

                       1,000,000 / (X * 14) = 44100 Hz
                        X = 1.619695497 microseconds

 Once X is known, the frequency 'divisor' is calculated by:

           divisor = 1,000,000 / (1.619695497 * # of active voices)

 A  frequency 'counter'  is used  to calculate how often  a voice is  updated
 by the  GF1.  To  calculate an  FC (frequency counter) for any given frequency
 with a particular # of  active voices, run it through this formula:

%C:
    fc = (unsigned int)(((speed_khz<<9L)+(divisor>>1L)) / divisor);
    fc = fc << 1;

 The left  shift  is  needed since  the  FC  is in  bits  15-1. This value
 is  then  put  in  the  frequency  control  register  for  that particular
 voice.

 Remember that the GF1 works on a voice every 1.6 microseconds.  This  means
 that the fewer voices, the faster  each voice gets updated.  The  frequency
 control register setting for the voice MUST take this into account.  The FC
 must get smaller if the  number of active voices  gets smaller.  This  will
 increase the number of points created between the actual data points so the
 perceived playback speed remains the same.

    See also: ~Sampling Control~,~U_Freq calculation~

:MIDI Interface

^MIDI Interface

 The MIDI 101 interface consists of standard UART functionality - Motorola
 MC68C50.  An interrupt to the PC can be generated for each byte of
 MIDI data received or transmitted.  This hardware is independent of
 any of the other hardware.  The main MIDI circuitry is included in
 the GF1 processor, but external to the chip is an optical isolator
 that is used on the serial input data and an open collector driver
 that is used for the serial output.  In addition, external logic is
 included on board to loop back transmit data to the receive data under
 software control.  The serial interface has a fixed configuration with
 no programmable options, as in the MC6850. A control register is used
 to enable and disable the interrupt generation logic.  A status register
 is used to determine if the transmit or receive register is interrupting.
 A read or write to the data register clears the interrupt status.

%The specifications for the interface are:

         31.25 kHz +- 1%
         asynchronous
         1 start bit
         8 data bits
         1 stop bit

 The MIDI signals are available on the 15 pin D connector used for the
 joystick.  An external cable assembly containing the optical isolator
 and driver is required to use the MIDI interface.


:GUS Port Map

^GUS I/O Port Map

 The following  describes I/O  address map  used on  the board.  The 'X'  is
 defined by the  jumper settings  on the  UltraSound and  should match  that
 specified in the ULTRASND environment variable.

%     INTERFACE                         I/O,MEM,  R,W       ADDRESS
%                                       INT,DMA             HEX
      ------------------------------------------------------------
      UltraSound Base Port:              ---       --        2X0

%     MIDI Interface:
           ~MIDI Control~                  I/O       W         3X0
           ~MIDI Status~                   I/O       R         3X0
           Transmit Data                 I/O       W         3X1
           Receive Data                  I/O       R         3X1
           Joystick Interface:
             Trigger Timer               I/O       W         201
             Read Data                   I/O       R         201

%     GF1 Synthesizer:
           GF1 ~Page Register~             I/O       R/W       3X2
           GF1/Global ~Select Register~    I/O       R/W       3X3
           GF1/~Global Data~ Low Byte      I/O       R,W       3X4
           GF1/Global Data High Byte     I/O       R/W       3X5
           ~IRQ Status~ Register 1=ACTIVE  I/O       R         2X6
           ~Timer Control port~            I/O       R/W       2X8
           ~Timer Data~                    I/O       W         2X9
           ~DRAM I/O~                      I/O       R,W       3X7
           DRAM                          DMA       R,W       1,3,5,6,7
           Record Digital Audio          DMA       R         1,3,5,6,7
           BOARD ONLY
             ~Mix Control~ register        I/O       W         2X0
             ~IRQ Control~ register        I/O       W         2XB
             (2X0- bit 6 = 1)
             ~DMA Control~ register        I/O       W         2XB
             (2X0- bit 6 = 0)
             ~Register Control~            I/O       R/W       2XF (Rev 3.4+)
             ~Board Version~               I/O       R         7X6 (Rev 3.7+)
             ~Mixer~ Control
              Control Port               I/O       W         7X6 (Rev 3.7+)
              Data Port                  I/O       W         3X6 (Rev 3.7+)
             ~Codec~
              Daughter Card              I/O       R/W       530-533
                                                          or 604-607
                                                          or E80-E83
                                                          or F40-F43
              UltraMax                   I/O       R/W       3XC-3XF

              Codec Addr Select          I/O       R/W       Base+0
              Codec Data                 I/O       R/W       Base+1
              Codec Status               I/O       R/W       Base+2
              Codec PIO                  I/O       R/W       Base+3

    ~UltraMax Control~ Port (MAX ONLY)     I/O       W         3X6

        See also: ~Global registers~,~Voice registers~


%MIDI Data Port - port 3x1h
    The transmit and receive registers are at 3X1 hex and are 8 bits wide.


:MIDI Control

^MIDI Control Port - port 3x0h

 Here are the bit definitions  for the MIDI control  byte. It is located  at
 address 3X0 hex and is write only.

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- 1 \ Master reset (when set)
        |   |   |   |   |   |   +-------- 1 /
        |   |   |   |   |   +------------ Reserved
        |   |   |   |   +---------------- Reserved
        |   |   |   +-------------------- Reserved
        |   |   +------------------------ 1 \ xmit IRQ enabled
        |   +---------------------------- 0 /
        +-------------------------------- 1 = Receive IRQ enabled

 Bit 0 & 1 will cause  a master reset when toggled  high and then low.  They
 must be  left low  when using  port. This  will normally  cause a  transmit
 buffer empty IRQ.

    See Also: ~MIDI Status Port~

:MIDI Status

^MIDI Status Port - port 3x0h

 Here are the bit definitions for  the MIDI status byte.   It is located  at
 address 3X0 hex and is read-only.

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Receive reg. full
        |   |   |   |   |   |   +-------- Transmit reg. empty
        |   |   |   |   |   +------------ Reserved
        |   |   |   |   +---------------- Reserved
        |   |   |   +-------------------- Framing Error
        |   |   +------------------------ Overrun error
        |   +---------------------------- Reserved
        +-------------------------------- Interrupt pending

 The MIDI control interface behaves identically to a 6850 UART.

    See also: ~MIDI Control Port~

:Page register:Voice select

^Page Register - port 3x2h

 This could also be called the voice select register. This register is  used
 to specify which voice's registers you  want to read/write. This value  can
 range from 0 to  the number of active  voices specified (13-31). Once  this
 has been specified, you may select the specific register within that voice.
 Be careful that  IRQs are  off during  the time  that the  page and  select
 registers are  being  modified.  This  will  prevent  the  foreground  from
 selecting a voice and having the background change it in the background.

:Select Register:Global Registers

^Select Register - port 3x3h

^Global Registers

 These are the global registers. They are not voice-specific.

%               Address     Mode    Width   Description

                  41        R/W       8     ~DRAM DMA Control~
                  42        W        16     ~DMA Start Address~
                  43        W        16     ~DRAM I/O Address~ (LOW)
                  44        W         8     DRAM I/O Address (HIGH)
                  45        R/W       8     ~Timer Control reg~
                  46        W         8     #1 ~Timer Count~
                  47        W         8     #2 Timer Count
                  48        W         8     Sampling Frequency
                  49        R/W       8     ~Sampling Control~
                  4B        W         8     ~Joystick DAC~
                  4C        R/W       8     ~RESET Register~

%   Sampling Frequency - (48)

    The formula for calculating this value is:
        rate = 9878400/(16*(FREQ+2))


    For Voice specific registers see ~Voice Registers~
    For Other I/O ports see ~GUS Port Map~

:DRAM DMA Control

^DRAM DMA Control Register - Global Registers(41)

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Enable DMA (1=go)
        |   |   |   |   |   |   +-------- DMA direction (1=read)
        |   |   |   |   |   +------------ DMA channel width
        |   |   |   |   +---------------- \
        |   |   |   +-------------------- / DMA Rate divider
        |   |   +------------------------ DMA IRQ Enable
        |   +---------------------------- (R) DMA IRQ Pending
        |                                 (W) DATA SIZE (0=8bit,1=16bit)
        +-------------------------------- Invert MSB (write only)

 Bit 0 -  Enable the  DMA  channel. The  GF1  will begin  sending  DMA  ACK
          protocol. If PC  DMA controller  is programmed,  data will  begin
          being transferred.  If not,  data  will move  as  soon as  it  is
          programmed.
 Bit 1 -  DMA  transfer  direction.  Read  is   taking  data  OUT  of   the
          UltraSound, Write sends data to it.
 Bit 2 -  0 = if DMA channel is an 8 bit channel (0-3).
          1 = If it is a 16 bit channel (4-7)
            Note: This is INDEPENDENT of the data size.
 Bit 3,4 -DMA Rate divisor. The Maximum rate is approx 650 khz.
            00 = divide by 1
            01 = divide by 2
            10 = divide by 3
            11 = divide by 4
 Bit 5 -  DMA terminal count interrupt enable
 Bit 6 -  Read  - DMA terminal count IRQ pending
          Write - Data size 0 = 8 Bit data
                            1 = 16 bit data
              Note: Data size is independent of channel size
 Bit 7 -  1 = Invert High bit to flip data to twos complement form.
              Note: This flips bit 7 for 8 bit data and bit 15 for
                    16 bit data.

    See Also: ~Global Registers~

:DMA Start Address

^DMA Start Address - Global Registers(42)

 Bits 15-0 are Address lines 19-4.

 This register defines where the DMA will  transfer data to or from.   Since
 only the upper 16 address bits are used and the lower 4 bits are set to  0,
 a DMA transfer MUST begin on an 16 byte  boundary for an 8 bit DMA  channel
 (0-3). If a 16 bit DMA channel is being used, the transfer MUST being on  a
 32 byte boundary. An  additional address translation is  necessary if a  16
 bit DMA  channel  is used.  For  simple example  code  on how  to  do  this
 translation, see the C function convert_to_16().

    See Also: ~Global Registers~

:DRAM I/O Address

^DRAM I/O Address - Global Registers(43,44)

 These 2 registers allow you to specify an address to peek and poke directly
 into UltraSound DRAM. Register 43 is  the lower 16 address lines.  Register
 44 is the upper 4 address lines. (bits 0-3). Read or write to register  3X7
 to get at the address location.

    See Also: ~Global Registers~

:Timer Control reg

^Timer Control - Global Registers(45)

           =================================
           | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
           =================================
             |   |   |   |   |   |   |   |
             |   |   |   |   |   |   |   +---- Reserved (Set to 0)
             |   |   |   |   |   |   +-------- Reserved (Set to 0)
             |   |   |   |   |   +------------ Enable Timer 1 IRQ
             |   |   |   |   +---------------- Enable Timer 2 IRQ
             |   |   |   +-------------------- Reserved (Set to 0)
             |   |   +------------------------ Reserved (Set to 0)
             |   +---------------------------- Reserved (Set to 0)
             +-------------------------------- Reserved (Set to 0)

    See Also: ~Global Registers~

:Timer count

^Timer 1 and Timer 2 Count - Global Registers(46,47)

 These counts are loaded by the application  and then they will count up  to
 $FF and generate  and IRQ.  Timer 1 has  a granularity  of 80  microseconds
 (0.00008 sec) and Timer  2 has a granularity  of 320 microseconds  (0.00032
 sec).

    See Also: ~Global Registers~

:Sampling Control

^Sampling Control Register - Global Registers(49)

           =================================
           | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
           =================================
             |   |   |   |   |   |   |   |
             |   |   |   |   |   |   |   +---- Start sampling
             |   |   |   |   |   |   +-------- Mode (0=mono, 1=stereo)
             |   |   |   |   |   +------------ DMA width (0=8bit,1=16bit)
             |   |   |   |   +---------------- Reserved (Set to 0)
             |   |   |   +-------------------- Reserved (Set to 0)
             |   |   +------------------------ DMA IRQ enable
             |   +---------------------------- (Read) DMA IRQ pending
             +-------------------------------- Invert MSB

 Bit 0 -If PC DMA controller is programmed, it will begin sampling as  soon
        as this is enabled.
 Bit 1 -0 = mono
        1 = stereo
        In stereo mode, the order of the  data bytes is left is first,  and
        right is second. If a 16 bit data  channel is used, the left is  in
        the lower byte.
 Bit 2 -DMA Channel width (0 = 8 bit, 1 = 16 bit)
 Bit 5 -Enable DMA terminal count IRQ
 Bit 6 -DMA terminal count IRQ pending
 Bit 7 -Flip bit 7 to get non-twos compliment data

    See Also: ~Global Registers~

:Joystick DAC

^Joystick Trim DAC - Global Registers(4B)

 This register is initialized to 4.3 volts (value = 29). It only needs to be
 modified to  account  for faster/slower  machines.  A utility  is  provided
 (ULTRAJOY.EXE) that  sets this  up.   There should  be no  reason for  your
 application to modify this register.

    See Also: ~Global Registers~

:RESET Register

^Reset Register - Global Registers(4C)

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Master Reset
        |   |   |   |   |   |   +-------- DAC Enable
        |   |   |   |   |   +------------ GF1 Master IRQ Enable
        |   |   |   |   +---------------- Reserved (Set to 0)
        |   |   |   +-------------------- Reserved (Set to 0)
        |   |   +------------------------ Reserved (Set to 0)
        |   +---------------------------- Reserved (Set to 0)
        +-------------------------------- Reserved (Set to 0)

 Bit 0 -GF1 Master Reset. 0 = reset,  1 = run. As long as  this is a 0,  it
        will be held in a reset state.
 Bit 1 -Enable DAC output. DAC's will not run unless this bit is set.
 Bit 2 -Master IRQ enable.  This bit MUST  be set  to get ANY  of the  GF1-
        generated IRQs (wavetable, volume, etc).

 This register will normally contain the value $07 while your application is
 running.

    See Also: ~Global Registers~

:Voice registers

^Voice-specific Registers - Select Register port 3x3h

 The following are the voice-specific registers. Each voice has its own bank
 of read and write  registers that alter its  behavior. The write  registers
 range from 0 to F and the corresponding read registers range from 80 to 8F.
 To convert from the write to the read, just add 80 hex.

%          Write    Read     Width   Description
             0       80        8     ~Voice Control~
             1       81       16     ~Freq Control~
             2       82       16     ~Starting Address~ (HIGH)
             3       83       16     Starting Address (LOW)
             4       84       16     ~Ending Address~ (HIGH)
             5       85       16     Ending Address (LOW)
             6       86        8     ~Volume Ramp Rate~
             7       87        8     ~Volume Ramp Start~
             8       88        8     ~Volume Ramp End~
             9       89       16     ~Current Volume~
             A       8A       16     ~Current Address~ (HIGH)
             B       8B       16     Current Address (LOW)
             C       8C        8     ~Pan Position~
             D       8D        8     ~Volume Ramp Control~
             E       8E        8     ~Active Voices~ (Voice independent)
             -       8F        8     ~IRQ Status~ (Voice independent)

^NOTE

 There are several 'self-modifying' bits  defined for these registers.  This
 means that the GF1 may change them at anytime  on its own. Due to the  fact
 that the software must accommodate this phenomena, it is possible that  the
 GF1 may change something immediately  after your application has  set/reset
 one of  the bits.  This is  due to  the GF1's  pipeline processor  type  of
 architecture: it does  a read-modify-write cycle,  and if your  application
 modifies one of these bits AFTER it has done the read portion and BEFORE it
 does the write portion, it's possible for the chip to perform  incorrectly.
 To overcome this, you need to do a  double write (with a delay in  between)
 when those particular  bits are  involved. This delay  must be  at least  3
 times the length of time necessary  to process a voice. (3*1.6  microsecs).
 In the lowlevel code,  this is done with  a function called GF1_Delay.  The
 self-modifying bits are  designated with an  (*) after  the particular  bit
 definition.

 Changing the start and  end points of  a voice while  its playing can  have
 some strange side  effects. For example,  if you change  end poistion to  a
 lower location than it is currently playing, you will get and IRQ (if  they
 are enabled). Also, since the high  and low bytes are set individually  and
 asynchronously to when the GF1 is working on a voice, it is possible to get
 an unexpected IRQ if the current  position and the new end position cross.

   For global registers see ~Global Registers~
   For Other I/O ports see ~GUS Port Map~

:Voice Control

^Voice Control Register - Voice Registers(0,80)

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Voice Stopped
        |   |   |   |   |   |   +-------- Stop Voice
        |   |   |   |   |   +------------ 16 bit data
        |   |   |   |   +---------------- Loop enable
        |   |   |   +-------------------- Bi-directional loop enable
        |   |   +------------------------ Wave table IRQ
        |   +---------------------------- Direction of movement
        +-------------------------------- IRQ pending

 * Bit 0- 1 = Voice is  stopped. This gets set  by hitting the end  address
          (not looping) or by setting bit 1 in this reg.
   Bit 1- 1 = Stop Voice. Manually force voice to stop.
   Bit 2- 1 = 16 bit wave data, 0 = 8 bit data
   Bit 3- 1 = Loop to begin address when it hits the end address.
   Bit 4- 1 = Bi-directional looping enabled
   Bit 5- 1 = Enable wavetable IRQ. Generate an IRQ when the voice hits the
          end address. Will generate IRQ even if looping is enabled.
 * Bit 6- 1 = Decreasing addresses, 0 =  increasing addresses. It is  self-
          modifying because it might shift directions  when it hits one  of
          the loop boundaries and looping is enabled.
 * Bit 7- 1 = Wavetable IRQ  pending. If IRQ's are  enabled and looping  is
          NOT enabled, an IRQ will be constantly generated until  the voice
          is stopped. This means  that you may  get more than  1 IRQ if  it
          isn't handled properly.

    See also: ~Voice Registers~

:Freq Control

^Frequency Control Register - Voice Registers(1,81)

      Bits 15-10 - Integer Portion
      Bits 9-1   - Fractional Portion
      Bit 0      - Not used.

 This register  determines the  amount added  to  (or subtracted  from)  the
 current position of the voice to determine where the next position will be.
 This is how the interpolated data points are determined. If the FC register
 is less than 0, the GF1 will interpolate the data point in between the  two
 actual data points. Note that the FC can be greater than 1. This allows for
 skipping over data bytes.  The actual frequency that  it will play back  is
 directly related to the number of active voice specified (register 8E).

    See also: ~Voice Registers~,~Freq calculation~,~U_Freq calculation~

:Starting address

^Starting location HIGH - Voice Registers(2,82)

 Bits 12-0  are the HIGH 13 bits of the address of the starting location of
            the waveform (Addr lines 19-7).
 Bits 15-13 are not used.


^Starting location LOW - Voice Registers(3,83)

 Bits 15-9  are the low 7 bits of  the address of the starting location  of
            the waveform. (Addr lines 6-0).
 Bits 8-5   are the fractional part of the starting address.
 Bits 4-0   are not used.

    See also: ~Voice Registers~,~U_DRAM Addressing~

:Ending address

^End Address HIGH - Voice Registers(4,84)

 Bits 12-0  are the high 13 bits of  the address of the ending location  of
            the waveform. (Addr lines 19-7)
 Bits 15-13 are not used.


^End Address LOW - Voice Registers(5,85)

 Bits 15-9  are the low 7 bits of the address of the ending location of the
            waveform. (Addr lines 6-0).
 Bits 8-5   are the fractional part of the ending address.
 Bits 4-0   are not used.

    See also: ~Voice Registers~,~U_DRAM Addressing~

:Volume Ramp Reg:Volume Ramp Rate:Volume Ramp Start:Volume Ramp End

^Volume Ramp Rate - Voice Registers(6,86)

 Bits 5-0   is the amount added to (or subtracted from) the  current volume
            to get the next volume. The  range is from 1 to 63.  The larger
            the number, the greater the volume step.
 Bits 7-6   defines the rate at which the increment is applied.

^Volume Ramp Start - Voice Registers(7,87)

 Bits 7-4   Exponent
 Bits 3-0   Mantissa

 This register specifies  the starting position  of a volume  ramp. See  the
 special section on volume  ramping for a more  complete explanation of  how
 this register works.

^Volume Ramp End - Voice Registers(8,88)

 Bits 7-4   Exponent
 Bits 3-0   Mantissa

 This register specifies  the ending  position of a  volume ramp.   See  the
 special section on volume  ramping for a more  complete explanation of  how
 this register works.

 Note:   The starting volume must always be less than the ending volume. If
         you want the volume  to ramp down, turn  on the decreasing  volume
         bit in the Volume Control Register.

 For more information about volume ramping, please read ~Volume Ramping~

    See also: ~Voice Registers~

:Current Volume

^Current Volume - Voice Registers(9,89)

 * Bits 15-12   Exponent
 * Bits 11-4    Mantissa
   Bits 3-0     Reserved (Set to 0)

 Note:   This register has 4 extra bits of precision that is  necessary for
         finer granularity of volume  placement.  The  extra bits are  used
         during a volume ramp.

 Note:   This is a self-modifying value. The GF1 will update  this register
         as it ramps.

 Note:   You should always  set this  register equal  to the  value of  the
         beginning of the volume ramp (start OR end).

 For more information about volume ramping, please read ~Volume Ramping~

    See also: ~Voice Registers~

:Current address

^Current Location HIGH - Voice Registers(A,8A)

 Bits 15-13 Reserved (Set to 0)
 Bits 12-0  High 13 bits of address (address lines 19-7)


^Current Location LOW - Voice Registers(B,8B)

 Bits 15-9  Low 7 bits of address. (address lines 6-0)
 Bits 8-0   9 bit fractional position.

    See also: ~Voice Registers~

:Pan Position

^Pan Position - Voice Registers(C,8C)

 Bits 8-4   Reserved (Set to 0)
 Bits 3-0   Pan position. (0=full left, 15=full right)

    See also: ~Voice Registers~

:Volume Ramp Control

^Volume Ramp Control Register - Voice Registers(D,8D)

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Ramp Stopped
        |   |   |   |   |   |   +-------- Stop Ramp
        |   |   |   |   |   +------------ Rollover condition
        |   |   |   |   +---------------- Loop Enable
        |   |   |   +-------------------- Bi-directional loop enable
        |   |   +------------------------ Volume ramp IRQ enable
        |   +---------------------------- Direction
        +-------------------------------- IRQ pending

 * Bit 0- Show the ramp has stopped
   Bit 1- Manually stop the ramp.
   Bit 2- Roll over condition. This bit pertains more towards  the location
          of the voice rather than its  volume. Its purpose is to  generate
          an IRQ and NOT stop  (or loop). It will  generate an IRQ and  the
          voice's address  will continue  to move  thru  DRAM in  the  same
          direction. This can  be a  very powerful feature.  It allows  the
          application to get  an interrupt without  having the sound  stop.
          This can be easily used to implement a ping-pong buffer algorithm
          so an application can keep feeding  it data and there will be  no
          pops. Even if looping is enabled, it will not loop.
   Bit 3- Enable looping. Loop from end to start (or start to end).
   Bit 4- Enable bi-directional looping.  When it  hits end  (or start)  it
          will change directions and proceed toward the other limit.
   Bit 5- Enable getting an IRQ when ramp hits end.
 * Bit 6- Ramp direction. 0=increasing, 1=decreasing.
 * Bit 7- (READ) Volume ramp IRQ pending.

 For more information about volume ramping, please read ~Volume Ramping~

    See also: ~Voice Registers~

:Active Voices

^Active Voices - Voice Registers(E,8E)

 Bits 7-6   Must be set to a 1
 Bits 5-0   # of voices to enable - 1.

 The range is from 14 - 32. Any value less than 14 will be forced to 14.

    See also: ~Voice Registers~

:IRQ Source Register

^IRQ Source Register - Voice Registers(F,8F)

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +----\
        |   |   |   |   |   |   +-------- \
        |   |   |   |   |   +------------  - Interrupting voice #
        |   |   |   |   +---------------- /
        |   |   |   +--------------------/
        |   |   +------------------------ 1
        |   +---------------------------- Volume Ramp IRQ pending
        +-------------------------------- WaveTable IRQ pending

 Bit 4-1-Voice # (0-31) of interrupting voice
 Bit 5-  ALWAYS a 1
 Bit 6-  0 = Volume Ramp IRQ occurred
 Bit 7-  0 = Wavetable IRQ occurred

 Note:   This is  a global  read only  register. There  is only  1 for  ALL
         voices. You MUST service any indicated IRQ's since a read  of this
         port will clear the associated IRQ bits in the  particular voice's
         control and/or volume control registers.

 Note:   It is possible that multiple  voices could interrupt at  virtually
         the same time.  In this  case, this  register will  behave like  a
         fifo. When in your IRQ handler, keep reading (and  servicing) this
         register until you do a read with  both IRQ bits set to a  1. This
         means there are no voice IRQs left to deal with.

 Note:   Since it is possible  to get ANOTHER IRQ  from the same voice  for
         the SAME  reason, you  must ignore  any subsequent  IRQ from  that
         voice while in the IRQ handler. For example, when a voice hits its
         end position and  generates an  IRQ back to  your application,  it
         will continue to generate IRQ's until either the voice is stopped,
         the IRQ enable is turned off, or the end location is moved.

    See also: ~Voice Registers~

:Global Data

^Global Data Low - port 3x4h

 This register can be used to do either a 16 bit transfer for one of the  16
 bit wide  GF1 registers  (Start addr  high etc)  when using  a 16  bit  I/O
 instruction or the low part of a 16 bit  wide register when using an 8  bit
 I/O instruction.


^Global Data High - port 3x5h

 This register is used to do either an 8 bit  transfer for one of the GF1  8
 bit registers or to do the high part of a 16 bit wide register.


:IRQ Status

^IRQ Status - port 2x6h

 CAUTION: Note that this is at 2X6 *** NOT 3X6 ***.

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- MIDI Transmit IRQ
        |   |   |   |   |   |   +-------- MIDI Receive IRQ
        |   |   |   |   |   +------------ Timer 1 IRQ
        |   |   |   |   +---------------- Timer 2 IRQ
        |   |   |   +-------------------- Reserved (Set to 0)
        |   |   +------------------------ WaveTable IRQ (any voice)
        |   +---------------------------- Volume Ramp IRQ (any voice)
        +-------------------------------- DMA TC IRQ (DRAM or Sample)



:Timer Control port

^Timer Control Register - port 2x8h

 This register  maps to  the  same location  as  the ADLIB  board's  control
 register. Writing a 4 here selects  the timer stuff. Bit  6 will be set  if
 timer #1 has expired. Bit 5 will be set it timer #2 has expired.


:Timer Data

^Timer Data Register - port 2x9h

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Timer 1 Start
        |   |   |   |   |   |   +-------- Timer 2 Start
        |   |   |   |   |   +------------ Reserved (Set to 0)
        |   |   |   |   +---------------- Reserved (Set to 0)
        |   |   |   +-------------------- Reserved (Set to 0)
        |   |   +------------------------ Mask Timer 2
        |   +---------------------------- Mask Timer 1
        +-------------------------------- Reset Timer IRQ

      Bit 0 - Start up timer #1
      Bit 1 - Start up timer #2
      Bit 5 - Mask off timer 2
      Bit 6 - Mask off timer 1
      Bit 7 - Clear Timer IRQ


:DRAM I/O

^DRAM I/O - port 3x7h

 This register is used to read or write  data at the location pointed at  by
 registers 43 and 44. This is used to peek and poke directly to DRAM.

:Mix Control

^Mix Control Register - port 2X0

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- 0=Enable Line IN
        |   |   |   |   |   |   +-------- 0=Enable Line OUT
        |   |   |   |   |   +------------ 1=Enable MIC IN
        |   |   |   |   +---------------- Enable latches
        |   |   |   +-------------------- Combine chan1 IRQ with Chan2
        |   |   +------------------------ Enable MIDI loopback TxD to RxD
        |   +---------------------------- Control Reg Select
        +-------------------------------- Reserved (Set to 0)

 Bit 0 -Enable UltraSound line Input
 Bit 1 -Enable UltraSound Line output
 Bit 2 -Enable Stereo Mic Input
 Bit 3 -Enable latches.This  provides power  to the  DMA/IRQ latches.  Once
        these are enabled, NEVER disable them.   Disabling them will  cause
        random IRQ's in the PC  since the DMA and  IRQ lines are not  being
        driven any more.
 Bit 4 -Combine Channel 1 (GF1) IRQ's with Channel 2 (MIDI)
 Bit 5 -Enable MIDI  loopback. Any  data sent  out  Transmit port  will  be
        looped back into the input port.
 Bit 6 -Control Register Select. When this is set to a 1, the next IO write
        to 2XB will be to the IRQ control latches. When this is set to a 0,
        the next IO write to  2XB will be to  the DMA channel latches.  The
        write to 2XB for either of these MUST occur as the NEXT IOW or else
        the write to  2XB will  be locked  out and  not occur.  This is  to
        prevent an application  that is  probing for  cards to  accidentaly
        corrupt the latches.


:IRQ Control

^IRQ Control Register - port 2xBh

%     IRQ  control register         I/O       W         2XB
      (2X0- bit 6 = 1)

      Bits 2-0 Channel 1 (GF1) IRQ Selector
          0=No Interrupt
          1=IRQ2
          2=IRQ5
          3=IRQ3
          4=IRQ7
          5=IRQ11
          6=IRQ12
          7=IRQ15

      Bits 5-3 Channel 2 (MIDI) IRQ selector
          0=No Interrupt
          1=IRQ2
          2=IRQ5
          3=IRQ3
          4=IRQ7
          5=IRQ11
          6=IRQ12
          7=IRQ15

     Bit 6 1 = Combine Both IRQS using Channel 1's IRQ
     Bit 7 Reserved (Set to 0)

 Note:   If the channels are sharing an IRQ, channel 2's IRQ must be set to
         0 and turn on bit 6. A bus conflict will occur if both latches are
         programmed with the same IRQ #.


:DMA Control

~DMA Control - port 2xBh

%     DMA control register          I/O       W         2XB
      (2X0- bit 6 = 0)

      Bits 2-0 DMA Select Register 1
         0=NO DMA
         1=DMA1
         2=DMA3
         3=DMA5
         4=DMA6
         5=DMA7

      Bits 5-3 DMA Select Register 2
         0=NO DMA
         1=DMA1
         2=DMA3
         3=DMA5
         4=DMA6
         5=DMA7

     Bit 6 - Combine Both on the same DMA channel.
     Bit 7 - Reserved (Set to 0).

 Note:   If the channels are sharing an DMA, channel 2's DMA must be set to
         0 and turn on bit 6. A bus conflict will occur if both latches are
         programmed with the same DMA #.

:Register Control

^Register Control - port 2xFh

 This register is  only valid  for UltraSound boards  that are  at or  above
 revision 3.4.  It is  not valid  for  boards which  have a  prior  revision
 number.

 On 3.4 and  above boards,  there is a  bank of  6 registers  that exist  at
 location 2XB. Register 2XF is used to select which one is being talked to.

 Register #     Use

      0         Same as pre-3.4 boards
      1-4       Unused - Reserved
      5         Write a 0 to clear IRQs on power-up
      6         'Jumper register'


    Jumper register definition:

      =================================
      | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
      =================================
        |   |   |   |   |   |   |   |
        |   |   |   |   |   |   |   +---- Reserved (Set to 0)
        |   |   |   |   |   |   +-------- 1=Enable MIDI port addr decode
        |   |   |   |   |   +------------ 1=Enable joystick port decode
        |   |   |   |   +---------------- Reserved (Set to 0)
        |   |   |   +-------------------- Reserved (Set to 0)
        |   |   +------------------------ Reserved (Set to 0)
        |   +---------------------------- Reserved (Set to 0)
        +-------------------------------- Reserved (Set to 0)

:Revision Level:Board Version

^Revision Level - port 7x6h

 This register is only valid for UltraSound boards that are 3.7 or greater.
 Any reads from this port on boards prior to 3.7 will return 0xff. This
 is a way for software to detect whether or not the ICS-2101 mixer is
 present. Here is a table of what is currently defined for each revision.

   Revision ID    Board Revision
        0xff        Pre 3.7 boards. ICS mixer NOT present
           5        Rev 3.7 with ICS Mixer. Some R/L: flip problems.
         6-9        Revision 3.7 and above. ICS Mixer present
     0x0A-NN        UltraMax. CS4231 present, no ICS mixer

:UltraMAX Control

^UltraMax Control Register - port 3x6h

 This is a write only register that is only valid for the UltraMax.
 Note that it is on the same port location as the data port for the
 ICS-2101 mixer. This implies that your software MUST know what device
 is there before it starts writing to them.

   =================================
   | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
   =================================
     |   |   |   |   |   |   |   |
     |   |   |   |   |   |   |   +---- Codec Addr Decode Bit 4
     |   |   |   |   |   |   +-------- Codec Addr Decode Bit 5
     |   |   |   |   |   +------------ Codec Addr Decode Bit 6
     |   |   |   |   +---------------- Codec Addr Decode Bit 7
     |   |   |   +-------------------- Capture Channel type (0=8 bit, 1=16 bit)
     |   |   +------------------------ Playback Channel type (0=8 bit, 1=16 bit)
     |   +---------------------------- Codec Enable (0=disable, 1=enable)
     +-------------------------------- Reserved (Set to 0)

 Bits 0-3 - Define the 'X' in 3XC to define the base port location.
            By convention, the 'X' is usually set to the same as the base port
            of the UltraSound, but it doesn't need to be. This value can range
            from 0 - F.
 Bit 4 -    Defines the type of DMA channel used for recording. Set this
            bit to 0 for an 8 bit channel and a 1 for a 16 bit channel.
 Bit 5 -    Defines the type of DMA channel used for playback. Set this
            bit to 0 for an 8 bit channel and a 1 for a 16 bit channel.

 Bits 4 and 5 need to be set up because the CS4231 is only capable of
 using and 8 bit DMA channel. To allow it to take advantage of the UltraSounds
 capability of using a 16-bit channel, extra hardware was added to buffer
 the data and send it out a 16 bit channel. An UltraMax CS4231 shares
 the DMA channels with base UltraSounds channels.

 See chapter ~Codec~ for more info on the interactions between the two.

 Bit 6 is to enable the CS4231. Until this bit is set, the CS4231 is
 inactive and will not appear in the address space.


:Mixer

^Mixer - Revision 3.7+

%Introduction

 Revision 3.7 and above UltraSounds have had a new mixer added to them.
 This document will not attempt to describe how the internals of the
 mixer works. If you want more detailed information that is provided
 by this document or the example code in mixer.c, you can get a data
 sheet from ICS or an ICS data book. The part number is ICS-2101. You
 can contact ICS directly at:

         Integrated Circuit Systems, Inc
         2435 Boulevard of the Generals
         P.O. Box 968
         Valley Forge, Pa. 19482-0968
         Phone # (215)-630-5300
          or
         Phone # (215)-630-5399

%Notes

 To determine if one of these mixers is present, you MUST look at the
 revision of the board. This can be determined by reading port location
 7X6. If the value read back is FF, then no revision ID is  present
 and means that the version is pre-3.4 and therefore no mixer is present.
 If the revision is between 5 and 9, then the version number of the
 base UltraSound is 3.7 or above. All those versions will have this
 mixer. See ~Revision Level~ for more information. If the version is 10
 or above, then it is an UltraMax. This mixer is NOT used on an UltraMax.
 The codec on the UltraMax has a mixer built into it.
 See ~Codec~ for more information on that.

 If your software determines that the board revision is 5, then you
 must do some special stuff. That specific revision of the UltraSound
 had a couple of the right\left input lines reversed. The ICS-2101 has
 the ability to flip them around inside the chip to correct for this
 problem. Subsequent versions of the board corrected this. The lines
 that were flipped were the synth input to the mixer and the master
 output. Look at the mixer.c code in the SDK sources to see and example
 of how to do this.

 Any application that uses the mixer MUST reset back to its transparent
 values when it exits so the any application that isn't aware of the
 mixer will operate properly.  The only exception to this may be some
 app that wants to adjust the volumes outside any running apps (TSR).
 Just be aware that any other programs that use the mixer will probably
 overwrite any values you may have set up. Since the mixer is a write
 only device, that app would have no idea that its values were changed.

:Codec Functions:Codec:Daughter card:UltraMAX Codec

^16 Bit Codec Functions (Rev 3.7+)

%Introduction

 Both the 16-bit daughter card and the UltraMax use the same chip to
 perform the extra recording and mixing functions. It is built by Crystal
 Semiconductors CS4231 Audio Codec. This section will describe how it
 fits into each of those boards. It will NOT describe much about how
 the internals of the CS4231 work. To get a data sheet on the part,
 contact Crystal Semiconductor at:

         Crystal Semiconductor Corporation
         P.O. Box 17847
         Austin, TX 78760
         Phone # (512) 445-7222
         Fax #      (512) 445-7581

 Tish SDK is not meant to be a complete toolkit for programming the
 CS4231. The CS4231 is a very versitile part that can be used in many
 different ways. This SDK give some simple simple example routines that
 can be very useful to get the part running. It is quite likely that
 you may find it necessary to modify or re-write some of the SDK code
 for use in your app. Please don't be afraid of doing just that.

%Features:

   - 8 or 16 bit playback and recording
   - Up to 48kHz
   - 2 DMA channels for simultaneous playback and record
   - 8 or 16 bit DMA channel selection (software selectable)
   - Multiple data formats
     - Linear PCM data
     - u-law compression (2-1)
     - a-law compression (2-1)
     - ADPCM (4-1)
   - 10 microsecond granularity timer
   - Extensive mixer
     - Line in level adjust
     - Line out level adjust
     - AUX1 and AUX2 input level adjust
     - Mic input level adjust

%Notes

 The L/M blocks are level adjustments and mutes.  Some can perform gain
 and attenuation. Some can do gain only. Refer to the CS4231 data sheet
 to see the use and range of each of these blocks.

 The microphone is mono only. The left side is connected to both right
 and left. This allows the same the recording to be the same whether
 the recording is being done thru MONO IN or MIC IN. MONO IN was connected
 to the MIC so that some user selectable gain could be used.

 This block diagram is the same for both the UltraMax and the 16-bit
 daughter card.

 Due to the need for backward compatibility, the mute settings for the
 base Ultrasound still apply.  If the either codec mutes or the mute
 switches on the base Ultrasound are set, the corresponding input WILL
 be muted.  To use only the codec mixer, use UltraEnableLineIn, UltraEnableMicIn,
 and UltraEnableOutput to ensure that the inputs are not being muted
 before they reach the CS4231.

%Daughter card Specific Info

 The daughter card has its own jumper selectable DMA channel and IRQ.
 These MUST be different than the software programmable ones on the
 base UltraSound. If not, conflicts will occur and will result in unpredictable
 behavior. Only 1,2 and 3 are valid DMA channels. No 16 bit channels
 are available. Since only 1 DMA channel is provided, simultaneous playback
 and record thru the codec is not possible. The base address for the
 codec on a daughter card can be at one of 4 locations (530,604,E80
 and F40)

%UltraMax Codec Specific Info

 Even though the same part is used for both the 16-bit daughter card
 and the Max, the Max has quite a bit more functionality. First of all,
 it can use a 16-bit DMA channel. It also has 2 DMA channels available
 so that it can do simultaneous playback and record. The Windows drivers
 demonstrate this feature.

 To support these added features, some extra hardware was added to an
 UltraMax. Since the CS4231 is an 8-bit DMA device, some hardware buffers
 were added that takes the output of the CS4231 and sends it out a 16
 bit DMA channel. These buffers essentially collect 2 8-bit DMA transfers
 and then does 1 16-bit transfer. This is why there are 2 control bits
 in register 3X6. The UltraMax hardware has to know if the destination
 DMA channels is 8 or 16 so it knows to do this buffering.

 The Max shares its DMA channels and IRQ with the base UltraSound. This
 limits the amount of resources that your Max will need from your system.
 The CS4231 will generate irqs on the same irq as the GF1. Your software
 will need to look at the codec (along with the GF1) when that particular
 level irq is generated to see if it need to be serviced.

%UltraMax DMA Channel block diagram

 Note that the DMA channels appear flipped between the GF1 and the codec.
 This is to allow us to DMA to dram to load patches while the codec
 is busy playing back .WAV data. We can also record the output of the
 GF1 (MIDI) by making sure that the patches have been loaded prior to
 starting the record. Since those two functions share the same DMA channel,
 you cannot be loading DRAM via DMA while you are recording with the
 codec. The codec is capable of combining its record channel with its
 play channel inside the codec. (That is what the 'C' is means inside
 the diagram above) However, because the Max does the 8-16 bit DMA channel
 conversion OUTSIDE the codec, this will only work on an 8 bit channel.
 If you try and combine the channels inside the codec and you are using
 16-bit channels, the recording will fail.

    See also: ~UltraMAX Control~

:Modulation Tables:TREMOLO Rate:VIBRATO Rate

^Modulation Tables - RATE table for TREMOLO* and VIBRATO**

%rate    frequency  rate    frequency  rate    frequency
%---------------------------------------------------------
 000:     0.050 Hz  085:     2.034 Hz  170:     4.018 Hz
 001:     0.073 Hz  086:     2.057 Hz  171:     4.041 Hz
 002:     0.097 Hz  087:     2.081 Hz  172:     4.064 Hz
 003:     0.120 Hz  088:     2.104 Hz  173:     4.088 Hz
 004:     0.143 Hz  089:     2.127 Hz  174:     4.111 Hz
 005:     0.167 Hz  090:     2.151 Hz  175:     4.135 Hz
 006:     0.190 Hz  091:     2.174 Hz  176:     4.158 Hz
 007:     0.213 Hz  092:     2.197 Hz  177:     4.181 Hz
 008:     0.237 Hz  093:     2.221 Hz  178:     4.205 Hz
 009:     0.260 Hz  094:     2.244 Hz  179:     4.228 Hz
 010:     0.283 Hz  095:     2.267 Hz  180:     4.251 Hz
 011:     0.307 Hz  096:     2.291 Hz  181:     4.275 Hz
 012:     0.330 Hz  097:     2.314 Hz  182:     4.298 Hz
 013:     0.353 Hz  098:     2.337 Hz  183:     4.321 Hz
 014:     0.377 Hz  099:     2.361 Hz  184:     4.345 Hz
 015:     0.400 Hz  100:     2.384 Hz  185:     4.368 Hz
 016:     0.423 Hz  101:     2.407 Hz  186:     4.391 Hz
 017:     0.447 Hz  102:     2.431 Hz  187:     4.415 Hz
 018:     0.470 Hz  103:     2.454 Hz  188:     4.438 Hz
 019:     0.493 Hz  104:     2.477 Hz  189:     4.461 Hz
 020:     0.517 Hz  105:     2.501 Hz  190:     4.485 Hz
 021:     0.540 Hz  106:     2.524 Hz  191:     4.508 Hz
 022:     0.563 Hz  107:     2.547 Hz  192:     4.531 Hz
 023:     0.587 Hz  108:     2.571 Hz  193:     4.555 Hz
 024:     0.610 Hz  109:     2.594 Hz  194:     4.578 Hz
 025:     0.633 Hz  110:     2.617 Hz  195:     4.601 Hz
 026:     0.657 Hz  111:     2.641 Hz  196:     4.625 Hz
 027:     0.680 Hz  112:     2.664 Hz  197:     4.648 Hz
 028:     0.704 Hz  113:     2.687 Hz  198:     4.671 Hz
 029:     0.727 Hz  114:     2.711 Hz  199:     4.695 Hz
 030:     0.750 Hz  115:     2.734 Hz  200:     4.718 Hz
 031:     0.774 Hz  116:     2.757 Hz  201:     4.741 Hz
 032:     0.797 Hz  117:     2.781 Hz  202:     4.765 Hz
 033:     0.820 Hz  118:     2.804 Hz  203:     4.788 Hz
 034:     0.844 Hz  119:     2.827 Hz  204:     4.811 Hz
 035:     0.867 Hz  120:     2.851 Hz  205:     4.835 Hz
 036:     0.890 Hz  121:     2.874 Hz  206:     4.858 Hz
 037:     0.914 Hz  122:     2.897 Hz  207:     4.881 Hz
 038:     0.937 Hz  123:     2.921 Hz  208:     4.905 Hz
 039:     0.960 Hz  124:     2.944 Hz  209:     4.928 Hz
 040:     0.984 Hz  125:     2.967 Hz  210:     4.951 Hz
 041:     1.007 Hz  126:     2.991 Hz  211:     4.975 Hz
 042:     1.030 Hz  127:     3.014 Hz  212:     4.998 Hz
 043:     1.054 Hz  128:     3.038 Hz  213:     5.021 Hz
 044:     1.077 Hz  129:     3.061 Hz  214:     5.045 Hz
 045:     1.100 Hz  130:     3.084 Hz  215:     5.068 Hz
 046:     1.124 Hz  131:     3.108 Hz  216:     5.091 Hz
 047:     1.147 Hz  132:     3.131 Hz  217:     5.115 Hz
 048:     1.170 Hz  133:     3.154 Hz  218:     5.138 Hz
 049:     1.194 Hz  134:     3.178 Hz  219:     5.161 Hz
 050:     1.217 Hz  135:     3.201 Hz  220:     5.185 Hz
 051:     1.240 Hz  136:     3.224 Hz  221:     5.208 Hz
 052:     1.264 Hz  137:     3.248 Hz  222:     5.231 Hz
 053:     1.287 Hz  138:     3.271 Hz  223:     5.255 Hz
 054:     1.310 Hz  139:     3.294 Hz  224:     5.278 Hz
 055:     1.334 Hz  140:     3.318 Hz  225:     5.301 Hz
 056:     1.357 Hz  141:     3.341 Hz  226:     5.325 Hz
 057:     1.380 Hz  142:     3.364 Hz  227:     5.348 Hz
 058:     1.404 Hz  143:     3.388 Hz  228:     5.372 Hz
 059:     1.427 Hz  144:     3.411 Hz  229:     5.395 Hz
 060:     1.450 Hz  145:     3.434 Hz  230:     5.418 Hz
 061:     1.474 Hz  146:     3.458 Hz  231:     5.442 Hz
 062:     1.497 Hz  147:     3.481 Hz  232:     5.465 Hz
 063:     1.520 Hz  148:     3.504 Hz  233:     5.488 Hz
 064:     1.544 Hz  149:     3.528 Hz  234:     5.512 Hz
 065:     1.567 Hz  150:     3.551 Hz  235:     5.535 Hz
 066:     1.590 Hz  151:     3.574 Hz  236:     5.558 Hz
 067:     1.614 Hz  152:     3.598 Hz  237:     5.582 Hz
 068:     1.637 Hz  153:     3.621 Hz  238:     5.605 Hz
 069:     1.660 Hz  154:     3.644 Hz  239:     5.628 Hz
 070:     1.684 Hz  155:     3.668 Hz  240:     5.652 Hz
 071:     1.707 Hz  156:     3.691 Hz  241:     5.675 Hz
 072:     1.730 Hz  157:     3.714 Hz  242:     5.698 Hz
 073:     1.754 Hz  158:     3.738 Hz  243:     5.722 Hz
 074:     1.777 Hz  159:     3.761 Hz  244:     5.745 Hz
 075:     1.800 Hz  160:     3.784 Hz  245:     5.768 Hz
 076:     1.824 Hz  161:     3.808 Hz  246:     5.792 Hz
 077:     1.847 Hz  162:     3.831 Hz  247:     5.815 Hz
 078:     1.871 Hz  163:     3.854 Hz  248:     5.838 Hz
 079:     1.894 Hz  164:     3.878 Hz  249:     5.862 Hz
 080:     1.917 Hz  165:     3.901 Hz  250:     5.885 Hz
 081:     1.941 Hz  166:     3.924 Hz  251:     5.908 Hz
 082:     1.964 Hz  167:     3.948 Hz  252:     5.932 Hz
 083:     1.987 Hz  168:     3.971 Hz  253:     5.955 Hz
 084:     2.011 Hz  169:     3.994 Hz  254:     5.978 Hz
 255:     6.002 Hz

 *  Tremolo rates for the GF1 UltraSound vary a small amount by depth.
    The larger the depth the more accurate the rate.
 ** Vibrato rates for the GF1 UltraSound lose resolution as the rate
    increases.

 In other words, you will hear a rate difference between 0 and 1, but
 not between 169 and 179.

    See also: ~TREMOLO Depth~, ~VIBRATO Depth~

:Tremolo Depth

^Modulation Tables - DEPTH table for TREMOLO

%depth   decibels  depth   decibels  depth   decibels
%--------------------------------------------------------
  000:   OFF        085:   4.031 dB   170:   8.016 dB
  001:   0.094 dB   086:   4.078 dB   171:   8.062 dB
  002:   0.141 dB   087:   4.125 dB   172:   8.109 dB
  003:   0.188 dB   088:   4.172 dB   173:   8.156 dB
  004:   0.234 dB   089:   4.219 dB   174:   8.203 dB
  005:   0.281 dB   090:   4.266 dB   175:   8.250 dB
  006:   0.328 dB   091:   4.312 dB   176:   8.297 dB
  007:   0.375 dB   092:   4.359 dB   177:   8.344 dB
  008:   0.422 dB   093:   4.406 dB   178:   8.391 dB
  009:   0.469 dB   094:   4.453 dB   179:   8.438 dB
  010:   0.516 dB   095:   4.500 dB   180:   8.484 dB
  011:   0.562 dB   096:   4.547 dB   181:   8.531 dB
  012:   0.609 dB   097:   4.594 dB   182:   8.578 dB
  013:   0.656 dB   098:   4.641 dB   183:   8.625 dB
  014:   0.703 dB   099:   4.688 dB   184:   8.672 dB
  015:   0.750 dB   100:   4.734 dB   185:   8.719 dB
  016:   0.797 dB   101:   4.781 dB   186:   8.766 dB
  017:   0.844 dB   102:   4.828 dB   187:   8.812 dB
  018:   0.891 dB   103:   4.875 dB   188:   8.859 dB
  019:   0.938 dB   104:   4.922 dB   189:   8.906 dB
  020:   0.984 dB   105:   4.969 dB   190:   8.953 dB
  021:   1.031 dB   106:   5.016 dB   191:   9.000 dB
  022:   1.078 dB   107:   5.062 dB   192:   9.047 dB
  023:   1.125 dB   108:   5.109 dB   193:   9.094 dB
  024:   1.172 dB   109:   5.156 dB   194:   9.141 dB
  025:   1.219 dB   110:   5.203 dB   195:   9.188 dB
  026:   1.266 dB   111:   5.250 dB   196:   9.234 dB
  027:   1.312 dB   112:   5.297 dB   197:   9.281 dB
  028:   1.359 dB   113:   5.344 dB   198:   9.328 dB
  029:   1.406 dB   114:   5.391 dB   199:   9.375 dB
  030:   1.453 dB   115:   5.438 dB   200:   9.422 dB
  031:   1.500 dB   116:   5.484 dB   201:   9.469 dB
  032:   1.547 dB   117:   5.531 dB   202:   9.516 dB
  033:   1.594 dB   118:   5.578 dB   203:   9.562 dB
  034:   1.641 dB   119:   5.625 dB   204:   9.609 dB
  035:   1.688 dB   120:   5.672 dB   205:   9.656 dB
  036:   1.734 dB   121:   5.719 dB   206:   9.703 dB
  037:   1.781 dB   122:   5.766 dB   207:   9.750 dB
  038:   1.828 dB   123:   5.812 dB   208:   9.797 dB
  039:   1.875 dB   124:   5.859 dB   209:   9.844 dB
  040:   1.922 dB   125:   5.906 dB   210:   9.891 dB
  041:   1.969 dB   126:   5.953 dB   211:   9.938 dB
  042:   2.016 dB   127:   6.000 dB   212:   9.984 dB
  043:   2.062 dB   128:   6.047 dB   213:   10.031 dB
  044:   2.109 dB   129:   6.094 dB   214:   10.078 dB
  045:   2.156 dB   130:   6.141 dB   215:   10.125 dB
  046:   2.203 dB   131:   6.188 dB   216:   10.172 dB
  047:   2.250 dB   132:   6.234 dB   217:   10.219 dB
  048:   2.297 dB   133:   6.281 dB   218:   10.266 dB
  049:   2.344 dB   134:   6.328 dB   219:   10.312 dB
  050:   2.391 dB   135:   6.375 dB   220:   10.359 dB
  051:   2.438 dB   136:   6.422 dB   221:   10.406 dB
  052:   2.484 dB   137:   6.469 dB   222:   10.453 dB
  053:   2.531 dB   138:   6.516 dB   223:   10.500 dB
  054:   2.578 dB   139:   6.562 dB   224:   10.547 dB
  055:   2.625 dB   140:   6.609 dB   225:   10.594 dB
  056:   2.672 dB   141:   6.656 dB   226:   10.641 dB
  057:   2.719 dB   142:   6.703 dB   227:   10.688 dB
  058:   2.766 dB   143:   6.750 dB   228:   10.734 dB
  059:   2.812 dB   144:   6.797 dB   229:   10.781 dB
  060:   2.859 dB   145:   6.844 dB   230:   10.828 dB
  061:   2.906 dB   146:   6.891 dB   231:   10.875 dB
  062:   2.953 dB   147:   6.938 dB   232:   10.922 dB
  063:   3.000 dB   148:   6.984 dB   233:   10.969 dB
  064:   3.047 dB   149:   7.031 dB   234:   11.016 dB
  065:   3.094 dB   150:   7.078 dB   235:   11.062 dB
  066:   3.141 dB   151:   7.125 dB   236:   11.109 dB
  067:   3.188 dB   152:   7.172 dB   237:   11.156 dB
  068:   3.234 dB   153:   7.219 dB   238:   11.203 dB
  069:   3.281 dB   154:   7.266 dB   239:   11.250 dB
  070:   3.328 dB   155:   7.312 dB   240:   11.297 dB
  071:   3.375 dB   156:   7.359 dB   241:   11.344 dB
  072:   3.422 dB   157:   7.406 dB   242:   11.391 dB
  073:   3.469 dB   158:   7.453 dB   243:   11.438 dB
  074:   3.516 dB   159:   7.500 dB   244:   11.484 dB
  075:   3.562 dB   160:   7.547 dB   245:   11.531 dB
  076:   3.609 dB   161:   7.594 dB   246:   11.578 dB
  077:   3.656 dB   162:   7.641 dB   247:   11.625 dB
  078:   3.703 dB   163:   7.688 dB   248:   11.672 dB
  079:   3.750 dB   164:   7.734 dB   249:   11.719 dB
  080:   3.797 dB   165:   7.781 dB   250:   11.766 dB
  081:   3.844 dB   166:   7.828 dB   251:   11.812 dB
  082:   3.891 dB   167:   7.875 dB   252:   11.859 dB
  083:   3.938 dB   168:   7.922 dB   253:   11.906 dB
  084:   3.984 dB   169:   7.969 dB   254:   11.953 dB
  255:   12.000 dB

:VIBRATO Depth

^Modulator Tables - DEPTH table for VIBRATO

%depth   centibels        depth   centibels       depth   centibels
%--------------------------------------------------------------------
  000:   OFF               085:   0403.1 cents     170:   0801.6 cents
  001:   0009.4 cents      086:   0407.8 cents     171:   0806.2 cents
  002:   0014.1 cents      087:   0412.5 cents     172:   0810.9 cents
  003:   0018.8 cents      088:   0417.2 cents     173:   0815.6 cents
  004:   0023.4 cents      089:   0421.9 cents     174:   0820.3 cents
  005:   0028.1 cents      090:   0426.6 cents     175:   0825.0 cents
  006:   0032.8 cents      091:   0431.2 cents     176:   0829.7 cents
  007:   0037.5 cents      092:   0435.9 cents     177:   0834.4 cents
  008:   0042.2 cents      093:   0440.6 cents     178:   0839.1 cents
  009:   0046.9 cents      094:   0445.3 cents     179:   0843.8 cents
  010:   0051.6 cents      095:   0450.0 cents     180:   0848.4 cents
  011:   0056.2 cents      096:   0454.7 cents     181:   0853.1 cents
  012:   0060.9 cents      097:   0459.4 cents     182:   0857.8 cents
  013:   0065.6 cents      098:   0464.1 cents     183:   0862.5 cents
  014:   0070.3 cents      099:   0468.8 cents     184:   0867.2 cents
  015:   0075.0 cents      100:   0473.4 cents     185:   0871.9 cents
  016:   0079.7 cents      101:   0478.1 cents     186:   0876.6 cents
  017:   0084.4 cents      102:   0482.8 cents     187:   0881.2 cents
  018:   0089.1 cents      103:   0487.5 cents     188:   0885.9 cents
  019:   0093.8 cents      104:   0492.2 cents     189:   0890.6 cents
  020:   0098.4 cents      105:   0496.9 cents     190:   0895.3 cents
  021:   0103.1 cents      106:   0501.6 cents     191:   0900.0 cents
  022:   0107.8 cents      107:   0506.2 cents     192:   0904.7 cents
  023:   0112.5 cents      108:   0510.9 cents     193:   0909.4 cents
  024:   0117.2 cents      109:   0515.6 cents     194:   0914.1 cents
  025:   0121.9 cents      110:   0520.3 cents     195:   0918.8 cents
  026:   0126.6 cents      111:   0525.0 cents     196:   0923.4 cents
  027:   0131.2 cents      112:   0529.7 cents     197:   0928.1 cents
  028:   0135.9 cents      113:   0534.4 cents     198:   0932.8 cents
  029:   0140.6 cents      114:   0539.1 cents     199:   0937.5 cents
  030:   0145.3 cents      115:   0543.8 cents     200:   0942.2 cents
  031:   0150.0 cents      116:   0548.4 cents     201:   0946.9 cents
  032:   0154.7 cents      117:   0553.1 cents     202:   0951.6 cents
  033:   0159.4 cents      118:   0557.8 cents     203:   0956.2 cents
  034:   0164.1 cents      119:   0562.5 cents     204:   0960.9 cents
  035:   0168.8 cents      120:   0567.2 cents     205:   0965.6 cents
  036:   0173.4 cents      121:   0571.9 cents     206:   0970.3 cents
  037:   0178.1 cents      122:   0576.6 cents     207:   0975.0 cents
  038:   0182.8 cents      123:   0581.2 cents     208:   0979.7 cents
  039:   0187.5 cents      124:   0585.9 cents     209:   0984.4 cents
  040:   0192.2 cents      125:   0590.6 cents     210:   0989.1 cents
  041:   0196.9 cents      126:   0595.3 cents     211:   0993.8 cents
  042:   0201.6 cents      127:   0600.0 cents     212:   0998.4 cents
  043:   0206.2 cents      128:   0604.7 cents     213:   1003.1 cents
  044:   0210.9 cents      129:   0609.4 cents     214:   1007.8 cents
  045:   0215.6 cents      130:   0614.1 cents     215:   1012.5 cents
  046:   0220.3 cents      131:   0618.8 cents     216:   1017.2 cents
  047:   0225.0 cents      132:   0623.4 cents     217:   1021.9 cents
  048:   0229.7 cents      133:   0628.1 cents     218:   1026.6 cents
  049:   0234.4 cents      134:   0632.8 cents     219:   1031.2 cents
  050:   0239.1 cents      135:   0637.5 cents     220:   1035.9 cents
  051:   0243.8 cents      136:   0642.2 cents     221:   1040.6 cents
  052:   0248.4 cents      137:   0646.9 cents     222:   1045.3 cents
  053:   0253.1 cents      138:   0651.6 cents     223:   1050.0 cents
  054:   0257.8 cents      139:   0656.2 cents     224:   1054.7 cents
  055:   0262.5 cents      140:   0660.9 cents     225:   1059.4 cents
  056:   0267.2 cents      141:   0665.6 cents     226:   1064.1 cents
  057:   0271.9 cents      142:   0670.3 cents     227:   1068.8 cents
  058:   0276.6 cents      143:   0675.0 cents     228:   1073.4 cents
  059:   0281.2 cents      144:   0679.7 cents     229:   1078.1 cents
  060:   0285.9 cents      145:   0684.4 cents     230:   1082.8 cents
  061:   0290.6 cents      146:   0689.1 cents     231:   1087.5 cents
  062:   0295.3 cents      147:   0693.8 cents     232:   1092.2 cents
  063:   0300.0 cents      148:   0698.4 cents     233:   1096.9 cents
  064:   0304.7 cents      149:   0703.1 cents     234:   1101.6 cents
  065:   0309.4 cents      150:   0707.8 cents     235:   1106.2 cents
  066:   0314.1 cents      151:   0712.5 cents     236:   1110.9 cents
  067:   0318.8 cents      152:   0717.2 cents     237:   1115.6 cents
  068:   0323.4 cents      153:   0721.9 cents     238:   1120.3 cents
  069:   0328.1 cents      154:   0726.6 cents     239:   1125.0 cents
  070:   0332.8 cents      155:   0731.2 cents     240:   1129.7 cents
  071:   0337.5 cents      156:   0735.9 cents     241:   1134.4 cents
  072:   0342.2 cents      157:   0740.6 cents     242:   1139.1 cents
  073:   0346.9 cents      158:   0745.3 cents     243:   1143.8 cents
  074:   0351.6 cents      159:   0750.0 cents     244:   1148.4 cents
  075:   0356.2 cents      160:   0754.7 cents     245:   1153.1 cents
  076:   0360.9 cents      161:   0759.4 cents     246:   1157.8 cents
  077:   0365.6 cents      162:   0764.1 cents     247:   1162.5 cents
  078:   0370.3 cents      163:   0768.8 cents     248:   1167.2 cents
  079:   0375.0 cents      164:   0773.4 cents     249:   1171.9 cents
  080:   0379.7 cents      165:   0778.1 cents     250:   1176.6 cents
  081:   0384.4 cents      166:   0782.8 cents     251:   1181.2 cents
  082:   0389.1 cents      167:   0787.5 cents     252:   1185.9 cents
  083:   0393.8 cents      168:   0792.2 cents     253:   1190.6 cents
  084:   0398.4 cents      169:   0796.9 cents     254:   1195.3 cents
  255:   1200.0 cents

%1 cent = 1/100 of a semitone
%1 semitone = 1 half step

^Patch editor rate table for envelopes.

%Best values     good values     Overlaps
%---------------------------------------------
 055 - 063       047 - 063       111 - 118 overlaps 061 - 063
 119 - 127       111 - 127       175 - 182 overlaps 125 - 127
 183 - 191       175 - 191       239 - 246 overlaps 189 - 191
 247 - 255       239 - 255


:Volume ramping

^Volume ramping description

 The UltraSound has built-in volume ramping to facilitate the implementation
 of the attack decay sustain release envelopes.  This ramping uses the  same
 principle as the voices for updating the  volume values.  A section of  the
 envelope can be programmed such  that the PC does  not need to be  burdened
 with the task of changing each volume  at specified intervals.  At the  end
 of that  particular section,  an IRQ  can  be generated  so that  the  next
 section can be programmed in.

 This continues until the entire envelope has been completed.  The start and
 end points as well as the increment rate are fully programmable.

%The hardware volume registers and bit definitions are:

       Current Volume (9,89)    EEEEMMMMMMMM    (Bits 15-4)

       Volume Start   (7,87)    EEEEMMMM        (Bits 7-0)

       Volume End     (8,88)    EEEEMMMM        (Bits 7-0)

       Volume Incr    (6,86)    RRMMMMMM        (Bits 7-0)

 Once the current  volume, start and  end volumes are  programmed, the  only
 thing left  is to  set up  the volume  increment register.   This  register
 determines how fast the  ramp takes place and  with what granularity.   The
 finer the granularity, the smoother (but  slower) the ramp.  The  increment
 register has 2 fields.   The first  is the amount  added to (or  subtracted
 from) the current volume to get to the next one.  These are the low 6  bits
 and can range from 1 to  63.  A 1  is a long, slow  ramp compared to a  63.
 The upper  2 bits  determine how  often  the increment  is applied  to  the
 current volume.  The rate bits are defined as:

% Rate Bits       Volume Update Rate
      00                FUR    (FUR = 1/(1.6*#active voices))
      01                FUR/8
      10                FUR/64
      11                FUR/512

 Each rate increment is 8 times longer  than the preceding one.  This  means
 that the value to store for the fastest possible ramp is 1Fh (63), and  the
 value for the slowest  possible ramp is 1Ch  (193).  The approximate  times
 for a full scale volume ramp (0-4095) are:

%                Rate    Vol Inc    14 Voices     32 Voices
                 ----    -------    ---------     ---------
                   0       63         1.4 ms        3.3 ms
                   0        1        91.7 ms      209.7 ms
                   1       63        11.5 ms       26.2 ms
                   1        1       733.8 ms        1.7 sec
                   2       63        91.8 ms      209.7 ms
                   3        1         5.9 sec      13.4 sec
                   3       63       734.0 ms        1.7 sec
                   3        1        47.0 sec     107.3 sec

 Note that these  times are for  full sweep ramping.   Since  a volume  ramp
 usually goes between points  in between the limits,  the actual ramp  times
 will be much smaller.

 Allowing to let the volume ramps to go  to the extremes can cause a  random
 oscillation of the volume when it reaches the limits.  This is caused by an
 overshoot past  the limit  due to  a large  step size.   The  SDK  routines
 protect against this by limiting how close to the rails you can get.

:Ultra clicks

^Clicks and click removal

 As was mentioned in  a few of the  preceding sections, 'clicks' and  'pops'
 can occur when the output of  the DAC changes suddenly.   This is the  most
 frequent type of click, since there  may not be a  way to control the  data
 values the voices are trying to play.

 In general, it is necessary to remember that all voices are being summed in
 to the  final output,  even if  they  are not  running.   This  means  that
 whatever data value that  the voice is pointing  at is contributing to  the
 summation.  It is important that a voice be  pointed to a known value at  a
 known location after it is  stopped so that some  control is kept over  it.
 For instance, if a voice  were left at whereever  the end position was  for
 the last time it played, a pop could  occur if new data were either  DMA'ed
 or poked over the  top of it.   For this reason, it  is recommended that  a
 voice be pointed to a location containing a 0 and that its volume be set to
 0.  At  that point,  the voice  will have  no contribution  to the  output.
 There are some particular cases where clicks most frequently occur:

%During Reset
 - Because of  the way  the card  is  reset, a  pop  can occur  through  the
   speakers when a reset occurs.  The way  to remove this pop is to  disable
   the output, reset the card, and then enable the output again.

%During a balance sweep
 - Since there are  only 16 pan  positions and there  is such  a large  jump
   between individual positions,  a relatively fast  balance sweep from  one
   side to another may produce  clicks.  You can  get a very smooth  balance
   sweep using 2 voices and volume  ramping.  Set one  voice up to one  side
   and one to the other, and ramp one down from volume X to zero at the same
   rate as you ramp the other from 0 up to volume  X.  The result is a  very
   smooth balance sweep.

%When starting and stopping a voice
 - By setting up fairly fast rates when  a sample start or ends and  ramping
   up or down appropriately, any pop created  by a sudden change in the  DAC
   value will be summed in at such a low volume, it will never be heard.

%End points not set properly
 - Make sure your end points are at the ends  of your samples. It is a  very
   common mistake  to set  an end  point to  1 sample  beyond the  end.  For
   example, if a sample is 100 bytes long an starts at location 100, the end
   point is at position 199,  NOT position 200.   Also, it is possible  that
   the GF1 will interpolate data at points beyond the end point.  To  ensure
   that this does not cause  'clicks', use a few  extra bytes after the  end
   point of the sample to maintain it.

%Loop points not set properly
 - The same problem as  stated above (end points)  is common for loop  start
   and end points.   Be sure that the  data at the end  of the loop and  the
   beginning of the  loop are  practically identical,  since if  there is  a
   large step between them  a click will result  because the DAC value  will
   change suddenly.

:Rollover

^Rollover feature

 Each voice  has a  'rollover'  feature that  allows  an application  to  be
 notified when a voice's playback position passes over a particular place in
 DRAM.  This  is very useful  for getting seamless  digital audio  playback.
 Basically, the GF1 will generate an IRQ when a voice's current position  is
 equal to the end position.  However, instead of stopping or looping back to
 the start position, the voice will continue playing in the same  direction.
 This means that there will be no pause (or gap) in the playback.  Note that
 this feature is enabled/disabled thru  the voice's VOLUME control  register
 (since there are no more bits available in the voice control registers).  A
 voice's loop enable  bit takes precedence  over the rollover.   This  means
 that if a  voice's loop enable  is on, it  will loop when  it hits the  end
 position, regardless of the state of the rollover enable.

%A simple example of this technique is:

 1)   Allocate a chunk of DRAM: 20K, for example.
 2)   Load the entire 20K with wave data.
 3)   Start up a voice with looping disabled and rollover enabled.  Set  its
      end position to the MIDDLE of the buffer.
 4)   When the voice hits  the middle, you  will get an  IRQ, but the  voice
      will continue to play.
 5)   At this point, enable looping and disable the rollover.  Also, set the
      end position to the end of the  buffer. This will make the voice  loop
      back to the beginning without stopping.
 6)   Now load the FIRST 10K with more  wave data. This will make sure  that
      there is correct data to play when the voice loops.
 7)   When the voice loops, you will get and IRQ.
 8)   At this  point,  disable looping,  enable  rollover and  set  the  end
      position back to the middle of the buffer.
 9)   Now load the SECOND 10K with more wave data. This will make sure  that
      there is corect data to play when the rollover occurs.
 10)  Continue in a loop, starting at step #4.

 Note:This algorithm does not take care  of an initial condition where  not
      enough data  exists to  fill one  complete  buffer. It  also  doesn't
      address how  to finish  playing the  last incomplete  buffer.   These
      points are left up to your implementation to resolve.

:Patch file format

%Patch Files Format

 This appendix contains  information about the  the patch file  format.   It
 assumes the reader is familiar with wave table synthesis, music, sound,
 and the GF1 ASIC chip that is the heart of the UltraSound audio card.

 The UltraSound patch file is a collection of data structures and sound data
 in the following format:

     patch header (# instruments)
        instrument header 1 (#layers)
            layer 1 header (# waves)
              wave 1 header
              wave 1 data
                 wave 2 header
                 wave 2 data
                 ...
                 wave n header
                 wave n data
             layer 2 header (# waves)
                 wave 1 header
                 wave 1 data
                 wave 2 header
                 wave 2 data
                 ...
                 wave n header
                 wave n data
         instrument header 2 (#layers)
     etc.

 All of the Advanced Gravis UltraSound patches contain one instrument at the
 current time.  Except for the main patch header, each of the headers has  a
 size field which can be used to seek past unwanted data.  For example, if a
 patch has two instruments  and you want to  skip the first instrument,  you
 would read  the  first instrument  header,  and then  skip  INSTRUMENT_SIZE
 bytes.  What follows is the patch header definitions given in C and Pascal.
 After the definitions, a field-by-field breakdown of the headers is given.

%======
%  C:
%======

 #define ENVELOPES                       6
 #define HEADER_SIZE                     12
 #define ID_SIZE                         10
 #define DESC_SIZE                       60
 #define RESERVED_SIZE                   40
 #define PATCH_HEADER_RESERVED_SIZE      36
 #define LAYER_RESERVED_SIZE             40
 #define PATCH_DATA_RESERVED_SIZE        36
 #define GF1_HEADER_TEXT                 "GF1PATCH110"
 #define MAX_LAYERS                      4
 #define INST_NAME_SIZE                  16

%typedef struct
 {
    char             header[ HEADER_SIZE ];
    char             gravis_id[ ID_SIZE ];   /* Id = "ID#000002" */
    char             description[ DESC_SIZE ];
    unsigned char    instruments;
    char             voices;
    char             channels;
    unsigned int     wave_forms;
    unsigned int     master_volume;
    unsigned long    data_size;
    char             reserved[ PATCH_HEADER_RESERVED_SIZE ];
 } PATCHHEADER;

%typedef struct
 {
    unsigned int     instrument;
    char             instrument_name[ 16 ];
    long             instrument_size;
    char             layers;
    char             reserved[ RESERVED_SIZE ];
 } INSTRUMENTDATA;

%typedef struct
 {
    char             layer_duplicate;
    char             layer;
    long             layer_size;
    char             samples;
    char             reserved[ LAYER_RESERVED_SIZE ];
 } LAYERDATA;

%typedef struct
 {
    char             wave_name[7];

    unsigned char    fractions;
    long             wave_size;
    long             start_loop;
    long             end_loop;

    unsigned int     sample_rate;
    long             low_frequency;
    long             high_frequency;
    long             root_frequency;
    int              tune;

    unsigned char    balance;

    unsigned char    envelope_rate[ ENVELOPES ];
    unsigned char    envelope_offset[ ENVELOPES ];

    unsigned char    tremolo_sweep;
    unsigned char    tremolo_rate;
    unsigned char    tremolo_depth;

    unsigned char    vibrato_sweep;
    unsigned char    vibrato_rate;
    unsigned char    vibrato_depth;

    /* bit 0 = 8 or 16 bit wave data. */
    /* bit 1 = Signed - Unsigned data. */
    /* bit 2 = looping enabled-1. */
    /* bit 3 = Set is bidirectional looping. */
    /* bit 4 = Set is looping backward. */
    /* bit 5 = Turn sustaining on. (Env. pts. 3)*/
    /* bit 6 = Enable envelopes - 1 */
    char             modes;

    int              scale_frequency;
    unsigned int     scale_factor;    /* from 0 to 2048 or 0 to 2 */

    char             reserved[ PATCH_DATA_RESERVED_SIZE ];
 } PATCHDATA;

^File Header

%'Header'
      The header field should contain the  text "GF1PATCH110."  The first  8
      bytes will always be GF1PATCH.   The next three bytes are the  version
      number of the patch  format.  As  fields are added  to the patch,  the
      number will  be  incremented.   All  of  the  UltraSound  patches  are
      currently at version  110.   The older  100 patches  are obsolete  and
      should no longer be in use.

%'Description'
      This description field is usually for copyright information.

%'Instruments'
      The number of  instruments in the  patch.  All  of the gravis  patches
      contain only one instrument.

%'Voices'
      The GF1 synth  can update  14 voices  at 44.1Khz.   As  the number  of
      voices increases, the  actual output rate  of each  voice drops.  This
      field should contain the number of voices that were used when creating
      the patch. This field could be used by  a MIDI engine to try and  make
      the patch sound the  same regardless of the  number of active  voices.
      Currently this feature is not implemented in the gravis MIDI engine.

%'Channels'
      This field is unused.  Only mono data  can be played out a voice  with
      the GF1.

%'Wave_Forms'
      The total number of  waveforms in the  patch.  This  field is used  by
      programs which need to preallocate space for wave form headers  before
      the patch is loaded.

%'Master_Volume'
      This field is currently unused.

%'Data_Size'
      The size of the  patch data after it  is loaded into  GF1 dram.   This
      number includes the space needed to align each of the waveforms on  32
      byte boundaries.    If  you patch  loader  maintains  linked  list  of
      waveforms in dram, and you need to use an extra 32 bytes per waveform,
      then you can use  the wave_forms field to  figure out how much  memory
      you will need to load the patch.  i.e.  data_size + (32 * wave_forms).


^Instrument Header

%'Instrument'
      This field is currently unused.

%'Instrument_Name'
      This field is currently unused.

%'Instrument_Size'
      The size of the instrument.  The number  of bytes to skip in order  to
      read the next instrument header.

%'Layers'
      The number of layers in this instrument.  Multiple layers are  usually
      used in patches where  more than one sound  is required with a  single
      MIDI event  (note on).   For  example, a  piano would  could have  two
      layers. The first would be the actual tone from the hammer hitting the
      strings, and the second would be  the (thunk) of the key being  struck
      and all of  the mechanisms moving  inside the piano.   The  mechanisms
      would probably be frequency independant,  and also independant of  the
      length of the tone.

^Layer Header

%'Layer_Duplicate'
      Currently unused.  If the layer duplicate  is nonzero, then this layer
      should use the  data from the  previous layer. Only  the headers  will
      follow.

%'Layer'
      The current layer number for this instrument

%'Layer_Size'
      The size of this layer.   Can be used to seek  past this layer in  the
      file.

%'Samples'
      The number  of waveforms  in this  layer.   This field  is ignored  if
      layer_duplicate is true.



^Wave Header

%'Wave_Name'
      This field is currently unused

%'Fractions'
      The start_loop and end_loop are the integer portions of the  wavetable
      address.  The GF1 can interpolate between sample points and  therefore
      meore resolution than just  the integer address is  needed.  The  most
      significant four bits are the  fractional address for the  start_loop,
      and the least significant four bits are the fractional address for the
      end_loop.

%'Wave_Size'
      The number  of bytes  of wave  table data  that follows  -- not  #  of
      samples.

%'Start_Loop'
      The integer  portion of  the starting  loop  address relative  to  the
      beginning of the wave.  This address is the relative number of  bytes,
      and not the number of samples.

%'End_Loop'
      The integer  portion  of  the ending  loop  address  relative  to  the
      beginning of the wave.  This address is the relative number of  bytes,
      and not the number of samples.

%'Sample_Rate'
      This is the  sample rate of  the recorded data.   This  number is  not
      related to the actual pitch of the recorded tone.

%'Low_Frequency'
      Each wave  covers a  specific frequency  range.   This is  the  lowest
      frequency that this wave can be used to play.  This field is scaled be
      1000 for accuracy.

%'High_Frequency'
      Each wave covers  a specific  frequency range.   This  is the  highest
      frequency that this wave can be used to play.  This field is scaled by
      1000 for accuracy.  If there is another wave adjacent to this one  and
      its range overlaps this range, then  the next waveform will always  be
      chosen.

%'Root_Frequency'
      If this wave  is played back  at the original  sample_rate, then  this
      number should  be the  pitch of  the  original tone.   This  field  is
      modified to tune the wave to a particular pitch.  This field is scaled
      by 1000 for accuracy.

%'Tune'
      This field is unused.   Tuning is accomplished  by modifying the  root
      frequency.

%'Balance'
      0 is 100% to the right, and 15 is 100% to the left.  As the balance is
      shifted from left to right, the total output power of both channels is
      constant.

%'Envelope_Rate'
      An array of 6 rates to  implement a 6-point envelope. The first  three
      rates can be used for attack and decay.   If the sustain flag is  set,
      than the third  envelope point  will be  the sustain  point. The  last
      three envelope  points are  for the  release, and  an optional  "echo"
      effect.  If the last envelope point is left at an audible level,  then
      a sampled release can  heard after the last  envelope point. The  rate
      values are sent directly to the GF1 hardware, and are described in the
      volume ramping section.

%'Envelope_Offset'
      An array of 6 offsets to implement a 6-point envelope. The first three
      offsets can be used for attack and decay.  If the sustain flag is set,
      than the third  envelope point will  be the sustain  point.  The  last
      three envelope  points are  for the  release, and  an optional  "echo"
      effect.  If the last envelope point is left at an audible level,  then
      a sampled release can heard after the last envelope point.  The offset
      values are sent directly to the GF1 hardware, and are described in the
      volume ramping section.

%'Tremolo_Sweep'
      Not implemented.  Tremolo starts automatically when the note sustains.
      This will be  changed in  future software  to gradually  sweep in  the
      tremolo depth from 0 at the rate of tremolo_sweep / 45 seconds.

%'Tremolo_Rate'
      The rate of amplitude modulation.  0 is 0.05 Hz,  and 255 is 6 Hz.
      A complete table is listed in ~TREMOLO Rate~.

%'Tremolo_Depth'
      0 means  turn tremolo  off.   255  provides a  16  dB modulation.
      A complete table is listed in ~TREMOLO Depth~.

%'Vibrato_Sweep'
      Gradually  sweep  in  the  vibrato  depth  from  0  at  the  rate   of
      vibrato_sweep / 45 seconds.

%'Vibrato_Rate'
      The rate of frequency modulation.  0 is 0.05 Hz, and 255 is 6 Hz.
      A complete table is listed in ~VIBRATO Rate~.

%'Vibrato_Depth'
      0 means turn vibrato off.  255 is a one octave modulation.
      A complete table is listed in ~VIBRATO Depth~.

%'Modes'
      A set of bit fields describing modes and data type:
      BIT 0- 16 bit data
      BIT 1- unsigned data
      BIT 2- looping enabled
      BIT 3- bidirectional loop
      BIT 4- play patch backwards.   start at end address,  loop backwards,
             and then end at beginning address.
      BIT 5- sustain - enveloping  stops at third  envelope point.   a note
             off will continue enveloping.
      BIT 6- currently means enveloping enabled.   All gravis  patches have
             this bit set.  This field will be modified  in the near future
             to implement a sampled release  at note off instead  of at the
             last envelope point.   If this bit  is on, the  sample release
             occurs after the last envelope point.  If this bit is off, the
             sampled release occurs at the note off.
      BIT 7- fast release.  The last three envelope points are ignored.

%'Scale_Frequency'
      Keyboard frequency scaling.  Normally, MIDI note 64 plays a middle  C.
      A 65 plays a C#.  frequency  scaling changes the distance in pitch  of
      each MIDI note.   The scale_frequency is the MIDI note number which is
      the pivot point for scaling.  If scale_frequency is 64, then MIDI note
      64 will sound like a C4 regardless of scale factor.

%'Scale_Factor'
      1024 means normal scaling.  Each MIDI note is  one semitone away  from
      its neighbor.  512 would be 1/2 semitone apart.  2048 is two semitones
      apart.

:U_Freq calculation

^Voice Frequency Calculation (UltraDox 2.0)

    Based on the number of voices set through register 0Eh (Number of
    active voices), the divisor changes.  The frequency outputted to the
    Ultrasound is not a frequency such as 22000hz, but rather the hertz
    divided by a modifier. See ~GF1~ for additional information

    We've traced the divisors down to 8 active voices.  Apparently, there
    are a minimum of 14.

%       # Voices     Divisor   # Voices     Divisor  # Voices     Divisor
%            
                                                         24          25
             8          74         16          37        25          24
             9          66         17          35        26          23
            10          60         18          33        27          22
            11          54         19          31        28          21
            12          50         20          30        29          20
            13          46         21          28        30          20
            14          43         22          27        31          19
            15          40         23          26        32          18

    It is recommended that you don't use values below 14 voices (even
    though it appears to work).

     See also: ~Freq calculation~

%   Example:
        mov   dx,BASE+103h          ; ~Select Register~ port
        mov   al,0Eh                ; Set active voices.
        out   dx,al
        mov   dx,BASE+105h          ; ~Global Data~ hi port
        mov   al,13 or 0C0h         ; Set number of active voices to 14.
        out   dx,al
        mov   dx,BASE+102h          ; ~Page Register~ port
        mov   al,2                  ; Use voice #2.
        out   dx,al
        mov   dx,BASE+103h          ; Select Register port
        mov   al,1                  ; Set Voice Frequency.
        out   dx,al
        mov   dx,BASE+105h          ; Global Data hi port
        mov   ax,511                ; 22000/43
        out   dx,al

      Do yourself a favor and make a table for your notes.

:U_DRAM Addressing

^DRAM Addressing (UltraDox 2.0)

       Through the use of these two registers, the starting location for
       the active voice can be set.  For an unknown reason, any memory
       addresses for the BEGIN, START, and END sample locations in DRAM
       must be divided by 128 and written to u_DataLo, then multiplied
       by 512 and written to u_DataLo.

       Set Sample Begin Location (0ah,0bh) and Set Sample End Location
       (4,5) will refer to this example.  They are both done the same
       way with the exception of the Select register outs.  @@Lo should be
       replaced with 2, 4, or 0ah (based on what you are doing), and
       @@Hi should be replaced with 3, 5, 0bh.

       @@AddrLo is the lower word of the 32-bit DRAM location.
       @@AddrHi is the upper word of the 32-bit DRAM location.

%      Example:
           mov   dx,BASE+102h          ; ~Page register~ port
           mov   al,3                  ; Use voice #3.
           out   dx,al
           mov   dx,BASE+103h          ; ~Select register~ port
           mov   al,@@Lo               ; Request new position.
           out   dx,al
           mov   dx,BASE+104h          ; ~Global Data~ low port
           mov   ax,@@AddrLo
           mov   cx,@@AddrHi
           call  RShift
           out   dx,ax
           mov   dx,BASE+103h          ; Select register port
           mov   al,@@Hi
           out   dx,al
           mov   dx,BASE+104h          ; Global Data low port
           mov   ax,@@AddrLo
           shl   ax,9
           out   dx,ax


:U_Poke DRAM:U_Peek DRAM

^Poking/Peeking a byte to DRAM directly (UltraDox 2.0)

       DRAM addresses can range from 00000h to fffffh.  By outputting the
       DRAM address and then accessing u_DRAMIO, direct peeks and pokes from
       the DRAM memory can be accomplished.

%      Example:
           mov   dx,BASE+103h           ; ~Select register~ port
           mov   al,43h
           out   dx,al
           mov   dx,BASE+104h           ; ~Global Data~ low port
           mov   ax,@@LoDRAMAddress
           out   dx,ax
           mov   dx,BASE+103h           ; Select register port
           mov   al,44h
           out   dx,al
           mov   dx,BASE+105h           ; Global Data hi port
           mov   al,@@HiDRAMAddress
           out   dx,al
           mov   dx,BASE+107h           ; ~DRAM I/O~ port

           ; At this point, you can either:
           in    al,dx       ; Peek a byte from the address just output

           ; or:
           out   dx,al       ; Poke a byte to the address just output.


:U_Probe:Probing Ultra Sound

^Example code to probe Gravis Ultrasound card

  out BASE+103h, 4Ch
  out BASE+105h, 0
  @DELAY
  @DELAY
  out BASE+103h, 4Ch
  out BASE+105h, 1
  Poke Data Byte   Loc:   0h, Byte: AA    ; Don't think this HAS to be an AA.
  Poke Data Byte   Loc: 100h, Byte: 55    ; Don't think this is needed.
  Peek Data Byte   Loc:   0h
  Store Byte
  out BASE+103h, 4Ch
  out BASE+105h, 0
  Restore Byte
  Is it AA?  If so, then we have found a GUS.

:U_Memory amount

^Example code to test for amount of memory installed on UltraSound card

  Poke Data Byte   Loc: 40000h, Byte: AA
  Peek Data Byte   Loc: 40000h
  Is it an AA?  If not, then there is 256k of DRAM.  Exit.
  Poke Data Byte   Loc: 80000h, Byte: AA
  Peek Data Byte   Loc: 80000h
  Is it an AA?  If not, then there is 512k of DRAM.  Exit.
  Poke Data Byte   Loc: C0000h, Byte: AA
  Peek Data Byte   Loc: C0000h
  Is it an AA?  If not, then there is 768k of DRAM.  Exit.
  Poke Data Byte   Loc: 0FFFFFh, Byte: AA
  Peek Data Byte   Loc: 0FFFFFh
  Is it an AA?  If not, then there is 1024k of DRAM.  Exit.

 Description:  Poke these bytes on the boundaries of 256k, 512k, 768k, and
              1024k.  If the memory isn't there, then it won't return what
              is poked.


:U_UltraReset:Resetting Ultrasound

^Ultrasound Reset (UltraDox 2.0)

  code:
         mov   bx,BASE+103h
         mov   cx,BASE+105h
         mov   dx,bx
         mov   al,4Ch
         out   dx,al
         mov   dx,cx
         mov   al,0
         out   dx,al
         @DELAY
         @DELAY
         mov   dx,bx
         mov   al,4Ch
         out   dx,al
         mov   dx,cx
         mov   al,1
         out   dx,al
         @DELAY
         @DELAY

         mov   dx,bx
         mov   al,41h
         out   dx,al
         mov   dx,cx
         mov   al,0
         out   dx,al
         mov   dx,bx
         mov   al,45h
         out   dx,al
         mov   dx,cx
         mov   al,0
         out   dx,al
         mov   dx,bx
         mov   al,49h
         out   dx,al
         mov   dx,cx
         mov   al,0
         out   dx,al

         mov   dx,bx
         mov   al,0Eh
         out   dx,al
         add   dx,2
         mov   al,MaxVoices
         or    al,0C0h
         out   dx,al

         mov   dx,BASE+6h
         in    al,dx
         mov   dx,bx
         mov   al,41h
         out   dx,al
         mov   dx,cx
         in    al,dx
         mov   dx,bx
         mov   al,49h
         out   dx,al
         mov   dx,cx
         in    al,dx
         mov   dx,bx
         mov   al,8Fh
         out   dx,al
         mov   dx,cx
         in    al,dx

         push  bx cx
         mov   cx,0
       @@VoiceClearLoop:
         mov   dx,BASE+102h
         mov   al,cl
         out   dx,al
         inc   dx
         mov   al,0
         out   dx,al
         add   dx,2
         mov   al,3      ; Turn voice off
         out   dx,al
         sub   dx,2
         mov   al,0Dh    ; Turn ramp off.
         out   dx,al
         add   dx,2
         mov   al,3
         out   dx,al
         inc   cx
         cmp   cx,32
         jnz   @@VoiceClearLoop
         pop   cx bx

         mov   dx,bx
         mov   al,41h
         out   dx,al
         mov   dx,cx
         in    al,dx
         mov   dx,bx
         mov   al,49h
         out   dx,al
         mov   dx,cx
         in    al,dx
         mov   dx,bx
         mov   al,8Fh
         out   dx,al
         mov   dx,cx
         in    al,dx

         mov   dx,bx
         mov   al,4Ch
         out   dx,al
         mov   dx,cx
         mov   al,7
         out   dx,al
         ret

:Module player:2_M_MAIN_

^Module player information


%Contents

    ~M_General~     - General information about .MOD files
    ~M_Fileformat~  - MOD File format by Thunder
    ~M_Timing~      - How fast should we play
    ~M_Periods~     - What frequency should we use to play a note
    ~M_FineTuning~  - What is finetuning and how to do it
    ~M_VolDb Table~ - Volume to Decibel conversion table
    ~M_GUSVol Table~- Volume table for Gravis UltraSound
    ~M_Effects~     - How to make the effects

    ~M_EffectList~  - List of standard effects
    ~M_ExtEffects~  - List of extended effects
    ~M_OtherInfo~   - Other information about effects

    ~M_ProFileFormat~   - Protracker 1.1B Module format
    ~M_S3M File Format~ - S3M and STM File Format
    ~M_ULT File Format~ - ULT File Format

:M_General

^General information about .MOD files

 Files with the  extension '.MOD'  are sequenced  music files.   The  file
 format has it's  roots in  the Commodore  Amiga computer (ugh!).    These
 files use different  digital 'samples' played  at various frequencies  to
 create three  octaves  of  'notes'  for  that sample.    In  addition  to
 different 'notes', there  are a large  number of  'effects' which can  be
 done to produce variations on the different notes.

 There are many variations on the MOD format.  Since the format originated
 on the Commodore Amiga computer, the files were geared towards  a machine
 with  4 voices.  These days, with a GUS (Gravis UltraSound),  you have 32
 independent voices.  If you are  programming for a sound board  or device
 that has only 1 or 2 digital voices, you will have to  mix together the 4
 to 8 output channels into those voices.  I will not go  into this process
 here, since I do not  have experience with it  (you don't need to  mix on
 the GUS).

 The earliest versions of the MOD format used a maximum of  15 instruments
 and had 4  channels.   Through some  modifications in  format, a  'newer'
 standard emerged, with a maximum of 31 instruments and up to  8 channels.
 You can tell what format of file you are working with by a four-character
 tag field.  The programs that are  used to play these files on  the Amiga
 are called 'Noisetracker', 'Soundtracker', and 'Protracker'.

:M_Fileformat

^.MOD File Format

 'Big-End Word' refers to the word format on the Amiga.  A  2-byte integer
 value  is  a  word.    On   the  Amiga,  this  value  has   the  internal
 representation HHLL, where HH means the high-order byte and LL  means the
 low-order byte.  The Intel chips (inside PCs) use a LLHH format for their
 words.  This means that if you are writing routines for the  PC, you have
 to flip the high and low order bytes to retrieve meaningful values.

% Offset   Length   Format    Description
%======== ======== ========= =============
       0       20   Chars     Title of the song.  If the title is not a
                              full 20 chars in length, it will be null-
                              terminated. ~M_F_Song name~

      20       22   Chars     Sample 1 name.  If the name is not a full
                              22 chars in length, it will be null
                              terminated. ~M_F_Sample Info~

      42        2   Big-End   Sample 1 length in 2-byte words.  Multiply
                    Word      this value by 2 to get the length of the
                              sample in bytes.

      44        1   SNibble   Sample 1 finetune.

      45        1   Byte      Sample 1 linear volume.

      46        2   Big-End   Sample 1 repeat offset in 2-byte words.
                    Word      Multiply this value by 2 to get the position
                              in bytes.

      48        2   Big-End   Sample 1 repeat length in 2-byte words.
                    Word      Multiply this value by 2 to get the length
                              in bytes.

      50       30             Sample 2 information.  Same format.
      80       30             Sample 3 information   Same format.

      .        There will either be 15 or 31 sample information blocks.
      .        See the format tag field below for a description of how
      .        to find out how many instruments there are.  We'll go on
      .        the assumption that there are 31 instruments in the file.

     920       30             Sample 31 information.

     950        1   Byte      Number of patterns in SONG as played.
                              ~M_F_NPatterns~

     951        1   Byte      Song end jump position.~M_F_EndJumpPos~

     952      128   Bytes     Pattern Table.  These list up to 128
                              pattern numbers and the order they should
                              be played in. ~M_F_PatternTbl~

    1080        4   Chars     File format tag. ~M_F_FileTag~

    1084 ... Pattern and Sample data.  Please see pattern section and
             sample section for more information.




:M_F_Song Name

^Song Name

 This data is pretty  self-representative.  This is  a C 'string' that  is
 null-terminated (i.e. ASCII character 0 is put at the end of the  text is
 the text does not  fill up the  entire field).   Some module writers  use
 this field and the  instrument name fields to  write 'hello' messages  to
 their friends or dedications instead of giving names to the song  or it's
 samples.  I in no way discourage this.


:M_F_Sample Info

^Sample Information

 Based on the format tag field, there can be 15 or 31  sampled instruments
 for the song.  These days it is  rare to run into an 'older'  format song
 with only 15  instruments. Please  see the ~M_F_Filetag~ field  for more
 information on  how to  determine how many  samples there  are in  a file.

%Sample Name

 The first field in a sample  information block is the sample's name.   As
 was mentioned above, these names are  frequently used by the  composer to
 say hello to his or her friends.  Again, I in no way discourage this.  If
 the sample name begins with a '#' character (ASCII $23 (35)) then this is
 assumed not to be an instrument name, and is probably a message.

%Sample Length

 The second field is the sample  length in words.  Once again,  since this
 is a 680x0 word, the bytes have the order HHLL, and you have to swap them
 to use the word on PCs.  The first 2 bytes of the sample  are used by the
 Amiga players for repeat information, and  therefore are NOT part  of the
 playable data.  Therefore, if this field is evaluated to a length of less
 than 3 bytes, there is NO sample.

%Sample finetune value

 The third field is the sample's  initial finetune value.  The  lower four
 bits represent a signed  nibble (-8..7). Each  finetune step changes  the
 note 1/8th  of  a  semitone.   This  is  implemented by  switching  to  a
 different table of period-values  for each finetune  value. See ~M_Periods~
 for a discussion of fine-tuning.

%Sample volume

 The fourth  field is  the sample's  playback volume.    These are  LINEAR
 values that range from 0 to 64, with 64 being maximum volume.  If you are
 implementing a  MOD  player,  remember  to  check  if  you  need  to  use
 logarithmic volumes.  'Decibel' is a logrithmical unit,  which represents
 how we feel  sound intensity.   The volume  and decibel  value table  for
 conversions is in ~M_VolDb Table~. If you have a GUS, read ~M_GUSVol~.

%Sample repeat start

 The fifth field  in the  sample information  block is  the sample  repeat
 start offset.  Once this sample has been played completely from beginning
 to end, if the  repeat length (next field)  is greater than two  bytes it
 will loop back to this position in the sample and continue playing.  Once
 it has played for  the repeat length,  it continues to  loop back to  the
 repeat start offset.  This means the sample continues playing until it is
 told to stop.

%Sample repeat length

 The last, or sixth field in the sample information is the  repeat length.
 A sample is only looped if this value  is greater than 2 bytes.

:M_VolDb Table

^Volume - Decibel conversion table

             Volume  Decibel Value     Volume  Decibel Value
          -------------------------  ------------------------
               64         0.0            32        -6.0
               63        -0.1            31        -6.3
               62        -0.3            30        -6.6
               61        -0.4            29        -6.9
               60        -0.6            28        -7.2
               59        -0.7            27        -7.5
               58        -0.9            26        -7.8
               57        -1.0            25        -8.2
               56        -1.2            24        -8.5
               55        -1.3            23        -8.9
               54        -1.5            22        -9.3
               53        -1.6            21        -9.7
               52        -1.8            20       -10.1
               51        -2.0            19       -10.5
               50        -2.1            18       -11.0
               49        -2.3            17       -11.5
               48        -2.5            16       -12.0
               47        -2.7            15       -12.6
               46        -2.9            14       -13.2
               45        -3.1            13       -13.8
               44        -3.3            12       -14.5
               43        -3.5            11       -15.3
               42        -3.7            10       -16.1
               41        -3.9             9       -17.0
               40        -4.1             8       -18.1
               39        -4.3             7       -19.2
               38        -4.5             6       -20.6
               37        -4.8             5       -22.1
               36        -5.0             4       -24.1
               35        -5.2             3       -26.6
               34        -5.5             2       -30.1
               33        -5.8             1       -36.1
                                          0    Minus infinity

 The reason  for  the  table starting  at  0  dB as  the  convention  from
 taperecorders of  having 0  dB as  the optimal  recording condition,  and
 displaying anything worse as a negative  number. See ~M_GUSVol~ for a
 complete linear volume format for Gravis UltraSound.


:M_F_NPatterns

^Number of patterns in song

 This byte represents the number of patterns which are played in the entire
 SONG.  This is NOT the number of patterns in the FILE.  The file may
 contain (theoretically) up to 256 patterns, whereas the song is just a
 selection of those patterns.  If I have 30 patterns in my file, and I just
 want to play patterns 6, 12, 3, 7, and 8 in that order, this byte will have
 the value 5.


:M_F_EndJumpPos

^Song end jump position

 Historically, this byte has been used  for many purposes.   Most commonly
 in the newer  format it  has been  used to  signify if  a song  is to  be
 repeated indefinitely.   Some game programs  have background music  which
 never ends.   If  this byte  is  less than  127,  then it  specifies  the
 position in the pattern table to  jump to when the last pattern  has been
 played.  If this byte is greater than or equal to 127, the song ends.


:M_F_PatternTbl

^Pattern table

 This 128 byte block lists the  order that patterns in the file  should be
 played in.  Only the number of bytes specified by the number  of patterns
 in the song (see ~M_F_NPatterns~) can be considered valid.  If the song is
 to play patterns 6, 0, 12, 11, 21, and 10 in that order, then the table
 will have those 6 values as the first 6 bytes:

                              Pattern Table
   Position --->  0   1   2   3   4   5   6 ---------> 127
                |---|---|---|---|---|---|---|---...---|---|
                |006|000|012|011|021|010|    ?????????    |
                |---|---|---|---|---|---|---|---...---|---|

 One of the  effects which  is possible (see ~M_Effects~)  is a  position
 jump.  The argument  to this effect is  where to jump  to in the  PATTERN
 TABLE.  This does NOT specify which PATTERN to jump to.

 In a particular pattern  there are 64 lines.   These lines are  played in
 order from  0 to  63.   When the  end of  a pattern  is reached,  playing
 continues with the next pattern in the pattern table, unless  the current
 pattern is the last one.  If  the current pattern IS the last  one, check
 the song end jump position (see ~M_F_EndJumpPos~) to see if the  song
 loops to a certain position  in the  pattern table.   Another one  of the
 effects which is possible (see ~M_Effects~)  is a pattern break.  If  this
 effect is encountered, playing immediately jumps to  the first line of
 the next pattern.


:M_F_Filetag

^File format tag

 This is the most  controversial field in the  file.  This field  has been
 the most 'ravaged', with  many people using it  in non-standard ways  for
 their own purposes.   There are a  few standard tags  which you can  find
 here which tell you  DEFINITELY what file format  the file is, but  there
 are many more  non-standard tags.   This makes the  job of deciding  what
 format a MOD is a  difficult one.  I  will attempt to describe  the known
 formats below.  If you know of one I miss, please let me know.

      'M.K.', 'FLT4',
      'M!K!', '4CHN' : 4 channels, 31 instruments

      '6CHN'         : 6 channels, 31 instruments

      '8CHN', 'OCTA' : 8 channels, 31 instruments

 Other information  that is  found in  this  field can  be assumed  to  be
 somebody's attempt at protection, or some other information that was used
 in the  'older'  file  format.   If  you  can't find  any  of  the  above
 information, it is best to assume that it's a 4 channel file.  As for how
 many instruments there are, check the bytes at location 471 in  the file.
 If there is text  there (ASCII $20-$7E (32-126)),  then you can  probably
 assume it's a 31-instrument file.  Otherwise, it's an older 15 instrument
 file.


:M_F_Patterns

^Patterns

 There can be any number of patterns  in the file.  They are  stored after
 the file header and before the sample data.  There are USUALLY  less than
 64, but the maximum is not limited - if the file tag  is 'M!K!' there are
 definitely more than 64 patterns.

 The patterns are stored sequentially (i.e.  the first pattern is  #0, the
 second pattern is  #1, etc.).   An individual  pattern is  made up of  64
 'lines', stored sequentially (i.e.  line 0 to line  63).  Each 'line'  is
 comprised of a note for each channel.  Each 'note' is made up of 4 bytes,
 so depending on the number of channels in the file, there are  16, 24, or
 32 bytes per line.

 For a four-channel file there are (4 bytes * 4 channels * 64 lines) =1024
 bytes of information per pattern.  To find out the number of  patterns in
 a particular file, calculate the  length of 'header' information  and add
 to it  the  lengths of  all  samples that  are  mentioned in  the  sample
 information blocks.  Subtract this number from the file's total  size and
 divide by the number just computed  (1024) to get the number  of patterns
 in the file.

 As mentioned above, each note is stored as 4 bytes.  The information held
 by these bytes has format shown  below.  How you display the  contents of
 the 4 bytes in  a player is up  to you.  There  is NO standard way  to do
 this.

%                Byte  1   Byte  2   Byte  3   Byte 4
%               --------- --------- --------- ---------
               7654-3210 7654-3210 7654-3210 7654-3210
               wwww XXXX xxxxxxxxx yyyy ZZZZ zzzzzzzzz

                   wwwwyyyy ( 8 bits) : sample number
               XXXXxxxxxxxx (12 bits) : sample 'period'
               ZZZZzzzzzzzz (12 bits) : effect and argument

 The sample number refers to a sample specified in the  sample information
 block. Please see ~M_F_SampleInfo~ for more  information on  the samples.

 The sample 'period' corresponds  to a delay value  on an Amiga  computer.
 Note that on  an Intel  processor, you  have to  order these  12 bits  as
 'xxxxxxxx0000XXXX' to read the value as a word. Please see ~M_Periods~ and
 ~M_Finetuning~ for more information on how to use these values.

 The effect is an  effect number and an  argument for the effect. Please
 see ~M_F_Effects~ for a  discussion of the  effects and  how to  implement
 them.


:M_F_Smp data

^Sample data

 The sample data  follows all of  the patterns.   After you have  finished
 reading the pattern data, there will be just enough data left in the file
 for all of the instruments  specified in the sample  information section.
 The samples are  stored sequentially  from sample 1  to sample  31.   The
 sample's data is in 8-bit two's  compliment format, so if it needs  to be
 in another  format for  your sound  device to  play it,  don't forget  to
 convert (UltraSound  users:  you don't  need  to  convert the  data  when
 downloading).

 Remember that first two bytes are used only by the Amiga MOD players for
 repeat information, and therefore are NOT part of the playable data.

:M_Timing

^Timing

 If lines are played  sequentially, then how long  should the player  wait
 between successive lines?  On the Amiga, the amount of time a note spends
 on a channel before the next note is started is calculated by  using some
 complex formulas based on  the PAL color carrier  frequency.  I will  not
 try to bore you with the  details of these calculations here, and  if you
 wan't them, email me.

 A song can be played at  a speed ranging from  1 to 127, where  the speed
 specifies how many  'ticks' before playing  the next sample.   A tick  is
 supposed to happen every .02 seconds, which gives 50 ticks per second.

 At the start of  a line all samples  specified on that line  are started,
 samples playing  are  modified, speed  is  changed,  etc.   Some  effects
 require that changes be made to a sample playing on a channel  during the
 course of a line.  For  example, the retrigger effect re-starts  a sample
 at a certain tick within a line.  If  the song is playing at speed  6 and
 the effect specifies a retrigger on the 4th tick:

%               Time Tick
                0.00  1 - start all samples and effects
                0.02  2
                0.04  3
                0.06  4 - retrigger sample here
                0.08  5
                0.10  6
                ------------
                0.00  1 - start next line
                    .
                    .

 Unless a speed is specified on  the first line of the first  pattern, the
 song should start playing at speed 6.Please see ~M_SetSpeed~, for more
 information on changes in speed.

:M_Periods

^Periods

 MOD  players  use  a  technique  called  frequency  shifting  to  produce
 different 'notes' of the same sample.  If  I play a sample at 10  KHz, it
 will sound one octave higher if I double the frequency to 20 KHz, and one
 octave lower if I halve the frequency to 5 KHz.  Since there are 12 notes
 per octave on a  keyboard (these are  called half-steps), each  frequency
 corresponds to one twelfth root of two (1.05946) times the  frequency of
 it's predecessor (to  the left).   Therefore, if  the C-1 frequency  (the
 note of C in octave 1) is 4144 Hz then:

 Note: C-1  C#1  D-1  ... C-2  ...
 Freq: 4144 4390 4651 ... 8288 ...

 The Amiga playing routines were  written to run off  different interrupts
 for different Amiga computers, based on whether the machine was a  PAL or
 NTSC machine.    The  'period' values  are  measures  which are  used  in
 calculating how much data  to send to  each of the  4 Amiga channels  per
 second (thereby specifying the frequency or pitch of the output).

 For PC programmers, you  don't have to worry  about this that much.   The
 thing to remember is  that a 'magic number'  divided by twice the  period
 value will give the rate (frequency) to play the sample at.  Here are the
 magic numbers and the corresponding formulae.  I don't know  which number
 is better to use - It doesn't make a huge difference.

%               PAL Value                NTSC Value
%              ===========              ============

                 7093789.2                       7159090.5
 SampleRate = --------------     SampleRate = --------------
                Period * 2                      Period * 2

 To determine what frequency  to play a sample  at, look up the  specified
 period value in a  table based on the  finetune setting (see
 ~M_Finetuning~ for more  information on  fine-tuning).   If the  period is
 0, then  the previous period used on that channel is used.

 As an example, let's look at the period table for finetune 0.   The notes
 that are possible in each octave are:

%          C    C#   D    D#   E    F    F#   G    G#   A    A#   B
 Octave 1: 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453
 Octave 2: 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226
 Octave 3: 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113

 Octave 0:1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907
 Octave 4: 107, 101,  95,  90,  85,  80,  76,  71,  67,  64,  60,  57

 If I was requested to play a  sample at period 302, I would  scan through
 the period table until I hit that value.  At that point,  I know that the
 note is called  'F#2', F-sharp  in octave 2.   I  calculate the  playback
 frequency by doing the calculations on the next page.

%      PAL Value                     NTSC Value
%      ===========                   ============

        7093789.2                     7159090.5
       ----------- = 11745 Hz        ----------- = 11853 Hz
         302 * 2                       302 * 2

 There are normally  only three octaves  (1 to 3)  used in playing  songs.
 Octaves 0 and 4 are NOT standard.  Some songs may use  the values though,
 and it's nice if your player can handle them.  Full period tables for all
 finetunes are listed in ~M_PeriodTbl~.

 If you wish to sample sounds  to include in MOD files, remember  that the
 data must be stored in 8-bit 2's complement format.  There is NO standard
 sample rate when creating the samples.   Most often the samples  are done
 on the rate corresponding to period C-3 (around 16.5 KHz),  and sometimes
 drums are sampled at A-3 (around 28 KHz).

 If sample number  is specified on  a channel (sample  #0), then the  last
 sample used on that channel will  be remembered if new notes  come along.
 Only one sample may play on a channel at a time, so  playing a new sample
 will cancel an old one - even if  there is no actual sample data  for the
 new sample (a 'silent' sample).   However, if you are constructing  a MOD
 file of your own and you  use a "silent" sample  it is polite to  set its
 default volume to 0.

 If you have some memory (around 2k or  so) to spare, you could make  up a
 table of words indexed  by period value.   The value of  the word at  the
 index of a period is the  corresponding frequency that the  sample should
 be played at.   This saves you from  having to calculate the  frequencies
 over and over again.  If you still don't get what I'm talking about here:

 I have a array of words, one for each period from the  lowest (around 50)
 to the highest (around 1712).  I precalculate the contents of  this table
 so that at index 302 (the period for note F#2), there is the value 11853,
 the frequency to use to get the note F#2.  Therefore, when my player runs
 accross this value and  needs to know what  frequency to play the  sample
 at, I simply look up the  value in the table directly -  no calculations.
 If you still don't get what I'm talking about, you're screwed.

:M_Finetuning

^Fine-Tuning

 Fine-tuning is a minor adjustment on  how an instrument sounds.   This is
 implemented by small changes  in the period values.   The finetune  value
 for a  sample specifies  the adjustment  on the  period  values for  that
 instrument.  A fine-tune can also be specified for a  specific instrument
 by an effect, at  which point the value  in the effect will  override the
 one in the sample information block.

 The value in  the sample information  block is a  signed nibble (4  bits,
 signed 2's complement).  Therefore, the values that can be found have the
 following corresponding finetunes:

 Value:    0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
 Finetune: 0  +1  +2  +3  +4  +5  +6  +7  -8  -7  -6  -5  -4  -3  -2  -1

 ~M_PeriodTbl~ specifies period values for all finetunes for octaves 1 to
 3. You could use these values in creating your array of frequency words
 (see ~M_Periods~).

:M_Effects

^Effects

 As was  mentioned ~M_F_Patterns~,  the 4  bytes  for  a note  have  the
 following format:

%               Byte  1   Byte  2   Byte  3   Byte 4
%              --------- --------- --------- ---------
               7654-3210 7654-3210 7654-3210 7654-3210
               wwww XXXX xxxxxxxxx yyyy ZZZZ zzzzzzzzz

                   wwwwyyyy ( 8 bits) : sample number
               XXXXxxxxxxxx (12 bits) : sample 'period'
               ZZZZzzzzzzzz (12 bits) : effect and argument

 Again, how you display this information in a player is up to you.  I have
 seen a  zillion different  formats.   I have  described  what the  sample
 number and period refer to.  Here,  we will look at the effects  that are
 possible.

 At this point  in time, the  Amiga Protracker  MOD player (version  2.3A/
 3.01)   has 28  effects.   Some of  these effects  are  redundant or  not
 possible on some PC  sound cards.   I will describe  the effects and  how
 they are implemented on the Amiga.  PC programmers will have to adapt the
 effects they wish to implement on  their own.  All numbers are  stated in
 hexadecimal.

 For the  discussion of  the effects,  we  will look  at the  'effect  and
 argument' part of the 4 bytes in the following way:

                Bit number:         $CBA987654321
                Mentioned above as:  ZZZZzzzzzzzz
                We will use:         ZZZZxxxxyyyy

 There are two types of effects,  standard and extended.  All  effects use
 the ZZZZ portion to declare the effect number.  Standard effects  use the
 xxxx and yyyy portions as one or two arguments, either as an  8-bit value
 when taken together in the form  xxxxyyyy or as 2 nibbles xxxx  and yyyy.
 Extended effects  have the  ZZZZ effect  number $E.   They  use the  xxxx
 portion to  declare the  extended effect  number and  the  only the  yyyy
 portion as an argument. See ~M_EffectList~ for list of standard effects.


:M_EffectList

^Standard Effects

 Here are the possible standard effects:
 -----------------------------------------------------------------------
%#   Effect name                          Uses Arguments as
 -----------------------------------------------------------------------
 0   Arpeggio                             xxxx  yyyy        ;~M_Arpeggio~
 1   Slide Up (Portamento Up)             xxxxyyyy          ;~M_Slide Up~
 2   Slide Down (Portamento Down)         xxxxyyyy          ;~M_Slide Dn~
 3   Tone Portamento                      xxxxyyyy          ;~M_TonePor~
 4   Vibrato                              xxxx  yyyy        ;~M_Vibrato~
 5   Tone Portamento + Volume Slide       xxxx  yyyy        ;~M_ToneSlide~
 6   Vibrato + Volume Slide               xxxx  yyyy        ;~M_VibrSlide~
 7   Tremolo                              xxxx  yyyy        ;~M_Tremolo~
 8   NOT USED                             n/a
 9   Set SampleOffset                     xxxxyyyy          ;~M_SetSmpOffs~
 A   VolumeSlide                          xxxx  yyyy        ;~M_VolumeSlide~
 B   Position Jump                        xxxxyyyy          ;~M_PosJump~
 C   Set Volume                           xxxxyyyy          ;~M_SetVolume~
 D   Pattern Break                        xxxxyyyy          ;~M_PattrnBreak~
 E   *Extended Effects                    varies            ;~M_ExtEffects~
 F   Set Speed                            xxxxyyyy          ;~M_SetSpeed~

:M_ExtEffects

^Extended Effect list

 And here are the possible extended effects:
                    ---------------------------------
%                    #   Effect name
                    ---------------------------------
                     E0  Set Filter             ;~M_E_SetFilter~
                     E1  FineSlide Up           ;~M_E_FineSlide Up~
                     E2  FineSlide Down         ;~M_E_FineSlide Dn~
                     E3  Glissando Control      ;~M_E_Glissando~
                     E4  Set Vibrato Waveform   ;~M_E_Set VibratoWave~
                     E5  Set FineTune           ;~M_E_Set FineTune~
                     E6  PatternLoop            ;~M_E_LoopPattrn~
                     E7  Set Tremolo Waveform   ;~M_E_Set TremoloWave~
                     E8  NOT USED
                     E9  Retrig Note            ;~M_E_Retrig Note~
                     EA  Fine VolumeSlide Up    ;~M_E_FineVolSlide Up~
                     EB  Fine VolumeSlide Down  ;~M_E_FineVolSlide Dn~
                     EC  NoteCut                ;~M_E_NoteCut~
                     ED  NoteDelay              ;~M_E_NoteDelay~
                     EE  PatternDelay           ;~M_E_PatternDelay~
                     EF  Invert Loop            ;~M_E_Invert Loop~


 A description of each  effect and how it  is implemented is given  on the
 following pages.  Once again, all values are given in  hexadecimal unless
 otherwise stated.

:M_Arpeggio

^0: Arpeggio

 If a note as an effect number of 0, it is only an arpeggio if there is at
 least one non-zero argument.  When there is at least one  valid argument,
 this effect means to  play the note specified,  then the note+xxxx  half-
 steps, then the  note+yyyy half-steps,  and then return  to the  original
 note.  These changes are evenly spaced  within the time for a line  to be
 played at the current speed.

 This effect is usually  used to simulate chords  (where a major chord  is
 the note+4 half  steps and the  note+7 half-steps).   This does not  work
 very well on  most samples.   This can also  be used  to produce a  heavy
 vibrato.  Here is an example of this effect:

 Note C-3, xxxx=4, yyyy=7

 this will attempt to produce a C-major chord.  At the beginning of a line
 the C-3 note is played, then at 1/3 of the way through  the line the note
 is retriggered at E-3, 2/3 of  the way through it is retriggered  at G-3,
 and at the beginning of the  next line (if there  are no new notes  to be
 played on the channel), it is retriggered at C-3 again.

 This presents a minor problem for timing, since you have to keep track of
 the arpeggio during the course of playing  a line.  What you could  do is
 use a  timer differently,  or set  up  another timer  that  independently
 tracks the timing of the arpeggio.

%  Cmd 0. Arpeggio [Range:$0-$F/$0-$F]
%  -----------------------------------
  Usage: $0 + 1st halfnote add
            + 2nd halfnote add
  Arpeggio is used to simulate chords.
  This is done by rapidly changing the
  pitch between 3(or 2) different notes.
  It sounds very noisy and grainy on
  most samples, but ok on monotone ones.
  Example: C-300047  C-major chord:
           (C+E+G  or C+4+7 halfnotes)
           C-300037  C-minor chord:
           (C+D#+G or C+3+7 halfnotes)


:M_Slide Up:M_Porta Up

^1: Slide up (Portamento Up)

 This effect will  slide up  the frequency  (decrease the  period) of  the
 sample being played on the channel by xxxxyyyy notes for every  tick that
 occurs during the line.   You usually cannot  slide past note B-3  unless
 you have implemented octave 4 (NON-STANDARD!).  The number of  ticks that
 occur per line is set with effect  $F, the set speed command.   Since the
 slide rate depends on  the speed, be careful  if you set are  composing a
 MOD when you change the speed.  An example of this effect is:

 Note C-3, xxxxyyyy = 2, playing at speed 3.

 At the beginning of the line the sample is started at period C-3.  At the
 first tick, the period is decremented by 2 (the frequency  is increased).
 At the  second tick,  the period  is  again decremented  by  2.   At  the
 beginning of the next line, if there is  not a new note to be  played the
 period is again decremented by 2.

%  Cmd 1. Portamento up [Speed:$00-$FF]
%  ------------------------------------
  Usage: $1 + portamento speed
  Portamento up will simply slide the
  sample pitch up. You can NOT slide
  higher than B-3! (Period 113)
  Example: C-300103  1 is the command,
             3 is the portamentospeed.
  NOTE: The portamento will be called as
  many times as the speed of the song.
  This means that you'll sometimes have
  trouble sliding accuratly. If you
  change the speed without changing the
  sliderates, it will sound bad...


:M_Slide Dn;M_Porta Dn

^2: Slide down (Portamento Down)

 This effect will slide  down the frequency (increase  the period) of  the
 sample being played on the channel by xxxxyyyy tones for every  tick that
 occurs during the line.  You  usually cannot slide below note  C-1 unless
 you have implemented octave 0 (NON-STANDARD!).  The number of  ticks that
 occur per line is set with effect  $F, the set speed command.   Since the
 slide rate depends on  the speed, be careful  if you set are  composing a
 MOD when you change the speed.  An example of this effect is:

 Note C-3, xxxxyyyy = 2, playing at speed 3.

 At the beginning of the line the sample is started at period C-3.  At the
 first tick, the period is incremented by 2 (the frequency  is decreased).
 At the  second tick,  the period  is  again incremented  by  2.   At  the
 beginning of the next line, if there is  not a new note to be  played the
 period is again incremented by 2.

%  Cmd 2. Portamento down [Speed:$00-FF]
%  -------------------------------------
  Usage: $2 + portamento speed
  Just like command 1, except that this
  one slides the pitch down instead.
  (Adds to the period).
  You can NOT slide lower than C-1!
  (Period 856)
  Example: C-300203  2 is the command,
             3 is the portamentospeed.


:M_SlidetoNote:M_TonePortamento

^3: Slide to note (Tone Portamento)

 This effect will slide  a note being played  on a channel to  a specified
 note.  The parameter xxxxyyyy will states the speed at which a slide will
 occur.  For each tick that  occurs during the line, the  period currently
 being played is altered by the number of notes specified.  The  number of
 ticks that occur per line is  set with effect $F, the set  speed command.
 Since the slide  rate depends on  the speed,  be careful  if you set  are
 composing a MOD when you change the speed.  An example of this effect is:

 Slide to note C-2, xxxxyyyy = 2, playing at speed 3.

 At the beginning  of the  line the current  frequency for  the sample  is
 altered to  be 2  notes closer  to  C-2.   At the  first  tick, the  same
 alteration occurs, changing the period to form a note even closer to C-2.
 The same occurs for  each tick after that.   This effect continues  until
 another effect is started or the specified frequency is reached.

 If a slide rate is not  specified (xxxxyyyy is zero) then the  last slide
 rate used on the channel is used again.

% Cmd 3. Tone-portamento [Speed:$00-$FF]
% --------------------------------------
  Usage: Dest-note + $3 + slidespeed
  This command will automatically slide
  from the old note to the new.
  You don't have to worry about which
  direction to slide, you need only set
  the slide speed. To keep on sliding,
  just select the command $3 + 00.
  Example: A-200000  First play a note.
           C-300305  C-3 is the note to
                slide to, 3 the command,
                and 5 the speed.


:M_Vibrato

^4: Vibrato

 Vibrato means to "oscillate the sample pitch using a  particular waveform
 with amplitude yyyy notes, such that (xxxx * speed)/64  full oscillations
 occur in the line".  The waveform to use in vibrating is set using effect
 E4 (see  below). By  placing vibrato  effects on  consecutive lines,  the
 vibrato effect can be sustained for  any length of time.  If  either xxxx
 or yyyy are 0,  then values from  the most recent  prior vibrato will  be
 used.

 An example is: Note C-3, with xxxx=8 and yyyy=1 when speed=6.   This will
 play tones  around  C-3,  vibrating through  D-3  and  B-2 to  C-3  again
 (amplitude - yyyy - is 1), with (8*6)/64 = 3/4 of a  full oscillation per
 line.  Please see effect E4 for the waveform to use for vibrating.

% Cmd 4. Vibrato [Rate:$0-$F,Dpth:$0-$F]
% --------------------------------------
  Usage: $4 + vibratorate + vibratodepth
  Example: C-300481  4 is the command,
        8 is the speed of the vibrato,
    and 1 is the depth of the vibrato.
  To keep on vibrating, just select
  the command $4 + 00. To change the
  vibrato, you can alter the rate,
  depth or both. Use command E4- to
  change the vibrato-waveform.


:M_ToneSlide

^5: Tone Portamento with Volume slide

 This effect will change the volume  of a channel while a  tone portamento
 (~M_TonePor~) is taking place.  The values xxxx or yyyy specify the speed
 of the volume change.   If xxxx is nonzero  the volume is increased,  and
 if yyyy is nonzero the volume is decreased.  It is illegal for both xxxx
 and yyyy to be non-zero.  You cannot slide past 64 or below 0.

 As an example, take  the xxxx to  be set to  3.  This  means that at  the
 beginning of the line, the current volume of the channel is  increased by
 3.  The volume  is increased again for  every tick on  this line and  the
 lines following (until there  is a new effect).   Once again, the  volume
 cannot slide up past 64.

% Cmd 5. ToneP + Volsl [Spd:$0-$F/$0-$F]
% --------------------------------------
  Usage: $5 + upspeed + downspeed
  This command will continue the current
  toneportamento and slide the volume
  at the same time. Stolen from NT2.0.
  Example: C-300503  3 is the speed to
                 turn the volume down.
           C-300540  4 is the speed to
                          slide it up.


:M_VibrSlide

^6: Vibrato with Volume slide

 This effect will change the volume  of a channel while a  vibrato
 (~M_Vibrato~) is taking place.   The values xxxx  or yyyy specify  the
 speed of  the volume change.  If xxxx is  nonzero the volume is increased,
 and  if yyyy is nonzero the volume is decreased.  It is illegal for both
 xxxx and yyyy to be non-zero.  You cannot slide past 64 or below 0.

 As an example, take  the yyyy to  be set to  2.  This  means that at  the
 beginning of the line, the current volume of the channel is  decreased by
 2.  The volume  is decreased again for  every tick on  this line and  the
 lines following (until there  is a new effect).   Once again, the  volume
 cannot slide down below 0.

% Cmd 6. Vibra + Volsl [Spd:$0-$F/$0-$F]
% --------------------------------------
  Usage: $6 + upspeed + downspeed
  This command will continue the current
  vibrato and slide the volume at the
  same time. Stolen from NT2.0.
  Example: C-300605  5 is the speed to
                 turn the volume down.
           C-300640  4 is the speed to
                          slide it up.


:M_Tremolo

^7: Tremolo

 Tremolo means to "oscillate the sample volume using a  particular waveform
 with   amplitude   yyyy*(speed-1),   such   that   (xxxx*speed)/64   full
 oscillations occur in the line".  The waveform to use to oscillate is set
 using the  effect  E7  (see ~M_E_Set TremoloWave~). By  placing  tremolo
 effects  on consecutive lines, the tremolo effect can be sustained for any
 length of time.  If either  xxxx or yyyy are  0, then values  from the
 most  recent prior tremolo will be used.

 The usage of this effect is similar to that of effect ~M_Vibrato~.

% Cmd 7. Tremolo [Rate:$0-$F,Dpth:$0-$F]
% --------------------------------------
  Usage: $7 + tremolorate + tremolodepth
  Tremolo vibrates the volume.
  Example: C-300794  7 is the command,
        9 is the speed of the tremolo,
    and 4 is the depth of the tremolo.
  To keep on tremoling, just select
  the command $7 + 00. To change the
  tremolo, you can alter the rate,
  depth or both. Use command E7- to
  change the tremolo-waveform.


:M_SetSmpOffs

^9: Set sample offset

 This effect allows you to start a sample from a specified position rather
 than the normal beginning position.   Multiply the value xxxxyyyy  by 512
 to get  the position  in bytes  from the  beginning of  the sample  where
 playback should start.   If no sample is  specified with the effect,  but
 one is  currently  playing on  the  channel,  then the  sample  currently
 playing is retriggered to offset specified.

 An example is instrument 2 being  played at note C-3,  with xxxxyyyy=$23.
 This would make playback of the sample start at offset $23*$200  = $4600.
 This effect gives a rough range to play the sample from.

% Cmd 9. Set SampleOffset [Offs:$00-$FF]
% --------------------------------------
  Usage: $9 + Sampleoffset
  This command will play from a chosen
  position in the sample, and not from
  the beginning. The two numbers equal
  the two first numbers in the length
  of the sample. Handy for speech-
  samples.
  Example: C-300923  Play sample from
                     offset $2300.


:M_VolumeSlide

^A: Volume slide

 This effect  will change  the volume  of all  samples being  played on  a
 channel.  The values xxxx or yyyy specify the speed of the volume change.
 If xxxx is nonzero  the volume is increased,  and if yyyy is  nonzero the
 volume is decreased.   It is illegal for  both xxxx and  yyyy to be  non-
 zero.  You cannot slide past 64 or below 0.

 As an example, take  the yyyy to  be set to  3.  This  means that at  the
 beginning of the line, the current volume of the channel is  decreased by
 3.  The volume is decreased  by 3 again for  every tick on this  line and
 the lines  following (until  there is  a new  effect).   Once again,  the
 volume cannot slide down below 0.

% Cmd A. Volumeslide [Speed:$0-$F/$0-$F]
% --------------------------------------
  Usage: $A + upspeed + downspeed
  Example: C-300A05  5 is the speed to
                 turn the volume down.
           C-300A40  4 is the speed to
                          slide it up.
  NOTE: The slide will be called as
  many times as the speed of the song.
  The slower the song, the more the
  volume will be changed on each note.


:M_PosJump

^B: Position Jump

 This effect xxxxyyyy parameter specifies a position in the  pattern table
 that playback should jump  to after this line.   Legal values are  in the
 range of the number of patters that  are supposed to be in the  song (see
 ~M_F_NPatterns~).  Values outside this range should be ignored.

%   Cmd B. Position-jump [Pos:$00-$7F]
%   ----------------------------------
  Usage: $B + position to continue at
  Example: C-300B01  B is the command,
                  1 is the position to
                  restart the song at.
  This command will also perform a
  pattern-break.
  You can use this command instead of
  restart as on noisetracker, but you
  must enter the position in hex!


:M_SetVolume

^C: Set volume

 Effect C will set the volume on a channel to the setting specified by the
 xxxxyyyy value.  Legal volumes are in the  range of 0 to 64.   An attempt
 to set the volume to a higher value than 64 will just set it to 64.

%   Cmd C. Set volume [Volume:$00-$40]
%   ----------------------------------
  Usage: $C + new volume
  Well, this old familiar command will
  set the current volume to your own
  selected. The highest volume is $40.
  All volumes are represented in hex.
  (Programmers do it in hex, you know!)
  Example: C-300C10  C is the command,
        10 is the volume (16 decimal).


:M_PattrnBreak

^D: Pattern Break

 This effect is equivalent to a  position jump to the next pattern  in the
 pattern table, with the arguments xxxx*10+yyyy specifying the line within
 that pattern to start playing at.  Note that this is NOT xxxx*16+yyyy.

 For example, the effect with  arguments xxxx=0, yyyy=0 would  simply jump
 to the first line in the next pattern in the pattern table  after playing
 the current line.   With arguments  xxxx=1 and yyyy=6  would jump to  the
 16th line of  the next  pattern in the  pattern table  after playing  the
 current line.

%      Cmd D. Pattern-break
%      [Pattern-pos:00-63, decimal]
%      ----------------------------
  Usage: $D + pattern-position
  This command just jumps to the next
  song-position, and continues play
  from the patternposition you specify.
  Example: C-300D00  Jump to the next
      song-position and continue play
             from patternposition 00.
       Or: C-300D32  Jump to the next
      song-position and continue play
     from patternposition 32 instead.


:M_E_SetFilter

^E0: Set filter on/off

 This sets a hardware sound filter to ON (if yyyy is 0) or OFF (if xxxx is
 nonzero).  If your sound device  has built-in filters, you  should ignore
 this effect command.  This effect is primarily used on Amiga 500 and 2000
 computers to dick around with the hardware filter.

%    Cmd E0. Set filter [Range:$0-$1]
%    --------------------------------
  Usage: $E0 + filter-status
  This command jerks around with the
  sound-filter on some A500 + A2000.
  All other Amiga-users should keep out
  of playing around with it.
  Example: C-300E01  disconnects filter
                  (turns power LED off)
           C-300E00  connects filter
                   (turns power LED on)


:M_E_FineSlide Up

^E1: Fineslide up

 This effect functions just like ~M_Porta Up~, except  that the frequency
 of the sample is only modified once.   At the beginning of a  line,
 whatever frequency is being  played on  a channel  is incremented  by yyyy
 notes. This effect does NOT continue on  the lines following.  You  cannot
 slide the frequency above the  note B-3 (unless you  implement octave 4 :
 NON- STANDARD!).

 An example here would be effect  E, xxxx=1 (the extended  effect number),
 yyyy=3.  This  would slide the  current frequency up  three notes at  the
 beginning of the line.

%   Cmd E1. Fineslide up [Range:$0-$F]
%   ----------------------------------
  Usage: $E1 + value
  This command works just like the
  normal portamento up, except that
  it only slides up once. It does not
  continue sliding during the length of
  the note.
  Example: C-300E11  Slide up 1 at the
                beginning of the note.
  (Great for creating chorus effects)

:M_E_FineSlide Dn

^E2: Fineslide down

 This effect functions just like ~M_Porta Dn~, except  that the frequency
 of the sample is only modified once.   At the beginning of a  line,
 whatever frequency is being  played on  a channel  is decremented  by yyyy
 notes. This effect does NOT continue on  the lines following.  You  cannot
 slide the frequency below the  note C-1 (unless you  implement octave 0 :
 NON- STANDARD!).

 An example here would be effect  E, xxxx=1 (the extended  effect number),
 yyyy=2.  This  would slide the  current frequency down  two notes at  the
 beginning of the line.

%  Cmd E2. Fineslide down [Range:$0-$F]
%  ------------------------------------
  Usage: $E2 + value
  This command works just like the
  normal portamento down, except that
  it only slides down once. It does not
  continue sliding during the length of
  the note.
  Example: C-300E26  Slide up 6 at the
                beginning of the note.

:M_E_Glissando

^E3: Set glissando on/off

 The argument yyyy to this  effect specifies whether the  glissando effect
 is ON (yyyy  is 1) or  OFF (yyyy is  0).   If glissando  is on, then  the
 'Slide to note' will  slide a half note  at a time.   Otherwise, it  will
 perform the default smooth slide.

%  Cmd E3. Glissando Ctrl [Range:$0-$1]
%  ------------------------------------
  Usage: $E3 + Glissando-Status
  Glissando must be used with the tone-
  portamento command. When glissando is
  activated, toneportamento will slide
  a halfnote at a time, instead of a
  straight slide.
  Example: C-300E31  Turn Glissando on.
           C-300E30  Turn Glissando off.


:M_E_Set VibratoWave

^E4: Set vibrato waveform

 This effect means to set the waveform appearance for succeeding 'vibrato'
 effects.  There  are currently  four possible appearances  for the  wave,
 each with a possible  'retrigger'.  Two cycles  are shown below for  each
 type of waveform:
                                              yyyy
     Waveform   Name                Retriggered  No Retrigger
     ---------- ------------------- -----------  ------------
     /\  /\     Sine (default)           0            4
       \/  \/

     |\ |\      Ramp down                1            5
       \| \|

     ,-, ,-,    Square                   2            6
       '-' '-'

     ?????????  Random                   3            7

 A "retriggered" waveform will  be reset to  the start of  a cycle at  the
 beginning of each new note.   If a wave is selected  "without retrigger",
 the  previous  waveform  will  be  continued.    Waveforms   are  usually
 retriggered.

%      Cmd E4. Set vibrato waveform
%      [Range:$0-$3]
%      ----------------------------
  Usage: $E4 + vibrato-waveform
  Example: C-300E40  Set sine(default)
                E44  Don't retrig WF
           C-300E41  Set Ramp Down
                E45  Don't retrig WF
           C-300E42  Set Squarewave
                E46  Don't retrig WF
           C-300E43  Set Random
                E47  Don't retrig WF


:M_E_Set FineTune

^E5: Set finetune value

 This effect command sets the finetune value for the current instrument to
 the signed nibble value  yyyy.  This value  overrides the value found  in
 the sample information block at the  beginning of the MOD file.   The new
 finetune remains until changed by another E5 effect.

            Value:  7  6  5  4  3  2  1  0  F  E  D  C  B  A  9  8
  Finetune to set: +7 +6 +5 +4 +3 +2 +1  0 -1 -2 -3 -4 -5 -6 -7 -8

 This effect  is implemented  by storing  period values  for all  possible
 finetunes, and simply switching to a different table of periods when this
 effect is encountered. See ~M_FineTuning~ for more information.
 ~M_PeriodTbl~ lists the period tables for finetunes for octaves 1 to 3.

%   Cmd E5. Set finetune [Range:$0-$F]
%   ----------------------------------
  Usage: $E5 + finetune-value
  Example: C-300E51  Set finetune to 1.
  Use these tables to figure out the
  finetune-value.
  Finetune: +7 +6 +5 +4 +3 +2 +1  0
     Value:  7  6  5  4  3  2  1  0
  Finetune: -1 -2 -3 -4 -5 -6 -7 -8
     Value:  F  E  D  C  B  A  9  8

:M_E_LoopPattrn

^E6: Loop pattern

 This effect  allows a  section of  a pattern  to be  'looped', or  played
 through, a certain number of times in succession.  If the effect argument
 yyyy is zero, the effect specifies the loop's start point.  Otherwise, it
 specifies the number of times to play this line and the  preceeding lines
 from the start point.   If no  start point was  specified in the  current
 pattern being played, the  loop start defaults to  the first line in  the
 pattern.  Therefore, you cannot loop through multiple patterns.

 An example:

 On line 3,  the effect E6  is encountered, with  yyyy=0.  This  specifies
 that line 3 is the beginning of a loop in this pattern.
 Down on line 52, the effect  E6 is encountered again, with yyyy=2.   This
 means to jump back and play the lines from line 3 to  line 52 again twice
 more before continuing with the rest of the pattern.

%   Cmd E6. PatternLoop [Loops:$0-$F]
%   ----------------------------------
  Usage: $E6 + number of loops
  This command will loop a part of a
  pattern.
  Example: C-300E60  Set loopstart.
           C-300E63  Jump to loop 3
            times before playing on.


:M_E_Set TremoloWave

^E7: Set tremolo waveform

 Line command  E4,  this  sets  the  waveform  appearance  for  succeeding
 'tremolo'  (volume)  effects.     There   are  currently  four   possible
 appearances for the wave, each with  a possible 'retrigger'.   Two cycles
 are shown below for each type of waveform:
                                              yyyy
     Waveform   Name                Retriggered  No Retrigger
     ---------- ------------------- -----------  ------------
     /\  /\     Sine (default)           0            4
       \/  \/

     |\ |\      Ramp down                1            5
       \| \|

     ,-, ,-,    Square                   2            6
       '-' '-'

     ?????????  Random                   3            7

 A "retriggered" waveform will  be reset to  the start of  a cycle at  the
 beginning of each new note.   If a wave is selected  "without retrigger",
 the  previous  waveform  will  be  continued.    Waveforms   are  usually
 retriggered.

%      Cmd E7. Set tremolo waveform
%      [Range:$0-$3]
%      ----------------------------
  Usage: $E7 + tremolo-waveform
  Example: C-300E70  Set sine(default)
                E74  Don't retrig WF
           C-300E71  Set Ramp Down
                E75  Don't retrig WF
           C-300E72  Set Squarewave
                E76  Don't retrig WF
           C-300E73  Set Random
                E77  Don't retrig WF

:M_E_Retrig Note

^E9: Retrigger sample

 Effect E9 allows  you to re-trigger  a specified  sample at a  particular
 note after yyyy  ticks during the  line.   For example,  say note C-3  is
 specified, with yyyy=2 when  the speed is currently  6.  This would  mean
 that at the beginning  of the line the  specified sample is started,  and
 after two ticks it is restarted.   This continues until the  beginning of
 the next line.  This effect is used mostly with samples of hi-hats.

%    Cmd E9. Retrig note [Value:$0-$F]
%    ---------------------------------
  Usage: $E9 + Tick to Retrig note at.
  This command will retrig the same note
  before playing the next. Where to
  retrig depends on the speed of the
  song. If you retrig with 1 in speed 6
  that note will be trigged 6 times in
  one note slot. Retrig on hi-hats!
  Example: C-300F06  Set speed to 6.
           C-300E93  Retrig at tick 3
                     out of 6.


:M_E_FineVolSlide Up

^EA: Fine volume slide up

 This effect increments  the volume of  a particular  channel once at  the
 beginning of the line  by yyyy points.   There is no continuation  of the
 slide on successive  lines or for  other notes.   You cannot slide  above
 volume 64.

%   Cmd EA. FineVolsl up [Range:$0-$F]
%   ----------------------------------
  Usage: $EA + value
  This command works just like the
  normal volumeslide up, except that
  it only slides up once. It does not
  continue sliding during the length of
  the note.
  Example: C-300EA3  Slide volume up 1
         at the beginning of the note.


:M_E_FineVolSlide Dn

^EB: Fine volume slide down

 This effect is  just like  effect ~M_E_FineVolSlide Up~,  except the
 volume is  decremented rather than incremented by the value  yyyy.  There
 is no  continuation of the slide on successive lines or for other notes.
 You cannot slide below volume 0.

%  Cmd EB. FineVolsl down [Range:$0-$F]
%  ------------------------------------
  Usage: $EB + value
  This command works just like the
  normal volumeslide down, except that
  it only slides down once. It does not
  continue sliding during the length of
  the note.
  Example: C-300EB6  Slide volume down
        6 at the beginning of the note.


:M_E_NoteCut

^EC: Cut sample

 This effect sets the  volume of the  sample which is  playing to 0  after
 yyyy ticks in the current line.  This has the effect of stopping a sample
 abruptly.  An example here  is to play the  note C-2, with effect  EC and
 argument yyyy=3, when the speed is 6.  The sample is started  at note C-2
 at the beginning of the line, and after the third tick of 6 in that line,
 the volume on the  channel is set to  0 (cutting it off).   Note that  if
 yyyy is 0, nothing will be heard.

%     Cmd EC. Cut note [Value:$0-$F]
%     ------------------------------
  Usage: $EC + Tick to Cut note at.
  This command will cut the note
  at the selected tick, creating
  extremely short notes.
  Example: C-300F06  Set speed to 6.
           C-300EC3  Cut at tick 3 out
                     of 6.
  Note that the note is not really cut,
  the volume is just turned down.


:M_E_NoteDelay

^ED: Delay sample

 This effect delays the start of  a sample until tick yyyy in  the current
 line.  For example,  if note C-2 is  played, with effect ED  and argument
 yyyy=3 when the speed is 6.   The note C-2  will be triggered at  the 3rd
 tick after the start of the line.  The purpose of this effect is to delay
 the start of a sample for a VERY short amount of time.

%     Cmd ED. NoteDelay [Value:$0-$F]
%     -------------------------------
  Usage: $ED + ticks to delay note.
  This command will delay the note
  to the selected tick.
  Example: C-300F06  Set speed to 6.
           C-300ED3  Play note at tick
                     3 out of 6.


:M_E_PatternDelay

^EE: Delay pattern

 This effect  forces a  small delay  in a  pattern  in between  successive
 lines.  All notes and effects  continue during this delay.   The argument
 yyyy specified the number of  line-equivalent time slices to  wait before
 resuming playback.  For example, if  effect EE is encountered  with speed
 being 6 and argument yyyy=4, then the next line will be delayed  24 ticks
 before it is executed.

%   Cmd EE. PatternDelay [Notes:$0-$F]
%   ----------------------------------
  Usage: $EE + notes to delay pattern.
  This command will delay the pattern
  the selected numbers of notes.
  Example: C-300EE8  Delay pattern 8
            notes before playing on.
  All other effects are still active
  when the pattern is being delayed.


:M_E_Invert Loop

^EF: Invert loop

 This effect is used on the Amiga to play samples backward at  a specified
 speed.  It is not really  feasible to implement on  other architechtures,
 and it is not used that often.

%    Cmd EF. Invert Loop [Speed:$0-$F]
%    ---------------------------------
  Usage: $EF + Invertspeed
  This command will need a short loop
  ($10,20,40,80 etc. bytes) to work.
  It will invert the loop byte by byte.
  Sounds better than funkrepeat...
  Example: C-300EF8 Set invspeed to 8.
  To turn off the inverting, set
  invspeed to 0, or press ctrl + Z.


:M_SetSpeed

^F: Set speed

 This effect changes the  speed of playback so  that xxxxyyyy ticks  occur
 during every line, starting on the NEXT line.  The initial  speed (before
 any 'set speed' effects are encountered) should be set to 6.   A value of
 xxxxyyyy=0 should technically cause playback  to stop, but this  value is
 commonly ignored as garbage.

 Valid values for speed setting in this manner are 1 to 31.  If a value is
 read that is above 31,  it means to set  a modified speed based  on beats
 per minute, where 4 lines are  1 beat.  This means  that if I try  to set
 the speed to 42, I am  specifying 42 beats per minute, or  42*4=168 lines
 per minute.    You then  have  to  figure out  how  long  to spend  on  a
 particular line.

 If multiple set speed  effects are performed on  a single line, then  the
 effects on the higher-numbered channels have precedence over  the effects
 on the lower-numbered channels.

 This effect has the largest  number of implementations and  is particular
 to the number of effects that a particular file player supports.

%    Cmd F. Set speed [Speed:$00-$FF]
%    --------------------------------
  Usage: $F + speed
  This command will set the speed of the
  song.


:M_OtherInfo

^Other information about the Effects

 If you're  sound  device  is able  to  provide  stereo output  (like  the
 UltraSound), then you  need to  know what  the balance  for each  channel
 should be.  Channels 1 and 4 are left, and 2 and 3 are right.

 If you are programming  for the UltraSound, it  is best not to  shove the
 balances all the way over to the left or to the right.  Try  a value of 2
 for channels 1 and  4 and a value  of 13 for  channels 2 and  3.  If  you
 don't like it - change it.

:M_PeriodTbl

^Period tables

 Here are the period tables for the different fine-tune values:

 856,808,762,720,678,640,604,570,538,508,480,453 : C-1 to B-1 Finetune 0
 428,404,381,360,339,320,302,285,269,254,240,226 : C-2 to B-2 Finetune 0
 214,202,190,180,170,160,151,143,135,127,120,113 : C-3 to B-3 Finetune 0

 850,802,757,715,674,637,601,567,535,505,477,450 : C-1 to B-1 Finetune +1
 425,401,379,357,337,318,300,284,268,253,239,225 : C-2 to B-2 Finetune +1
 213,201,189,179,169,159,150,142,134,126,119,113 : C-3 to B-3 Finetune +1

 844,796,752,709,670,632,597,563,532,502,474,447 : C-1 to B-1 Finetune +2
 422,398,376,355,335,316,298,282,266,251,237,224 : C-2 to B-2 Finetune +2
 211,199,188,177,167,158,149,141,133,125,118,112 : C-3 to B-3 Finetune +2

 838,791,746,704,665,628,592,559,528,498,470,444 : C-1 to B-1 Finetune +3
 419,395,373,352,332,314,296,280,264,249,235,222 : C-2 to B-2 Finetune +3
 209,198,187,176,166,157,148,140,132,125,118,111 : C-3 to B-3 Finetune +3

 832,785,741,699,660,623,588,555,524,495,467,441 : C-1 to B-1 Finetune +4
 416,392,370,350,330,312,294,278,262,247,233,220 : C-2 to B-2 Finetune +4
 208,196,185,175,165,156,147,139,131,124,117,110 : C-3 to B-3 Finetune +4

 826,779,736,694,655,619,584,551,520,491,463,437 : C-1 to B-1 Finetune +5
 413,390,368,347,328,309,292,276,260,245,232,219 : C-2 to B-2 Finetune +5
 206,195,184,174,164,155,146,138,130,123,116,109 : C-3 to B-3 Finetune +5

 820,774,730,689,651,614,580,547,516,487,460,434 : C-1 to B-1 Finetune +6
 410,387,365,345,325,307,290,274,258,244,230,217 : C-2 to B-2 Finetune +6
 205,193,183,172,163,154,145,137,129,122,115,109 : C-3 to B-3 Finetune +6

 814,768,725,684,646,610,575,543,513,484,457,431 : C-1 to B-1 Finetune +7
 407,384,363,342,323,305,288,272,256,242,228,216 : C-2 to B-2 Finetune +7
 204,192,181,171,161,152,144,136,128,121,114,108 : C-3 to B-3 Finetune +7

 907,856,808,762,720,678,640,604,570,538,504,480 : C-1 to B-1 Finetune -8
 453,428,404,381,360,339,320,302,285,269,254,240 : C-2 to B-2 Finetune -8
 226,214,202,190,180,170,160,151,143,135,127,120 : C-3 to B-3 Finetune -8

 900,850,802,757,715,675,636,601,567,535,505,477 : C-1 to B-1 Finetune -7
 450,425,401,379,357,337,318,300,284,268,253,238 : C-2 to B-2 Finetune -7
 225,212,200,189,179,169,159,150,142,134,126,119 : C-3 to B-3 Finetune -7

 894,844,796,752,709,670,632,597,563,532,502,474 : C-1 to B-1 Finetune -6
 447,422,398,376,355,335,316,298,282,266,251,237 : C-2 to B-2 Finetune -6
 223,211,199,188,177,167,158,149,141,133,125,118 : C-3 to B-3 Finetune -6

 887,838,791,746,704,665,628,592,559,528,498,470 : C-1 to B-1 Finetune -5
 444,419,395,373,352,332,314,296,280,264,249,235 : C-2 to B-2 Finetune -5
 222,209,198,187,176,166,157,148,140,132,125,118 : C-3 to B-3 Finetune -5

 881,832,785,741,699,660,623,588,555,524,494,467 : C-1 to B-1 Finetune -4
 441,416,392,370,350,330,312,294,278,262,247,233 : C-2 to B-2 Finetune -4
 220,208,196,185,175,165,156,147,139,131,123,117 : C-3 to B-3 Finetune -4

 875,826,779,736,694,655,619,584,551,520,491,463 : C-1 to B-1 Finetune -3
 437,413,390,368,347,338,309,292,276,260,245,232 : C-2 to B-2 Finetune -3
 219,206,195,184,174,164,155,146,138,130,123,116 : C-3 to B-3 Finetune -3

 868,820,774,730,689,651,614,580,547,516,487,460 : C-1 to B-1 Finetune -2
 434,410,387,365,345,325,307,290,274,258,244,230 : C-2 to B-2 Finetune -2
 217,205,193,183,172,163,154,145,137,129,122,115 : C-3 to B-3 Finetune -2

 862,814,768,725,684,646,610,575,543,513,484,457 : C-1 to B-1 Finetune -1
 431,407,384,363,342,323,305,288,272,256,242,228 : C-2 to B-2 Finetune -1
 216,203,192,181,171,161,152,144,136,128,121,114 : C-3 to B-3 Finetune -1

:M_GusVol Table

^Volume table for GUS

 The Amiga uses linear volumes from  0 to 64.  The volume  table specified
 below lists the logarithmic volume to  use on the UltraSound for  each of
 the 65 settings in order to get a linear spread.  If you need volumes for
 another sound device, you will have to find them elsewhere.

    0 |    0
    1 | 1750      17 | 2332      33 | 3469      49 | 3528
    2 | 2503      18 | 3240      34 | 3473      50 | 3532
    3 | 2701      19 | 3248      35 | 3478      51 | 3534
    4 | 2741      20 | 3256      36 | 3481      52 | 3538
    5 | 2781      21 | 3263      37 | 3484      53 | 3543
    6 | 2944      22 | 3271      38 | 3489      54 | 3545
    7 | 2964      23 | 3279      39 | 3492      55 | 3549
    8 | 2981      24 | 3287      40 | 3495      56 | 3552
    9 | 3000      25 | 3294      41 | 3499      57 | 3556
   10 | 3017      26 | 3303      42 | 3502      58 | 3558
   11 | 3034      27 | 3310      43 | 3506      59 | 3563
   12 | 3052      28 | 3317      44 | 3509      60 | 3565
   13 | 3070      29 | 3325      45 | 3513      61 | 3570
   14 | 3207      30 | 3458      46 | 3517      62 | 3573
   15 | 3215      31 | 3462      47 | 3520      63 | 3577
   16 | 3224      32 | 3466      48 | 3524      64 | 3580

:M_ProFileFormat

^Protracker 1.1B Song/Module Format
^by Lars "ZAP" Hamre/Amiga Freelancers

%Offset  Bytes  Description
    0     20    Songname. Remember to put trailing null bytes at the end...

%Information for sample 1-31:

%Offset  Bytes  Description
   20     22    Samplename for sample 1. Pad with null bytes.
   42      2    Samplelength for sample 1. Stored as number of words.
                Multiply by two to get real sample length in bytes.
   44      1    Lower four bits are the finetune value, stored as a signed
                four bit number. The upper four bits are not used, and
                should be set to zero.

%               Value   Finetune    Value   Finetune    Value   Finetune
                  0        0          5       +5          A       -6
                  1       +1          6       +6          B       -5
                  2       +2          7       +7          C       -4
                  3       +3          8       -8          D       -3
                  4       +4          9       -7          E       -2
                                                          F       -1

   45      1    Volume for sample 1. Range is $00-$40, or 0-64 decimal.
   46      2    Repeat point for sample 1. Stored as number of words offset
                from start of sample. Multiply by two to get offset in bytes.
   48      2    Repeat Length for sample 1. Stored as number of words in
                loop. Multiply by two to get replen in bytes.

 Information for the next 30 samples starts here. It's just like the info for
 sample 1.

%Offset  Bytes  Description
   50     30    Sample 2...
   80     30    Sample 3...
    .
    .
    .
  890     30    Sample 30...
  920     30    Sample 31...

%Offset  Bytes  Description
  950      1    Songlength. Range is 1-128.
  951      1    Well... this little byte here is set to 127, so that old
                trackers will search through all patterns when loading.
                Noisetracker uses this byte for restart, but we don't.
  952    128    Song positions 0-127. Each hold a number from 0-63 that
                tells the tracker what pattern to play at that position.
 1080      4    The four letters "M.K." - This is something Mahoney & Kaktus
                inserted when they increased the number of samples from
                15 to 31. If it's not there, the module/song uses 15 samples
                or the text has been removed to make the module harder to
                rip. Startrekker puts "FLT4" or "FLT8" there instead.

%Offset  Bytes  Description
 1084    1024   Data for pattern 00.
    .
    .
    .
 xxxx  Number of patterns stored is equal to the highest patternnumber
       in the song position table (at offset 952-1079).

 Each note is stored as 4 bytes, and all four notes at each position in
 the pattern are stored after each other.

 00 -  chan1  chan2  chan3  chan4
 01 -  chan1  chan2  chan3  chan4
 02 -  chan1  chan2  chan3  chan4
 etc.

 Info for each note:

  _____byte 1_____   byte2_    _____byte 3_____   byte4_
 /                 /        /                 /
 0000          0000-00000000  0000          0000-00000000

 Upper four    12 bits for    Lower four    Effect command.
 bits of sam-  note period.   bits of sam-
 ple number.                  ple number.

%Periodtable for Tuning 0, Normal
   C-1 to B-1 : 856,808,762,720,678,640,604,570,538,508,480,453
   C-2 to B-2 : 428,404,381,360,339,320,302,285,269,254,240,226
   C-3 to B-3 : 214,202,190,180,170,160,151,143,135,127,120,113

 To determine what note to show, scan through the table until you find
 the same period as the one stored in byte 1-2. Use the index to look
 up in a notenames table.

 This is the data stored in a normal song. A packed song starts with the
 four letters "PACK", but i don't know how the song is packed: You can
 get the source code for the cruncher/decruncher from us if you need it,
 but I don't understand it; I've just ripped it from another tracker...

 In a module, all the samples are stored right after the patterndata.
 To determine where a sample starts and stops, you use the sampleinfo
 structures in the beginning of the file (from offset 20). Take a look
 at the mt_init routine in the playroutine, and you'll see just how it
 is done.

:M_ULT File Format

^Mysterious's ULTRA TRACKER File Format
^by FreeJack of The Elven Nation

 I've done my best to document the file format of Ultra Tracker (UT). If you
 find any errors please contact me. The file format has stayed consistent
 through the first four public releases. At the time of this writting,
 UltraTracker is up to version 1.3

 Thanks go to :
 SoJa of YLYSY for help translating stuff.

 Marc Andre Schallehn
 Thanks for putting out this GREAT program.
 Also thanks for the info on 16bit samples.

 With all this crap out of the way lets get to the format.


%Sample Structure :
 ______________________________________________________________________________
 Samplename : 32 bytes (Sample name)
 DosName    : 12 bytes (when you load a sample into UT,
                       it records the file name here)
 LoopStart  : dbl word (loop start point)
 LoopEnd    : dbl word (loop end point)
 SizeStart  : dbl word (see below)
 SizeEnd    : dbl word (see below)
 volume     : byte (UT uses a logarithmic volume setting, ranging from 0-255)
 Bidi Loop  : byte (see below)
 FineTune   : word (Fine tune setting, uses full word value)
 ______________________________________________________________________________

^8 Bit Samples

%SizeStart  :
 The SizeStart is the starting offset of the sample.
 This seems to tell UT how to load the sample into the Gus's onboard memory.
 All the files I have worked with start with a value of 32 for the first sample,
 and the previous SizeEnd value for all sample after that. (See Example below)
 If the previous sample was 16bit, then SizeStart = (Last SizeEnd * 2)
 SizeEnd :
 Like the SizeStart, SizeEnd seems to tell UT where to load the sample into the
 Gus's onboard memory. SizeEnd equal SizeStart + the length of the sample.

%Example :
 If a UT file had 3 samples, 1st 12000 bytes, 2nd 5600  bytes, 3rd 8000 byte.
 The SizeStart and SizeEnd would look like this:

%Sample        SizeStart         SizeEnd
 1st            32                12032
 2nd            12032             17632
 3rd            17632             25632

%***Note***
 Samples may NOT cross 256k boundaries. If a sample is too large to fit
 into the remaining space, its Sizestart will equal the start of the next
 256k boundary. UT does keep track of the free space at the top of the 256k
 boundaries, and will load a sample in there if it will fit. Example :
 EndSize = 252144 If the next sample was 12000 bytes, its SizeStart would
 be 262144, not 252144. Note that this leaves 10000 bytes unused. If any of
 the following sample could fit between 252144 and 262144, its Sizestart
 would be 252144. Say that 2 samples after the 12000 byte sample we had a
 sample that was only 5000 bytes long. Its SizeStart would be 252144 and
 its SizeEnd would be 257144. This also applies to 16 Bit Samples.

^16 Bit Samples

 16 bit samples are handled a little different then 8 bit samples.
 The SizeStart variable is calculated by dividing offset (last SizeEnd)
 by 2. The SizeEnd variable equals SizeStart + (SampleLength / 2).
 If the first sample is 16bit, then SizeStart = 16.

%Example :
           sample1 = 8bit, 1000 bytes
           sample2 = 16bit, 5000 bytes

           sample1 SizeStart = 32
                   SizeEnd   = 1032 (32 + 1000)

           sample2 SizeStart = 516 (offset (1032) / 2)
                   SizeEnd   = 3016 (516 + (5000/2))

%***Note***
 If a 16bit sample is loaded into banks 2,3, or 4
 the SizeStart variable will be
 (offset / 2) + 262144 (bank 2)
 (offset / 2) + 524288 (bank 3)
 (offset / 2) + 786432 (bank 4)
 The SizeEnd variable will be
 SizeStart + (SampleLength / 2) + 262144 (bank 2)
 SizeStart + (SampleLength / 2) + 524288 (bank 3)
 SizeStart + (SampleLength / 2) + 786432 (bank 4)

%BiDi Loop : (Bidirectional Loop)
 UT takes advantage of the Gus's ability to loop a sample in several different
 ways. By setting the Bidi Loop, the sample can be played forward or backwards,
 looped or not looped. The Bidi variable also tracks the sample
 resolution (8 or 16 bit).

%The following table shows the possible values of the Bidi Loop.
 Bidi = 0  : No looping, forward playback,  8bit sample
 Bidi = 4  : No Looping, forward playback, 16bit sample
 Bidi = 8  : Loop Sample, forward playback, 8bit sample
 Bidi = 12 : Loop Sample, forward playback, 16bit sample
 Bidi = 24 : Loop Sample, reverse playback 8bit sample
 Bidi = 28 : Loop Sample, reverse playback, 16bit sample

%Event Structure
 ------------------------------------------------------------------------------
 Note                : byte (See note table below)
 SampleNumber        : byte (Sample Number)
 Effect1             : nib (Effect1)
 Effect2             : nib (Effect2)
 EffectVar           : word (Effect variables)

 The High order byte of EffectVar is the Effect variable for Effect1.
 The Low order byte of EffectVar is the Effect variable for Effect2.

%***(Note)***
 UT uses a form of compression on repetitive events. Say we read in the first
 byte, if it = $FC then this signifies a repeat block. The next byte is the
 repeat count. followed by the event structure to repeat.
 If the first byte read does NOT = $FC then this is the note of the event.
 So repeat blocks will be 7 bytes long : RepFlag      : byte ($FC)
                                         RepCount     : byte
                                         note         : byte
                                         samplenumber : byte
                                         effect1      : nib
                                         effect2      : nib
                                         effectVar    : word

 Repeat blocks do NOT bridge patterns.

%Note Table:
 ______________________________________________________________________________
 note value of 0 = pause
 C-0 to B-0    1 to 12
 C-1 to B-1    13 to 24
 C-2 to B-2    26 to 36
 C-3 to B-3    39 to 48
 C-4 to B-4    52 to 60

%Offset     Bytes            Type                   Description
 ------------------------------------------------------------------------------
 0             15            byte           ID block : should contain
                                                       'MAS_UTrack_V001'

 15            32            AsciiZ         Song Title
 47            1             reserved       This byte is reserved and
                                            always contain 0;

 48            1             byte           Number of Samples (NOS)
 49            NOS * 64      SampleStruct   Sample Struct (see Sample Structure)

 Patt_Seq = 48 + (NOS * 64)

 Patt_Seq          256       byte            Pattern Sequence
 Patt_Seq+256      1         byte            Number Of Channels (NOC) Base 0
 Patt_Seq+257      1         byte            Number Of patterns (NOP) Base 0
 Patt_Seq+258      varies    EventStruct     Pattern Data (See Event Structure)

 The remainder of the file is the raw sample data.

 That should about cover it. If you have any questions , feel free to
 e-mail me at freejack@shell.portal.com

 I can also be contacted on The UltraSound Connection   (813) 787-8644 The
 UltraSound Connection is a BBS dedicated to the Gravis Ultrasound Card.

 Also I'm the author of Ripper and Gvoc. If anyone has any questions or
 problems, please contact me.


:M_S3M File Format:M_STM File Format

^Scream Tracker 3.0 file formats
 
^Song/Module header

%         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
        Ŀ
  0000:  Song name, max 28 chars (incl. NUL)                           
        Ĵ
  0010:                                                1AhTyp x  x 
        Ĵ
  0020: OrdNum InsNum PatNum  Flags  Cwt/v   Ffv  'S''C''R''M'
        Ĵ
  0030: m.vi.si.tm.m x  x  x  x  x  x  x  x  x  x  x  x 
        Ĵ
  0040: Channel settings for 32 channels, 255=unused,+128=disabled     
        Ĵ
  0050:                                                                
        Ĵ
  0060: Orders; length=OrdNum (must be even)                           
        Ĵ
  xxxx: Parapointers to instruments; length=InsNum*2                   
        Ĵ
  xxxx: Parapointers to patterns; length=PatNum*2                      
        

 
        Typ     = File type: 16=module,17=song
        Ordnum  = Number of orders in file
        Insnum  = Number of instruments in file
        Patnum  = Number of patterns in file
        Cwt/v   = Created with tracker / version: &0xfff=version, >>12=tracker
                        ST30:0x1300
        Ffv     = File format version;
                        1=original
                        2=original BUT samples unsigned
        Parapointers are OFFSET/16 relative to the beginning of the header.
 
%       PLAYING AFFECTORS / INITIALIZERS:
        Flags   =  +1:st2vibrato 
                   +2:st2tempo
                   +4:amigaslides
                   +8:0vol optimizations
                   +16:amiga limits
                   +32:enable filter/sfx
        m.v     = master volume
        m.m     = master multiplier (&15) + stereo(=+16)
        i.s     = initial speed (command A)
        i.t     = initial tempo (command T)
 
%       Channel types:
        &128=on, &127=type: (127=unused)
        8  - L-Adlib-Melody 1 (A1)      0  - L-Sample 1 (S1)
        9  - L-Adlib-Melody 2 (A2)      1  - L-Sample 2 (S2)
        10 - L-Adlib-Melody 3 (A3)      2  - L-Sample 3 (S3)
        11 - L-Adlib-Melody 4 (A4)      3  - L-Sample 4 (S4)
        12 - L-Adlib-Melody 5 (A5)      4  - R-Sample 5 (S5)
        13 - L-Adlib-Melody 6 (A6)      5  - R-Sample 6 (S6)
        14 - L-Adlib-Melody 7 (A7)      6  - R-Sample 7 (S7)
        15 - L-Adlib-Melody 8 (A8)      7  - R-Sample 8 (S8)
        16 - L-Adlib-Melody 9 (A9)
                                        26 - L-Adlib-Bassdrum (AB)
        17 - R-Adlib-Melody 1 (B1)      27 - L-Adlib-Snare    (AS)
        18 - R-Adlib-Melody 2 (B2)      28 - L-Adlib-Tom      (AT)
        19 - R-Adlib-Melody 3 (B3)      29 - L-Adlib-Cymbal   (AC)
        20 - R-Adlib-Melody 4 (B4)      30 - L-Adlib-Hihat    (AH)
        21 - R-Adlib-Melody 5 (B5)      31 - R-Adlib-Bassdrum (BB)
        22 - R-Adlib-Melody 6 (B6)      32 - R-Adlib-Snare    (BS)
        23 - R-Adlib-Melody 7 (B7)      33 - R-Adlib-Tom      (BT)
        24 - R-Adlib-Melody 8 (B8)      34 - R-Adlib-Cymbal   (BC)
        25 - R-Adlib-Melody 9 (B9)      35 - R-Adlib-Hihat    (BH)
        
                
^Digiplayer/ST3.0 samplefileformat

%         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
        Ŀ
  0000: [T] Dos filename (12345678.ABC)                       MemSeg 
        Ĵ
  0010: Length HI:lengLoopBegHI:LBegLoopEndHI:LendVolDsk[P][F]
        Ĵ
  0020: C2Spd  HI:C2sp x  x  x  x GVSPOS Int:512Int:lastused   
        Ĵ
  0030:  Sample name, 28 characters max... (incl. NUL)                 
        Ĵ
  0040:  ...sample name...                             'S''C''R''S'
        
  xxxx:	sampledata

%       NOTES:
        Inside module, MemSeg tells the paragraph position of
        the actual sampledata (offset/16). In separate insfile the same,
        in memory segment of data relative to beginning of module.
        GVSPOS=Position in gravis memory /32 (used inside player only)
        [T]ype, 1=Sample
        [F]lags, +1=loop on
                 +2=stereo (after Length bytes for LEFT channel,
                          another Length bytes for RIGHT channel)
                 +4=16-bit samples (intel LO-HI byteorder)
        { [P]ack, 0=8 bit normal (1=DP30ADPCM1 for holland project) }
 
^ST3.0 adlib instrument format

%         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
        Ŀ
  0000: [T] Dos filename (12345678.123)                   00h00h00h
        Ĵ
  0010: D00D01D02D03D04D05D06D07D08D09D0AD0BVolDsk x  x 
        Ĵ
  0020: C2Spd  HI:C2sp x  x  x  x  x  x  x  x  x  x  x  x 
        Ĵ
  0030:  Sample name, 28 characters max... (incl. NUL)                 
        Ĵ
  0040:  ...sample name...                             'S''C''R''I'
        

%       NOTES:
        [T]ype, 2..7=amel,abd,asnare,atom,acym,ahihat
        modulator:                                              carrier:
        D00=[freq.muliplier]+[?scale env.]*16+[?sustain]*32+
                [?pitch vib]*64+[?vol.vib]*128                  =D01
        D02=[63-volume]+[levelscale&1]*128+[l.s.&2]*64          =D03
        D04=[Attack]*16+[decay]                                 =D05
        D06=[15-sustain]*16+[release]                           =D07
        D08=[wave select]                                       =D09
        D0A=[modulation feedback]*2+[?additive synthesis]
        D0B=unused
 
 
^Unpacked Internal memoryformat for patterns
 
%REMARK
  each channel takes 320 bytes, rows for each channel are sequential.

% byte:
   0 - Note; hi=oct, lo=note, 255=empty note,254=key off (used with adlib)
   1 - Instrument ;255=..
   2 - Volume ;255=..
   3 - Special command ;255=..
   4 - Command info


^Packed Internal memoryformat for patterns

 Pattern length fixed for 64 rows.

 BYTE: flag, 0=end of row
           &31=channel
           &32=follows;  BYTE:note, BYTE:instrument
           &64=follows;  BYTE:volume
          &128=follows;  BYTE:command, BYTE:info

%NOTES on [memseg].
 In memory, the memseg's highest byte (3) is always zero
 (thus also the ASCIIZ terminator). For the actual 16 bit
 memseg the following storage method is used:
 0..EFFF = Segment to memory
 F000... = EMS page ####-F000

^STM File Format

 Song/Module file structure:

%        Offset: Info:
         0       Song/File name, max 20 chars, ASCIIZ, except if 20 chars long
         20      Tracker name, max 8 chars, NO NUL
         28      0x1A
         29      File type: 1=song, 2=module
         30      Version major (eg. 2)
         31      Version minor (eg. 2)
         32      byte; tempo
         33      byte; num of patterns saved
         34      byte; global volume
         36      reserved, 13 bytes

         48      Instruments (31 kpl) (see below) Instrument structure:
%                Offset  Info
                 0       Inst. Filename, 12 bytes max, ASCIIZ
                 12      0x00
                 13      byte; instrument disk
                 14      word; reserved (used as internal segment while playing)
                 16      word; length in bytes
                 18      word; loop start
                 20      word; loop end
                 22      byte; volume
                 23      byte; reserved
                 24      word; speed for mid-C (in Hz)
                 26      reserved, 4 bytes
                 30      word; internal segment address/(in modules:)length in paragraphs

         XXXX    Music pattern orders (64 bytes/orders)

         XXXX    Patterns (number in header, each pattern 1KB)
                 Patterns consist of 64 rows, each 4 channels. Each channel
                 is 4 bytes in length, and the channels are stored from left
                 to right, row by row.
%                Special [BYTE0] contents:
                          251=last 3 bytes NOT in file, all bytes 0
                          252=last 3 bytes NOT in file, note: -0-
                          253=last 3 bytes NOT in file, note: ...
                          254=(in memory), -0-
                          255=(in memory), ...
%                otherwise:
                         note=[BYTE0] and 15 (C=0,C#=1,D=2...)
                         octave=[BYTE0] / 16
                         instrument=[BYTE1]/8
                         volume=([BYTE1] and 7)+[BYTE2]/2
                         command=[BYTE2] and 15
                         command info=[BYTE3]

         [XXXX]  In modules: Samples, padded to 16 byte limits. Sample lengths
                 in paragraphs (and as saved) are storen in instruments
                 internal segment address.

