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.