This next device is a departure both from the CDP1800 series and from the CMOS technology I've been leaning towards so far.
It's an AM9511A-1DC Arithmetics Processing Unit, or APU, by AMD. The original AM9511 was from 1978, and my AM9511A-1DC is (c)1979, so it's period.
The device handles signed 16- or 32-bit fixed point and 32-bit floating point add, subtract, multiply and divide. Plus it has 11 "derived" functions, such as square root, trig functions like sine, log and exp, and power.
There are also some data manipulation functions, such as converting from fixed to floating, or vice versa.
And all of this in a 24.6 package.
The device is stack oriented. First, you have to use two or four 8-bit pushes to load one operand, then another two or four to load the other operand. The command is then issued and the APU processes. When it finishes, it asserts the !END line and the answer can be popped off the top of stack. Or, another operand can be pushed and another operation begun.
Depending upon the operation, it may take anywhere from 10 - 20 cycles, to several thousand for some of the derived functions.
The APU also has a !PAUSE line to make the CPU wait if it is not ready for access.
It all looks straight forward to add to the ELF-ish in memory-mapped I/O space. I placed it at CC00. Only two addresses are needed; CC00 for the data and CC01 for the command and status register.
One little gotchya is that it's an older style NMOS, requiring both +5V and +12V supplies. So I decided to feed the ELF-ish 5V regulator with a 12V supply instead of the original 9V, and then patch over the 12V supply directly to the APU.
It needs a clock, with the AM9511-1DC version supporting up to 3Mhz, so I use a buffered version of the 2.4576Mhz CPU clock.
I can't remember why I added the pull-up resisters to the buffered memory bus, except perhaps since the data sheet says that VOH was a minimum of 3.7V. Although that looks like under TTL load conditions, so it probably should have been just fine driving CMOS.
There it is in the upper right, with the connector for the +12V feed.
So, did it work? Again, since it's memory-mapped, I can access it directly from UT4 using memory read and write commands.
With my first attempt to access it, the ELF-ish just locked up and needed to be reset.
Time to break out the logic analyzer and see what's going down in groove town.
This was a simple attempt to read the status register at CC01.
What we see here is standard CDP1802 execute of a memory read. The !CS, which is decoded from the high addresses, occurs near the end of timing pulse TPA, with !MRD being asserted near the middle of TPA.
MA0 only takes on the value for the lower byte, the 01, after TPA. So what we have here is a timing problem. At the time that !CS and !MRD are asserted, A0 = 0, so the device thinks this is a data read (POP from the stack), which it is slow at due to the internal stack access time, so it asserts the !PAUSE line to make the CPU wait. The CPU !WAIT line asserts a moment later due to the propagation delay in the control gating.
But, the APU never de-asserts !PAUSE, so we're waiting forever. The timing diagram in the data sheet does show that !CS should occur at least 25ns before !MRD is asserted, which we have clearly violated here since !MRD is coming before !CS.
The data sheet doesn't say what happens if this is violated, but a separately available manual says this will cause the AM9511 to malfunction - which I guess we could say we're seeing here.
So I need to delay the !MRD signal. If I gate it with the !CS signal, that solves the malfunction issue, but the !MRD would still be occurring before the A0 has taken on its value from the lower byte of the address, so an access to the Data register may occur when we wanted an access to the Control or Status register.
In other words, I need to gate !MRD with a sufficiently delayed version of the !CS signal.
I know there are better ways to do this, but I'm out of space on the board for any more chips, so I just used the some of the spare gates sitting around to compound propagation delays. This ugly hack is what I ended up with.
Here's the signals with this change in place.
The key is that !MRD is now happening well after !CS, at the same time as A0 is asserting high. According to the timing in the data sheet, the minium hold time between C/!D (which A0 is connected to) and !MRD is 0ns, so it's okay for these to happen together.
There is still a brief assertion of the !PAUSE line - the AM9511 pauses for every access, even if just briefly as in this case.
But then the read occurs and everything proceeds.
Here's a screen shot of the UT4 basic APU test.
The plan is to do a 16-bit fixed point add of 0x1234 with 0x5678, which should equal 0x68AC.
The first four lines push the operands onto the internal stack, at CC01, LSB first.
I then issue the add command by writing 6C to the command register at CC01.
I then pop the two byte result off the stack, MSB first.
Looks like success to me! Yay!
One more signal trace for all of the nerds in the audience. This is captured between issuing the 6C add command, and the APU asserting the !END line.
Issuing a command is a write cycle. The CDP1802 asserts the !MWR much later in the execute cycle, so there wasn't any timing issues here. The APU starts executing the command when !MWR de-asserts, as shown by the blue line.
Then, a couple machine cycles later, the APU finishes and pulses the !END line. If that was tied to !INTERRUPT (or one of the !IRx lines of the CDP1877 PIC), an ISR could process the results.
I'm happy with these results. If you're interested in this APU, or floating point maths in general, and all kinds of AM9511 and AM9512 gory details, check out the extended manual.
I found a copy at http://ep.homeserver.hu/PDF/AM9511A-9512.pdf.