I'm trying to get the ay-3-8913 sound chip to work with my z80 but so far I haven't gotten any sound output yet. I know the chip, my amp circuit and the clock circuit work because it works when I connect it to my Arduino and run a program I found on the internet. I have tried running my z80 at 9.6MHz, 4.8MHz, 2.4MHz, 1.2MHz and 0.6MHz with no success. I've got the CS pin going to my pld which enables it when the address bus is in the correct range and when the IORQ is active and I've checked this is working, I have the BC1 going to A1 and BDIR going to A0 but I've also tried wiring BDIR to RD with no success. This is my code:

write_reg: macro LT VALUE ; LT=LocaTion 
ld bc,AY3891X_LOCATION+0x3
ld a,LT
out (c),a
ld bc,AY3891X_LOCATION+0x2
ld a,VALUE
out (c),a
write_reg  0 0x28
write_reg  1 0x02
write_reg  2 0xee 
write_reg  3 0x0e 
write_reg  4 0xdb
write_reg  5 0x01
write_reg  6 0x1f
write_reg  7 0x2a
write_reg  8 0x0e
write_reg  9 0x00
write_reg 10 0x00
write_reg 11 0x00
write_reg 12 0x00
write_reg 13 0x00

I also have this in my config file

AY3891X_LOCATION: equ 0000000000010000B

I've tried setting those registers with my arduino and it does work so i know the values are right and they produce a tone, they are just not getting to the ay-3-8913 :( what could be wrong with my setup?


  • How have you dealt with bridging BC1, 2 and DIR to the z80's IOREQ machine cycle?
    – Tommy
    Commented Mar 21, 2018 at 23:22
  • No since the cs pin is high if ioreq is not low, I use the ay-3-8913 which doesn't have a bc2 and has a cs pin
    – C32
    Commented Mar 21, 2018 at 23:26
  • 1
    Can you give us a schematic of how you've connected it? Worth checking that you've got the address selection logic right, etc...
    – Jules
    Commented Mar 22, 2018 at 2:32
  • ... and you definitely don't have any interrupt servicing interceding or else are smart enough not to trigger the AY chip select when M1 is active?
    – Tommy
    Commented Mar 22, 2018 at 3:37
  • here is a small schematic : imgur.com/vOHuwaW and the pld source code : pastebin.com/qL3qrdGJ . I'm also not using interrupts at all
    – C32
    Commented Mar 22, 2018 at 9:34

1 Answer 1


Brief look shows that you use [A15:A8] in circuit feeding CS pin; Z80 is having only 256 distinctive ports controlled by OUT command family, thus you must drop [A15:A8] out of the equation. Please look into the Z80 manual/datasheet here, you will find the following:

The contents of Register C are placed on the bottom half (A0 through A7) of the address bus to select the I/O device at one of 256 possible ports. The contents of Register B are placed on the top half (A8 through A15) of the address bus at this time. Then the byte contained in register r is placed on the data bus and written to the selected peripheral device.

In your current setup you do not need contents of register B. As B is most probably is not zero defined by ld bc,AY3891X_LOCATION+0x3, your CS signal does not activate.

Depending on value of AY3891X_LOCATION you may just be writing to the wrong port. /CS pins is active low, thus per your current PLD equation correct port range is 010h to 017h (not consideting [A15:A8]).

that's unfortunatly probably working

You must make it right, not probably right? You are lucky that this code works in this configuration; if B will happen to be other than 0 it will stop working.

Next, formally you have no output on the /RESET wire. You just connect two inputs on the circuit.

You must draw proper circuit diagram, with pin numbers and all connections. I bet you will find a mistake when doing it.

Update: I used to use AY8910; this AY8913 is having /CS pin, and there's nothing in the datasheet on the timing of this pin, and there's almost nothing about which event actually writes data into the chip's latch.

/CHIP SELECT (Input): pin 24 (AY-3-8913 only)

This input signal goes low to enable the PSG to read data on the data bus or write data from the data bus to one of the internal registers. For these above operations to occur, this signal must be true in addition to the current bus address being a valid PSG address. This signal must be valid for all read and write operations. This pin has an internal pull down to Vss.

Readable web source

There's high probability that /CS signal goes inactive before BDIR and BC1 change (Z80 holds valid address for some time after deactivating /IORQ); thus if we imagine that write to PSG is performed on change of BDIR/BC1 to inactive state, then removing /CS before changing BDIR/BC1 will cancel the write operation.

As a test I recommend you to pull /CS low (or leave it unconnected as it has internal pull-down); in your current setup there should be no false positives no I am wrong here, there will be false positives because A0/A1 reading the ROM will drive PSG malfunction.

I am afraid you will have to rewire BDIR/BC1 to the PLD and mix them with IORQ in there so that they go to INQACTIVE state (00) for PSG when IORQ is deactivated.

I still don't understand why it wouldn't work before though. BDIR is always 1 when CS is active so it wouldn't go to INACTIVE (00) right?

Glad that it works now. If you did what I recommended above, you have CS low (always active), and operation of PSG is controlled by the BDIR/BC1 signals. They must be of some specific combination to start operation, and changed to other combination (I guess to 0/0) to finish operation.

Thus to latch address you must set BDIR/BC1 to 1/1, and when you switch to 0/0 (inactive mode) it stores the address. To latch register you set them 1/0, and then change to 0/0 and store happens. With read it should be differently, you change from 0/0 to 0/1 and data appears on data pins within specific timeframe.

When you had /CS controlled, it was a combination of (/IORQ) OR A3 OR (NOT A4) ..., and was deactivating when /IORQ goes inactive. It happens before A1/A0 (in your case BDIR/BC1) transition from 1/1 or 0/0, thus chip appeared to be deselect before actual write operation is initiated.

Update: some people do not like me saying that Z80 us having only 256 ports. First, it is official position of the Zilog (see manual). Second, using B register is a hack as B in data transfer commands is used as counter. Third, all the devices I have seen decode only low 8-bits of address, therefore if you start using B and C you risk accessing already defined/existing port defined by in its B part.

  • in another file i have AY3891X_LOCATION: equ 0000000000010000B (sorry for not adding that) and i also checked on a scope that i have 28 negative pulses on CS so that's unfortunatly probably working
    – C32
    Commented Mar 22, 2018 at 17:02
  • B will be the correct value in my case because i'm always setting 16bit values to ports and assigning them to bc, the reset wire goes to the cpu and the reset circuitry (a button and a pullup for now, i know it's not clean but that's not the problem), i will draw a proper diagram but the rest of the system should be correct because i'm interfacing with a ctc fine.thanks for helping so far btw
    – C32
    Commented Mar 22, 2018 at 17:36
  • I have the BC1 going to A2 and BDIR going to A1 this seems to be different on the circuit diagram.
    – Anonymous
    Commented Mar 22, 2018 at 17:56
  • On the question I was using A1 and A2 with A1 being the least significant bit (A1-A16) but in the picture I'm using A0 as the least significant bit (A0-A15).oops
    – C32
    Commented Mar 22, 2018 at 18:32
  • 1
    @BruceAbbott I added this circuit between the bc1 and bdir imgur.com/a/2hbT6
    – C32
    Commented Mar 22, 2018 at 19:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .