SBC-85 Cassette Tape Interface

Every retro system needs a good, reliable cassette interface to save and retrieve programs and the SBC-85 is no different.

Similar projects worth following
Starting from
ccandrews has 94 orders / 1reviews
Ships from United States of America
Of course we have all heard of, and many have probably used, the Tarbell and Kansas City cassette tape interfaces but there was also the Intel cassette tape interface. Intel was an advocate of the paper tape storage, obviously because teletypes were so prevalent in the industry, but in the early '70s they also came around to the idea of using cassette tape storage. Probably not the best cassette tape format but it was a good demonstration of the 8080 and 8085 hardware like the SDK-85 and a good addition to the SBC-85 ecosystem.

This project is a cassette tape interface for the SBC-85 to read and write tapes using this Intel Format.

NOTE: Much of this project, including the schematic and software, was lifted directly from the Intel MCS-85 user's manual.

The SBC-85 cassette tape interface has the default SBC-85 form factor and can use the SID and SOD lines off the backplane.  However, for most systems those lines are busy with the serial port onboard the CPU so there is also a connection using the standard SBC-85 I/O 26 pin header.  Unfortunately, this requires one input pin so, if using the 8155 I/O connector, it needs to occupy one bit of an input port and at least one bit of an output port.  There are three additional software controlled LEDs to give status to the user such as adjusting volume or whatever the programmer sees most suitable.

The nicest thing about the Intel interface in general, and this board in particular, is that they are bone simple.    Intel was all about reliability so they picked the simplest encoding scheme they could imagine that would be immune to all the crap a cassette player did to the information.  In the Intel scheme, they break each bit into three segments.  The first segment is always a tone burst, the last segment is always a pause (silence), and the middle segment held the data.  In practice, to receive data the interface simply waits for a tone burst to announcing the beginning of a bit, determine the value of the data bit, and then wait for the next tone burst.  Since each bit began with a tone and ended with a space, the bits were distinctly separated from one another making it easy to know when a bit started and ended no matter the tape speed.  The CPU itself was used to create the tone bursts during write (e.g., 2kHz bursts) and to decode the bits during read.  Decoding the bits is extremely simple, straightforward, and immune from most tape distortions.  Given that each bit started with a tone burst and ended with a space, given just those two the bit time would have a 50% duty cycle, i.e., one burst, one space.  So the data bit will either change the overall bit duty cycle up to 2/3 when the bit is 1, or down to 1/3 when the bit is a zero.  It does not take a very sophisticated decoding routine to separate a 33% duty cycle from a 66% duty cycle.  In practice, during receiving mode the software sets a counter to zero and then begins polling the input at a fixed rate during each bit.  If it polls a logic one it increments a counter.  If it polls a logic zero it decrements the counter.  At the end of the bit the count will be, ideally, be 33% of the total counts above zero or 33% of the counts below zero.  It is much easier to simply put zero as the deciding point so the sign of the counter shows if the bit was a one or a zero.

In the end, the code to write and read tape is straightforward and, so far, pretty robust.

Since the CPU is doing all the timing for data writing and all the discriminating for data reading, the circuit can be extremely simple.  The circuit is based around a quad op-amp with one op-amp serving as an output driver that buffers the signal from 0-5V logic to +/- 1V.  The input circuit is not much more complicated with one amp as the input buffer whose output is inverted by op-amp #3.  The natural and inverted signals are then summed using diodes and the integrated sum going to the fourth op-amp which is a  comparator to generate a TTL signal.  All totaled, the circuit takes one LM324 quad op amp, a dozen resistors, and a few capacitors.

  • SBC-85 Cassette Tape Interface Build Files Released

    Craig03/30/2020 at 00:59 0 comments

    If you head on over to the SBC-85 project website, the documentation and build files for the cassette tape interface are available.  Note that this interface is not limited to the SBC-85 project since the port to the computer is simple TTL and could be driven by any system.

    For the software, I will be uploading the current version of the SBC-85 Utilities that has functions for reading and writing to the tape as well as adding the leader.  In the SBC-85_Utility_Call_Examples.A85 file there are examples on how to write to a tape, read 100 bytes from the tape, and dump the received data to the terminal.

    Enjoy !

  • Planning for v2

    Craig03/17/2020 at 16:47 0 comments

    The first version of this cassette tape interface can either run off the SID and SOD lines on the SBC-85 backplane or it can use an I/O port header.  On most systems the SID/SOD are probably busy with the RS232 interface on the SBC board and the expansion port is inconvenient because it takes one bit out of two different ports (unless running off a 8755 with its bit defined port direction)

    So I am thinking that v2 will be stand alone and take its own I/O space.  I have not decided if this should be via an I/O chip like the 8255 PPI so there are additional ports available or if I should just create one port for the cassette interface and have this card dedicated just to the cassette.  No more work either way, but the 8255 is a little harder to find for most than just a 74xx latch.

    I have a few other things on the front burner now and it will be a month or so before I am submitting another board run so time to think about it.  Any suggestions would be appreciated.

  • Software-Check. Testing-Check. Reliability-Check. That's a wrap.

    Craig03/15/2020 at 21:21 0 comments

    Assemble....probe....tweak.....repeat pretty much sums up getting the details refined for this tape software.  Have it working reliably now after adding a couple of details that I hadn't thought about in the beginning.  First I added a really long (15s) burst leader to the tape output to give me time to get the tape started and into position and to give the player's automatic adjustment time to decide what it is going to do with this strange music it is hearing.  Then the leader finishes with an ASCII countdown from nine to zero as a data integrity check and then jumps right to the data.  As of right now I do not have any error checking on the data other than confirmation of the leader countdown.

    There are two software parameters:

    • Tone frequency of burst (I picked 2kHz)
    • Number of cycles in bit (I picked 5 cycles per 1/3 segment so 15 cycles per bit)

    These values give an output rate of 7.5ms per bit or 133 bits per second, a.k.a., 133 BAUD which is a little less than 900 bytes per minute of tape.  Not bad for a first try and there is still plenty of room to play with these two software parameters.  Standard Tarbell was about 10x that speed so there is a great deal of room for improvement.   I may take it up to at least an even 1kB per minute of tape if I feel the need for round numbers.  A lot of my old data tapes are 7.5 minute which will hold much more than the available RAM in the SBC-85.  I never liked putting multiple programs on one tape since I don't have a position counter on most of my players and I like the simplicity of one-tape-one-program.  One thing that I need to remember to do is to write on each tape the parameters I used until I settle on final values. Otherwise future me will have to go back to the logic probe to figure them out.

    After getting the basic tape output and tape input portion going, I started doing little features like controlling the board status LEDs and such.  The basics of those are done but adding features will probably continue as I am actually using the cassette interface to save and retrieve data for the SBC-85.

    Admittedly I used Tarbell standard back in the day and actually never used the Intel format before now.  One thing that has surprised me is the insensitivity to output volume on playback.  Once the volume is high enough for the integration RC into the last op-amp to maintain a logic one, additional volume comes with no penalty and the circuit seems to be completely immune to clipping or saturation.  As a result, I have been running with the output volume pegged on max with no ill effect.  That is something that the Kansas City and Tarbell circuits always seemed to have difficulty since there was a volume sweet spot for playback.

    So, except for the documentation, I am calling this project done except for determining the maximum reliable data rate.  With some early playing around with this, it is apparent that too much modification of the output frequency will require an update to the values of the RC in the integrator.  If this doesn't drain quick enough there is a period of time where the logic at the end of a tone burst becomes indeterminate which can lead to false triggers of the next bit.  For now, I need to update the user's manual and include waveform captures for diagnostics.

  • Hardware Checks, Software Status

    Craig03/14/2020 at 21:04 0 comments

    The first task was to write the code to output the bursts and spaces.  30 or so lines of assembly code later and that is done. 

    Back to the hardware......Here is the schematic

    For the first test I simply looped the output directly back into the input and went through the various test points with the scope to see if the signals were as expected.  For the most part, the hardware worked as designed, one tweak on the resistor value R6 which is the threshold value used by comparator.  With a normal 0.6V drop across the two summing diodes D1 and D2, the summed signal (at TP3) was not quite high enough to trigger the comparator U1D to swing to the high rail.  In the end, I put in a 0-ohm for R6 so that the DC output of U1B and U1C is the same as the reference voltage for the comparator U1D.  That done, the signals started popping out the comparator and TP2 is getting nice rail-to-rail swings.  To better integrate the spikes at the summing point, R12 went up to 10K.  I think that I am going to call it on the hardware.  Something may pop up later, but things are good to move on.

    Here is what the output of an ASCII SPACE looks like with the output looped back to the input.  The top line is the output to the tape, middle line reference spikes, bottom line the signal at JP2, i.e., the end result after the output character is read back and integrated over the bursts. (To save you the trouble, a space is 0010 0000 which is why we used to always use it to auto-set the baud rate).  Timing spikes on one of the LEDs were added to help find the beginning of each character and data bytes are sent LSBit to MSBit.  While logic probes can fudge the voltage levels, on the scope the input to the CPU is a hard 0V to 3.8V.

    Immediately following the first marker the bit pattern is  0 0 0 0 0 1 0 0 0.  The trailing zero is used as the starting point for the data input routine.  After the 8-bits of data are received the input should be the tone burst of the 9th bit (trailing zero) and the code loops here until the end of the burst.  Much like one would wait watching for a start bit on a serial input.

    This afternoon's project is to write the data byte input code which is where I will pick up next time.

View all 4 project logs

Enjoy this project?



greenaum wrote 04/05/2020 at 20:34 point

Mate, you might want to look at how the Sinclair Spectrum did tapes. It was the fastest 8-bit tape loader / saver I'm aware of, could load 48K in about 4 minutes.

Basically it was header first, containing data about the data, then data.

It went

Tone burst, Header (about 1 second long, containing name, load address, etc)
pause for a second
tone burst, 4 minutes of data

Encoding was done by pulse length. Long pulse for 1, short for 0, say. Might be other way round, doesn't matter. The hardware was pretty much just a zero-crossing detector connected to the tape player. With that you can measure pulse length, and it doesn't matter if the pulses are inverted by the tape player, or smoothed out into rough sine waves.

All done in software. CPU reads the zero-crosser for the first edge, then starts counting. Upon recieving the next edge, it checks the count for long or short. Then carry on!

The tone burst helped give an idea of what sort of pulse length to expect, what with tape stretching and the like.

The Spectrum's ROM was famously disassembled in a book (The Complete Spectrum ROM Disassembly) which annotated all the functions. Might be a help, and will certainly reduce thumb-twiddling time. ONE BIT at a time!? Were Intel insane!? Well, looking at the 8086...

If you chose Intel's horrible slow format for historical reasons, fair enough, ignore this. It's just that Sinclair achieved the fastest, simplest, cheapest tape access in 1982 in software, and I like to spread that knowledge.

  Are you sure? yes | no

Craig wrote 04/05/2020 at 23:36 point

Good to know about the Sinclair and maybe something I will look into someday.  But for cassette my interest is in the various standards of the '70s.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates