SID 6581 w/ Uno basic questions

Hi. I'm new to the Arduino and relatively new to electronics, so please bear with me, as I probably will have a few stupidities along the way. I like to learn by throwing myself into the fire and working on an intermediate project and making a whole lot of mistakes along the way. Anyhow, I do know there are a few SID projects out there, and I have looked at them, but I'm also trying to figure this out for myself and conceptually how all the parts fit together. I am familiar with the Commodore 64 and SID registers and how to program it from that computer. I have the SID pinout chart and data sheet as well.

So let me explain what I do have in my project: I have two 595 shift registers cascaded together. One shift register is for the address bus (of which I use the lower five bits), the second is for the data. I have LEDs connected to each so I can see what's going on. My sequence of steps is to clear the registers, set the volume to max, wait, set frequency, set envelope, then turn on the waveform. I tested the equivalent code on a C64 emulator, and a sound is produced. At the end of each address & data pair, I have a pause of a second, so I could see what LEDs light up and what values are going through. So far as I can tell, the correct addresses and data are being sent.

Now, here is where I get a little confused. I have the SID's address and data pins connected to the appropriate output pins on the shift register. I have a 12V power supply to the Arduino and VDD (12V) is connected to VIn (which shows 12.5V on my multimeter) and VCC is connected to 5V. R-/W is grounded. RES pin is set +5V. My /CS pin is set to a pin on the Arduino--I originally tried just tying this to ground. The clock pin is connected to pin 9 using code in the setup that I found that generates a 1 MHz pulse. How am I supposed to synchronize this all? Right now I just shiftOut the address and data to the registers and before I set the latchPin HIGH, I set the 6581's /CS low. I wait a bit, then reset the /CS to high. Is that supposed to work in theory, or am I completely off-base with how it works? And how is this supposed to sync with the 1 MHz clock?

And the dumbest question: can I just connect a cheap earphone to the Audio Out and the other end to ground to hear if it's working, or am I even wrong about that?

Sorry about the really dumb questions, but I want to understand where conceptually I'm not understanding what I'm supposed to be doing.

A 6500/6800 device Clocks in data with the E pin going high when CS is Active.
Yes, it will work, but you need to wait at least 2uS Before deselecting CS so that there will be at least one E Clock.

A simple headset/earphone works on the 6581 chip but needs a series electrolytic cap.
Dont try with a speaker, it will kill the outputstage of the chip.

OK, that should give me some place to start. I also got another SID on order in case I already screwed this one up. I also read somewhere that audio out needs to be connected to 1k resistor to ground.

So this is the information I found: "Maximum audio output level is approx. 3V p-p at a 6V DC level. A 1k? resistor should be connected from AUDIO OUT to ground, and a 1-10µF electrolytic capacitor should be used for AC coupling."

Right now, I'm using a cheap mono earphone, like the kinds you would get in those Radio Shack X-in-one project kits. How would this be connected correctly to the audio out pin? And what is the issue with attaching a speaker? Feel free to just direct me to what materials I need to read to understand what is going on here if the answer is long.

Looking at the schematic on this site, the audio out is connected to that 1kOhm resistor, and then to a polarized 4.7uF capacitor, which goes to an RCA jack, right? So if I connect audio out to a 1K resistor to ground, and also to the positive end of the 4.7 uF cap, then to an earphone, then to ground, is that correct? Remember, I'm pretty new at this, so I apologize if I'm asking stupid questions.

The issue with a speaker is that it is only 8ohms.

3volts/8ohms is 375mA and that is basically a shortcircuit.

3volts/32ohm is 93mA in the earphone case and is also too much.
But the capacitor will have a reactans and that is also a resistans in series with the earphone so it will work.

Well, you're right--the speaker is 8 ohms according to my multimeter, but the earphone I'm using is showing a range of 2-5M Ohms. It's one of those old crystal radio earphones that looks like this. My regular headphones, though, are showing 32 ohms.

Anyway, I wouldn't be surprised if I've already fried the chip, so when I get the new one, I'll connect the audio out to the RCA plug as shown in the schematic I previously linked to.

Then the earphone is ok.

An RCA line input has an impendance of something like 10Kohm.

Hmm...yeah...I am wondering if I did bake my chip. It seems to get quite hot pretty quickly.

Anyhow, no noise from it yet, but, in theory, should this code work? Am I on the right track?

void SIDwrite (int address, int data) {
  digitalWrite(CSPin, HIGH);
  
  //This is the code for writing to the two shift registers. 
  //address and data are both 8-bit values (even though only 5 bits of address are used)

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, address);
  shiftOut(dataPin, clockPin, MSBFIRST, data);
  digitalWrite(latchPin, HIGH);
  
  //I have LEDs connected to my 595s, and the correct data is being output when I set the latchPin high.
  //This is the point where I'm trying to write to the SID. I put the CSPin low, wait 4 microseconds to catch two clock cycles, then release.
  //Is this how I'm supposed to be handling this here?
  digitalWrite(CSPin, LOW);
  delayMicroseconds(4);
  digitalWrite(CSPin, HIGH);
}

The code I have for generating 1 MHz on Pin 9 is:

//CLOCK CODE
    DDRB = _BV(DDB1);                  //set OC1A/PB1 as output (Arduino pin D9, DIP pin 15)
    TCCR1A = _BV(COM1A0);              //toggle OC1A on compare match
    OCR1A = 7;                         //top value for counter
    TCCR1B = _BV(WGM12) | _BV(CS10);   //CTC mode, prescaler clock/1
    //END CLOCK CODE

I admit, I just copied and pasted that. I have no idea how it works or where the documentation for what that does is. Same thing happened to me when I was looking at the SIDShield or SIDAster code. It was fairly impenetrable to me, with lines like "SPCR &= ~( (1<<SPR1) | (1<<SPR0) | (1<<DORD) )". It looks like there's a bunch of bit-banging going on there, but I don't even know where to look to learn about this, or where SPCR, SPR1, DORD, etc., even come from.

Anyhow, I have that in my void setup(). Is there anything else I'm supposed to do there? I checked the voltage on pin 9, and it's 2.5V, which sounds right, as it's basically half-on, and half-off cycling. I do not have an oscilloscope or anything that advanced.

So, conceptually, should this work, or am I missing something important?

Holy cow! I got it to work. The code listed above does indeed work. I still gotta work some kinks out, but I've gotten the chip (or at least the replacement one--I haven't checked the old chip, but I'm pretty sure I did fry it) to make some clean sounds! Wow...that took a little fiddling around, but I managed to figure it out! Thanks for the help.

Its good to let others know what you did wrong and how you fixed it.

Pretty much just listened to you. :slight_smile:

I just assume I shorted the chip either when a) I connected the audio output directly to a speaker or b) when I accidentally had either ground, Vcc, or Vdd going to the wrong power rail. So, just a bone-headed moment of inattention. Plugging back in the original chip indicates that there still is some faint, faint sound there (you can make out the notes being played), but it sounds similar to how the working chip sounds if you disconnect the 12V source.

So, the main thing for me was getting the audio out connection right. I followed the schematic I linked to earlier and just connected that to some powered computer speakers, and all was well.

Anyhow, here's a link to the thing in action, playing a song from an April 1985 edition of Family Computing that I ported over to the Arduino.

And, to outline the process for other beginners like me, (although there are a lot of good resources out there and the SID chip is well-documented), this is basically what I did to figure out how to make this work. This is probably blindingly obvious to everyone, but in case there is someone else starting with very little electronics experience, but some basic conceptualization of how computers work:

  1. Picked up this SID data sheet

  2. Figured out there are 5 pins for the address register, and 8 for the data register. You use these to directly POKE the chip, to use C64 BASIC terminology. OK, so now what? How do I put these values in? Do I connect 13 pins to the Arduino? That seems like too many. There must be an easier way. So ---

  3. I took this Arduino tutorial on shift registers. Once I learned how to make it work, and hook two shift registers together, I now basically had one shift register controlling the address bus, and the other controlling the data bus. The top three bits are discarded, the next five are the address, and the next eight are the data.

  4. Now, I connect A0-A4 on the 6581 SID to the five shift register pins that represent the data bus. Next, I connect D0-D7 to the appropriate data pins.

  5. Now, I have to figure out what to do with the other SID pins. I found a 12V wall wart that I connected to the Ardunio board. I checked the voltage out of the 5V pin. It read 5V. I checked the voltage out of the Vin pin. It read 11.5V (or something just below 12V). Close enough for now, but I want to clean up the power supply a bit later. So Vin went to Vdd, and 5V wend to Vcc on the SID.

  6. Reading the specs, the RW pin is write when LOW, so I tied that to ground. The reset pin I put to the reset pin on the Arduino (following someone else's schematic I found online). I put 470pF caps across pins 1&2 and 3&4 (2200pF is recommended in the spec, but I saw online that many folks were using the easier-to-find 470pF caps).

  7. The clock pin. This I was confused about. I saw some people using a 1 MHz crystal directly, but most went for a solution using the Arduino or PIC's signal. So after finding the clock code given above, I connected it to pin 9 of the Arduino.

8 ) Audio out: connected to the circuit given above.

  1. After that, it's a matter of looking up how to program a SID chip. I used a C64 emulator to help out and make sure I was writing the correct data and in the right order.

Now, there is one bit of flakiness: occasionally, the sound registers don't come out at full volume. Usually, restarting once or twice gets them to behave as expected. I'm going to guess (?) that this may have to do with my 12V supply, as it's not well regulated? I also just learned of "decoupling capacitors" and I haven't put any on my board yet. I wonder if that will help with the problem. I'm otherwise not sure exactly why sometimes it comes out loud and clear, and other times, it's muffled (it almost sounds as if some voices are at different volumes than others, but that shouldn't be possible, should it?)

Anyhow, I'll let you know how this develops. And, as always, if anyone sees any obvious idiocy here, please point it out. I am very much a noob when it comes to electronics.

Great work!

I used to program the SID back in the god old C64 Days.

Now the SID chip connected to a Nano with MIDI and a keyboard could make a very cool 3 osc analog synth.

Yeah, I think you see where I'm going with this... :slight_smile: I have an M-Audio Oxygen MIDI keyboard and the long-term project idea is, indeed, to interface it with the SID, complete with an LCD display and all that. I know there's a few solutions out there already for this type of thing, but I'm going to try to figure as much out for myself as I can, as that's what I hoping to accomplish by getting an Arduino to begin with (learning a bit about electronics and how exactly the parts work with each other).

I think the next step is actually going to be mostly a software one. I want to play .SID/.MUS (Sidplayer) files on the 6581 through the Arduino. I see the file specs are out there, but it looks like it's going to be a good bit of coding, trying to translate the file into the correct 6581 and Arduino/ATmega328 instructions.

ETA: Adding the 0.1 uF bypass caps voltage-to-ground against every voltage source pin on the ICs seems to have helped with the stability and clarity of the signal. So, that means 0.1 uF each going pin-to-ground on Vdd and Vcc on the SID, and one each on the Vcc for the 595 shift registers.

ETA2: It doesn't seem the 2us delay in the code for pulsing the CS pin is strictly necessary, either. I assume this is because digitalWrite takes a few microseconds to execute (I've seen something like 5 microseconds bandied about), so it'll catch the clock pin high even without an explicit delay. I'm guessing if you were directly manipulating the ports (which pretty much all the other SID-Arduino code I've been able to find does), you'd need to delay 2us for it to work, but I haven't worked with directly manipulating the ports.

So here's the current state of the project, with 3-note polyphony, plus sliders programmed for the ADSR envelope.

The only question I might have at this point is does anyone know how polyphony is normally programmed? That is, how does the synth normally decide which voice to shut off? Right now, I just use this approach:

  1. Keep track of what notes are being played on which voice

  2. If noteOn command is received, look for an empty voice
    a) if found, play it on that voice, and update the currentNote value for that voice
    b) if not, just play it on voice 1, and update the currentNote value (I assume something like keeping track of the oldest voice played would be the "correct" way to do this.)

  3. If noteOff command is received, look for that note being played on one of the voices
    a) if found, turn that note off, and update the currentNote to 0
    b) if not found, do nothing (this means all three voices are full and the note has already been replaced by a noteOn command)

Besides the best implementation for which voice to put the newest note on (2b), is there anything I might be missing. For my purposes, this works fine for the moment, although I should implement a method that replaces the oldest note with the newest note, which shouldn't be too difficult to do.

I'm in exactly the same spot you were in with your original post, but my project uses the AY-3-8910 instead of the SID. I did buy a SID chip, but there was an article in the wiki about the AY-3-8910 and how to use it, so I went with that. Now, the guy that posted it is long gone, and there is one forum post about it where a few people tried the code and couldn't get it to work. But anyway....I am about to post what I have so far in another thread, if you could take a look and see if I am making similar mistakes, I would really appreciate it!