SEGA Megadrive/Genesis YM2612 + SN76489 synth

Status
Not open for further replies.
That code is pretty advanced, they're doing all kinds of fancy stuff with sample play back. The http://danceswithferrets.org/ blog post I sent you has a much better introduction to how to code for the chip.

I am trying to get this code to work, without success. only a drone sound. i have changed my code to match pins after pin 3, which i used for the clock output.

http://milkcrate.com.au/_other/downloads/teensy/SN76489_USB_MIDI_100/SN76489_USB_MIDI_100.ino

i used the teensy clock, not sure where this code should go in the program

Code:
  analogWriteFrequency(kPin_CLK, 4000000);
  analogWrite(kPin_CLK, 128);
 
That code is an entire midi controlled synth! That's trying to run before you can walk.

The code below is slightly adapted from http://danceswithferrets.org/geekblog/?p=93 it sends a byte to the SN76489 and (slowly) toggles the WE (Write Enable) pin so that the SN76489 reads the byte. Maually work out the bytes you need to send to play different notes of the 3 channels using the information I gave you and make a series of calls to SendByte to get the chip to play different notes.

To make sure everything is working before wiring up to the chip you should wire up the outputs from the Teensy you are using for D7..D0 and WE to LEDS (I have a breadboard with 9 LEDS setup exactly for this) and check that the bits you are sending are the bits you expect - I managed to reverse the order of my outputs so was sending the data 'backwards' which I debugged by hooking up to LEDS.

You also need to wire the CE pin to Ground using a resistor. This is called a pulldown resistor. IF the CE pin is not wired to Ground then the chip ignores all information you send it.

Code:
void SendByte(byte b)
{
  digitalWrite(PIN_D0, (b&1)?HIGH:LOW);
  digitalWrite(PIN_D1, (b&2)?HIGH:LOW);
  digitalWrite(PIN_D2, (b&4)?HIGH:LOW);
  digitalWrite(PIN_D3, (b&8)?HIGH:LOW);
  digitalWrite(PIN_D4, (b&16)?HIGH:LOW);
  digitalWrite(PIN_D5, (b&32)?HIGH:LOW);
  digitalWrite(PIN_D6, (b&64)?HIGH:LOW);
  digitalWrite(PIN_D7, (b&128)?HIGH:LOW);
  digitalWrite(PIN_NotWE, HIGH);
  delay(1000);
  digitalWrite(PIN_NotWE, LOW);
  delay(1000);
  digitalWrite(PIN_NotWE, HIGH);
}
 
You also need to wire the CE pin to Ground using a resistor. This is called a pulldown resistor. IF the CE pin is not wired to Ground then the chip ignores all information you send it.

thank you very much!

which one of these pins do you mean? or are you referring to the YM2612?

853px-TI_SN76489_pinout.svg.png
 
/OE on that chip diagram

For some reason it is known as /CE on some diagrams and /OE on others but it has the same function and it needs to be connected to ground through a resistor for the chip to accept input on the Data inputs.
 
Last edited:
Cool,

Now your next step is to understand how that doorbell sketch is doing it and start modifying it to produce a different tune.

i did do that by tweaking the hex in the melody array. but since i don't know how to write midi natively in hex, i gave that up after a few tries. one thing i noticed is that if i increase the value of those numbers, the sound goes lower in pitch, or at least i think that happened.

i have been going through the code excruciatingly slow, and trying different things. as soon as i figure out what is going on, i will invoke the MIDI and put it in the loop instead of the music that is stored as an array.

on a side note, i am wondering about how grounding that pin made it work, how i would have ever guessed that would do the trick, and if i need to do the same with the ym2612 chip on one or more of its pins.

one thing is for sure, i am not going to be fussing around with 'portD' or any of those port arrangements with these ancient chips, they are too slow to care about 1 or 2 picoseconds.
 
Last edited:
You need to read through http://www.smspower.org/Development/SN76489 again and read the section "How the SN76489 makes sound" to understand the connection between the value you are sending to the chip and the sound it makes.

The second thing to understand is that you are not "writing midi natively in hex" you are writing tone data to the registers in the SN76489 of a format the chip understands. MIDI is not involved in any way, the mSN76489 knows nothing about MIDI. The Teensy can understand Midi messages and execute a function every time it receives such a message. Then in that function you get it to send bytes to the SN76489 appropriate for the midi message. But that is for the future once you understand the relationship between the data you are sending the chip.

As for grounding the pin making the chip work please read on.

If you had read and understoof the data sheet for the SN76489 that I linked to http://members.casema.nl/hhaydn/howel/parts/76489.htm you would have seen in section "7 DATA TRANSFER" the line "The microprocessor selects the SN76489AN by asserting !CE (active low). Unless !CE is asserted, no data transfer can occur."

This line means that the SN76489AN will only accept input on it's data lines if !CE is low (i.e. zero). To make !CE low you have to attach it to 0V, you can't just leave it unattached, ;eaving in unattached is known as 'floating' which is bad. Connecting a resistor between the pin and ground connects it to 0V. This is called using a "pull down" resistor (you are pulling down the input to zero). You can also do the opposite and connect a input pin to Vcc with a resistor to set it to High, this is called a "pull up" resistor.

If you don't know about pull up resistors and pull down resistors then you absolutely need to stop what you are doing and independently read about them before continuing experimenting with your chips, incorrectly wiring up inputs to inappropritate voltage sources (or indeed leaving them unconnected so floating) can easily permanently damage your chips. Pull ups and p[ulldowns are a fundemantl piece of knowledge about Integrated Circuits without which nothing will make very much sense.
 
That g_SoundData array in the doorbell has absolutely nothing to do with MIDI, nagual.

Each line has two numbers. The first is the duration of the command in units of "kTimeMultiplier" milliseconds. As "kTimeMultiplier" is 10, a value of "4" leads to a delay of 40 milliseconds.

The second number is the command that is sent to the SN76489. If you read the docs (like this one), you see that the chip knows several commands. This sketch uses volume control commands and tone commands. The tone commands require two transfers, the volume control commands just one.

Actually, the comments in the sketch explain what the SN76489 is supposed to do: "C0 vol 14" means that channel 0 is set to volume 14. See?
Now, the tone commands specify a time period for the generated output. That time period corresponds to a frequency: the higher the period, the lower the frequency, which is exactly what you observed.

Now, getting back to the numbers: As I said, they're interleaved. One byte (the first, third, fifth, ... in the array) specifies the time period in units of 10 milliseconds. The next one is the command. And if you take a look at the previously linked chip documentation, you see that the command codes are not really straightforward.

Some commands require only a single byte, others require a second byte transfer:

  • 0x8x, followed by another byte yy: set tone period on channel 0 to the value of yyx, yy must not be above 0x3F
  • 0x9x: set volume on channel 0 to (15-x)
  • 0xAx, followed by another byte yy: set tone period on channel 1 to the value of yyx, yy must not be above 0x3F
  • 0xBx: set volume on channel 1 to (15-x)
  • 0xCx, followed by another byte yy: set tone period on channel 2 to the value of yyx, yy must not be above 0x3F
  • 0xDx: set volume on channel 2 to (15-x)
  • 0xEx: control the noise generator, won't explain here
  • 0xFx: set volume on noise channel to (15-x)


So, the byte sequence
Code:
[COLOR=#000000]       0, 0x84, 0, 0x27, // C0 tone 0x274
[/COLOR][COLOR=#000000]       0, 0x90, // C0 vol 15
[/COLOR][COLOR=#000000]       5, 0x91, // C0 vol 14
[/COLOR][COLOR=#000000]       4, 0x92, // C0 vol 13
[/COLOR][COLOR=#000000]       4, 0x93, // C0 vol 12
[/COLOR]


at the beginning of the array does this: It sends the byte 0x84 to the chip - check the list above about what this command is supposed to do. Without any delay (this is the byte "0") after the 0x84, it sends the next command: 0x27.

I came to the conclusion, that this generates a tone of period 0x274 (which, in decimal, is 2*256 + 7*16 + 4 = 628) on channel 0 of the SN74689. Look the comment: C0 tone 0x274!

Then, without any delay (0), it sends a byte 0x90. Which does what? Again, see the list above: It sets the volume on channel to (15-0), which is 15. Check the comment: C0 vol 15. Got it?

Before the next command is sent to the chip, the software pauses. How long is specified with the next byte, which is 5. 5 means 50 milliseconds. Then the next byte is sent: 0x91, which sets the volume on channel 0 to (15-1)=14. So, it reduces the volume.

After another 40 milliseconds (the next byte with value "4"), the volume is reduced to 13. Do you see how this happens? And, after another 40 milliseconds, it reduces to 12. So, actually, the tone is faded.

Try to discover what the other codes mean and how the delay works. Try to reduce or increase some numbers that you think might give an audible effect. For example, that 48 in the middle of the array. What do you think it's there for? Change it to 10 and see (actually hear) what happens. Try generating polyphonic sounds - two tones of different frequencies at the same time (use different channels for this).

You've come far in the last few days and gotten to a point where, maybe, curiosity might give you a steeper learning curve than asking. Go for it!
 
Last edited:
so now i got a teensy 2++

and its been a couple months. so now it feels like im starting over from scratch. does anyone know what the general concept of the pins are in the 2++?
i have the pic that shows what the pins are called.

I had a clock generated on one of my pins on the teensy 3, can i just pick any pin to generate a 7.6 MHZ clock on the 2++ or do i need a special pin or can it even do that?
 
Last edited:
the 2 can't generate your clock signal and also perform useful work in real-time. I recommend a discrete oscillator
 
arg. knew there could be a catch.
i have a crystal, just dont know how to make it oscillate. but i do have a teensy 3.1 so i guess i can get it to do the job. im going to try this using your example. i forgot almost everything about this project since the only reason i bought a teensy was to drive this chip. its really crazy since i could as well code an FM synth using only the teensy and just skip the yamaha chip altogether, but I want to figure this thing out anyway.
 
to follow your design, i recall that there are some peripheral components. do i need that stuff or can this be done with only the Teensy 2++ and the ym2612 chip and an external mixer to amplify the DAC on the ym2612? also the crystal/clock i realize.
 
nah get a 7.62mhz crystal oscillator or make an oscillator with a crystal and components. Or use a discrete programmable oscillator.

You need to be removing complexity, not adding it, considering the questions you are asking. Put aside a few bucks to spend on components and keep your project as simple as possible or all you'll produce is a little puff of magic smoke.
 
nah get a 7.62mhz crystal oscillator or make an oscillator with a crystal and components. Or use a discrete programmable oscillator.

You need to be removing complexity, not adding it, considering the questions you are asking. Put aside a few bucks to spend on components and keep your project as simple as possible or all you'll produce is a little puff of magic smoke.
ć

I have a bunch of 7.6 mhz crystals. Two legs though and schematics on how to use or oscillate one is surprisingly scarce. No luck on google. I've seen these on pcbs all my life, but its one component that could use some how-to articles.
 
7.6x MHz clock oscillators .. they seem to be rare, neither mouser or digikey stocks them.

can't really help with the crystal schematic, but my impression is you're after what's called a Pierce oscillator. there's plenty of application notes etc.



... its really crazy since i could as well code an FM synth using only the teensy and just skip the yamaha chip altogether, but I want to figure this thing out anyway.

... and maybe. fwiw, i once bought a few ymf262 on ebay and recently found them again so i hooked them up to a teensy 3.1 the other day (in this case you need a 14.31818 MHz oscillator, which are readily available).

22218767566_c6d70226a8_c.jpg

it sounds alright but unless you're nostalgic or something i'd say ultimately a teensy-based FM synth is the better investment (of time and effort). not that that's any easier. then again you wouldn't have to start from scratch. for example, here's a fixed-point implementation for STM32F103; it should be fairly doable to extract the synthesis core and run it on teensy 3.x.
 
7.6x MHz clock oscillators .. they seem to be rare, neither mouser or digikey stocks them.

can't really help with the crystal schematic, but my impression is you're after what's called a Pierce oscillator. there's plenty of application notes etc.





... and maybe. fwiw, i once bought a few ymf262 on ebay and recently found them again so i hooked them up to a teensy 3.1 the other day (in this case you need a 14.31818 MHz oscillator, which are readily available).

View attachment 5307

it sounds alright but unless you're nostalgic or something i'd say ultimately a teensy-based FM synth is the better investment (of time and effort). not that that's any easier. then again you wouldn't have to start from scratch. for example, here's a fixed-point implementation for STM32F103; it should be fairly doable to extract the synthesis core and run it on teensy 3.x.

oh wow is that the Preen? it runs on a Teensy type microprocessor?
 
oh wow is that the Preen? it runs on a Teensy type microprocessor?

no, that's the ymf262 + yac512. (there's also a teensy on the other side of the board. i suppose it's easier to work with because it plays nice with 3v3 signals (except /IC and MCLK, which need 5V. i used a 74LV1T125 for the /IC, as seen on LC)).

but yeah, the gist of the preen mk1 code should run very ok on a teensy 3.x
 
it sounds alright but unless you're nostalgic or something i'd say ultimately a teensy-based FM synth is the better investment (of time and effort).

main reason i'm keen on ym2612 and teensy is because I bought 5 * ym2612 and a teensy 3.1 and teensy 2++, but this whole endeavor brought down the house in terms of stuff I need to learn to even copy (in rote) the pre-existing designs.
 
main reason i'm keen on ym2612 and teensy is because I bought 5 * ym2612 and a teensy 3.1 and teensy 2++, but this whole endeavor brought down the house in terms of stuff I need to learn to even copy (in rote) the pre-existing designs.

oh, i didn't mean to sound too negative. those yamaha ICs are neat in their own way, i suppose ... and as long as you learn something in the process, even better.
 
oh, i didn't mean to sound too negative. those yamaha ICs are neat in their own way, i suppose ... and as long as you learn something in the process, even better.

im trying to learn algebra2, trig, precal, cal, C, electronics, and reaJS at the same time so it's going slow.
 
@nagual: very nice project.

I'm experimenting occasionally with these Sega sound chips using an arduino UNO or Mega 2650.
Normally I use µC only for automatation and data aq. but wanna continue with a little vgm project.

My question is now how to read vgm data. Can you give a small introduction in vgm data stream?
I know there's a header that contains data e.g. frequency, etc. but how to read the actual data
from the vgm stream? I would read the data from the vgm into an array, right? Is there a specific
velocity? What is the size of such an array? Afterwards the registers are set.

So let's say I would store a vgm on a EEPROM. How the data stream needs to be interpreted.
I'd like to start with the SN76489 chip, it seems easier to me
 
Hey guys, sorry to dig up this thread but I am planning on designing an arpeggiator based on the YM2612 (and also one based on the SN76489 either together or separately,) and so I am trying to figure out which microcontroller will be the best for this.

I am leaning toward buying a Teensy 2.0++ since it has lots of I/O pins (which I might not need for this project, but nice to have in case I do.) Would this be a good microcontroller for this project? I already own a few Arduino Unos, an Arduino Mega2560, a Raspberry PI, and a PIC18, but I see a lot of people have success programming these kinds of projects on the Teensy MC's.

Any help would be appreciated, thanks!

Also I can start a new thread if it would be better than resurrecting this one. I just figured it's better to search the forum for what has already been discussed on this project.
 
Status
Not open for further replies.
Back
Top