Interfacing with an AY 3-8910 Chip

I've seen this topic been tossed around before, but I've yet to see it actually see it go somewhere.
Essentially, I have an AY 3-8910, a sound chip that was commonly found in computers of the 80s and 90s. I'd like to use this with an Arduino board, and it seems very plausible- I've read through the manual for the chip several times over, and I have a fair understanding of how the chip works.
I have plenty experience with both the Arduino platform and vintage sound chips, but I would like a starting point... Does anyone have any example code, perhaps some wiring diagrams? Has anybody attempted something like this before that could help me with this?
Thanks!

Hi Komaru;

You have an old sound chip... I read something like that in one in the datasheets I have, ( I got to find it ). I may have this chip in my parts bins somewhere...

1st. Get the datasheet of this chip. http://www.msxarchive.nl/pub/msx/mirrors/hanso/datasheets/chipsay38910.pdf
2nd. Proper interface circuit with the Arduino and an audio circuit. Don't forget a reset circuit. or use the Arduino
3rd. The chip use an 8 bit parallel interface, so the Arduino has to send data ( command register ) to the chip in this fashion.

As for programming, I recommend you create a block diagram of your circuit and a flow diagram of your program to help program the chip. Testing and experiments to test your setup.

That will be my steps. Possibility to interface with an Arduino ? YES

Heh; this is a very interesting project.

I don't know if I am allow to photocopies from books and post-it...You know copyright...

You'll need an 8-bit parallel bus to connect to the AY-3-8910's data pins. The Arduino can do this, using pins 0 to 7. But, the first two pins (0 and 1) are connected to the serial interface that's used to boot-load the chip and to make 'Serial.print' work with the serial monitor. So it may be more useful to avoid using those two pins. My suggestion would be to use a 74HC595 shift register to make the 8-bit bus, and then use other Arduino pins directly to generate the BC1, BC2 and BDIR signals. You'll need the usual pull-up resistors on the three audio output pins, and you'll need a clock signal (square wave) of between 1 and 2MHz. One way to make the clock would be to divide down the Arduino's 16MHz clock, but I don't think there's any support for doing that in the existing software. The AVR chip itself is able to take the 16Mhz master clock and divide it by a programmable divisor before sending it out on an I/O pin.

I have some AY-3-8910 chips (and a SID and a YM2612) and I'd like to get them working with the Arduino. I've not made any progress yet, but will post info if/when I do.

@Anachrocomputer

I agree to use shift register to generate 8 bits. That will free-up some pins of the Arduino to use. Thabk for the tips.

I still don't know if I am allowed to post photo-copies of schematics from the books I have. I will like to share with you guys.

Hi guys, I'm working on a similar project and figured it would be more useful to post in this thread rather than start a new one. I actually have an AY-3-8914 taken from an Intellivision, but I found a datasheet for it and it's basically the same. My arduino is set up like this:
pins 4-13 : DA0 through DA7 (the 8-bit bus)
pin 3: 2 MHz clock
pins 2, 13, 12: BDIR, BC1, BC2, respectively, for bus commands

I really wanted to use PORTD for the bus but didn't want to run into problems with pins 0 & 1, and I don't have a shift register.

My main concern at the moment is the timing: let's say I want to change the period of channel A, then change the noise frequency. I'll go through what my API does 'cause I want to make my question clear:

regWrite(R4, B00000100); //coarse tune channel A
regWrite(R11, B00011111); // set noise freq.

the regWrite function does:

busWrite(B11110100); //address for R4
busCmd(BAR); //Bus to Address Register
busWrite(B00000100); //data to write to R4
busCmd(DW); //Data Write

busWrite is just a loop that goes through pins 4-13 and "digitalWrite"s each bit. busCmd uses digitalWrite to set BDIR, BC1, and BC2 to the corresponding command.
Now my question is, how do I know that the register address is latched into the AY-3-8914 before the arduino writes the next byte to the bus? What if the bus control is currently sitting at DW when I write an address to the bus in preparation for a BAR? could it write half of the address into the previous register's data before the PSG selects the right register? I'm guessing it has to do with the PSG's clock cycle :slight_smile:

anyway, this is my first time using a bus or interfacing the arduino with anything complex, so I'd appreciate some help from someone with more experience :slight_smile:

edit: in addition, the 8914 has 3 pins that I have no clue what to do with: !CS0, CS1, and CS2. From my datasheet:

The AY-3-8910 is organized as 16 consecutive memory locations starting at the base address which is decoded by the chip select lines (CS0-CS2)... a 3-bit code on these lines selects the AY-3-8910 for sound programming or parallel input/output.

unfortunately there is no other mention of their function in the documentation. The datasheet is from GI's catalogue of chips for their Gimini game system, which served as the basis for the Intellivision. I got them from Index of /~im14u2c/intv/gi_micro_programmable_tv_games (the PSG starts at page 7_100)

Techone, if you don't want to post your schematics publicly you can send them to me :wink:

@cmpennoob

Techone, if you don't want to post your schematics publicly you can send them to me :wink:

I dont want to dissapointed you, the schematic I was talking about came from the datasheet.

I see you want to use the Arduino output to generate the 2 MHz clock signal. I recommend NO. Use a crystal ocillator circuit to use for the clock for the sound chip. My opinion is 2 MHz is a bit fast , and the Arduino will not have the time to do its things between clock cycle. A 2 MHz is 0.5 uS period, Arduino 16 MHz - 0.062 uS - period - one clock cycle So 0.5 / 0.062 = 8 <-- Clock Cycle of the Arduino. The Arduino is not going to "cut it"

I really wanted to use PORTD for the bus but didn't want to run into problems with pins 0 & 1, and I don't have a shift register

edit : fix the link.

Check this site about Arduino pins & ports https://spreadsheets.google.com/spreadsheet/pub?key=0AtfNMvfWhA_ccnRId19SNmVWTDE0MEtTOV9HOEdQa0E&gid=0 look at the Port's carefully, all ports can not show a full 8 bits. So what about using 2 ports going to the data pins ? Here my idea... Let say you want to send into the data bus a 0x6A --> b01101010, and let separed the data into nibbles ( 1/2 a byte ). Upper byte : 0x6 --> b0110 and lower byte : 0xA --> b1010 So you send PortD = b01100000 and send PortB = b00000110, and then you "latch in" the data into the sound chip. Make sure the digital pins are properlely connected to the data pins of the sound ship.

The CS(0 to 2) are chip select, they have to be activated when you want to read/write into the sound chip. I think ?

@cmpennoob

I just happen to harvest a old pong game from Radio-Shack ( it was in a shed being visit by racoons for 10 years :grin: ) I took apart the external parts except the parts on the PCB board. I check the net and I found a datasheet for the chip AY-3-8500-1 here the link : http://www.datasheetarchive.com/AY-3-8500-1-datasheet.html. I may re-build that pong game unit after all. So I notice this chip also need a 2 MHz clock, and in the datasheet happen to have a small schematic of a crystal oscillator. You may use that schematic to generate the 2 Mhz need for the sound chip. A idea...

I've found this project, it's maybe not as optimized as one with a shift register, but it's easier:

I've just assembled it and it's working really good...

Re the 986-Studio circuit and code, I only got sound out of my AY-3-8910 after I did a proper reset for it. I added code to use another pin as a /RESET signal and hold it low for 500ms in setup() before writing to the AY-3-8910 registers for the first time. Obviously you only do this once, not before every register write.

Regards,
David.

Sorry to dig up an old thread but I noticed it was dug up recently. :slight_smile:

I am working on making a shield that uses the AY-3-8912. I have developed a VGM player that streams VGM music from SD card and plays with the AY. Sounds amazing.

My library also supports the SN76489 and will even play both chips at the same time.

I'm debating putting the SN76489 on my shield too. The problem is that I am out of pins because it expects a shift register for each audio chip.

I don't like using pins 0 or 1 and I don't enjoy using the analog pins for digital output. But since it's such a niche product, I guess I can get away with it.

I will open source the code sometime soon. If anyone wants more info, feel free to email me.

cbmeeks [ a t ] g m a i l [d 0 t] c o m

RE: 2mhz from Arduino - can't you just turn off the prescaler for one of the timers, put it into fast PWM mode, and set top to 8 (or is it 7?), compare to 4 (or 3)... ?

I don't enjoy using the analog pins for digital output.

Curious to know why. The normal default function for these pins is as digital I/O, it is just that they have an alternative function, rather like a super hero's secret identity. The Arduino model pushes that as a "feature" but that is only the alternative reality, not the fundamental one.