After migrating to the new clock architecture last week, I've had to spend quite a while redoing various timing-sensitive units of the processor, including the L register's various strobes (a really annoying task). But at last it's done, and the Verilog simulation is reporting all-clear, with a ‘Hello, World!’ message successfully sent to the (simulated) debug board's serial port.
I've had to relax the timing requirements, though. I did this because I need to talk to slow devices like 70 ns memory. At 4 MHz, the processor cycle period is 250 ns. In that time, the 50–70 ns microcode ROM needs to be consulted, signals decoded and asserted, and a memory or I/O cycle may need to be performed. The original plan only allowed for 125 ns of time for memory cycles, and this is cutting it a bit too close (as my 70 ns simulated SRAM discovered). So, rather than slowing down the processor clock or allowing for 2–4 tick memory cycles like other CPUs, I opted to just spend more time driving the bus. The bus is now driven immediately after decoding the signals. Write strobes still happen towards the end of the cycle, of course, but there's enough address set-up time for slow devices. You can see this in action in the simulation waveforms below.
In other news, I bought a few General Instrument AY-3-8910 chips on Ebay — I hope they're not fakes. These are the full-blown, 40-pin Programmable Sound Generator (PSG) chips that pretty much everyone used (who didn't use the SID) in the Eighties. One of them is going to be interfaced to the CFT, and I spent some time puzzling out a schematic for it. If you've ever used a 891x chip, you'll remember they're almost never directly attached to a computer. On at least the Orics and the Apple II's Mockingbird audio card, they're connected through an 6522 VIA. There are two reasons for that. One, the PSG is slow as treacle. The minimum width for valid data, strobe pulses and the like is 500 ns. The other reason is because of its weird microprocessor interface that's pretty much incompatible with every major CPU of the 70s and 80s, the vast majority of the minor ones, and many of the downright weird ones. With a VIA, you can output data slowly, using multiple CPU instructions to start and stop the PSG transaction, and you can drive the chip select and strobe (latch, actually) signals in software.
I don't want to use LSI chips if I can help it, of course. So far, the only exceptions are the memory chips, UARTs, Ethernet interface and the PSG. The latter because I'm quite fond of it, and the CFT would just have to have one.
So I had to cobble together a CFT processor interface. It uses a delay line that makes processor-to-PSG chip selects to last until the third clock rising edge. This gives us something like 570–750ns to talk to the PSG. This ﬁts naturally to the timing of the
OUT instruction, which needs four cycles (1000ns) to run (two 250ns cycles to fetch and decode, two 250ns cycles for an I/O write transaction). This way we don't need wait states. To keep things simple I didn't implement reading from the PSG. This isn't much of an issue, since it's a write-mostly device. The only time you'd need to read from it would be to sample its two GPIO ports. We lose 16 bits of input, but we can still program the GPIO ports as outputs and have 16 bit of output. This is precisely what I've done, bringing the IOA and IOB ports out to a 2×10 pin header for future expansion.
To talk to the PSG, the processor
OUTs to port
&F0. Writing a value with the ninth bit set (
&100 — remember, the CFT has a pure 16-bit word architecture) selects a PSG register to receive data. Because bits 4–7 are used as chip selects, the data sent must be in the range
&0100–&010F (inclusive). Writing a value with the ninth bit clear writes data to the selected register.
The PSG is clocked at either 2 MHz or 1 MHz, generated on-board by a 4 MHz crystal divided by 2 or 4 using a 7474 dual D flip-flop. This clock controls the sound generation, not the processor interface, and as a result has a bearing on what frequency is produced by what tune values. I'm using a jumper to select between the two rates. I'd like to be able to play some pre-existing AY tracks, and the clock value is crucial. The PSG in the Amstrad CPCs runs at 1 MHz. I'm sticking with that as the default because I don't want to lose the lowest octave, and 15 Hz to 62.5 kHz is a pretty good range.
The board produces stereo from the three PSG channels in a popular way implemented (among many) by the Amstrad CPC464: channel A goes to the left, channel B goes to the left and right, and channel C goes to the right. These two channels are provided on a three-pin header (with Ground) for use by a 3.5mm jack. The return signals from the jack (connected when no headphones are plugged in) are taken to a textbook stereo ampliﬁed using LM386-1 op amps. This bit is optional, and will get implemented when/if I decide to put speakers in the case. Until then, the jack would make more sense: it'll work just ﬁne with ampliﬁed speakers.
You've probably heard the 891x PSGs: they were used in arcade machines, home computers, and lots of other places. Their square wave output is pretty characteristic and easy to spot even if you don't have a very good ear. It sweeter-sounding than the harsh, 1-bit Apple (or IBM) built-in beeper. In short, you get three audio channels, each of which can play a tone between 15 Hz and 62.5 KHz (with 4,095 diﬀerent discrete tones exponentially distributed in that range) at one of 16 volumes. A channel of semi-random white noise (with a controllable pitch) can be assigned to any combination of the three channels. A common trick allows you to play arbitrary 4-bit PCM samples by just setting the output amplitude without the tone timer running. And that's pretty much it. Sounds simple, but a fast computer (like the Atari 520ST) could generate pretty fancy sounds. If you need an example of what can be done on a slower machine, you could play this following YouTube video of Atari's Gyruss for the NES (the arcade version of this game used several 891x PSGs mixed together and sounded incredible for 1983):