home *** CD-ROM | disk | FTP | other *** search
- Greetings,
-
- Here is a first run at some documentation for the optional CMS Music chips
- available for the Soundblaster 1.5 and 2.0. (Previous versions of the
- Soundblaster included these CMS chips).
-
- Please let me know if you have any problems or additions to this. If my
- network administrator will ever quit having fun in redefining our internet
- addresses, I may actually receive the mail!
-
- This document is done in the style of the document by Jeffrey S. Lee which
- documented the Adlib FM Music Chips. Hopefully, future documents will stick
- to this format.
-
- +----------------------------------------------------------------------+
- | Jerry Joplin | joplin@mcode.amdahl.com | All these worlds are yours |
- | Sunnyvale, CA | Compu$erve: 70441,2627 | except California. |
- +---------------+-------------------------+----------------------------+
-
- -------------------------------------------------------------------------------
-
- Programming the Soundblaster
- CMS Music Chips
- Version 1.0 (6 Mar 1992)
-
- Copyright (c) 1991, 1992 by Jerry Joplin
- joplin@mcode.amdahl.com
-
-
-
- Format and much of the text of this document was taken from:
-
- Programming the AdLib/Sound Blaster
- FM Music Chips
- Version 2.0 (24 Feb 1992)
-
- Copyright (c) 1991, 1992 by Jeffrey S. Lee
-
- jlee@smylex.uucp
-
-
-
-
- Warranty and Copyright Policy
-
- This document is provided on an "as-is" basis, and its author makes no
- warranty or representation, express or implied, with respect to its
- quality performance or fitness for a particular purpose. In no event
- will the author of this document be liable for direct, indirect,
- special, incidental, or consequential damages arising out of the use or
- inability to use the information contained within. Use of this document
- is at your own risk.
-
- This file may be used and copied freely so long as the applicable
- copyright notices are retained, and no modifications are made to the
- text of the document. No money shall be charged for its distribution
- beyond reasonable shipping, handling and duplication costs, nor shall
- proprietary changes be made to this document so that it cannot be
- distributed freely. This document may not be included in published
- material or commercial packages without the written consent of its
- author.
-
-
-
- Overview
-
- Two of the most popular sound cards for the IBM-PC, the AdLib and the
- Sound Blaster, suffer from a real dearth of clear documentation for
- programmers. AdLib Inc. and Creative Labs, Inc. both sell developers'
- kits for their sound cards, but these are expensive, and (in the case of
- the Sound Blaster developers' kit) can be extremely cryptic.
-
- This document is submitted to the Soundblaster Freedom Project and is
- intended to provide programmers with a FREE source of information about
- the programming of these sound cards.
-
- The information contained in this document is a combination of
- information found in the Sound Blaster Software Developer's Kit, and
- that learned by painful experience. This document only applies to the
- optional CMS Music chips available for the Sound Blaster 1.5 and 2.0.
- All previous versions of the Soundblaster included these CMS chips.
-
- Please note that numbers will be given in hexadecimal, unless otherwise
- indicated. If a number is written out longhand (sixteen instead of 16)
- it is in decimal.
-
-
- Chapter One - CMS Chip I/O
-
- CMS chips provide the Sound Blaster with an additional twelve stereo
- voices, and four noise generators. A programmable sound generator is
- used to create amplitude modulated sound on each voice.
-
- The chips are programmed by sending data to a voice's internal registers
- via its two I/O ports:
-
- Voice 1 - Voice 6 Voice 7 - Voice C
-
- 02?1 (hex) - register address 02?3 (hex) - register address
- 02?0 (hex) - data to register 02?2 (hex) - data to register
-
- The ports given are relative to the base I/O address. Using the default
- base I/O address of 0220 (hex):
-
- Voice 1 - Voice 6 Voice 7 - Voice C
-
- 0221 (hex) - register address 0223 (hex) - register address
- 0220 (hex) - data to register 0222 (hex) - data to register
-
- The CMS chips possess an array of thirty two registers; to write to a
- voice's particular register, send the register number (00-1F) to the
- address port, followed by the desired value to the data port.
-
-
-
- Chapter Two - The Registers
-
- The following table shows the function of each CMS chip register.
- Registers will be explained in detail after the table. Registers not
- listed are unused.
-
- Address Function
- ------- ----------------------------------------------------
- 00 Right and Left Channel Amplitude for Voice 1/ Voice 7
- 01 Right and Left Channel Amplitude for Voice 2/ Voice 8
- 02 Right and Left Channel Amplitude for Voice 3/ Voice 9
- 03 Right and Left Channel Amplitude for Voice 4/ Voice A
- 04 Right and Left Channel Amplitude for Voice 5/ Voice B
- 05 Right and Left Channel Amplitude for Voice 6/ Voice C
-
- 08 Tone Frequency for Voice 1/ Voice 7
- 09 Tone Frequency for Voice 2/ Voice 8
- 0A Tone Frequency for Voice 3/ Voice 9
- 0B Tone Frequency for Voice 4/ Voice A
- 0C Tone Frequency for Voice 5/ Voice B
- 0D Tone Frequency for Voice 6/ Voice C
-
- 10 Octave for Voice 2/8, Octave for Voice 1/7
- 11 Octave for Voice 4/A, Octave for Voice 3/9
- 12 Octave for Voice 6/C, Octave for Voice 5/B
-
- 14 Frequency enable bits
- 15 Noise enable bits
- 16 Noise frequency select bits
-
- 1C Frequency Reset/Sound enable
-
-
-
- Explanations of Registers
-
- Registers 00 through 05
-
- - These registers are used to set the Right and Left
- channel amplitude control. The 4 bits of amplitude
- control are defined as:
-
- 0000 minimum amplitude, off
- 1111 maximum amplitude
-
- - Register 00
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- |right amp. Voice 1/7 | left amp. Voice 1/7 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 01
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- |right amp. Voice 2/8 | left amp. Voice 2/8 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 02
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- |right amp. Voice 3/9 | left amp. Voice 3/9 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 03
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- |right amp. Voice 4/A | left amp. Voice 4/A |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 04
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- |right amp. Voice 5/B | left amp. Voice 5/B |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 05
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- |right amp. Voice 6/C | left amp. Voice 6/C |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
-
- Registers 08 through 0D
-
- - These registers are used to set the tone frequency. The
- frequency is combined with the octave value for the voice
- to determine the frequency of the sound generated.
-
- - Register 08
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | tone frequency Voice 1/7 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 09
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | tone frequency Voice 2/8 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 0A
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | tone frequency Voice 3/9 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 0B
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | tone frequency Voice 4/A |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 0C
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | tone frequency Voice 5/B |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 0D
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | tone frequency Voice 6/C |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
-
- Registers 10 through 12
-
- - These registers are used to set the octave value. The 3
- bits of octave control are defined as:
-
- 000 minimum octave (28 Hz to 55 Hz)
- 001 (55 Hz to 109 Hz)
- 010 (109 Hz to 218 Hz)
- 011 (218 Hz to 437 Hz)
- 100 (437 Hz to 875 Hz)
- 101 (875 Hz to 1.75 kHz)
- 110 (1.75 kHz to 3.50 kHz)
- 111 maximum octave (3.50 kHz to 6.99 kHz)
-
- To produce a note, set the octave to a value of 0 through
- 7, then set the tone frequency for the desired note within
- the octave.
-
- Note Tone frequency value
- A 03
- A# 1F
- B 3A
- C 53
- C# 6B
- D 82
- D# 97
- E AC
- F BF
- F# D1
- G E2
- G# F2
-
-
- - Register 10
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | | Octave 2/8 | | Octave 1/7 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 11
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | | Octave 4/A | | Octave 3/9 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- - Register 12
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | | Octave 6/C | | Octave 5/B |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
-
- Register 14
-
- - This register contains the frequency enable bits for all
- voices. Setting the enable bit for the voice allows sound
- generation for the programmed frequency. Turning off the
- bit turns the frequency off.
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | | | 6/C | 5/B | 4/A | 3/9 | 2/8 | 1/7 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
-
- Register 15
-
- - This register contains the noise enable bits for all voices.
- Setting the enable bit for the voice allows noise generation,
- turning off the bit turns noise generation off.
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | | | 6/C | 5/B | 4/A | 3/9 | 2/8 | 1/7 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
-
- Register 16
-
- - This register is used to set the noise generation frequency.
- There are four noise generators. Each generator is dedicated
- to three voices:
-
- Noise generator 1, voice 1 through voice 3
- Noise generator 2, voice 4 through voice 6
- Noise generator 3, voice 7 through voice 9
- Noise generator 4, voice A through voice C
-
- The 2 bits of noise generator control are defined as:
-
- 00 (clock frequency)
- 01 (28.0 Hz)
- 10 (14.0 Hz)
- 11 (6.8 Hz)
-
- 7 6 5 4 3 2 1 0
- +-----+-----+-----+-----+-----+-----+-----+-----+
- | | | gen. 2/4 | | | gen. 1/3 |
- +-----+-----+-----+-----+-----+-----+-----+-----+
-
- Register 1C
-
- - This register contains a sound enable bit for all voices and
- a requency reset signal bit.
-
- The sound enable bit (SE) is defined as
-
- 0 (all channels disabled)
- 1 (all channels enabled)
-
- The reset bit (RST) is used to send a Reset signal to all
- frequency generators.
-
- 0 (all generators disabled)
- 1 (all generators reset and synchronized)
-
-
-
- Detecting CMS Chips
-
- Hmmmm, Anybody know of a good way to detect CMS Chips?
-
-
-
- Making a Sound
-
- The CMS chips are very easy to program. The following code written in
- Turbo C provides a good start on mastering the CMS chips. The global
- variable SbIOaddr should be set to the base I/O address of the Sound
- Blaster.
-
- extern unsigned SbIOaddr;
-
- /*****************************************************************/
- /* Function to set a register to a specified value using a */
- /* given register address port. */
- /*****************************************************************/
-
- void CmsSetReg(unsigned regAddr, unsigned reg, unsigned val)
- {
- outportb(regAddr, reg); /* Select the register */
- regAddr--; /* Get data to register port */
- outportb(regAddr, val); /* Set the value of the register */
- }
-
-
- /*****************************************************************/
- /* Function to initialize the Music chip by setting all internal */
- /* registers to zero. */
- /*****************************************************************/
-
- void CmsInit() {
- unsigned reg;
- unsigned port;
-
- port = SbIOaddr + 1; /* Voice 1-6 registers */
- for (reg=0; reg < 0x20; reg++) /* Loop through all registers */
- CmsSetReg(port,reg,0x0); /* Zero the register */
- CmsSetReg(port,0x1C,0x2); /* Set the Reset bit (RST) */
-
- port = SbIOaddr + 3; /* Voice 7-C registers */
- for (reg=0; reg < 0x20; reg++) /* Loop through all registers */
- CmsSetReg(port,reg,0x0); /* Zero the register */
- CmsSetReg(port,0x1C,0x2); /* Set the Reset bit (RST) */
- }
-
-
- /*****************************************************************/
- /* Function to set the left and right channel amplitudes of a */
- /* voice to specified values. */
- /*****************************************************************/
-
- void CmsSetAmp(int voice, unsigned rAmp, unsigned lAmp) {
- unsigned regAddr;
-
- if (voice < 7) /* Select the correct register */
- regAddr = SbIOaddr + 1; /* address for the voice */
- else
- regAddr = SbIOaddr + 3;
-
- /* Set the voice right and left amplitude */
- CmsSetReg(regAddr, voice-1, (rAmp << 4) + lAmp);
- }
-
-
- /*****************************************************************/
- /* Function to set the tone frequency for a specified voice */
- /*****************************************************************/
-
- void CmsSetFreq(int voice, unsigned freq) {
- unsigned regAddr;
-
- if (voice < 7) /* Select the correct register */
- regAddr = SbIOaddr + 1; /* address for the voice */
- else
- regAddr = SbIOaddr + 3;
-
- /* Set the voice tone frequency */
- CmsSetReg(regAddr, 0x8 + voice-1, freq);
- }
-
-
- /*****************************************************************/
- /* Function to set the octave for a specified voice */
- /*****************************************************************/
-
- void CmsSetOctave(int voice, unsigned octave) {
- unsigned regAddr;
- unsigned reg;
- unsigned val;
-
- if (voice < 7) /* Select the correct register */
- regAddr = SbIOaddr + 1; /* address for the voice */
- else
- regAddr = SbIOaddr + 3;
-
- /* Compute the register and value to send to CmsSetReg */
- val = (voice & 0x1 ? octave : octave << 4);
- switch (voice) {
- case 1:
- case 2:
- case 7:
- case 8:
- reg = 0x10;
- break;
-
- case 3:
- case 4:
- case 9:
- case 10:
- reg = 0x11;
- break;
-
- case 5:
- case 6:
- case 11:
- case 12:
- reg = 0x12;
- break;
- }
-
- CmsSetReg(regAddr, reg, val);
- }
-
-
- /*****************************************************************/
- /* Function to enable sound frequency for a voice. */
- /*****************************************************************/
-
- void CmsEnableVoice(int voice) {
- unsigned regAddr;
- unsigned val;
-
- if (voice < 7) /* Select the correct register */
- regAddr = SbIOaddr + 1; /* address for the voice */
- else
- regAddr = SbIOaddr + 3;
-
- val = 0x40; /* Compute the value to send */
- if (voice < 7) /* to CmsSetReg */
- val >>= 7 - voice;
- else
- val >>= 13 - voice;
-
- CmsSetReg(regAddr, 0x14, val); /* Set the voice enable bit */
- CmsSetReg(regAddr, 0x1C, 0x1); /* Set the sound enable bit */
- }
-
-
- Acknowledgements
-
- Thanks are due to the following people:
-
- Jeffrey S. Lee (jlee@smylex.uucp) for writing the original document
- on Programming the AdLib/Sound Blaster. This is a must read for anyone
- trying to hack their way through the AdLib programming interface.
-
- Mike Kretzer (tanith@csd4.csd.uwm.edu) for providing information on the
- availability of CMS chips on the Sound Blaster.
-
-