Using An AdLib-Compatible Sound Card's FM Chip:

The FM chip's register port is BaseAddress + 8. The chip's data port is
BaseAddress + 9. So, for example, if your sound card's base address is 220h
(as most sound cards are set by default to be), your FM chip's register port
is 228h and the data port is 229h. Wasn't that easy! (The AdLib card's base
address was 380h, and so most Sound Blaster cards will also work with
addresses 388h and 389h for backward compatibility.)

To set a register on the chip, all you have to do is first send the value of
the register you want to set to the register port; Then you send the new
value for that register to the data port. It's that simple. For example, if
you want to set register 20 to equal 15, then you'd send 20h to port 388h,
and then 15h to port 389h.

There are 224 registers on the basic Sound Blaster (or compatible) card's FM
chip. If you memorize all of them and their functions, you are a very boring
person. The most important registers the actual note registers, where the
actual notes are sent. Because the notes are 10 bits, and the registers are
only 8 bits wide, two registers are required for each. Registers A0h (for
channel 1) to A8h (for channel 9) hold the 8 least significant bits (LSBs),
while the last two bits of registers B0h (for channel 1) to B8h (for channel
9) hold the two most significant bits (MSBs) for the notes. The next 3 bits
of those registers (B0 to B8) hold the octave number, the next bit is a
switch (when set to 1, the channel is on; when set to 0, the channel is off),
and the final two bits are unused. In theory, you can play a monotone melody
by simply sending values to registers A0 and B0; In practice, unfortunately,
some preparation must be done before you can start playing notes. This
preparation involves arcane concepts like "carriers" and "modulators", which
are the very basis for FM synthesis.

If you've done much work with MIDI using Windows programs, you've probably
gotten used to the concept of having big lists of instruments which you can
choose from and make individual notes out of. Well, FM synthesis doesn't use
instruments; The concept of picking an instrument from a list is only
possible with wave-table synthesis, in which a ROM chip on the sound card
simply holds a bunch of instrument sounds and you can pick from them. FM
synthesis uses sine waves to create an approximation of an instrument's
sound, and it doesn't come with pre-defined instruments built into the
hardware; You have to make your own instrument sounds using the sine waves.

Below are listed the primary registers for the FM chip. Registers are shown
in the following format:
Channel: Carrier register/Modulator register
For example, if you want the key scaling level/output level registers for
channel 4, the carrier register for that channel is 48h, and the modulator
register is 4Bh. (All register numbers are given in hexadecimal.)

Amplitude modulation/Vibrato/EG type/Key scaling/Octave shift registers:
1: 20/23
2: 21/24
3: 22/25
4: 28/2B
5: 29/2C
6: 2A/2D
7: 30/33
8: 31/34
9: 32/35
Key scaling level/Output level registers:
1: 40/43
2: 41/44
3: 42/45
4: 48/4B
5: 49/4C
6: 4A/4D
7: 50/53
8: 51/54
9: 52/55
Attack rate/Decay rate registers:
1: 60/63
2: 61/64
3: 62/65
4: 68/6B
5: 69/6C
6: 6A/6D
7: 70/73
8: 71/74
9: 72/75
Sustain level/Release time registers:
1: 80/83
2: 81/84
3: 82/85
4: 88/8B
5: 89/8C
6: 8A/8D
7: 90/93
8: 91/94
9: 92/95

And now for the formats of all those registers. (All registers are 8 bits in
size):

Amplitude modulation/Vibrato/EG type/Key scaling/Octave shift register format:
First bit: If on, amplitude modulation (AM) is enabled.
Second bit: If on, vibratio is enabled.
Third bit: EG type. (?)
Fourth bit: Key scaling. (?)
Last four bits: Octave. If set to 1, the note is played at the specified
  octave. If set to 0, the note is played one octave below. If set to 2, the
  note is played one octave above.

Key scaling level/Output level register format:
First two bits: Scaling level.
Last six bits: Output level. How loud the note is.

Attack rate/Decay rate register format:
First four bits: Attack rate. (First stage in an FM note.)
Last four bits: Decay rate. (Second stage in an FM note.)

Sustain level/Release time register format:
First four bits: Sustain level. (Third stage in an FM note.)
Last four bits: Release time. (Fourth and last stage in an FM note.)

Actual note values for all musical notes are as follows:

C# (Db): 16Bh (0101101011)
D: 181h (0110000001)
D# (Eb): 198h (0110011000)
E: 1B0h (0110110000)
F: 1CAh (0111001010)
F# (Gb): 1E5h (0111100101)
G: 202h (1000000010)
G# (Ab): 220h (1000100000)
A: 241h (1001000001)
A# (Bb): 263h (1001100011)
B: 287h (1010000111)
C: 2AEh (1010101110)

Remember, the notes are 10 bits, but the registers are only 8 bits, so the
first 2 bits of the note make the last 2 bits of the B register (B0 to B8,
depending on what channel the note is for), and the last 8 bits of the note
go to the A register (A0 to A8).

Once again, the format for the B register is:

First two bits: Unused.
Third bit: Switch (turns channel on or off).
Fourth to sixth bits: Octave.
Last two bits: First two bits of note.

Thus, when calculating what value to send to the B register to make a note,
you must add 20h (100000) (to turn on the channel), plus the octave number
times 4 (this will correctly set the octave), plus the actual first two bits
of the note. So the formula for the value to send to the B register is:

20h + (octave * 4) + the first two bit values

Why do we multiply the octave by 4? Because it perfectly sets the octave bits
to the way we need them. Suppose that we wanted to set the octave to 2. 2 * 4
is 8, or 1000 in binary. If we set the B register to 8, then the octave bits
form 010, which is 8 in binary. Another example: If we want to make the
octave 5, we multiply 5 * 4, which is 20, or 10100 in binary, making the
octave bits 101, which is 5. See how it works?

Now for some note-sending examples. To make the note C, which has a note
value of 1010101110, and use octave 1, we would calculate:

20h + (1 * 4) + 2

(...Because 2 is 10 is binary.) This equals 26h, or 00100110. So we would
send 26h to the B register, and then the remaining 8 bits of the note
(10101110, or AEh) to the A register.

One more example: To make the note E (0110110000) and use octave 3...

20h + (3 * 4) + 1

...Which equals 2Dh, or 00101101. So we send 2Dh to the B register, and
10110000 (B0h) to the A register. Simple, isn't it?

    Source: geocities.com/siliconvalley/2072

               ( geocities.com/siliconvalley)