Author Topic: AY-3-8910 - can't write odd values to its registers?  (Read 5058 times)

0 Members and 1 Guest are viewing this topic.

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
AY-3-8910 - can't write odd values to its registers?
« on: February 26, 2019, 05:54:25 pm »
Hi everyone,

This is a pernicious problem that has me stumped - I've built an 8-bit sound card from my homebrew computer based on the AY-3-8910 PSG.  Problem is, it's not working, at least it's not making music like it should do.

I'm using a reference design for the LM386 amplifier stage and am not overly concerned about that at the moment - my problem lies with the PSG chip itself.  For some unfathomable reason, I'm unable to write any odd values (bit 0 set) to any of the registers.

I can read values from the registers, I can write even values to the registers and read them back just fine, but if I try to write an odd value to any of the registers, the chip just seems to ignore the write and returns its previous value when I next read it.

I've checked the data bus to the chip and it seems to be fine.  I'm getting values of FFh returned from the IO ports, which is correct as nothing is connected to them and they have internal pull-up resistors according to the documentation, so I'm happy that the data bus is okay and D0 is functioning in some capacity, unless I'm missing something.  :-//

I've even swapped the chip out for a duplicate - same problem.  :palm:

Does anybody, anywhere, have a clue what might be going on or how I might go about finding the problem?  Or have I missed something obvious in the datasheet where it says it only takes even values, and the sound distortion is being caused by a problem elsewhere downstream of the PSG?
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #1 on: February 26, 2019, 06:32:19 pm »
but if I try to write an odd value to any of the registers, the chip just seems to ignore the write and returns its previous value

this behavior has strong indication that there is something wrong with data line D0, check it's connection.
Probably you just connected it to a different pin. Or mixed it with other signal
 

Offline floobydust

  • Super Contributor
  • ***
  • Posts: 7676
  • Country: ca
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #2 on: February 26, 2019, 06:33:20 pm »
I would look at write bus timing including BC1 and BC2. It's a slow chip, write timing tDW is 500ns-10us (8910,8912) plus databus setup time and hold time. It's an NMOS IC and might have weak drive if your databus load is high.

Otherwise, I can't see a reason for the LSB to not stick unless you are hitting the wrong registers.

"General Instruments did take orders for customized MSB bits (factory set to other than '0000'). The chips made with customize-set MSB register bits allow the same processor to control more than one AY chip on the same bus (e.g. Mockingboard sound card for Apple or TurboSound for ZX Spectrum). There are many new-old-stock (NOS) chips on the secondary market with MSB bits factory set to a non-'0000' value. The non-0000 value can cause significant developmental troubles for designers and repair technicians. Software must be written to identify the correct value of the MSB bits on any given chip. Also, software must be changed or hardware added to allow these factory set MSB chips to be used in place of the default '0000' chips."
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #3 on: February 26, 2019, 08:04:57 pm »
but if I try to write an odd value to any of the registers, the chip just seems to ignore the write and returns its previous value

this behavior has strong indication that there is something wrong with data line D0, check it's connection.
Probably you just connected it to a different pin. Or mixed it with other signal

Yes, this was the first thing I thought of as well - I've checked the entire data bus to the PSG and there's nothing wrong with it that I can detect.  I'm seeing highs and lows on D0 via my oscilloscope as well.
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #4 on: February 26, 2019, 08:12:33 pm »
then may be there is short circuit of line D0 with some control line?

Try to disconnect D0 from computer and connect it to the ground and Vcc, and check how it works in such mode.
If there is some short circuit between D0 and control line, it will not work with D0 connected to the ground.
Then you can find the location of short circuit.
« Last Edit: February 26, 2019, 08:17:27 pm by radiolistener »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #5 on: February 26, 2019, 08:15:57 pm »
I would look at write bus timing including BC1 and BC2. It's a slow chip, write timing tDW is 500ns-10us (8910,8912) plus databus setup time and hold time. It's an NMOS IC and might have weak drive if your databus load is high.

Hmm.. possibly.  Thing is, this setup worked fine on the breadboard prototype - now I've got it on a proper PCB, the problem is showing itself.  I guess this doesn't exclude timing issues, though.  FWIW, the CPU is running at 4 MHz, but the clock for the PSG is halved to 2 MHz via a 7474 FF.  I can quarter the clock speed down to 1 MHz by swapping a jumper, but that makes no difference to the problem it seems.

Otherwise, I can't see a reason for the LSB to not stick unless you are hitting the wrong registers.

"General Instruments did take orders for customized MSB bits (factory set to other than '0000'). The chips made with customize-set MSB register bits allow the same processor to control more than one AY chip on the same bus (e.g. Mockingboard sound card for Apple or TurboSound for ZX Spectrum). There are many new-old-stock (NOS) chips on the secondary market with MSB bits factory set to a non-'0000' value. The non-0000 value can cause significant developmental troubles for designers and repair technicians. Software must be written to identify the correct value of the MSB bits on any given chip. Also, software must be changed or hardware added to allow these factory set MSB chips to be used in place of the default '0000' chips."

These two chips worked just fine on the breadboard prototype, so there's no hardware masking going on.   I'm testing the registers directly in my monitor program (the commands should be self-explanatory, although they're not assembler mnemonics, they're more akin to BASIC commands):

Code: [Select]
OUT &08,02      // Latch Register 2
Ready
IN &08             // Read latched register (2)
VALUE: 00        // Contains 00h
Ready
OUT &09,08     // Write 08h to latched register (2)
Ready
IN &08            // Read latched register (2)
VALUE: 08       // Contains 08h (write was successful)
Ready
OUT &09,09     // Write 09h to latched register (2)
Ready
IN &08            // Read latched register (2)
VALUE: 08       // Still contains 08h....
Ready
OUT &09,04     // Write 04h to latched register (2)
Ready
IN &08            // Read latched register (2)
VALUE: 04       // Contains 04h

I can show you identical output for the other registers as well - none of them will accept odd values. :/
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #6 on: February 26, 2019, 08:20:27 pm »
if it works fine with even register address, I don't think that there is an issue with clock frequency.
It looks like D0 line affects some other control line and it leads to such effect. So, there is most likely short circuuit of D0 with some other signal.
« Last Edit: February 26, 2019, 08:21:58 pm by radiolistener »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #7 on: February 26, 2019, 08:21:06 pm »
then may be there is short circuit of line D0 with some control line?

Try to disconnect D0 from computer and connect it to the ground and Vcc, and check how it works in such mode.
If there is some short circuit between D0 and control line, it will not work with D0 connected to the ground.
Then you can find the location of short circuit.

I will test this further tomorrow when I break out the logic analyser and really go to town on the data bus and monitor an IO transaction, but I'm fairly happy there's no issue with D0 as I'm getting odd values back from the IO ports:

Code: [Select]
OUT &08,0E
Ready
IN &08
VALUE: FF
Ready

In the extract above, I'm selecting register OEh (IO Port A) which is returning a value of FFh.  This is expected behaviour as Port A isn't connected to anything, so the internal pull-ups will give it a value of FFh.  If there was an issue with the D0 line, I'd expect this to return F0h?
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #8 on: February 26, 2019, 08:29:28 pm »
If there was an issue with the D0 line, I'd expect this to return F0h?

0xFE to be exact, but D0 may have short circuit with some input control line. In such case it will not affect D0, but vice versa D0 value will affect some control line and it may prevent read/write operation for example.
For example D0 may have short circuit wiht ~RESET line. In such case zero value on D0 will leads to reset AY8910.
Another possible short circuit lines: BDIR, BC1, BC2 or something other

If you have logic analyzer, you can connect it to control lines and check what happens exactly
« Last Edit: February 26, 2019, 08:41:50 pm by radiolistener »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #9 on: February 26, 2019, 08:59:08 pm »
If there was an issue with the D0 line, I'd expect this to return F0h?

0xFE to be exact...

Yes, my mistake.   ^-^

...but D0 may have short circuit with some input control line. In such case it will not affect D0, but vice versa D0 value will affect some control line and it may prevent read/write operation for example.
For example D0 may have short circuit wiht ~RESET line. In such case zero value on D0 will leads to reset AY8910.
Another possible short circuit lines: BDIR, BC1, BC2 or something other

If you have logic analyzer, you can connect it to control lines and check what happens exactly

Ah yes, good point. I'll take a look tomorrow and see what I can find - thanks for the direction!  :-+
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #10 on: February 27, 2019, 01:01:27 pm »
Okay.  :wtf:

Here's the result and my analysis of the logic testing:



Code: [Select]
	XOR	A
OUT (AY_LATCH),A ; Clear register 0
psgrl_test:
1 LD A,$10 ; Value = $10
2 OUT (AY_WRITE),A ; Write $10 to register 0
3 IN A,(AY_READ) ; Port = RSEL/RD
4 LD A,$11 ; Value = $11
5 OUT (AY_WRITE),A ; Write $11 to register 0
6 IN A,(AY_READ) ; Port = RSEL/RD
7 JP psgrl_test ; Loop

The above logic analyser trace was produced using the above code (line numbered for ease of reference).

I have an 8-channel logic analyser, so I have restricted the data bus analysis to the lower 5 bits and the values used in the test accordingly, so I can record BC1, BDIR and ~WR (direct from the Z80) as well.

The first LOW in WR is line 2 of the code. BDIR goes HIGH, BC1 remains LOW for a WRITE operation to the PSG.  The value on the data bus is 0x10, as loaded into the accumulator in line 1.

Line 3 executes a READ operation on the PSG, signified by the LOW on BDIR and HIGH on BC1.  The value read on the data bus is 0x10, which is correct.

The next LOW on WR is line 5 of the code.  A WRITE operation SHOULD be executed here, but it is not – BDIR remains LOW.  The data bus correctly contains the value 0x11.

 :-//

So it's obviously performing a write to receive the first value of 0x10, and returning that value on a read, but when I try to write an odd value BDIR doesn't go high to signal a write to the PSG's register.

I can't see how DQ0 (D0) would interfere with BDIR.  The BDIR line from the 7402 (where WR is NOR'd with the chip select) doesn't go anywhere near DQ0 on the PCB!  |O

Here's a gratuitous snapshot of the relevant (I hope!) part of the schematic:



EDIT: Something else I just noticed - there's no corresponding RD transaction after the attempt to write the odd value, either!
« Last Edit: February 27, 2019, 01:11:48 pm by nockieboy »
 

Offline nick_d

  • Regular Contributor
  • *
  • Posts: 120
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #11 on: February 27, 2019, 01:32:12 pm »
You mentioned swapping out the sound chip -- did you try swapping out the Z80? An internal short between BDIR and D0 or similar could be causing this.
cheers, Nick
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #12 on: February 27, 2019, 02:17:19 pm »
You mentioned swapping out the sound chip -- did you try swapping out the Z80? An internal short between BDIR and D0 or similar could be causing this.
cheers, Nick

Sorry Nick, I don't understand?  You think the Z80 may be at fault?  I'm 99.9999% sure it's not the Z80.  Everything else (including running CP/M) works fine.

An internal short in the PSG may be the issue, I suppose, but I've tried it with two PSG chips - I would have thought it highly unlikely they'd both have the same problem, especially as the first one was working just fine in the breadboard prototype.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15794
  • Country: fr
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #13 on: February 27, 2019, 02:31:38 pm »
I can't see how DQ0 (D0) would interfere with BDIR.  The BDIR line from the 7402 (where WR is NOR'd with the chip select) doesn't go anywhere near DQ0 on the PCB!  |O

Have you taken a look at the /(P=Q) signal from U4.1 when this happens?
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #14 on: February 27, 2019, 03:14:29 pm »
there is definitely something wrong with SN74F521, probably some input lines are incorrect.
Unfortunately it's not clean what you put on the input of SN74F521.
Try to check if D0 is connected to the input lines of SN74F521.
« Last Edit: February 27, 2019, 03:20:48 pm by radiolistener »
 

Offline NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 2507
  • Country: gb
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #15 on: February 27, 2019, 03:49:32 pm »
FWIW Here's a snippet of an old time Z80 and Sound Generator.  Nothing special required but maybe it will trigger some thoughts
 
The following users thanked this post: nockieboy

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #16 on: February 27, 2019, 04:18:10 pm »
there is definitely something wrong with SN74F521, probably some input lines are incorrect.
Unfortunately it's not clean what you put on the input of SN74F521.

The IN_B_x inputs to the 521 are from a DIP switch block, with the lines pulled high through pull-ups or grounded if the switch is closed. They're all grounded except IN_B_2 to correspond to the 0x08-09 IO address space.

Try to check if D0 is connected to the input lines of SN74F521.

The 521 (and the address lines) are on one side of the PCB, the data lines are on the other - D0 doesn't go anywhere near the 521 or even the 7402 that generates the BDIR and BC1 signals.  :-//

 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #17 on: February 27, 2019, 04:20:26 pm »
I can't see how DQ0 (D0) would interfere with BDIR.  The BDIR line from the 7402 (where WR is NOR'd with the chip select) doesn't go anywhere near DQ0 on the PCB!  |O

Have you taken a look at the /(P=Q) signal from U4.1 when this happens?

Nooo.... sounds like a good idea, though.  Will make some alterations to the test setup (will have to use D0-D3 and the extra line to record /(P=Q)) and let you know.  :-/O

UPDATE:

Well, that doesn't make much sense but it gives me a couple more leads to check.  Thanks for the pointer, SiliconWizard - it turns out that /(P=Q) isn't going low for the write of the odd value.  It's not going low for the read afterwards either, which makes no sense to me, but I'll turn my attention to the 521 and its wiring now.



As you can see above, /(P=Q) (let's call it PSG_SELECT) goes LOW with the two even-value operations - the WR and RD.  But when I try to write an odd value, PSG_SELECT doesn't change at all...  :-BROKE
« Last Edit: February 27, 2019, 04:30:45 pm by nockieboy »
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #18 on: February 27, 2019, 04:30:36 pm »
The IN_B_x inputs to the 521 are from a DIP switch block, with the lines pulled high through pull-ups or grounded if the switch is closed. They're all grounded except IN_B_2 to correspond to the 0x08-09 IO address space.

are you sure, there is no mistake? Check connections between sn74f521 pins and Z80 A1-A8 pins with multimeter.
What is connected to ~OE line of sn74f521?

Does it take into account ~IORQ line from Z80?
« Last Edit: February 27, 2019, 04:36:15 pm by radiolistener »
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #19 on: February 27, 2019, 04:35:06 pm »
The IN_B_x inputs to the 521 are from a DIP switch block, with the lines pulled high through pull-ups or grounded if the switch is closed. They're all grounded except IN_B_2 to correspond to the 0x08-09 IO address space.

are you sure, there is no mistake? Check connections between sn74f521 pins and Z80 A1-A8 pins with multimeter.
What is connected to ~OE line of sn74f521?

Here's the full schematic for the PSG:



The PCB is auto-routed, so unless I've bridged two lines somewhere with some horrendously inept soldering, I'm not expecting to find any problems with the lines, though I might have to start looking at them in more detail if I exclude all other possibilities.  ???
 

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #20 on: February 27, 2019, 04:39:21 pm »
all looks good. May be there is some mistake with connection between PSG board and Z80
 

Offline nockieboyTopic starter

  • Super Contributor
  • ***
  • Posts: 1812
  • Country: england
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #21 on: February 27, 2019, 05:38:05 pm »


Above is the latest trace.  This time I'm looking at AQ0, WR and P=Q (PSG_SELECT) to confirm correct generation of BC1 and BDIR signals to the PSG.  All looks to be fine.  ???

Next I'm going to see if I can hook up the 521 and see what the IN_B_x lines are doing - they should be constant throughout - then check the AQ address lines for the other half of the comparator input.

UPDATE:

So it seems AQ8 is pulsing high twice, corresponding to the WR and RD with the odd value.  This could be a coincidence that these HIGHs on AQ8 are corresponding to the IN/OUT with odd values, but in any case will prevent /(P=Q) going low.  I will disconnect AQ8 from the 521 and pull that pin LOW.  Not sure why I connected it in the first place, tbh, there was no requirement for it - just a free pin.  |O
« Last Edit: February 27, 2019, 05:56:32 pm by nockieboy »
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15794
  • Country: fr
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #22 on: February 27, 2019, 06:12:55 pm »
I take it that AQ8 is A8 from the Z80's address bus?

IIRC, the Z80 only uses the lower 8 address bits for IN/OUT requests, so the upper 8 address bits may hold any value - I don't think this is specified. So don't use them for decoding IO accesses.
« Last Edit: February 27, 2019, 06:15:26 pm by SiliconWizard »
 
The following users thanked this post: nockieboy

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3382
  • Country: gb
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #23 on: February 27, 2019, 06:29:07 pm »
FWIW this is documented in the Z80 manual:

OUT (n),A
The operand n is 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 the Accumulator (Register A)
also appear on the top half (A8 through A15) of the address bus at this time. Then the byte
contained in the Accumulator is placed on the data bus and written to the selected peripheral
device.

OUT (C),r
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.
Register r identifies any of the CPU registers shown in the following table, which also
shows the corresponding three-bit r field for each that appears in the assembled object
code.

I'm almost certain some of the old Z80 machines used the value placed on the upper bits to simplify decoding.
 
The following users thanked this post: nockieboy

Offline radiolistener

  • Super Contributor
  • ***
  • Posts: 4135
  • Country: 00
Re: AY-3-8910 - can't write odd values to its registers?
« Reply #24 on: February 27, 2019, 06:33:21 pm »
the Z80 only uses the lower 8 address bits for IN/OUT requests, so the upper 8 address bits may hold any value - I don't think this is specified. So don't use them for decoding IO accesses.

thats not true, Z80 uses all 16 address lines for IN/OUT operations.

For non-prefixed IN/OUT operations, the high byte address is taken from register A.
So, this code:
Code: [Select]
LD    A,#AA
OUT (#55),A

is equals to OUT (#AA55),#55

For #ED prefixed IN/OUT operations, 16-bit address is taken from register BC.

For example, ZX Spectum used address lines A14 and A15 for AY8910 port decoding.

So it seems, that the issue happens just because topic starter uses address line A8 for port decoding and didn't set port address properly in the code :)

There are 3 ways to fix it:
1) set all 16 bits of the port address in the code properly. There is need to load high address byte into A.
But since unprefixed OUT instructions uses A to store output value, and at the same time it uses A to store high byte of port address, you will not be able to use this instruction to write odd or even values (it will depends on jumper for 74f521 decoder)

2) use #ed prefixed instruction to access port, and load all 16 bits of port address into BC

3) just disconnect A8 from 74f521 and pull that pin to the ground or VCC (jumper also should be set properly)


« Last Edit: February 27, 2019, 06:45:37 pm by radiolistener »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf