How to get notes and noises from the Lynx audio hardware

Warning: alpha/incomplete

Lynx audio docs are a bit scarce. This one is the result of many hours of messing about with cc65 and Handy 0.80. This stuff works on Handy. It may not work on the real thing.

The Lynx's Audio Hardware

Read the Lynx docs for more information, and also refer to the hardware addresses for the audio section of Mikey.

Procedure for setting up a channel to play a tone

Starting from a reset:
  1. Wait 100ms (for hardware to initialise)
  2. Disable channel
  3. Stop counter for channel
  4. Write backup (reload) value to channel
  5. Write counter value to channel
  6. Write shift register bit pattern to channel
  7. Write feedback register bit pattern to channel (must be >0 to get sound!)
  8. Enable counter and set timer pre-selector
  9. Enable channel
Example source code:

... source code here ...

Frequency Calculations

The output frequency is a function of the timer pre-selector period and the counter value. It is also affected by the feedback taps. Hmmmm....

The timer pre-selector can be either 1us, 2us, 4us, 8us, 16us, 32us or 64us, where "us" is microseconds (millionth of a second). The counter value is an 8-bit number from 0 to 255.

The counter for the audio channel is decremented at the rate specified by the pre-selector. When the counter hits 0, the next bit in the shift register is multiplied by the volume value, and output to the DAC. The counter value is then reloaded from the counter "backup" register.

Say we want to generate a note of 440Hz (middle A). This note has a period of 1/440 second = 0.002273 second = 2273 microseconds. This is equal to 142.0625 ticks of the 16us clock.

So we set up the timer on this channel so that it's clocking with the 16us pre-selector, and counting 142 ticks before outputting the next bit in the shift register, like so:
channelB.backup = 142
channelB.control = %0001100100

Other stuff

The audio hardware has no envelope generator or any other fancy features. You have to do it all in software. The Atari sound driver apparently updated at 240Hz, which is a nice update frequency for something like Cakewalk on a Pentium, but for the scrawny little 65C02 at 4MHz, it's a bit heavy.

Updating the sound output every "frame" (~60Hz) may be acceptable for your purposes.

A basic sound driver for the Lynx would include a volume and frequency envelope generator. More sophisticated functions would be a simple sequencer for tunes.

SndInit:
1. All volumes 0 (channelA/B/C/D.volume = 0)
2. $fd44 = 0 (panning)
3. $fd50 = $FF (mstereo) all channels off
4. channelA/B/C/D.control = %01011000 (timer reset, enable)
1