I have been looking at what I can do to improve the tape loading on the Minstrel computer kits.
The challenge is the signals can vary markedly from device to device. Some will be loading from a sound card on a PC or laptop, some from a phone, some from an Arduino based device, and some from tape.
The outputs of the tape player will vary based on age and state of the tapes and the player. Many of the tapes would have been recorded almost 50 years ago.
The input stages have to handle a variety of waveform shapes from clean square waves or sine wave from digital devices to signals that have been through various types of automatic level control, maybe audio filters, noise reduction, high- and low-pass filters, to and from tape, possibly several times, even ones that have been high-speed-dubbed on an 1980s double-tape stereo.
Trying to find one solution to cope with all of that has been quite a challenge.
I have created several circuits that were better with some of the tapes, but did badly with the others, and circuits that would do well with those, but fail with the first set.
After many variations, I think I have come up with one which is a good balance of all of these types.
I will go through the details of that (and probably some of the others) in the second part.
In this first part, I am going to start by looking at the input stages of the original ZX80, ZX81 and Jupiter Ace.
ZX80 Tape Input
The ZX80 tape input is fairly minimal, like the rest of the machine, as simple as it could be to work.
In this circuit, the 180Ω resistor acts as current limiting on the input. The 47nF capacitor performs two functions. Firstly it AC couples the input, removing any DC bias on the input and dropping the signal to go positive and negative around the 0V rail, as referenced by the 1KΩ resistor.
The 47nF capacitor and 1KΩ resistor also form a high-pass filter, which will attenuate signals below around 3.4KHz (f= 1/2πRC)
That is an interesting choice, as the data signals on the ZX80 are about 3KHz, so it will let through the harmonics but not the main signal.
This turns a 3KHz square wave into a series of impulses at the point where the square wave changes direction.
(the high-pass filter is effectively differentiating the input signal, so the output is showing the rate of change of voltage over time. When the square wave goes high, this is a large change, so the output peaks, it then settles down and there is a second, opposite, peak as the square wave goes low again)
A 3KHz sine wave, which is more typical of what might come back from a tape, passes with reduced amplitude. (it is also appears shifted out of phase, as differentiating the sine wave gives a cosine)
The resulting waveform is fed to the input of a 74LS365 input buffer. When the ZX80 wants to read the tape (and / or the keyboard as they use the same chip), the /Port Read signal goes low and the value read is transferred to bit 7 of the Z80 databus.
This is the schematic from the Minstrel 2, which uses the same circuit. The jack there is stereo, so the tip is wired for signal and the sleeve is wired to ground. The ring is not connected, so you can use either stereo or mono plugs. Stereo will only listen to the right channel. The ZX80 original was a mono socket, so if you plugged in a stereo jack, it would short the left channel to ground.
The 74LS365 has standard TTL level inputs.
The threshold between logic 0 and logic 1 is 1.5V, but a signal should be below 0.8V to be counted as a logic 0, and above 2V to be counted as a logic 1. Voltages in between should be avoided as they are not guaranteed either way, and it depends on the particular chip and various other factors such as supply voltage, temperature, output loading, what colour T-shirt you are wearing etc.
The output of the RC input filter varies a lot depending on the shape and amplitude of the input source, which is why it is often necessary to fiddle with the volume control to get it to load properly. If it is too low, it will not get cleanly into the logic 1 area. Too high, and not all the low points will be low enough to count as logic 0.
If you are feeding the ZX80 a 1V peak-peak sine wave, the signal level at the input to the buffer is going to be barely 300mV, solidly in the logic 0 region.
Even with the 5V peak to peak since wave, the output wave tops out at about 1.4V, clear of logic 0, but not high enough to be safely read as a logic 1.
It was only the 5V square wave that actually got comfortably into the logic 1 area, hitting about 3.5V.
Data Generator
I have been testing this in CircuitLabs (#NotSponsored), and have found that very useful to see what is going on with the various filter designs I have been looking it, and seeing how changing the values of the components affects the output.
However, the input signals I have been using have been from the signal generator, so simple square waves and sine waves.
You might have noticed the output takes a short while to settle down at the start of the square wave, the time when the decoupling capacitor is changing. That can make a difference. The ZX80 has no leader tone, no headers, no blocks etc. The first pulse is the start of the first bytes. If it misses that, it gets the data wrong.
I was concerned it might miss the start of every train of pulses, so I built something a bit more representative.
There are limited building blocks available, there are no counters and the D-type flip-flops did not have the control signals I needed, so I used a bunch of T-type flip-flops. These are less common and will toggle the output on clock pulses only when the T input is high.
The 1's in circles represent a fixed logic 1, so the four flip-flops will always toggle and form a ripple counter. When it gets to 8, it turns the T output of the final flip-flop on, counts 8 more and turns it off again, and then repeats.
This lets the final flip-flop toggle for 8 cycles, then stays static for 8 cycles, giving a representation of the 4 pulses which represent a zero to the ZX80.
When put through the ZX80 input filter, you can see the train of impulses reacting a little differently each bit, but all within range.
I thought I should extend that and look at the ZX80 signal for a 1, which is 9 pulses. I took the easier option and went for 8 pulses.
I added an extra stage and a switch to select between counting up to 16 each cycle or 32.
I extended the sample time to 10ms to see a second set of 8.
So that is the ZX80. It works as long as you have a strong enough, and square enough, input signal.
ZX81 Tape Input
The ZX81 input stage has been shuffled around and the values changed.
The output goes into the black box which is the ULA. The same pin is the tape input, tape output and TV output, quite impressive.
I don't know how that magic pin is setup, so I don't know how it is biased, what there is in the way of pull-ups and pull-downs, so it is difficult to know how to analyse it.
If it were an ideal input, the signal would be AC coupled, and pass through with no attenuation.
If it was pretty much shorted to ground (at least in AC terms), C10 and R2 would form another high-pass filter, here the numbers work out the same (1 x 47 = 4.7 x 10), so would form the same 3.4KHz high-pass filter as the ZX80.
The ZX81 will have similar requirements for the input signal as the ZX80.
Jupiter Ace
The Ace input is again a different arrangement of two resistors and a capacitor.
I have reversed it and tidied up, but it's still not that clear, so here it is redrawn in CircuitLabs.
Here the 1KΩ is a load resistor for the source, the 47nF capacitor AC couples the input and the 12KΩ references this to ground.
The 47nF and 12KΩ also form a high-pass filter, this time only 280Hz, 12 times lower than the ZX80.
The Ace does not use the train of 3KHz pulses like the ZX80 and ZX81, instead it has 1KHz and 2KHz pulses for 0 and 1.
I adapted my data generator circuit to produce 2KHz and 1KHz signals.
Here I have made a multiplexor out of logic gates. For 16 cycles, the Q output on the bottom flip-flop is low, so the top AND gate output is low. The /Q output is high, so the second AND gate passes the 2KHz clock to the OR gate which feeds that to the output via the OR gate.
For the next 16 cycles, that is reversed and the 1KHz signal is passed through.
That gives a reasonable approximation of the tape signal for testing.
A lot more of the signal is passed through now, with the lower cut-off frequency, so the output is regarded as logic 1 for the full width of the input pulses.
This is important as the Ace reads data based on the pulse width.
The ZX80 didn't care about the pulse widths, it is actually counting the time between the start of the trains of 4 or 9 pulses and a when the pulses stop.
Since the Minstrel 4th now has Ace, ZX80 and ZX81 ROMs, I would like it to be able to cope with both formats of data.
It seems happy enough to pass the ZX80/81 3KHz pulses, again high for the whole pulse width.
However, like those machines the Ace needs a strong signal.
With a 1V peak to peak signal, the output drops to less than the full pulse width, and even the high points are below 0.8V on the shorter pulses, so is never going to be read as a logic 1.
Minstrel 4th
On the first versions of the Minstrel 4th, I modified the input slightly, changing the 12KΩ pull-down for a pair of 10KΩ resistors biasing the input around 2.5V.
I then use a 74HC367 rather than the 74LS367 as would have originally been used.
The 74HC logic matched the rest of the board, but the thresholds were a little larger, needing to extend further above and below the 2.5V mark.
I changed the design for later boards, removing the 10KΩ pull-up and switching back to the 74LS367.
For the remaining boards, I instructed that a 74LS367 would be supplied and that R16 should not be fitted. I did consider changing the 10KΩ pull-down for 12KΩ to match the Ace, but it didn't seem to make any difference, so I left it at 10KΩ like all the rest.
Tape Inputs
This is all based on neat square waves being generated, in practice, it is in many and varied forms and levels.
I added a circuit to the data generator model to filter the signal a bit, to act like it had come from tape.
The ZX80 circuit does not fair too well based on that input.
The Ace looks to start OK, but only the decoupling takes effect, the level goes down to 0.6V.
Testing with real tapes gives similar result, although they all seem to be different.
I took thousands of photos, screenshots, scope caps and trace outputs during the few weeks I have been working on this.
They generally show the input waveform, an intermediate processing stage and the final recovered data.
I will probably use hardly any of them, but here are an assortment in no particular order of some of the signals I have read from tapes and attempted to process.
The number of times I must have typed load TUTTUT or LOAD "" ...
The voltage levels and time scale varies, these were parts of full scope captures like the one above, but I just wanted to show the input part, a mix of Ace and ZX81 tapes.
I have designed several different input circuits with varying degrees of success.
In the next post, I shall go through some of those and look at the one I have arrived at for the next batch of Minstrel 4th boards.
Adverts
My boss (that's me) won't let any of his staff (also me) have any time off. But since I am told it is a bank holiday weekend, why not have 10% off everything in my Tindie Store:
If you don't want to use Tindie, you can always contact me using the link at the top of the page and let me know what you want and which country you are in, and I will get you a price if you want to buy direct.
Patreon
If you enjoy posts like these, you can support me via Patreon, and get access to advance previews of blog posts (except when I am running behind, like today, sorry), and exclusive posts (like the update I just posted).
You also get progress updates on new projects and other behind the scenes updates, as well as access to my Patreon only Discord server for even more regular updates, and to discuss your own projects.
Patreon tells me you will all be rushing to join if I give you 50% off the first month, so I have:
(I hadn't realised both of those discounts would happen in the same week, but why not take advantage of my lack of planning and get both)