Close

Sound

A project log for Dodo: 6502 Game System

Handheld Game System featuring the 6502

peter-noyesPeter Noyes 03/03/2016 at 21:250 Comments

All along I knew I wanted to figure out sound for Dodo because a game system just wouldn't be right without it. I have been going back and forth with lots of different approaches in my mind. Dedicated sound generation chips that mixed both digital and analog circuitry were the norm in the 80s. Perhaps the most famous chip of all was the Commodore 64's SID. Unfortunately, these style of chips are all out of production and I really wanted a design that avoids using old chips that are hard to find. I omitted a sound chip from the PCB so that pretty much left me with a single option, the 6522 VIA.

There are several methods for generating sound on the VIA using the shift register. I could either try for sampled audio or generate square waves at varying frequencies directly. For sampled audio the best I could get would be a 4khz sampling rate with 3-bit resolution, which is really only usable for barely intelligable voice. I opted for option 2 where I use the shift register to generate a square wave.

The Commodore PET lacked a sound chip so anyone wishing for audio did the exact same thing I have done, which is how I learned about the approach. It is documented in the PET programming manual.

For a square wave, either 15, 51, or 85 needs to be loaded into the shift register. The binary values are 0001111, 00110011, and 01010101. You can see from their bit patterns how they each result in a square wave. In VIA SR mode 4, the shift register is free-running and is based on the T2 clock, which is exactly what I want to get the sound going. Thankfully, the PET engineers did all the math to figure out exactly what values need to be loaded into the T2 clock to generate specific notes. This is straight from the PET manual:

       octave=15     octave=51     octave=85
  Note  Oct.0 Oct.1 ! Oct.1 Oct.2 ! Oct.2 Oct.3
  Freq  ------------+-------------+-------------- 
   B     251   125  !  251   125  !  251   125
   C     238   118  !  238   118  !  238   118
   C#    224   110  !  224   110  !  224   110
   D     210   104  !  210   104  !  210   104
   D#    199    99  !  199    99  !  199    99
   E     188    93  !  188    93  !  188    93
   F     177    88  !  177    88  !  177    88
   F#    168    83  !  168    83  !  168    83
   G     158    78  !  158    78  !  158    78
   G#    149    74  !  149    74  !  149    74
   A     140    69  !  140    69  !  140    69
   A#    133    65  !  133    65  !  133    65

For amplifying a square wave not much is needed. I found an old NPN transistor (type bc170c) which I wired up to a 1w 8ohm speaker.

For the initial test I implemented some code that played the intro to Fur Elise!

            ...

            lda ACR
            and #%01111111
            ora #%01000000
            ora #%00010000      ; For sound (T2 free running)
            sta ACR
            lda #%11000000
            sta IER
            
            ; Music
            lda #15             ; Low octave
            sta SR
            ldx #0
@next_note:
            lda music,x
            beq @done
            sta T2CL
            inx
            lda #250
            jsr _delay_ms
            jmp @next_note
@done:
            lda #0
            sta T2CL
            rts

music:              .byte 93, 99, 93, 99, 93, 125, 104, 118, 140, 0

This Shift Register based sound generation will work well for my system because the CPU usage should be relatively low. Because the output is free-running, it will keep generating the same sound until instructed to do something different. I don't have to oscillate a pin directly myself to generate the square waves.

I can just have my interrupt that is already firing do a little extra work to orchestrate which sound to play next, should work well!

Discussions